Certificados SSL SNI e curinga no mesmo servidor com o IIS

12

Eu gostaria de hospedar um site que deve escutar subdomínios (por exemplo, sub.domínio.com) junto com vários sites que residem apenas em um domínio de segundo nível (por exemplo, domínio2.com, domínio3.com) com IIS e SSL.

Para o site com os subdomínios, tenho um certificado curinga (* .domínio.com) e também tenho certificados específicos para os outros sites (domínio2.com e domínio3.com).

Essa configuração pode ser hospedada no mesmo IIS (se isso importa, em uma função da Web do Serviço em Nuvem do Azure)?

A questão é exatamente o que titobf explicou aqui : teoricamente, para isso, precisaríamos de ligações usando SNI, com o host especificado para domain2 / 3.com e, em seguida, um site abrangente com * host para * .domínio.com. Mas, na prática, não importa como as ligações sejam configuradas, se o site abrangente estiver presente, ele também receberá todas as solicitações para domain2 / 3.com (embora supostamente seja correspondido apenas como último recurso).

Qualquer ajuda seria apreciada.

Ainda não resolvido

Infelizmente, não consegui resolver isso: parece ser solucionável apenas de maneiras extremamente complicadas, como a criação de um software que fica entre o IIS e a Internet (basicamente um firewall) e modifica as solicitações recebidas (antes que o handshake SSL ocorra! ) para permitir o cenário. Estou bastante confiante de que isso não é possível com o IIS, não importa o que seja, nem mesmo de um módulo nativo.

Preciso esclarecer: usamos os Serviços de Nuvem do Azure, por isso temos mais uma restrição de que não podemos usar vários endereços IP (consulte: http://feedback.azure.com/forums/169386-cloud-services-web-and -worker-role / sugestões / 1259311-vários-ssl-e-domínios-para-um-aplicativo ). Se você pode apontar vários IPs para o servidor, não há esse problema, pois você também pode criar ligações para IPs, e elas funcionarão juntas. Mais especificamente, você precisa de um IP para o site curinga (mas como você tem um IP separado agora, não precisará configurar uma ligação de nome de host curinga) e outro IP para todos os outros não curinga.

Na verdade, nossa solução alternativa foi o uso de uma porta SSL não padrão, 8443. Portanto, a ligação SNI está realmente vinculada a essa porta, portanto, funciona junto com as outras ligações. Não é legal, mas uma solução aceitável para nós até que você possa usar vários IPs para funções da web.

As ligações não úteis agora

A primeira ligação https é SNI com um certificado simples, a segunda não é SNI, com um certificado curinga.

O site http funciona, bem como o site SNI https, mas aquele com a ligação curinga fornece um "Erro HTTP 503. O serviço está indisponível". (sem mais informações, não há rastreamento de solicitação com falha ou entrada no log de eventos). Ligações

Finalmente fazendo com que funcione basicamente

A ativação do log de rastreamento ETW como Tobias descrito mostrou que o erro raiz era o seguinte:

Solicitação (ID da solicitação 0xF500000080000008) rejeitada devido ao motivo: UrlGroupLookupFailed.

Pelo que entendi, isso significa que o http.sys não pode rotear a solicitação para nenhum terminal disponível.

A verificação dos pontos de extremidade registrados com netsh http show urlaclmostrou que realmente havia algo registrado para a porta 443:

Reserved URL            : https://IP:443/
    User: NT AUTHORITY\NETWORK SERVICE
        Listen: Yes
        Delegate: No
        SDDL: D:(A;;GX;;;NS)

Removendo isso com netsh http delete urlacl url=https://IP:443/finalmente ativado minha ligação SSL.

Piedone
fonte
Você absolutamente deve conseguir fazer isso no IIS usando SNI, sem recorrer a vários IPs ou portas não padrão.
Joe Sniderman 14/09
Você quer dizer que o IIS deve suportar isso? Concordo :-).
Piedone
Eu concordo totalmente com você, Piedone. Estou realmente decepcionado que o IIS (ou, mais precisamente, http.sys) NÃO suporta a combinação de um certificado curinga como um certificado SSL padrão e vários certificados concretos com o SNI COMO ESPERADO. O problema é bem conhecido desde 2012, como você pode ver aqui: forums.iis.net/t/1192170.aspx . Acabei de escrever um email para a Microsoft e espero receber feedback em breve.
Tobias J.
Obrigado Tobias. Volte aqui quando a Microsoft responder.
Piedone
2
Provavelmente o http.sys está recusando a solicitação, portanto nenhuma Solicitação com Falha é registrada no IIS. Crie um log de rastreamento ETW http.sys: 1) inicie o log de rastreamento. execute: logman start httptrace -p Microsoft-Windows-HttpService 0xFFFF -o httptrace.etl -ets2) faça a solicitação 503 3) pare o log de rastreamento. execute: logman stop httptrace -ets4) grave o log de rastreamento no arquivo. run: tracerpt.exe httptrace.etl -of XML -o httptrace.xml5) verifique o motivo do 503 no arquivo xml e poste-o aqui.
Tobias J.

Respostas:

6

Baris está certo! O certificado SSL configurado em uma ligação IP: PORT (exemplo: 100.74.156.187:443) sempre tem precedência no http.sys! Portanto, a solução é a seguinte:

Não configure uma ligação IP: 443 para seu certificado curinga-fallback, mas configure uma ligação *: 443 (* significa "All Unassigned") para ela .

Se você configurou seu certificado curinga no ponto de extremidade do SSL Cloud Service (como eu), altere a ligação SSL criada pelo Azure Cloud Service Runtime (IISconfigurator.exe) de IP: PORT para *: PORT. Estou chamando o seguinte método no OnStart da minha função da web:

public static void UnbindDefaultSslBindingFromIp()
{
    Trace.TraceInformation(">> IISTenantManager: Unbind default SSL binding from IP");
    using (var serverManager = new Microsoft.Web.Administration.ServerManager())
    {
        try
        {
            var websiteName = string.Format("{0}_Web", Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance.Id);
            var site = serverManager.Sites[websiteName];
            var defaultSslBinding = site.Bindings.Single(b => b.IsIPPortHostBinding && b.Protocol == "https");
            defaultSslBinding.BindingInformation = string.Format("*:{0}:", defaultSslBinding.EndPoint.Port);
            serverManager.CommitChanges();
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }
    }
}

A captura de tela a seguir mostra uma configuração funcional do nosso serviço em nuvem. Por favor, não fique confuso sobre as portas não padrão. A captura de tela é do serviço de nuvem emulada.

configuração do IIS funcionando

Mais uma coisa a mencionar: não altere todas as ligações para * porque a ligação HTTP (porta 80) funciona apenas com a ligação IP: PORT no serviço de nuvem implementado. Outra coisa está ligada ao IP: 80, portanto *: 80 não funciona porque * significa "todos não atribuídos" e o IP já está atribuído em outro lugar no http.sys.

Tobias J.
fonte
Obrigado pela sua resposta detalhada. Atualizei minha pergunta: como me lembro agora, provavelmente não fui com essa configuração porque recebi o mesmo erro que agora.
Piedone
4

Verifique se a ligação abrangente não é do tipo IP: Port. Quando existe uma ligação IP: Port para uma ligação HTTPS enquanto o SNI não é necessário, essa ligação sempre terá precedência. Para o seu caso abrangente, use uma ligação *: Port (* sendo todos os não atribuídos).

bariscaglar
fonte
Obrigado, mas como você pode ver na minha descrição, inicialmente tentei configurar a ligação SNI sem porta, mas como isso não funcionou, terminei com uma ligação de porta personalizada.
Piedone 30/10
Por porta, entendo que você quer dizer o IP. Você não pode ter uma ligação sem uma porta. O Inetmgr não permitirá isso. Para as ligações SNI, você pode usar o IP específico ou "All Unassigned" e o resultado será o mesmo. É a ligação Catch All, para a qual você tem um certificado curinga, que precisa estar em "All Unassigned" e não em um IP específico.
Bariscaglar #
Eu quis dizer porta, mas eu queria dizer "porta não padrão". O IP não foi especificado, como você diz e ainda não funciona, veja também o link do Tobias. Há duas maneiras de contornar essa limitação do IIS: use uma porta personalizada ou um IP diferente das outras ligações: nos serviços de nuvem do Azure, o último não está disponível, portanto, optamos por uma porta personalizada.
Piedone 30/10
bariscaglar é o desenvolvedor da Microsoft (trabalhando no IIS) com quem tive uma conversa muito agradável e útil! Thx Baris! Juntos, analisamos o comportamento e chegamos à conclusão de que o comportamento descrito é o comportamento desejado do http.sys. Mas há uma boa solução alternativa. Veja minha resposta para detalhes.
Tobias J.
Apenas uma observação para quem estiver lendo, descobri recentemente que, se você usar o Portal do Azure para configurar um serviço para a Área de Trabalho Remota (ou alterar a configuração do certificado), poderá causar uma ligação IP: Porta a ser criada automaticamente e interromper todo o seu SNI . Não tenho uma solução para esse problema em particular. Isso acontece depois de RoleEnvironment.Changed, então não consigo pegá-lo no WebRole.cs.
Mike
1

O IIS oferece suporte ao SNI, mesmo em funções da web de serviço de nuvem azul, embora você não possa acessar a configuração pelo portal e, se o fizer na caixa após a implantação, ele será apagado na sua próxima implantação. A solução é automatizar a configuração. Dê uma olhada aqui para mais detalhes:

http://www.vic.ms/microsoft/windows-azure/multiples-ssl-certificates-on-windows-azure-cloud-services/

CamW
fonte
Obrigado, mas como expliquei, não há problema com o próprio SNI (estou usando), mas como a correspondência de nome de host curinga funciona no IIS.
Piedone
Este artigo não existe mais, mas aqui está no arquivo da Web: web.archive.org/web/20151020041907/http://www.vic.ms/microsoft/…
Mike