Twisted listenSSL虚拟主机
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Twisted listenSSL虚拟主机相关的知识,希望对你有一定的参考价值。
目前使用一个非常简单的Twisted NameVirtualHost
与一些JSON配置文件相结合,在一个Site
对象中提供真正的基本内容。 Twisted提供的资源都是在flask中构建的WSGI对象。
我想知道如何用SSLContext
包装与这些域的连接,因为reactor.listenSSL
只采用一个上下文,如何给每个域/子域提供它自己的crt / key对并不是很明显。有没有办法为每个不需要代理的域设置带有ssl的命名虚拟主机?我找不到任何使用NameVirtualHost
和SSL的Twisted示例,而且他们唯一可以工作的是挂在反应器上,仅在一个域的上下文中侦听端口443?
我想知道是否有人试过这个?
我的简单服务器没有任何SSL处理:
https://github.com/DeaconDesperado/twsrv/blob/master/service.py
TLS(替代SSL的现代协议的名称)最近才支持您正在寻找的功能。该功能称为Server Name Indication(或SNI)。现代平台上的现代浏览器支持它,但不是一些较旧但仍广泛使用的平台(有关支持的浏览器列表,请参阅维基百科页面)。
Twisted没有特定的内置支持。但是,它不需要任何。 twisted的SSL支持所基于的pyOpenSSL确实支持SNI。
set_tlsext_servername_callback pyOpenSSL API为您提供了构建所需行为的基本机制。这使您可以定义一个回调,该回调可以访问客户端请求的服务器名称。此时,您可以指定要用于连接的密钥/证书对。你可以在pyOpenSSL的examples目录中找到an example demonstrating the use of this API。
以下是该示例的摘录,为您提供依据:
def pick_certificate(connection):
try:
key, cert = certificates[connection.get_servername()]
except KeyError:
pass
else:
new_context = Context(TLSv1_METHOD)
new_context.use_privatekey(key)
new_context.use_certificate(cert)
connection.set_context(new_context)
server_context = Context(TLSv1_METHOD)
server_context.set_tlsext_servername_callback(pick_certificate)
您可以将此方法合并到自定义上下文工厂中,然后将该上下文工厂提供给listenSSL
调用。
只是为此添加一些闭包,并为将来的搜索,这里是打印SNI的示例中的echo服务器的示例代码:
from twisted.internet import ssl, reactor
from twisted.internet.protocol import Factory, Protocol
class Echo(Protocol):
def dataReceived(self, data):
self.transport.write(data)
def pick_cert(connection):
print('Received SNI: ', connection.get_servername())
if __name__ == '__main__':
factory = Factory()
factory.protocol = Echo
with open("keys/ca.pem") as certAuthCertFile:
certAuthCert = ssl.Certificate.loadPEM(certAuthCertFile.read())
with open("keys/server.key") as keyFile:
with open("keys/server.crt") as certFile:
serverCert = ssl.PrivateCertificate.loadPEM(
keyFile.read() + certFile.read())
contextFactory = serverCert.options(certAuthCert)
ctx = contextFactory.getContext()
ctx.set_tlsext_servername_callback(pick_cert)
reactor.listenSSL(8000, factory, contextFactory)
reactor.run()
并且因为让OpenSSL工作总是很棘手,所以这里是您可以用来连接它的OpenSSL语句:
openssl s_client -connect localhost:8000 -servername hello_world -cert keys/client.crt -key keys/client.key
针对pyOpenSSL == 0.13运行上面的python代码,然后运行上面的s_client命令,将其打印到屏幕:
('Received SNI: ', 'hello_world')
现在有一个txsni项目,负责根据请求查找正确的证书。 https://github.com/glyph/txsni
以上是关于Twisted listenSSL虚拟主机的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Twisted IRCClient 获取用户的主机掩码
如何通过python twisted HTTPClient生成POST和GET请求?