Ответ 1
Если вас интересует только то, как заставить Ruby вести себя так же, как OpenSSL s_client
или ваш браузер, вы можете перейти к самому последнему разделу, я расскажу о мелкой печати в следующем.
По умолчанию OpenSSL::X509::Store
, используемый для подключения, вообще не использует доверенных сертификатов. Основываясь на ваших знаниях о домене приложения, вы обычно пишете экземпляр X509::Store
с доверенным сертификатом (сертификатами), которые имеют отношение к вашему приложению. Для этого есть несколько вариантов:
- Store # add_file принимает путь к сертификату, закодированному PEM/DER
- Store # add_cert принимает экземпляр X509:: Certificate
- Store # add_path принимает путь к каталогу, в котором могут быть найдены надежные сертификаты
Подход "Браузер"
Это отличается от браузеров захода на посадку, Java (cacerts) или Windows со своим собственным внутренним хранилищем доверенных сертификатов. Там программное обеспечение предварительно оборудовано набором доверенных сертификатов, который считается "хорошим", по мнению поставщика программного обеспечения. Как правило, это неплохая идея, но если вы действительно заглянете в эти наборы, то вы скоро заметите, что существует слишком много сертификатов. Человек не может действительно сказать, следует ли доверять всем этим сертификатам вслепую или нет.
Подход Ruby
Требования вашего типичного приложения Ruby, с другой стороны, сильно отличаются от требований вашего браузера. Браузер должен быть в состоянии позволить вам перейти на любой "законный" веб-сайт, который поставляется с сертификатом TLS и обслуживается через https. Но в типичном приложении Ruby вам придется иметь дело только с несколькими службами, использующими TLS, или в противном случае требовать проверки сертификата.
И есть преимущество подхода Ruby - хотя для этого требуется более ручная работа, в конечном итоге вы получите ручное решение, которое точно доверяет сертификатам, которым он должен доверять в вашем конкретном контексте приложения. Это утомительно, но безопасность намного выше, потому что вы подвергаете намного меньше поверхности атаки. Возьмите последние события: если вам никогда не приходилось включать DigiNotar или любой другой скомпрометированный корень в ваш набор доверия, тогда нет таких нарушений, которые могут повлиять на вас.
Однако, как вы уже заметили, недостатком этого является то, что по умолчанию, если вы не активно добавляете доверенные сертификаты, расширение OpenSSL вообще не сможет проверять какой-либо одноранговый сертификат. Чтобы все было в порядке, вам нужно настроить конфигурацию вручную.
Это неудобство привело к множеству сомнительных мер, чтобы обойти его, а самое худшее - глобально установить OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
. Пожалуйста, не делайте этого. Мы даже шутили о добавлении кода, который позволяет вашему приложению разбиваться случайным образом, если мы сталкиваемся с этим взломом:)
Если ручная настройка доверия кажется слишком сложной, теперь я предлагаю легкую альтернативу, которая делает расширение OpenSSL вести себя точно так же, как команды CLI OpenSSL, такие как s_client
.
Почему s_client может проверить сертификат
OpenSSL использует аналогичный подход для браузеров и Windows. Типичная установка поместит на ваш жесткий диск набор доверенных сертификатов (что-то вроде /etc/ssl/certs/ca-bundle.crt
), и это будет служить стандартным набором доверенных сертификатов. Что там, где s_client
выглядит, когда нужно проверять одноранговые сертификаты и почему ваш эксперимент преуспел.
Приведение Ruby как s_client
Если вы все равно хотите иметь такой же комфорт при проверке сертификатов с Ruby, вы можете сказать, что он использует пакет доверенных сертификатов OpenSSL, если он доступен в вашей системе, вызывая OpenSSL::X509::Store#set_default_paths
. Дополнительную информацию можно найти здесь. Чтобы использовать это с помощью XMLRPC::Client
, просто убедитесь, что set_default_paths
вызывается в X509::Store
, который он использует.