Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
扭曲的listenSSL虚拟主机_Ssl_Twisted_Twisted.web - Fatal编程技术网

扭曲的listenSSL虚拟主机

扭曲的listenSSL虚拟主机,ssl,twisted,twisted.web,Ssl,Twisted,Twisted.web,目前使用一个非常简单的Twisted NameVirtualHost和一些JSON配置文件在一个站点对象中提供真正基本的内容。Twisted提供的资源都是内置在flask中的WSGI对象 我想知道如何用SSLContext包装到这些域的连接,因为reactor.listenSSL只接受一个上下文,所以不清楚如何为每个域/子域提供自己的crt/密钥对。有没有办法为每个不需要代理的域设置带ssl的命名虚拟主机?我找不到任何使用NameVirtualHost和SSL的扭曲示例,我唯一能做的就是在反应器

目前使用一个非常简单的Twisted NameVirtualHost和一些JSON配置文件在一个站点对象中提供真正基本的内容。Twisted提供的资源都是内置在flask中的WSGI对象

我想知道如何用SSLContext包装到这些域的连接,因为reactor.listenSSL只接受一个上下文,所以不清楚如何为每个域/子域提供自己的crt/密钥对。有没有办法为每个不需要代理的域设置带ssl的命名虚拟主机?我找不到任何使用NameVirtualHost和SSL的扭曲示例,我唯一能做的就是在反应器上挂起钩子,在端口443上只监听一个域的上下文

我想知道是否有人尝试过这个

我的简单服务器没有任何SSL处理:


TLS是取代SSL的现代协议的名称,仅在最近才支持您正在寻找的功能。该功能称为SNI。它由现代平台上的现代浏览器支持,但不是一些较旧但仍被广泛使用的平台。有关支持的浏览器列表,请参阅wikipedia页面

Twisted对此没有特定的内置支持。然而,它不需要任何。Twisted的SSL支持所基于的pyOpenSSL确实支持SNI

pyOpenSSL API为您提供了构建所需行为的基本机制。这允许您定义一个回调,该回调被授予对客户端请求的服务器名称的访问权。此时,您可以指定要用于连接的密钥/证书对。您可以在pyOpenSSL的examples目录中找到

下面是该示例的摘录,为您提供要点:

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调用。

TLS现代协议的名称,它仅在最近才取代SSL,支持您正在寻找的功能。该功能称为SNI。它由现代平台上的现代浏览器支持,但不是一些较旧但仍被广泛使用的平台。有关支持的浏览器列表,请参阅wikipedia页面

Twisted对此没有特定的内置支持。然而,它不需要任何。Twisted的SSL支持所基于的pyOpenSSL确实支持SNI

pyOpenSSL API为您提供了构建所需行为的基本机制。这允许您定义一个回调,该回调被授予对客户端请求的服务器名称的访问权。此时,您可以指定要用于连接的密钥/证书对。您可以在pyOpenSSL的examples目录中找到

下面是该示例的摘录,为您提供要点:

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')

为了给这一个添加一些结尾,为了将来的搜索,下面是打印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项目负责为每个请求查找正确的证书

现在有一个txsni项目负责为每个请求查找正确的证书

什么是SSLContext?Twisted不使用这些来支持SSL或HTTPS。本例中第13行的内容是什么?对不起,我的名字缩短了。什么是SSLContext?Twisted不使用这些来支持SSL或HTTPS。本例中第13行的内容是什么?对不起,我的名字缩短了。不确定我是否正确地使用了你的建议。。。我在PyOpenSSL文档中找不到这些示例。以下是我在代码中修改的内容:出于某种原因,我的任何导入twisted的脚本都使用OpenSSL的版本12,尽管事实上virtualenv已经安装了.13。此版本在set_tlsext_servername_callback中引发属性错误。您必须弄清楚如何让您的环境使用pyOpenSSL 0.13。该功能在0.12中不可用。我现在使用的是0.13,但我仍然不知道在该回调中挂接在哪里。twisted文档说ssl工厂的getContext方法应该返回一个Context对象,但这不是set_tlsext_servername_回调的钩子的作用吗?SNI有效
通过使用新上下文替换原始上下文。第一个上下文是具有servername回调的上下文。第二个上下文是具有要使用的密钥/证书的上下文。如果您没有getContext返回的第一个上下文,那么当从客户端接收到servername时,就没有任何东西可以告诉OpenSSL您希望调用回调。但是您在什么时候挂接set_tlsext_servername_回调?不在SSL工厂的getContext方法中,对吗?除非我弄错了,否则每次请求都会重复。getContext方法没有收到连接实例,所以我如何才能让它对每个请求执行sni查找?不确定我是否正确使用了您的建议。。。我在PyOpenSSL文档中找不到这些示例。以下是我在代码中修改的内容:出于某种原因,我的任何导入twisted的脚本都使用OpenSSL的版本12,尽管事实上virtualenv已经安装了.13。此版本在set_tlsext_servername_callback中引发属性错误。您必须弄清楚如何让您的环境使用pyOpenSSL 0.13。该功能在0.12中不可用。我现在使用的是0.13,但我仍然不知道在该回调中挂接在哪里。twisted文档说ssl工厂的getContext方法应该返回一个Context对象,但这不是set_tlsext_servername_回调的钩子的作用吗?SNI通过用新的上下文替换原始上下文来工作。第一个上下文是具有servername回调的上下文。第二个上下文是具有要使用的密钥/证书的上下文。如果您没有getContext返回的第一个上下文,那么当从客户端接收到servername时,就没有任何东西可以告诉OpenSSL您希望调用回调。但是您在什么时候挂接set_tlsext_servername_回调?不在SSL工厂的getContext方法中,对吗?除非我弄错了,否则每次请求都会重复。getContext方法没有收到连接实例,因此如何使其对每个请求执行sni查找?