Используйте cURL с SNI (указание имени сервера)

Я пытаюсь использовать cURL для публикации в API, который только начал использовать SNI (чтобы они могли размещать несколько сертификатов ssl на 1 IP-адресе).

Мой cURL перестал работать в результате этого перехода на SNI. Они объяснили это тем, что cURL возвращает *.domain-a.com вместо *.domain-b.com, поэтому SSL не работает.

Похоже, это ошибка в cURL, поскольку URL-адрес API не содержит ошибок при посещении из браузера.

Используя этот код, он работает:

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

Однако использование -k плохо, поскольку оно не проверяет сертификат SSL.

Используя этот код, НЕ работает:

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

Итак, мой вопрос: как я могу использовать curl с SNI и при этом проверять SSL (не обязательно использовать -k). Есть ли другой параметр в PHP или параметр cURL, который я могу обойти?


person Justin    schedule 17.10.2012    source источник


Ответы (2)


Чтобы иметь возможность использовать SNI, необходимы три условия:

  • Использование поддерживаемой версии Curl (не ниже 7.18.1) в соответствии с журналами изменений.
  • Использование версии Curl, скомпилированной с библиотекой, поддерживающей SNI, например. OpenSSL 0.9.8j (в зависимости от параметров компиляции некоторых более старых версий).
  • По крайней мере, используя TLS 1.0 (не SSLv3).

Обратите внимание, что отладочный код Curl (-v) отображает только основной номер версии (главным образом для того, чтобы различать типы сообщений SSLv2 и SSLv3+, см. ssluse.c#L1383" rel="noreferrer">ssl_tls_trace), поэтому он по-прежнему будет отображать "SSLv3" при использовании TLS 1.0 или выше (поскольку они фактически являются SSL версии 3.1 или выше, 3 – тот же основной номер версии).

Вы можете проверить, может ли ваша установленная версия curl использовать SNI с помощью Wireshark. Если вы устанавливаете соединение с помощью curl -1 https://something, если вы развернете сообщение «Client Hello», вы сможете увидеть расширение «server_name».

Я не уверен, какая версия SSL/TLS используется по умолчанию (в зависимости от ваших параметров компиляции), когда вы используете curl без -1 (для TLS 1.0) или -3 (для SSLv3), но вы можете попробовать принудительно установить -1 по своей команде, так как он все равно не будет работать с SSLv3.

person Bruno    schedule 17.10.2012
comment
Если вы хотите использовать libcurl, установите CURLOPT_SSLVERSION на 1 (что эквивалентно -1 в командной строке). - person Bruno; 18.10.2012
comment
Для меня была установлена ​​старая версия cURL. Обновление это исправило. - person Justin; 20.07.2013
comment
Обратите внимание, что curl в Mac OS X (начиная с Yosemite) не отправляет SNI при использовании с -k или --insecure. - person ghodss; 28.02.2016

Наряду с требуемой библиотекой и версией Curl запрос должен использовать разрешение для отправки SNI в curl:

curl -vik --resolve example.com:443:198.18.110.10 https://example.com/
person non communist mao    schedule 16.10.2018
comment
В моем случае я обращался к серверу по IP. Сертификат был загружен путем доступа к тому же серверу по IP с помощью Firefox. Если бы я доверял сертификату в цепочке ключей моего Mac, тогда все работало бы с доступом к нему по IP и без проверки сертификата в cURL. Но когда я удалил этот сертификат из цепочки для ключей и попытался проверить его в cURL, я продолжал получать ошибки проверки, пока не разрешил этот IP-адрес имени, с которого я загрузил исходный сертификат, как предполагает этот ответ. - person riverhorse; 14.04.2020