Автоматизируйте сопоставление имен хостов

Я использую Mechanize для очистки сайта и получаю сообщения об ошибках, связанных с несоответствием имени хоста. Я обнаружил, что корень проблемы заключается в том, что SNI используется на сайте, который я очищаю, и я хотел бы указать имя хоста, чтобы убедиться, что используется правильный сертификат.

Вот моя текущая установка:

agent = Mechanize.new
agent.user_agent = custom_user_agent
agent.verify_mode = OpenSSL::SSL::VERIFY_PEER

page = agent.get "website.com"

И вот что, я думаю, мне нужно добавить (или что-то в этом роде), чтобы убедиться, что используется правильный сертификат:

OpenSSL::SSL::SSLSocket.hostname = "website.com"

Возможно ли это сделать в Mechanize или мне нужно выяснить, как вручную указать сертификат для использования?

Для контекста, я знаю о решении VERIFY_NONE, но предпочел бы избегать его, учитывая уязвимости, которые оно вносит.


person Luke Keller    schedule 17.07.2016    source источник
comment
OpenSSL 1.0.2 и более ранние версии не выполняют сопоставление имен хостов. Приложения, такие как cURL и Mechanize, должны выполнять сопоставление. OpenSSL 1.1.0 планируется реализовать. Если у вас возникли проблемы с сопоставлением имен хостов, то на данный момент они наверняка исходят от Mechanize. SNI — это функция TLS, поэтому убедитесь, что вы используете TLS 1.0 или выше. Я предполагаю, что ваша проблема заключается в том, что Mecahanize (или Ruby) не использует SNI.   -  person jww    schedule 18.07.2016
comment
@jww Кажется, нет способа установить его в Mechanize. Знаете ли вы способ сделать это или альтернативы Mechanize, которые поддерживают SNI?   -  person Luke Keller    schedule 18.07.2016
comment
Возможно, связано (я не разработчик Ruby или Mechanize): Как установить параметры контекста TLS в Ruby (например, OpenSSL::SSL::SSL_OP_NO_SSLv2) и OpenSSL::SSL::SSLError: имя хоста не соответствует сертификату сервера. Функция OpenSSL, которую необходимо вызвать, называется SSL_set_tlsext_host_name, но ее неясно для меня, если/когда Ruby позвонит.   -  person jww    schedule 18.07.2016
comment
@jww похоже, что имя хоста нужно установить в Net::HTTP (жемчужина, от которой зависит Mechanize), но, похоже, нет способа передать его Mechanize в качестве аргумента.   -  person Luke Keller    schedule 18.07.2016


Ответы (1)


Вам не нужно указывать имя хоста или проверять имя хоста с помощью Mechanize.

Ruby's Net::HTTP сделает это за вас:

https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L928

Исключение OpenSSL::SSL::SSLError будет вызвано, если есть несоответствие имени хоста.

person Tim Craft    schedule 21.07.2016
comment
Интересно. Таким образом, проблема несоответствия имени хоста возникает случайным образом, и я слышал, что это может быть вызвано проблемами SNI. Если спецификация имени хоста не является проблемой, знаете ли вы, как я могу отладить эту проблему? - person Luke Keller; 21.07.2016
comment
Если вы хотите избавиться от Ruby, вы можете использовать openssl для его отладки. Правильная настройка SNI должна завершиться ошибкой с openssl s_client -connect example.com:443, а затем завершиться успешно, если вы укажете -servername example.com. Если он постоянно или периодически выходит из строя, это проблема с сервером. Предполагая, что вы не контролируете сервер, вы можете связаться с владельцем/администратором и попросить их исправить настройку SSL. - person Tim Craft; 25.07.2016
comment
Кажется, только периодически происходит сбой в Mechanize. Однако я заметил ошибку при использовании openssl: verify error:num=19:self signed certificate in certificate chain. Не вызовет ли это периодические сбои в Mechanize? - person Luke Keller; 26.07.2016