我想用Ruby编写一个简单的服务器,根据主机名返回不同的TLS证书。目前,我这样做是为了指定一个具有SSLContext的TCPServer,并提供SSLContext证书和密钥。然后,无论主机名如何,该证书都将用于所有连接。
context = OpenSSL::SSL::SSLContext.new
context.min_version = :TLS1_2
context.add_certificate cert, key
serv = TCPServer.new host, port
secure = OpenSSL::SSL::SSLServer.new(serv, context)
Thread.new(secure.accept) do |conn|
# do stuff
end
因此,应根据SNI发送不同的证书。如何实现?
您可以使用servername_cb
:
context.servername_cb = lambda do |_, name|
ctx = OpenSSL::SSL::SSLContext.new
# load certificate for name
ctx.add_certificate cert[0], cert[1]
return ctx
end
或者,您可以使用现有的上下文:
context.servername_cb = lambda do |socket, name|
ctx = socket.context
# load certificate for name
ctx.add_certificate cert[0], cert[1]
return ctx
end
在TLS握手期间调用servername_cb的函数。它被传递一个SSLSocket和作为参数的名称。它应该返回一个SSLContext和相应的证书。https://ruby-doc.org/3.1.2/exts/openssl/OpenSSL/SSL/SSLContext.html#attribute-i-servername_cb