Twisted中的两个SSL证书

2 投票
1 回答
683 浏览
提问于 2025-04-18 15:01

我有这段代码:

from twisted.web.server import Site
from twisted.web.static import Data
from twisted.internet import reactor, ssl

root = Data("", "text/plain")
site = Site(root)
reactor.listenSSL(config.ws_port, site,
                      ssl.DefaultOpenSSLContextFactory(
                        '/etc/apache2/ssl/wc.key',
                        '/etc/apache2/ssl/wc.crt')
                      )

但是我又买了一个新域名,并为它申请了另一个证书。我需要让twisted支持两个域名,每个域名都有自己的证书。我该怎么给twisted添加第二个证书呢?

1 个回答

3

TLS和HTTP一起工作,支持多个主机名的方式有两种:一种是使用一个包含所有主机名的单一证书(比如通过subjectAltName扩展来实现),另一种是使用多个证书(每个证书包含的主机名少于完整的集合)并结合SNI TLS扩展。

如果你想使用第一种方法,你只需要获取正确构建的证书。获取证书的方式可能取决于你从哪里获取这些证书。也许证书供应商有一个特别的用户界面,或者你使用的证书请求生成器有一些选项可以控制这个过程。

如果你想使用第二种方法,可以了解一下txSNI

from txsni.snimap import SNIMap
from txsni.tlsendpoint import TLSEndpoint

from twisted.web.server import Site
from twisted.web.static import Data
from twisted.internet import reactor
from twisted.internet.ssl import Certificate, KeyPair, PrivateCertificate
from twisted.internet.endpoints import serverFromString

def main(reactor):
    root = Data("", "text/plain")
    site = Site(root)

    def load(key_path, cert_path):
        with open(key_path) as key_file:
            key = KeyPair.loadPEM(key_file.read())

        with open(cert_path) as cert_file:
             cert = cert.read()

        return PrivateCertificate.fromCertificateAndKeyPair(cert, key)

    snimap = SNIMap({
        "DEFAULT": load('/etc/apache2/ssl/wc.key', '/etc/apache2/ssl/wc.crt').options(),
        "another.host.name": load(another_key, another_cert).options(),
        ...
    })

    endpoint = TLSEndpoint(serverFromString(reactor, "tcp:80"))
    endpoint.listen(site)

    reactor.run()

撰写回答