web-dev-qa-db-fra.com

Plusieurs domaines SSL sur la même adresse IP et le même port?

Il s'agit d'une Question canonique sur l'hébergement de plusieurs sites Web SSL sur la même IP.

J'avais l'impression que chaque certificat SSL exigeait sa propre combinaison unique d'adresse IP/port. Mais le réponse à une question précédente que j'ai postée est en contradiction avec cette affirmation.

En utilisant les informations de cette question, j'ai pu obtenir plusieurs certificats SSL pour travailler sur la même adresse IP et sur le port 443. Je suis très confus quant à la raison pour laquelle cela fonctionne étant donné l'hypothèse ci-dessus et renforcée par d'autres que chaque site Web de domaine SSL sur le le même serveur nécessite son propre IP/port.

Je soupçonne que j'ai fait quelque chose de mal. Plusieurs certificats SSL peuvent-ils être utilisés de cette façon?

109
John

Pour les informations les plus à jour sur Apache et SNI, y compris les RFC supplémentaires spécifiques à HTTP, veuillez vous référer au Apache Wiki


FYsI: "Plusieurs (différents) certificats SSL sur une IP" vous est présenté par la magie de la mise à niveau TLS. Il fonctionne avec les nouveaux serveurs Apache (2.2.x) et les navigateurs raisonnablement récents (je ne connais pas les versions du haut de ma tête).

RFC 2817 (mise à niveau vers TLS dans HTTP/1.1) a les détails sanglants, mais en gros cela fonctionne pour beaucoup de gens (sinon la majorité).
Vous pouvez reproduire l'ancien comportement funky avec _ s_client commande (ou tout autre navigateur "assez ancien").

Modifier pour ajouter: apparemment, curl peut vous montrer ce qui se passe ici mieux que 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.
68
voretaq7

Oui, mais il y a quelques mises en garde.

Ceci est accompli grâce à Server Name Indication, une extension de Transport Layer Security.

Qu'est-ce que l'indication du nom du serveur?

Indication du nom du serveur ( RFC 6066 ; obsolète RFC 4366 , RFC 3546 ) est une extension de Transport Layer Security qui permet au client d'indiquer au serveur le nom de l'hôte qu'il tente d'atteindre.

SNI est compatible avec TLS 1.0 et supérieur selon les spécifications, mais les implémentations peuvent varier (voir ci-dessous). Il ne peut pas être utilisé avec SSL, donc une connexion doit négocier TLS (voir RFC 4346 annexe E ) pour que SNI soit utilisé. Cela se produit généralement automatiquement avec les logiciels pris en charge.

Pourquoi SNI est-il nécessaire?

Dans une connexion normale [[# # ~] http [~ # ~] , le navigateur informe le serveur du nom d'hôte du serveur qu'il tente d'atteindre en utilisant le Host: entête. Cela permet à un serveur Web sur une seule adresse IP de servir du contenu pour plusieurs noms d'hôte, ce qui est communément appelé hébergement virtuel basé sur le nom .

L'alternative consiste à attribuer des adresses IP uniques pour chaque nom d'hôte Web à servir. Cela a été généralement fait dans les tout premiers jours du Web, avant qu'il ne soit largement connu que les adresses IP s'épuiseraient et que les mesures de conservation commenceraient, et c'est toujours le cas pour les hôtes virtuels SSL (n'utilisant pas SNI).

Étant donné que cette méthode de transmission du nom d'hôte nécessite que la connexion soit déjà établie, elle ne fonctionne pas avec les connexions SSL/TLS. Au moment où la connexion sécurisée est établie, le serveur Web doit déjà savoir quel nom d'hôte il va servir au client, car le serveur Web lui-même établit la connexion sécurisée.

SNI résout ce problème en demandant au client de transmettre le nom d'hôte dans le cadre de la négociation TLS, afin que le serveur sache déjà quel hôte virtuel doit être utilisé pour entretenir la connexion. Le serveur peut ensuite utiliser le certificat et la configuration pour l'hôte virtuel correct.

Pourquoi ne pas utiliser des adresses IP différentes?

Le HTTP Host: l'en-tête a été défini pour permettre à plusieurs hôtes Web d'être servis à partir d'une seule adresse IP en raison du manque d'adresses IPv4, reconnu comme un problème dès le milieu des années 90. Dans les environnements d'hébergement Web partagé, des centaines de sites Web uniques et non liés peuvent être servis en utilisant une seule adresse IP de cette façon, en préservant l'espace d'adressage.

Les environnements d'hébergement partagé ont ensuite constaté que le plus grand consommateur d'espace d'adressage IP était la nécessité pour les sites Web sécurisés d'avoir des adresses IP uniques, créant le besoin de SNI comme mesure provisoire sur la voie de l'IPv6. Aujourd'hui, il est parfois difficile d'obtenir aussi peu que 5 adresses IP (/ 29) sans justification significative, ce qui entraîne souvent des retards de déploiement.

Avec l'avènement d'IPv6, de telles techniques de conservation d'adresses ne sont plus nécessaires, car un seul hôte peut avoir plus d'adresses IPv6 qui lui sont attribuées que n'en contient tout Internet aujourd'hui, mais les techniques seront probablement encore utilisées très loin dans le futur pour entretenir l'IPv4 hérité. Connexions.

Avertissements

Certaines combinaisons de système d'exploitation/navigateur ne prennent pas en charge SNI (voir ci-dessous), donc l'utilisation de SNI n'est pas appropriée dans toutes les situations. Les sites ciblant de telles combinaisons système/navigateur devraient renoncer à SNI et continuer à utiliser des adresses IP uniques pour chaque hôte virtuel.

Il convient de noter en particulier qu'aucune version d'Internet Explorer sur Windows XP prend en charge SNI. Comme cette combinaison représente toujours une portion importante (mais en constante diminution; environ 16% du trafic Internet en décembre 2012 selon NetMarketShare)) du trafic Internet, SNI serait inapproprié pour un site ciblant ces populations d'utilisateurs.

Soutien

De nombreux progiciels, mais pas tous, couramment utilisés prennent en charge SNI.

(L'omission de cette liste ne signifie pas nécessairement un manque de support; cela signifie qu'il y avait une limite à la quantité que je pouvais taper, ou je ne pouvais pas trouver rapidement les informations dans une recherche. Si votre progiciel n'est pas répertorié, la recherche pour son nom plus sni devrait révéler si le support existe et comment le configurer.)

Prise en charge de la bibliothèque

La plupart des packages dépendent d'une bibliothèque externe pour fournir une prise en charge SSL/TLS.

  • GNU TLS
  • JSSE (Oracle Java) 7 ou supérieur, niquement en tant que client
  • libcurl 7.18.1 ou supérieur
  • NSS 3.1.1 ou supérieur
  • OpenSSL 0.9.8j ou supérieur
    • OpenSSL 0.9.8f ou supérieur, avec indicateurs de configuration
  • Qt 4.8 ou supérieur

Support serveur

La plupart des versions actuelles des logiciels de serveur populaires prennent en charge SNI. Des instructions d'installation sont disponibles pour la plupart d'entre elles:

Support client

La plupart des navigateurs Web et agents utilisateurs en ligne de commande prennent en charge SNI.

Bureau

  • Chrome 5 ou supérieur
    • Chrome 6 ou supérieur sur Windows XP
  • Firefox 2 ou supérieur
  • Internet Explorer 7 ou supérieur, fonctionnant sous Windows Vista/Server 2008 ou supérieur
    • Internet Explorer sur Windows XP ne prend pas en charge SNI quelle que soit la version IE version
  • Konqueror 4.7 ou supérieur
  • Opera 8 ou supérieur (peut nécessiter que TLS 1.1 soit activé pour fonctionner)
  • Safari 3.0 sur Windows Vista/Server 2008 ou supérieur, ou Mac OS X 10.5.6 ou supérieur

Mobile

  • Navigateur Android sur 3.0 Honeycomb ou supérieur
  • iOS Safari sur iOS 4 ou supérieur
  • Windows Phone 7 ou supérieur

Ligne de commande

  • cURL 7.18.1 ou supérieur
  • wget 1.14 ou supérieur (les distributions peuvent avoir rétroporté un patch pour le support SNI)

Pas de support

  • Navigateur BlackBerry
  • Internet Explorer (toute version) sur Windows XP

(Remarque: certaines informations pour cette réponse ont été obtenues auprès de Wikipedia .)

97
Michael Hampton

Le problème:

Lorsqu'un client Web et un serveur Web se parlent via HTTPS, la toute première chose qui doit se produire est la prise de contact sécurisée.

Voici un exemple simplifié d'une telle poignée de main:

tls handshake

S'il s'agissait de HTTP et non de HTTPS, la première chose que le client aurait envoyée aurait été quelque chose comme ceci:

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

Cela a rendu possible plusieurs hôtes virtuels sur une seule adresse IP, car le serveur sait exactement à quel domaine le client veut accéder, à savoir example.com.

HTTPS est différent. Comme je l'ai dit plus tôt, la poignée de main passe avant tout le reste. Si vous regardez la troisième étape de la prise de contact illustrée ci-dessus (certificat), le serveur doit présenter un certificat au client dans le cadre de la prise de contact, mais n'a aucune idée du nom de domaine auquel le client tente d'accéder. La seule option dont dispose le serveur est d'envoyer à chaque fois le même certificat, son certificat par défaut.

Vous pouvez toujours configurer des hôtes virtuels sur votre serveur Web, mais le serveur enverra toujours le même certificat à chaque client. Si vous essayez d'héberger les sites Web example.com et example.org sur votre serveur, le serveur enverra toujours le certificat pour example.com lorsqu'un client demande une connexion HTTPS. Ainsi, lorsqu'un client demande example.org via une connexion HTTPS établie, cela se produit:

enter image description here

Ce problème limite efficacement le nombre de domaines que vous pouvez serveur via HTTPS à un par adresse IP.

La solution:

Le moyen le plus simple de résoudre ce problème est que le client indique au serveur à quel domaine il souhaite accéder pendant la prise de contact. De cette façon, le serveur peut servir le bon certificat.

C'est exactement ce que fait SNI , ou l'indication du nom du serveur.

Avec SNI, le client envoie le nom du serveur auquel il veut accéder dans le cadre du premier message, l'étape "Client Hello" dans le diagramme de prise de contact ci-dessus.

Certains navigateurs Web plus anciens ne prennent pas en charge SNI. Par exemple, sur Windows XP il il n'y a pas une seule version d'Internet Explorer qui prend en charge SNI. Lors de l'accès à une ressource via HTTPS sur un serveur qui utilise des hôtes virtuels SNI, un certificat générique vous sera présenté, ce qui peut entraîner un avertissement ou une erreur du navigateur.

enter image description here

J'ai simplifié les choses ici pour simplement expliquer le principe derrière le problème et la solution. Si vous souhaitez une explication plus technique, la page wikipedia ou RFC 6066 peut servir de bon point de départ. Vous pouvez également trouver une liste à jour des serveurs et des navigateurs qui prennent en charge SNI sur wikipedia

37
Kenny Rasschaert

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

Le navigateur client doit également prendre en charge SNI. Voici quelques navigateurs qui le font:

* 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 
16
Craig

L'extension TLS d'indication de nom de serveur (RFC6066) est requise pour que les hôtes virtuels basés sur le nom fonctionnent sur HTTPS.

L'extension est largement implémentée et je n'ai pas encore rencontré de problème avec le logiciel actuel, mais il est possible que certains clients (ceux qui ne la prennent pas en charge) soient routés vers votre site par défaut si vous dépendez de SNI.

6
Falcon Momot