J'ai un x.example
Qui dessert le trafic à la fois a.example
Et b.example
. x.example
Possède des certificats pour a.example
Et b.example
. Le DNS pour a.example
Et b.example
N'est pas encore configuré.
Si j'ajoute une entrée /etc/hosts
Pour a.example
Pointant vers l'ip de x.example
Et que je lance curl -XGET https://a.example
, J'obtiens un 200.
Cependant, si je lance curl --header 'Host: a.example' https://x.example
, J'obtiens:
curl: (51) SSL: aucun autre nom de sujet de certificat ne correspond au nom d'hôte cible x.example
Je pense qu'il utiliserait a.example comme hôte. Peut-être que je ne comprends pas comment fonctionne SNI/TLS.
Parce que a.example
Est un en-tête HTTP, la prise de contact TLS n'y a pas encore accès? Mais l'URL à laquelle elle a accès?
En effet SNI dans TLS ne fonctionne pas comme ça. SNI, comme tout ce qui concerne TLS, se produit avant tout type de trafic HTTP, donc l'en-tête Host
n'est pas pris en compte à cette étape (mais sera utile plus tard pour que le serveur web sache quel hôte vous connectez aussi).
Donc, pour activer SNI, vous avez besoin d'un commutateur spécifique dans votre client HTTP pour lui dire d'envoyer l'extension TLS appropriée pendant la négociation avec la valeur de nom d'hôte dont vous avez besoin.
Dans le cas de curl
, vous avez besoin d'au moins la version 7.18.1 (basée sur https://curl.haxx.se/changes.html ), puis il semble utiliser automatiquement le valeur fournie dans l'en-tête Host
. Cela dépend également de la version d'OpenSSL (ou de la bibliothèque équivalente sur votre plateforme) à laquelle il est lié.
Voir le point 1.10 de https://curl.haxx.se/docs/knownbugs.html qui parle d'un bogue mais explique ce qui se passe:
Lorsqu'une URL avec un point de fin pour la partie Nom d'hôte: " https://example.com./ ", libcurl supprime le point et utilise le nom sans point en interne et l'envoie sans point dans HTTP Host: en-têtes et dans le champ TLS SNI.
L'option --connect-to
Pourrait également être utile dans votre cas. Ou --resolve
En remplacement de /etc/hosts
, Voir https://curl.haxx.se/mail/archive-2015-01/0042.html pour un exemple par exemple , ou https://makandracards.com/makandra/1613-make-an-http-request-to-a-machine-but-fake-the-hostname Vous pouvez ajouter --verbose
dans tous les cas pour voir plus en détail ce qui se passe. Voir cet exemple: https://www.claudiokuenzler.com/blog/693/curious-case-of-curl-ssl-tls-sni-http-Host-header ; vous y verrez également comment tester directement avec openssl
.
Si vous avez a.example
Dans votre /etc/hosts
, Vous devez simplement exécuter curl avec https://a.example/
Et il doit prendre en charge l'en-tête Host
et donc SNI (ou utiliser --resolve
À la place)
La réponse sélectionnée m'a aidé à trouver la réponse, même si elle ne contient pas la réponse. La réponse dans le lien mail/archive fourni par Patrick Mevzek a le mauvais numéro de port . Donc, même en suivant cette réponse, elle continuera à échouer.
J'ai utilisé ce conteneur pour exécuter un serveur de débogage pour inspecter les demandes. Je suggère fortement à quiconque débogue ce type de problème de faire de même.
Voici comment répondre à la question du PO.
# Instead of this:
# curl --header 'Host: a.example' https://x.example
# Do:
Host=a.example
target=x.example
ip=$(Dig +short x.example | head -n1)
curl -sv --resolve $Host:443:$ip https://$Host
Remarque : Puisque vous utilisez https, vous devez utiliser 443
dans le --resolve
argument au lieu de 80
comme indiqué sur le mail/archive