web-dev-qa-db-fra.com

Utiliser cURL avec SNI (Server Name Indication)

J'essaie d'utiliser cURL pour publier sur une API qui vient de commencer à utiliser SNI (afin qu'ils puissent héberger plusieurs certificats SSL sur 1 adresse IP).

Mon cURL a cessé de fonctionner à la suite de ce passage à SNI. Ils ont expliqué que c'est parce que cURL récupère * .domain-a.com au lieu de * .domain-b.com donc le SSL échoue.

Cela semble être un bogue dans cURL car l'URL de l'API ne contient aucune erreur lorsqu'elle est visitée à partir d'un navigateur.

En utilisant ce code, cela fonctionne:

exec('curl -k -d "parameters=here", https://urlhere.com/', $output);
print_r($output);

Cependant, l'utilisation de -k est mauvaise car elle ne vérifie pas le certificat SSL.

L'utilisation de ce code ne fonctionne PAS:

exec('curl -d "parameters=here", https://urlhere.com/', $output);
print_r($output);

Donc ma question est, comment puis-je utiliser curl avec SNI et toujours vérifier le SSL (pas besoin d'utiliser -k). Existe-t-il un autre paramètre dans PHP ou une option cURL que je peux définir pour contourner ce problème?

22
Justin

Pour pouvoir utiliser SNI, trois conditions sont requises:

  • Utiliser une version de Curl qui le supporte, au moins 7.18.1, selon le change logs .
  • Utilisation d'une version de Curl compilée avec une bibliothèque qui prend en charge SNI, par exemple OpenSSL 0.9.8j (selon les options de compilation certaines versions plus anciennes).
  • Utilisation de TLS 1.0 au moins (pas SSLv3).

Notez que le code de débogage de Curl (-v) affiche uniquement le numéro de version principal (principalement pour faire la distinction entre les types de messages SSLv2 et SSLv3 +, voir ssl_tls_trace ), il affichera donc toujours "SSLv3" lorsque vous utilisez TLS 1.0 ou supérieur (car ils sont effectivement SSL v3.1 ou supérieur, 3 est le même numéro de version principal).

Vous pouvez vérifier que votre version installée de curl peut utiliser SNI à l'aide de Wireshark. Si vous établissez une connexion à l'aide de curl -1 https://something, si vous développez le message "Client Bonjour", vous devriez pouvoir voir un "server_name "extension.

Je ne sais pas quelle version SSL/TLS est utilisée par défaut (selon vos options de compilation) lorsque vous utilisez curl sans -1 (pour TLS 1.0) ou -3 (pour SSLv3), mais vous pouvez essayer de forcer -1 sur votre commande, car cela ne fonctionnera pas avec SSLv3 de toute façon.

47
Bruno

Avec la bibliothèque requise et la version Curl, la demande doit utiliser résoudre pour envoyer SNI dans la boucle:

curl -vik --resolve example.com:443:198.18.110.10 https://example.com/
11
hardik p