1

次のシナリオに直面しています。HTTPSサーバーに接続するためにHTTPプロキシを使用する必要があります。いくつかの理由で、(暗号化の前に)生データにアクセスする必要があるため、HTTP固有のライブラリの1つではなくソケットライブラリを使用しています。したがって、最初にTCPソケットをHTTPプロキシに接続し、connectコマンドを発行します。

この時点で、HTTPプロキシは接続を受け入れ、それ以降のすべてのデータをターゲットサーバーに転送しているように見えます。ただし、SSLに切り替えようとすると、

エラー:140770FC:SSLルーチン:SSL23_GET_SERVER_HELLO:不明なプロトコル

ソケットがHTTPSターゲットではなくHTTPプロキシを使用してハンドシェイクを試行したことを示します。

これが私がこれまでに持っているコードです:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
s.connect(('proxy',9502))  
s.send("""CONNECT en.wikipedia.org:443 HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:15.0) Gecko/20100101 Firefox/15.0.1  
Proxy-Connection: keep-alive  
Host: en.wikipedia.org 

""")  

print s.recv(1000)  

ssl = socket.ssl(s, None, None)  
ssl.connect(("en.wikipedia.org",443))  

HTTPプロキシに接続した後にターゲットサーバーへのSSLソケットを開く正しい方法は何でしょうか?

4

2 に答える 2

1

(一般に、すべてを自分で実装するよりも、PyCurl などの既存の HTTPS ライブラリを使用する方が簡単であることに注意してください。)

まず、 variable を呼び出さないでくださいssl。この名前はsslモジュールで既に使用されているため、非表示にする必要はありません。

第二に、二度と使用しないでくださいconnect。すでに接続されています。必要なのは、ソケットをラップすることです。Python はデフォルトで証明書の検証を行わないため、リモート証明書を検証し、ホスト名も検証する必要があります。

必要な手順は次のとおりです。

  • プレーンテキスト接続を確立CONNECTし、最初の数行で行っているように使用します。
  • 取得した HTTP 応答を読み、ステータス コード 200 を取得していることを確認します。(ヘッダーを 1 行ずつ読む必要があります)。
  • ssl_s = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLS1, ca_certs='/path/to/cabundle.pem')ソケットを包むために使用します。次に、ホスト名を確認します。この回答を読む価値があります:connectメソッドとソケットをラップした後の動作。
  • 次に、ssl_s通常のソケットのように使用します。二度と電話しないでくださいconnect
于 2013-03-17T16:46:40.597 に答える