Vários domínios SSL no mesmo endereço IP e na mesma porta?

109

Esta é uma pergunta canônica sobre a hospedagem de vários sites SSL no mesmo IP.

Fiquei com a impressão de que cada certificado SSL exigia uma combinação única de endereço IP / porta. Mas a resposta a uma pergunta anterior que eu postei está em desacordo com essa reivindicação.

Usando as informações dessa pergunta, consegui que vários certificados SSL funcionassem no mesmo endereço IP e na porta 443. Estou muito confuso sobre o motivo pelo qual isso funciona, dada a suposição acima e reforçada por outros que cada site de domínio SSL no site mesmo servidor requer seu próprio IP / porta.

Suspeito de ter feito algo errado. Vários certificados SSL podem ser usados ​​dessa maneira?

John
fonte
Esse corpo Q diz vários certificados e as respostas estão corretas para isso. Mas o título diz vários domínios e você pode ter vários domínios com um certificado (e nenhum SNI); consulte serverfault.com/questions/126072/… e serverfault.com/questions/279722/… também se destacam no security.SX.
David_thompson_085

Respostas:

68

Para obter as informações mais atualizadas sobre Apache e SNI, incluindo RFCs específicas para HTTP adicionais, consulte o Wiki do Apache


FYsI: "Vários certificados SSL (diferentes) em um IP" são trazidos a você pela mágica da atualização do TLS. Funciona com servidores Apache mais recentes (2.2.x) e navegadores razoavelmente recentes (não sei as versões em cima da minha cabeça).

O RFC 2817 (atualizando para TLS dentro do HTTP / 1.1) tem os detalhes sangrentos, mas basicamente funciona para muitas pessoas (se não a maioria).
Você pode reproduzir o antigo comportamento desagradável com o s_clientcomando openssl (ou qualquer navegador "com idade suficiente").

Edite para adicionar: aparentemente curl, você pode mostrar o que está acontecendo aqui melhor do que o openssl:


SSLv3

mikeg@flexo% curl -v -v -v -3 https://www.yummyskin.com
* About to connect() to www.yummyskin.com port 443 (#0)
*   Trying 69.164.214.79... connected
* Connected to www.yummyskin.com (69.164.214.79) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: serialNumber=wq8O9mhOSp9fY9JcmaJUrFNWWrANURzJ; C=CA; 
              O=staging.bossystem.org; OU=GT07932874;
              OU=See www.rapidssl.com/resources/cps (c)10;
              OU=Domain Control Validated - RapidSSL(R);
              CN=staging.bossystem.org
*    start date: 2010-02-03 18:53:53 GMT
*    expire date: 2011-02-06 13:21:08 GMT
* SSL: certificate subject name 'staging.bossystem.org'
       does not match target host name 'www.yummyskin.com'
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
curl: (51) SSL: certificate subject name 'staging.bossystem.org'
does not match target host name 'www.yummyskin.com'

TLSv1

mikeg@flexo% curl -v -v -v -1 https://www.yummyskin.com
* About to connect() to www.yummyskin.com port 443 (#0)
*   Trying 69.164.214.79... connected
* Connected to www.yummyskin.com (69.164.214.79) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: C=CA; O=www.yummyskin.com; OU=GT13670640;
              OU=See www.rapidssl.com/resources/cps (c)09;
              OU=Domain Control Validated - RapidSSL(R);
              CN=www.yummyskin.com
*    start date: 2009-04-24 15:48:15 GMT
*    expire date: 2010-04-25 15:48:15 GMT
*    common name: www.yummyskin.com (matched)
*    issuer: C=US; O=Equifax Secure Inc.; CN=Equifax Secure Global eBusiness CA-1
*    SSL certificate verify ok.
voretaq7
fonte
2
Isso é muito útil - Obrigado! Alguma informação sobre como configurar o Apache para TLS em vez de SSL?
Josh
2
Eu acho que o Apache 2.2 só precisa ter os bits TLS ativados em sua lista de códigos. Admito que nunca vi o bit "Atualizando do SSL para TLS" em ação até esses dois sites. Meu entendimento dos docs TLS é que é uma situação permitida (mas incomum) para negociar este tipo de atualização ...
voretaq7
Esta é a primeira vez que eu já vi ele quer e eu ainda estou tentando puxar meu queixo do chão ...
Josh
1
OK, minha resposta apenas triplicou - aparentemente, o curl pode fazer as negociações SSLv3 e TLSv1, para que eu possa mostrar a falha e o sucesso. Eu gostaria de ter um depurador de protocolo à mão para mostrar a parte mágica. (Também testado e feliz de informar servidor que de johnlai2004 nega corretamente conexões SSLv2 :-)
voretaq7
Isso é extremamente útil e espero que johnlai2004 aceite sua resposta. Muito obrigado!
217 Josh Josh
97

Sim, mas existem algumas ressalvas.

Isso é feito através da Indicação de nome do servidor, uma extensão do Transport Layer Security.

O que é indicação de nome de servidor?

A indicação de nome de servidor ( RFC 6066 ; obsoleta RFC 4366 , RFC 3546 ) é uma extensão do Transport Layer Security que permite ao cliente informar ao servidor o nome do host que está tentando acessar.

O SNI é compatível com o TLS 1.0 e superior, de acordo com as especificações, mas as implementações podem variar (veja abaixo). Ele não pode ser usado com SSL, portanto, uma conexão deve negociar o TLS (consulte o RFC 4346 apêndice E ) para que o SNI seja usado. Isso geralmente acontece automaticamente com o software suportado.

Por que o SNI é necessário?

Em uma conexão HTTP normal , o navegador informa ao servidor o nome do host do servidor que está tentando acessar usando o Host:cabeçalho. Isso permite que um servidor da Web em um único endereço IP sirva conteúdo para vários nomes de host, geralmente conhecidos como hospedagem virtual baseada em nome .

A alternativa é atribuir endereços IP exclusivos para cada nome de host da web a ser exibido. Isso era comum nos primeiros dias da Web, antes de ser amplamente conhecido que os endereços IP acabavam e as medidas de conservação começavam, e ainda é feito dessa maneira para hosts virtuais SSL (não usando SNI).

Como esse método de transmissão do nome do host exige que a conexão já esteja estabelecida, ele não funciona com conexões SSL / TLS. No momento em que a conexão segura é configurada, o servidor da Web já deve saber qual nome de host será veiculado no cliente, porque o próprio servidor da Web está configurando a conexão segura.

A SNI resolve esse problema fazendo com que o cliente transmita o nome do host como parte da negociação TLS, para que o servidor já esteja ciente de qual host virtual deve ser usado para atender à conexão. O servidor pode então usar o certificado e a configuração para o host virtual correto.

Por que não usar endereços IP diferentes?

O Host:cabeçalho HTTP foi definido para permitir a exibição de mais de um host da Web a partir de um único endereço IP devido à falta de endereços IPv4, reconhecidos como um problema desde meados da década de 90. Em ambientes de hospedagem compartilhada, centenas de sites exclusivos e não relacionados podem ser exibidos usando um único endereço IP dessa maneira, economizando espaço de endereço.

Os ambientes de hospedagem compartilhada descobriram que o maior consumidor de espaço de endereço IP era a necessidade de sites seguros terem endereços IP exclusivos, criando a necessidade de SNI como uma medida de interrupção no caminho para o IPv6. Hoje, às vezes, é difícil obter até 5 endereços IP (/ 29) sem justificativa significativa, geralmente resultando em atrasos na implantação.

Com o advento do IPv6, essas técnicas de conservação de endereço não são mais necessárias, pois um único host pode ter mais endereços IPv6 atribuídos a ele do que toda a Internet contém hoje, mas as técnicas provavelmente ainda serão usadas no futuro para atender ao IPv4 legado. conexões.

Ressalvas

Algumas combinações de sistema operacional / navegador não suportam SNI (veja abaixo), portanto, o uso de SNI não é apropriado para todas as situações. Os sites direcionados a essas combinações de sistema / navegador teriam que renunciar ao SNI e continuar usando endereços IP exclusivos para cada host virtual.

Vale ressaltar que nenhuma versão do Internet Explorer no Windows XP suporta SNI. Como essa combinação ainda representa uma parte significativa (mas em constante redução; cerca de 16% do tráfego da Internet em dezembro de 2012, de acordo com o NetMarketShare) do tráfego da Internet, o SNI seria inadequado para um site direcionado a essas populações de usuários.

Apoio, suporte

Muitos, mas não todos, pacotes de software comumente usados ​​suportam SNI.

(A omissão nesta lista não significa necessariamente falta de suporte; significa que havia um limite para o quanto eu poderia digitar ou não consegui encontrar rapidamente as informações em uma pesquisa. Se o seu pacote de software não estiver listado, procure pelo nome plus snideve revelar se existe suporte e como configurá-lo.)

Suporte da Biblioteca

A maioria dos pacotes depende de uma biblioteca externa para fornecer suporte a SSL / TLS.

  • GNU TLS
  • JSSE (Oracle Java) 7 ou superior, apenas como um cliente
  • libcurl 7.18.1 ou superior
  • NSS 3.1.1 ou superior
  • OpenSSL 0.9.8j ou superior
    • OpenSSL 0.9.8f ou superior, com sinalizadores de configuração
  • Qt 4.8 ou superior

Suporte ao servidor

As versões mais recentes do popular software de servidor suportam SNI. As instruções de configuração estão disponíveis para a maioria destes:

Suporte ao Cliente

Os navegadores da Web mais atuais e os agentes de usuário da linha de comando suportam SNI.

Área de Trabalho

  • Chrome 5 ou superior
    • Chrome 6 ou superior no Windows XP
  • Firefox 2 ou superior
  • Internet Explorer 7 ou superior, executando no Windows Vista / Server 2008 ou superior
    • O Internet Explorer no Windows XP não suporta SNI, independentemente da versão do IE
  • Konqueror 4.7 ou superior
  • Opera 8 ou superior (pode exigir que o TLS 1.1 esteja ativado para funcionar)
  • Safari 3.0 no Windows Vista / Server 2008 ou superior, ou Mac OS X 10.5.6 ou superior

Móvel

  • Navegador Android em 3.0 Honeycomb ou superior
  • iOS Safari no iOS 4 ou superior
  • Windows Phone 7 ou superior

Linha de comando

  • cURL 7.18.1 ou superior
  • wget 1.14 ou superior (as distribuições podem ter suportado um patch para suporte SNI)

Sem suporte

  • Navegador BlackBerry
  • Internet Explorer (qualquer versão) no Windows XP

(Nota: algumas informações para esta resposta foram obtidas na Wikipedia .)

Michael Hampton
fonte
1
Muito melhor :-) Espero que isso possa ter uma pontuação mais alta do que a atualmente aceita, que, além da última edição no topo, está incorreta, infelizmente.
de Bruno
1
@ Bruno, certamente não vou reclamar se você encontrar algumas centenas de pessoas para aprová-lo. :)
Michael Hampton
O BlackBerry Browser mais recente (10?) Usa uma versão recente do WebKit, por isso é muito provável que ele suporte SNI agora.
precisa saber é o seguinte
37

O problema:

Quando um cliente da Web e um servidor da Web conversam sobre HTTPS, a primeira coisa que precisa acontecer é o handshake seguro.

Aqui está um exemplo simplificado de um aperto de mão:

tls aperto de mão

Se fosse HTTP e não HTTPS, a primeira coisa que o cliente teria enviado seria algo como isto:

GET /index.html HTTP/1.1
Host: example.com

Isso possibilitou vários hosts virtuais em um único endereço IP, pois o servidor sabe exatamente qual domínio o cliente deseja acessar, como example.com.

HTTPS é diferente. Como eu disse anteriormente, o aperto de mão vem antes de tudo. Se você observar a terceira etapa do handshake ilustrada acima (Certificado), o servidor precisará apresentar um certificado ao cliente como parte do handshake, mas não tem idéia do nome de domínio que o cliente está tentando acessar. A única opção que o servidor tem é enviar o mesmo certificado todas as vezes, seu certificado padrão.

Você ainda pode configurar hosts virtuais no servidor da Web, mas o servidor sempre envia o mesmo certificado para cada cliente. Se você tentasse hospedar os sites example.com e example.org em seu servidor, o servidor sempre enviaria o certificado para example.com quando um cliente solicitasse uma conexão HTTPS. Portanto, quando um cliente solicita o example.org por uma conexão HTTPS estabelecida, isso acontece:

insira a descrição da imagem aqui

Esse problema limita efetivamente o número de domínios que você pode servidor através de HTTPS a um por endereço IP.

A solução:

A maneira mais fácil de resolver esse problema é o cliente informar ao servidor qual domínio ele deseja acessar durante o handshake . Dessa forma, o servidor pode fornecer o certificado correto.

É exatamente isso que o SNI , ou Server Name Indication, faz.

Com o SNI, o cliente envia o nome do servidor que deseja acessar como parte da primeira mensagem, a etapa "Client Hello" no diagrama de handshake acima.

Alguns navegadores mais antigos não suportam SNI. Por exemplo, no Windows XP, não existe uma única versão do Internet Explorer que suporte SNI. Ao acessar um recurso por HTTPS em um servidor que faz uso de hosts virtuais SNI, você receberá um certificado genérico, o que pode fazer com que o navegador exiba um aviso ou erro.

insira a descrição da imagem aqui

Simplifiquei as coisas aqui para apenas explicar o princípio por trás do problema e da solução. Se você quiser uma explicação mais técnica, a página da wikipedia ou a RFC 6066 podem servir como bons pontos de partida. Você também pode encontrar uma lista atualizada de servidores e navegadores compatíveis com SNI na wikipedia

Kenny Rasschaert
fonte
16

http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

O navegador do cliente também deve suportar SNI. Aqui estão alguns navegadores que fazem:

* Mozilla Firefox 2.0 or later
* Opera 8.0 or later (with TLS 1.1 enabled)
* Internet Explorer 7.0 or later (on Vista, not XP)
* Google Chrome
* Safari 3.2.1 on Mac OS X 10.5.6 
Craig
fonte
6

A extensão TLS de indicação de nome de servidor (RFC6066) é necessária para que vhosts baseados em nome funcionem em HTTPS.

A extensão está amplamente implementada e ainda não encontrei problemas com o software atual, mas há uma chance de que alguns clientes (aqueles que não o suportam) sejam roteados para o site padrão se você depende do SNI.

Falcon Momot
fonte
Além da resposta do Falcon, o IIS também exige algumas alterações especiais para fazer com que vários sites do IIS funcionem no mesmo IP. É necessário editar manualmente o arquivo de configuração do servidor ou usar uma ferramenta CLI para fazer as alterações de ligação, a ferramenta GUI não pode fazê-lo. No IIS, é chamado de atribuição de certificados SSL aos cabeçalhos do host. O Apache não tem esse problema há um tempo.
Brent Pabst
Ah, tudo bem, isso esclarece um pouco. Como você pode saber se um cliente (navegador) suporta isso? Por exemplo, se eu quiser verificar o MSIE6, como posso testá-lo sem precisar instalar uma máquina virtual XP ou algo assim?
Luc
1
O @Falcon SNI não funciona com o IE no XP; que ainda responde por quase um quarto dos usuários da Internet para desktop. Eu não chamaria isso de "amplamente implementado" quando um quarto dos visitantes em potencial não funciona.
Chris S
1
O @MichaelHampton IE usa a pilha de criptografia nativa do Windows para SSL. O XP não suporta SNI, portanto, qualquer versão do IE executando o XP também não. O IE suporta apenas SNI no Vista e em sistemas operacionais mais recentes.
Chris S