SNI(服务器名称指示)与龙卷风
SNI (Server Name Indication) with tornado
如标题所述,我想了解如何将 SNI(服务器名称指示)与 tornado 网络服务器一起使用。
我希望能够根据给定请求的主机名出示特定证书。
在深入研究之后,我找到了使用来自 ssl.SSLContext
的 sni_callback
的解决方案。
这将为您提供一个在建立 TLS 握手之前包含主机名的方法。
在 servername_callback
方法中,您可以根据主机名选择要加载的证书。
工作解决方案
import tornado.ioloop
import tornado.web
import tornado.httpserver
import ssl
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write('Hello, world')
application = tornado.web.Application([
(r'/', MainHandler)
])
def servername_callback(sock, hostname, cb_context):
# hostname contains the hostname that the client is requesting
print("hostname", hostname)
# now that we have the hostname we can dynamically pick the correct certificate
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# this part is up to you to store via a config file or even in a database
ssl_context.load_cert_chain(certfile="/path/to/cert", keyfile="/path/to/key")
sock.context = ssl_context
if __name__ == '__main__':
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_context.sni_callback = servername_callback
http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_context)
http_server.listen(443)
tornado.ioloop.IOLoop.instance().start()
如标题所述,我想了解如何将 SNI(服务器名称指示)与 tornado 网络服务器一起使用。
我希望能够根据给定请求的主机名出示特定证书。
在深入研究之后,我找到了使用来自 ssl.SSLContext
的 sni_callback
的解决方案。
这将为您提供一个在建立 TLS 握手之前包含主机名的方法。
在 servername_callback
方法中,您可以根据主机名选择要加载的证书。
工作解决方案
import tornado.ioloop
import tornado.web
import tornado.httpserver
import ssl
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write('Hello, world')
application = tornado.web.Application([
(r'/', MainHandler)
])
def servername_callback(sock, hostname, cb_context):
# hostname contains the hostname that the client is requesting
print("hostname", hostname)
# now that we have the hostname we can dynamically pick the correct certificate
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# this part is up to you to store via a config file or even in a database
ssl_context.load_cert_chain(certfile="/path/to/cert", keyfile="/path/to/key")
sock.context = ssl_context
if __name__ == '__main__':
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_context.sni_callback = servername_callback
http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_context)
http_server.listen(443)
tornado.ioloop.IOLoop.instance().start()