2011-11-23 69 views
4

我有一些困難,嘗試在Python中使用代理創建SSL套接字這需要認證。我是非常感謝,但我覺得最好儘可能包含更多細節。Python SSLError:客戶端錯誤(EOF發生違反協議),服務器端錯誤(SSL3_GET_RECORD:錯誤的版本號)

首先,服務器的代碼如下所示:

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 

    def __init__(self, server_address, RequestHandlerClass, client_manager, recv_queue): 
     SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate=True) 

     <snipped out extra code> 

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): 

    def setup(self): 

     while True: 
      try: 
       print 'trying to wrap in ssl' 
       self.request = ssl.wrap_socket(self.request, 
            certfile=(os.getcwd() + '/ssl_certs/newcert.pem'), 
            keyfile=(os.getcwd() + '/ssl_certs/webserver.nopass.key'), 
            server_side=True, 
            cert_reqs=ssl.CERT_NONE, 
            ssl_version=ssl.PROTOCOL_TLSv1, 
            do_handshake_on_connect=False, 
            suppress_ragged_eofs=True) 
       break 

      except Exception, ex: 
       print 'error trying to wrap in ssl %s' % ex 

    def handle(self): 
     # Display message that client has connected 
     print '\r[*] Received connection from %s:%s\r' % (self.client_address[0], self.client_address[1]) 

     while self.stopped() == False: 
      recv_msg = self.request.read(1024) 

      if recv_msg == '': 
       self.stop.set() 
       server.recv_queue.put(recv_msg) 
       break 
      else: 
       server.recv_queue.put(recv_msg) 

     if self.stopped(): 
      print '[!] Received STOP signal from %s:%s; Exiting!' % (self.client_address[0], self.client_address[1]) 

其次,這是我設置了通過需要身份驗證的代理連接所需的信息的客戶端代碼:

class proxyCommsHandler(): 

    def __init__(self, user, password, remote_host, remote_port, list_of_proxies): 
     # information needed to connect 
     self.user = 'username' 
     self.passwd = 'password' 
     self.remote_host = 'remote_host_ip' 
     self.remote_port = 8008 
     self.list_of_proxies = [['proxyserver.hostname.com', 8080]] 

     # setup basic authentication to send to the proxy when we try to connect 
     self.user_pass = base64.encodestring(self.user + ':' + self.passwd) 
     self.proxy_authorization = 'Proxy-authorization: Basic ' + self.user_pass + '\r\n' 
     self.proxy_connect = 'CONNECT %s:%s HTTP/1.1\r\n' % (self.remote_host, self.remote_port) 
     self.user_agent = "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1\r\n" 
     self.proxy_pieces = self.proxy_connect + self.proxy_authorization + self.user_agent + '\r\n' 

現在,這裏是我最初連接到代理的地方,在那裏我得到沒有錯誤(我得到'200'狀態碼):

self.proxy = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
self.proxy.connect((proxy_host, proxy_port)) 
self.proxy.sendall(self.proxy_pieces) 
self.response = proxy.recv(1024) 

這裏是客戶端失敗的地方(我認爲)。我試圖把self.proxy和SSL包裝它,就像這樣:

sslsock = ssl.wrap_socket(self.proxy, server_side=False, do_handshake_on_connect=True, 
             ssl_version=ssl.PROTOCOL_TLSv1) 

這是我看到的客戶端上的錯誤:

Traceback (most recent call last): 
    File "C:\Python27\pyrevshell.py", line 467, in <module> 
     proxyCommsHandler(None, None, None, None, list_of_proxies).run() 
    File "C:\Python27\pyrevshell.py", line 300, in run 
     ssl_version=ssl.PROTOCOL_TLSv1) 
    File "C:\Python27\lib\ssl.py", line 372, in wrap_socket 
     ciphers=ciphers) 
    File "C:\Python27\lib\ssl.py", line 134, in __init__ 
     self.do_handshake() 
    File "C:\Python27\lib\ssl.py", line 296, in do_handshake 
     self._sslobj.do_handshake() 
    SSLError: [Errno 8] _ssl.c:503: EOF occurred in violation of protocol 

客戶連接,如同自所示輸出這裏:

trying to wrap in ssl 
[*] Received connection from x.x.x.x:47144 
[*] x.x.x.x:47144 added to the client list 

但後來它緊跟着的一個例外:

---------------------------------------- 
Exception happened during processing of request from ('x.x.x.x', 47144) 
Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 582, in process_request_thread 
    self.finish_request(request, client_address) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 323, in finish_request 
    self.RequestHandlerClass(request, client_address, self) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 639, in __init__ 
     self.handle() 
    File "shell_server.py", line 324, in handle 
     recv_msg = self.request.read(1024) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 138, in read 
     return self._sslobj.read(len) 
SSLError: [Errno 1] _ssl.c:1348: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number 
---------------------------------------- 

雖然我知道這聽起來像基於被拋出的異常的明顯的問題,有趣的部分是:

  • 我順利地開始通過代理連接如上圖所示
  • 我可以在同一代理後面成功連接後面的網頁瀏覽器,並且不會引發異常;我可以將數據傳遞給瀏覽器
  • 我已經在服務器和客戶端都嘗試了不同的SSL協議版本,如Python documentation中的表中所示;它每次在客戶端發生錯誤

我在連接的兩端都使用了Wireshark。在使用普通瀏覽器並連接到服務器時,我會看到整個SSL握手和協商過程,並且一切運行順利。但是,當我使用上面顯示的客戶端時,只要我連接它,我看到客戶端發送一條Client Hello消息,但然後我的服務器發送一個RST數據包來終止連接(我還沒有確定是否這是拋出異常之前或之後)。

再一次,我很抱歉的長度,但我急需專家的意見。

回答

1

我已經找到了我的問題的問題。當我第一次通過代理進行連接時,我將self.user_agent發送到遠程主機,這會干擾SSL握手。

爲了解決這個問題,我把初始self.request.recv()def setup(self)功能之前,我打電話ssl.wrap_socket在插座上。

相關問題