1

現在、非常に単純な TwistedNameVirtualHostをいくつかの JSON 構成ファイルと組み合わせて使用​​し、1 つのSiteオブジェクトで非常に基本的なコンテンツを提供しています。Twisted が提供するリソースはすべて、flask で構築された WSGI オブジェクトです。

これらのドメインへの接続SSLContextreactor.listenSSL. プロキシを必要としないドメインごとに ssl で名前付き仮想ホスティングを設定する方法はありますか? SSLを使用する Twisted の例が見つかりませんNameVirtualHost。1 つのドメインのコンテキストだけでポート 443 をリッスンしているリアクターにフックするだけで作業できますか?

誰かがこれを試みたかどうか疑問に思っていましたか?

SSL処理のない私の単純なサーバー:

https://github.com/DeaconDesperado/twsrv/blob/master/service.py

4

3 に答える 3

6

TLS (SSL に代わる最新のプロトコルの名前) は、探している機能をサポートするようになったのはごく最近のことです。この機能はServer Name Indication (またはSNI ) と呼ばれます。最新のプラットフォーム上の最新のブラウザーでサポートされていますが、一部の古いがまだ広く使用されているプラ​​ットフォームではサポートされていません (サポートされているブラウザーのリストについては、ウィキペディアのページを参照してください)。

Twisted には、これに対する特定の組み込みサポートはありません。ただし、何も必要ありません。Twisted の SSL サポートのベースとなっている pyOpenSSL は、SNI をサポートしています。

set_tlsext_servername_callback pyOpenSSL API は、必要な動作を構築するための基本的なメカニズムを提供します。これにより、クライアントから要求されたサーバー名にアクセスできるコールバックを定義できます。この時点で、接続に使用するキー/証明書のペアを指定できます。pyOpenSSL のサンプル ディレクトリで、この 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呼び出しに提供できます。

于 2012-08-28T18:26:41.343 に答える
3

これにいくつかのクロージャを追加し、将来の検索のために、SNI を出力するサンプルからのエコー サーバーのサンプル コードを次に示します。

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

上記の python コードを pyOpenSSL==0.13 に対して実行してから、上記の s_client コマンドを実行すると、これが画面に表示されます。

('Received SNI: ', 'hello_world')
于 2013-12-29T05:36:17.953 に答える
0

現在、要求ごとに適切な証明書を見つける処理を行う txsni プロジェクトがあります。https://github.com/glyph/txsni

于 2019-04-02T17:01:13.837 に答える