2014-06-20 21 views
1

我目前正在做一个代理,位于浏览器和网站之间。除https之外的所有内容我有麻烦理解它的一些段落,并没有发现在网络上的许多资源。所以我被卡住了。卡住了编程https代理 - 接下来要做什么?

我正在使用的代码是:

conn, addr = server.accept() 
request = conn.recv(9999) #get a CONNECT request 
conn.send(b'HTTP/1.1 200 Connection estabilished\n\n') 
enc_req = conn.recv(9999) #this gets an encrypted request 
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #plaintext client 
client.connect((host, 443)) #connect to chosen host 
client.send(enc_req) 
resp1 = client.recv(9999) #this gets something unreadable (encrypted?) 
#could it be the certificate? 

#now what? 

是对resp1我得到证书?之后我需要做些什么? (或者,这是相同的,接下来通常会发生什么https?)

P.S.我知道这个问题有点泛泛,但请不要太苛刻地评论我。我试过在Web上进行研究,但我一直发现的是用于ssl的加密方法。我真的不知道如何继续。

+0

HTTPS(SSL)连接是端对端加密的,所有代理可以做的是在客户端和服务器之间传递数据,没有别的。 –

+0

这正是我想要完成的,但我不确定。 – user3725459

+0

@Martijn - SSL/TLS不提供端到端加密(尽管我们经常希望如此)。 [Trustwave](http://lwn.net/Articles/480279/)证明了这个承诺没有被传递。有一整套代理用于打破期望,并且它们带来了自己的一系列问题,例如组织的攻击面经常增加。请参阅[SSL/TLS拦截代理和传递信任](http://www.secureworks.com/cyber-threat-intelligence/threats/transitive-trust/)。 – jww

回答

2

我还没有测试过这个代码(主要是伪代码),但是这应该让你知道你需要做什么。

conn, addr = server.accept() 
request = conn.recv(9999) #get a CONNECT request 
# Here, parse the CONNECT string and get the host and port (not sure if you were doing that already. 

# Then, try to connect *before* you tell the client the connection was established (in case it fails) 
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #plaintext client 
client.connect((host, 443)) #connect to chosen host 

conn.send(b'HTTP/1.1 200 Connection estabilished\n\n') 

# Then loop until the connections are closed. 
while True: 
    # Read from the client, send the data to the server. 
    enc_req = conn.recv(9999) #this gets an encrypted request 
    client.send(enc_req) 

    # Read from the server, send the data to the client. 
    resp1 = client.recv(9999) #this gets something unreadable (encrypted?) 
    #could it be the certificate? 
    #now what? 
    # The first time it's certainly the Client Hello message, not encrypted, but in a binary format indeed. 
    # Just send everything you've just read to the server. 
    conn.send(resp1) 

这只是您需要编写的循环概念的快速概览。实际上,您可能能够并行处理两者。关闭连接时也要谨慎一点(允许它以任意顺序发生,同时仍然中继任何一方发送的最后一个数据)。

+0

感谢您的帮助,我已经在这方面进行了一些修改,并且它可以正常工作!我的代码也主要是伪代码;) – user3725459

2

正如评论中所述,处理加密的端到端流量的代理服务器只能将其传递。

下面是使用circuits写了一个有效的代理已经用传球和代理SSH交通得到了充分的测试,因此它应该工作一样好,即使SSL参与直通TCP代理:

#!/usr/bin/env python 

from uuid import uuid4 as uuid 

from circuits import Component 
from circuits.net.events import close, connect, write 
from circuits.net.sockets import TCPClient, TCPServer 


class Client(Component): 

    channel = "client" 

    def init(self, sock, host, port, channel=channel): 
     self.sock = sock 
     self.host = host 
     self.port = port 

     TCPClient(channel=self.channel).register(self) 

    def ready(self, *args): 
     self.fire(connect(self.host, self.port)) 

    def disconnect(self, *args): 
     self.fire(close(self.sock), self.parent.channel) 

    def read(self, data): 
     self.fire(write(self.sock, data), self.parent.channel) 


class Proxy(Component): 

    channel = "server" 

    def init(self, bind, host, port): 
     self.bind = bind 
     self.host = host 
     self.port = port 

     self.clients = dict() 

     TCPServer(self.bind).register(self) 

    def connect(self, sock, host, port): 
     channel = uuid() 

     client = Client(
      sock, self.host, self.port, channel=channel 
     ).register(self) 

     self.clients[sock] = client 

    def disconnect(self, sock): 
     client = self.clients.get(sock) 
     if client is not None: 
      client.unregister() 
      del self.clients[sock] 

    def read(self, sock, data): 
     client = self.clients[sock] 
     self.fire(write(data), client.channel) 


app = Proxy(("0.0.0.0", 3333), "127.0.0.1", 22) 

from circuits import Debugger 
Debugger().register(app) 

app.run() 
+0

我试图在这个答案中说明的一点是为这类问题使用合适的框架。我只是简单地提倡[Twisted](https://pypi.python.org/pypi/twisted),它也有类似的例子可供使用。 –

+0

其实我试图为了教育目的在较低的水平上解决它,我没有任何压力让工作很快完成。 – user3725459

+0

这完全没问题,但最终你会想要使用像AsyncIO,扭曲,电路或龙卷风。 –