Python 编程https代理时遇到问题-下一步要做什么?
我目前正在制作一个位于浏览器和web之间的代理。除了https,一切都正常。我在理解其中的一些段落时遇到了困难,并且在网上找不到很多资源。所以我被卡住了 我使用的代码是:Python 编程https代理时遇到问题-下一步要做什么?,python,sockets,ssl,Python,Sockets,Ssl,我目前正在制作一个位于浏览器和web之间的代理。除了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
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?
我拿到证书的原因是什么?那之后我需要做什么?(或者,同样的,https下一步通常会发生什么?)
另外,我知道这个问题有点笼统,但请不要对我太苛刻。我曾尝试在web上进行研究,但我一直在寻找用于ssl的加密方法。我真的不知道如何继续。如评论中所述,处理加密的端到端流量的代理只能传递它 下面是一个使用编写的完全工作的代理,它已通过传递和代理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()
如注释中所述,处理加密端到端流量的代理只能将其传递 下面是一个使用编写的完全工作的代理,它已通过传递和代理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()
我还没有测试过这段代码(主要是伪代码),但这应该会让您知道需要做什么
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)
这只是您需要编写的循环概念的一个快速概述。实际上,您可能能够并行处理这两个问题。在关闭连接时,您还需要更加小心一点(允许它以任何顺序发生,同时仍然中继任何一方发送的最后一个数据)。我还没有测试这段代码(它主要是伪代码),但这应该让您知道需要做什么
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)
这只是您需要编写的循环概念的一个快速概述。实际上,您可能能够并行处理这两个问题。在关闭连接时,您还需要更加小心(允许它以任何顺序发生,同时仍然中继任何一方发送的最后一个数据)。HTTPS(SSL)连接是端到端加密的,代理所能做的只是在客户端和服务器之间传递数据,而不是其他。这正是我试图实现的,我不知道怎么做。@Martijn-SSL/TLS不提供端到端加密(尽管我们经常希望这样)。证明了这一承诺没有兑现。有一整类代理用于打破期望,它们带来了自己的一系列问题,因此组织的攻击面通常会增加。请参阅。@jww,该问题主要是由于CA管理不善造成的。SSL/TLS在正确配置时确实提供端到端加密。在主流操作系统/浏览器中拥有证书的CA永远不应该这样做,但一家公司完全可以拥有自己的CA来做到这一点。@Bruno-SSL/TLS在理论上是端到端的,而不是在实践中。理论上,我们应该通过机会加密(ADH或自签名证书)实现端到端安全性。但我们不能丢弃威胁和漏洞以满足我们的定义:)HTTPS(SSL)连接是端到端加密的,代理所能做的只是在客户端和服务器之间传递数据,而不是其他。这正是我试图实现的,但我不确定如何实现。@Martijn-SSL/TLS不提供端到端加密(尽管我们经常希望如此)。演示了该承诺是如何没有实现的。有一整类代理用于打破预期,它们带来了自己的一系列问题,因此组织的攻击面通常会增加。请参阅。@jww,该问题主要是由于CA管理不好。SSL/TLS在正确配置时,确实提供端到端加密。将证书放入主流操作系统/浏览器的CA永远不应该这样做,但一家公司完全可以拥有自己的CA来做到这一点。@Bruno-SSL/TLS在理论上是端到端的,而不是在实践中。理论上,我们应该通过机会加密(ADH或自签名证书)实现端到端的安全性.但我们不能抛弃威胁和漏洞以适应我们的定义:)我在回答中试图说明的一点是,对这类问题使用合适的框架。我只是很容易地提倡,它也有类似的例子准备好了。实际上,出于教育目的,我正在尝试在较低的层次上解决它,我没有任何压力来快速完成工作。这完全是好的,但最终你会想使用AsyncIO、Twisted、,我想在这个答案中说明的一点是,对这类问题使用一个合适的框架。我只是很容易地提倡,也有类似的例子准备好了。实际上,为了教育的目的,我正在尝试在较低的层次上解决它,我没有任何压力来快速完成工作。这很好,但最终你会想使用AsyncIO、Twisted、circuits或Tornado。谢谢你的帮助,我已经在这上面做了一点修改,而且很有效!我的代码也主要是伪代码;)谢谢你的帮助,我已经在这上面黑了一点,它工作了!我的代码也主要是伪代码;)