【问题标题】:OpenSSL::SSL::SSLContext SNI servername_cb Not WorkingOpenSSL::SSL::SSLContext SNI servername_cb 不工作
【发布时间】:2015-05-14 18:33:41
【问题描述】:

OpenSSL::X509::Certificate Showing Certificate for Wrong Domain中所引用,我需要使用TLSv1或更高版本 Server Name Indication扩展。

即使通过SSLContext 设置了ssl_versionservername_cb,我仍然得到myproair.com 的错误证书。

  begin 
    timeout(1) do
      tcp_client = TCPSocket.new("#{instance["domain"]}", 443)
      ssl_context = OpenSSL::SSL::SSLContext.new()
      ssl_context.ssl_version = :TLSv1
      ssl_context.servername_cb = "https://#{instance["domain"]}"
      ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, ssl_context)
      ssl_client.connect
      cert = OpenSSL::X509::Certificate.new(ssl_client.peer_cert)
      ssl_client.sysclose
      tcp_client.close
      #http://ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html
      date = Date.parse((cert.not_after).to_s)
      row.push("#{date.strftime('%F')} #{cert.signature_algorithm} #{cert.subject.to_a.select{|name, _, _| name == 'CN' }.first[1]}".downcase.ljust(57))
    end
  rescue SocketError
    row.push("down".ljust(57))
  rescue Errno::ECONNREFUSED
    row.push("connection refused".ljust(57))
  rescue Errno::ECONNRESET
    row.push("connection reset".ljust(57))
  rescue Timeout::Error
    row.push("no 443 listener".ljust(57))
  rescue OpenSSL::SSL::SSLError
    row.push("bad certificate - ssl error".ljust(57))
  rescue Exception => ex
    row.push("error: #{ex.class} #{ex.message}".ljust(57))
  end

如何在 OS X 上的 Ruby 2.0 中设置服务器名称?


$ ruby --version
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14]

$ openssl version
OpenSSL 0.9.8zc 15 Oct 2014

【问题讨论】:

  • servername_cb 用于服务器端。当服务器获得连接时,它会调用回调以允许服务器选择与 SNI 相关的证书 :) 在客户端上,您正在寻找与 SSL_set_tlsext_host_name 等效的 Ruby。您可以在 OpenSSL 的 SSL/TLS Client 上看到一个基于 C 的示例。
  • 另见How to set TLS context options in Ruby (like OpenSSL::SSL::SSL_OP_NO_SSLv2)。它向您展示了如何在 Ruby 中获取“TLS 1.0 及更高版本”。
  • @jww 感谢您的所有见解 - 我正在进入边缘案例领域,但这很有趣 :) 仍在四处寻找 Ruby 等价物...
  • Ruby 让我非常沮丧。我发现安全地做基本的事情太难了,比如建立一个安全的通道。 (当谈到安全通道时,我对“安全”有自己的定义)。我最终放弃了它并停止尝试学习它。
  • 在过去几个月沉浸在 Ruby 中之后,我得出了同样的结论——我正在讨论用 Python 重写。你的偏好是什么?

标签: ruby macos openssl sni server-name


【解决方案1】:

你自然会为 OpenSSL::SSLSocket 使用undocumented 'hostname' 方法!

tcp_client = TCPSocket.new("#{instance["domain"]}", 443)
ssl_context = OpenSSL::SSL::SSLContext.new()
ssl_context.ssl_version = :TLSv1
ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, ssl_context)
ssl_client.hostname = instance["domain"]
ssl_client.connect
cert = OpenSSL::X509::Certificate.new(ssl_client.peer_cert)
ssl_client.sysclose
tcp_client.close

我在编写具有类似目标的代码时发现了here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2012-06-10
    • 2015-05-10
    • 1970-01-01
    相关资源
    最近更新 更多