Ruby net / imap получает OpenSSL :: SSL :: SSLError - самозаверяющий сертификат? - PullRequest
0 голосов
/ 09 мая 2019

При попытке разработать инструмент, который бы использовал IMAP для доступа к Gmail, я сталкиваюсь с трудностями даже с этим простым кодом запуска:

require 'net/imap'
imap = Net::IMAP.new('imap.gmail.com', ssl: true)

При запуске этого происходит сбой следующим образом (Примечание: слегка отредактировано для облегчения отображения) :

Traceback (most recent call last):
        5: from test-imap:2:in `<main>'
        4: from test-imap:2:in `new'
        3: from /.../.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/net/imap.rb:1092:in `initialize'
        2: from /.../.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/net/imap.rb:1533:in `start_tls_session'
        1: from /.../.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/net/protocol.rb:44:in `ssl_socket_connect'
/.../.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/net/protocol.rb:44:in
  `connect_nonblock': SSL_connect returned=1 errno=0 state=error:
  certificate verify failed (self signed certificate) (OpenSSL::SSL::SSLError)

При поиске я обнаружил несколько схожих проблем, например, проблема с резервным копированием imap # 57 , выпуск ruby ​​/ openssl # 238 ( по-прежнему открыт, на момент написания этой статьи закрыт после обмена ответом ниже) и выпуск rbenv / ruby-build # 380 ..... но ничего на SO.

Собирая информацию из вышеперечисленных ресурсов вместе, я пришел с этой командой, чтобы попробовать:

openssl s_client -connect imap.gmail.com:993 \
  -CAfile $(ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE') \
  < /dev/null > /dev/null

, которая сообщает:

depth=2 /OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign
verify return:1
depth=1 /C=US/O=Google Trust Services/CN=Google Internet Authority G3
verify return:1
depth=0 /C=US/ST=California/L=Mountain View/O=Google LLC/CN=imap.gmail.com
verify return:1
DONE

Таким образом, кажется, что сертификат SSL действительно подтверждает, что все в порядке (как и следовало ожидать).

Я нашел некоторые инструкции для использования net/imap с SSL с host-проверка отключена, что работает ... но я бы действительно предпочел не делать этого.

Я также нашел не IMAPинтерфейс gmail , но мое намерение - это инструмент, который также можно использовать с другими поставщиками IMAP, поэтому я специально собираюсь придерживаться IMAP здесь.Итак:

Как я могу получить net/imap для успешного подключения с использованием SSL и при этом подтвердить сертификат (учитывая, что он действительно действителен)?

Ответы [ 2 ]

3 голосов
/ 09 мая 2019

Идеально: обновление до Ruby 2.6.3 или новее

Обновление до Ruby версии 2.6.3 или новее должно исправить ситуацию, например ruby ​​pull # 2077 , которая предоставляет исправление для связанная проблема # 15594 , была включена в список изменений 2.6.3 .В версии 2.6.3 оригинальный тестовый фрагмент в вопросе теперь работает.

Если вы не можете выполнить обновление:

При этом, если обновление по какой-либо причине нецелесообразно, фиксация Эта исправленная проблема с резервным копированием imap # 57 предлагает решение обходного типа.Вместо следующего:

imap = Net::IMAP.new('imap.gmail.com', ssl: true)

Попробуйте это:

imap = Net::IMAP.new('imap.gmail.com', ssl: {ssl_version: :TLSv1_2})

Это, кажется, заставляет вещи работать даже в Ruby 2.6.0.

0 голосов
/ 28 июня 2019

В Ruby 2.4 мне пришлось использовать этот патч:

require 'net/imap'

class Net::IMAP
  module UseSNI
    def start_tls_session(*)
      @sock.instance_variable_set(:@hostname, @host)
      super
    end
  end

  prepend UseSNI
end

class OpenSSL::SSL::SSLSocket
  module UseSNI
    def connect(*)
      self.hostname = io.instance_variable_get(:@hostname)
      super
    end
  end

  prepend UseSNI
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...