2010-06-25 4 views
8

Kürzlich habe ich mit dem HTTP-Proxy in verdreht gespielt. Nach viel Versuch und Irrtum denke ich, dass ich endlich etwas arbeite. Was ich jedoch wissen möchte, ist, wie, wenn es möglich ist, erweitere ich diesen Proxy, um auch mit HTTPS-Seiten umgehen zu können? Hier ist, was ich bisher habe:Konvertieren von HTTP-Proxy zu HTTPS-Proxy in Twisted

from twisted.internet import reactor 
from twisted.web import http 
from twisted.web.proxy import Proxy, ProxyRequest, ProxyClientFactory, ProxyClient 



class HTTPProxyClient(ProxyClient): 
    def handleHeader(self, key, value): 
     print "%s : %s" % (key, value) 
     ProxyClient.handleHeader(self, key, value) 

    def handleResponsePart(self, buffer): 
     print buffer 
     ProxyClient.handleResponsePart(self, buffer) 

class HTTPProxyFactory(ProxyClientFactory): 
    protocol = HTTPProxyClient 

class HTTPProxyRequest(ProxyRequest): 
    protocols = {'http' : HTTPProxyFactory} 

    def process(self): 
     print self.method 
     for k,v in self.requestHeaders.getAllRawHeaders(): 
      print "%s : %s" % (k,v) 
     print "\n \n" 

     ProxyRequest.process(self) 

class HTTPProxy(Proxy): 

    requestFactory = HTTPProxyRequest 


factory = http.HTTPFactory() 
factory.protocol = HTTPProxy 

reactor.listenSSL(8001, factory) 
reactor.run() 

Da dieser Code demonstriert, zum Wohle Beispiel für jetzt bin ich nur Druck aus, was durch die Verbindung geht. Ist es möglich, HTTPS mit den gleichen Klassen zu behandeln? Wenn nicht, wie sollte ich eine solche Sache umsetzen?

+0

Wie möchten Sie das Problem der Serverzertifikatsvertrauensstellung behandeln? – MattH

+0

MattH, ich arbeite mit einem anderen Programmierer für dieses Projekt zusammen und er hat bereits herausgefunden, wie man das SSL-Zertifikat in Twsited bekommt. Anscheinend können Sie laufen: reactor.listenSL (Hafen, Fabrik, CERT) und Sie können HTTPS Verbindungen hören. Obwohl, wenn Sie wissen über das Thema sind, würde ich definitiv jede Eingabe zu schätzen wissen! – themaestro

+0

Wie Marcus Adams darauf hinweist. Sie haben das Problem der Zertifikatsvertrauensstellung. Wenn ein Webbrowser für die Verwendung eines Proxy für HTTPS konfiguriert ist, sendet er einen "connect host: port" und erwartet, dass er an den Server weitergeleitet wird. Der beteiligte Proxy sieht nur den verschlüsselten SSL-Verkehr, den er zwischen Client und Server vermittelt. Wenn Sie sich auf magische Weise als Server für den Client ausgeben möchten, müssen Sie den Client dazu bringen, Ihrem Zertifikat zu vertrauen, um auf die Website zugreifen zu können, die der Client besuchen möchte. – MattH

Antwort

12

Wenn Sie eine Verbindung zu einer HTTPS-Website über einen HTTP-Proxy herstellen möchten, müssen Sie das HTTP-Verb CONNECT verwenden (weil so ein Proxy für HTTPS funktioniert). In diesem Fall verbindet sich der Proxy-Server einfach mit dem Zielserver und leitet alle vom Server gesendeten Daten zurück an den Socket des Clients (und umgekehrt). In diesem Fall ist kein Caching erforderlich (Sie können jedoch möglicherweise die Hosts protokollieren, mit denen Sie eine Verbindung herstellen).

Der Austausch wird so (Client-Proxy) aussehen:

C->P: CONNECT target.host:443 HTTP/1.0 
C->P: 

P->C: 200 OK 
P->C: 

Danach öffnet sich der Proxy einfach eine einfache Buchse an den Zielserver (keine HTTP oder SSL/TLS noch) und leitet alles zwischen der ursprüngliche Client und der Zielserver (einschließlich des TLS-Handshakes, den der Client initiiert). Der Client aktualisiert den vorhandenen Socket, den er für den Proxy hat, um TLS/SSL zu verwenden (indem er den SSL/TLS-Handshake startet). Sobald der Client die Statuszeile '200' gelesen hat, ist es für den Client so, als hätte er direkt die Verbindung zum Zielserver hergestellt.

+0

Ich habe schwer zu verstehen, wie Sie das genau machen. Ich bekomme den ganzen Prozess, aber wenn es wirklich darauf ankommt, verstehe ich nicht, wie "Proxy einfach einen einfachen Socket zum Zielserver öffnet". Client sendet CONNECT, dann antwortet Server 200 und öffnet den Server-Socket. Das ist einfach. Nun wird der Client, der sendet, über diesen Socket gesendet, aber ich weiß nicht, wie ich das machen soll. Wie kann ich feststellen, an welchen Socket ein Client etwas sendet, wenn mehrere Verbindungen bestehen? Wie "ordne" ich eine Client-Verbindung zu, die Daten an den bereits geöffneten Socket an den Zielserver weiterleitet? – stewenson

+0

@stewenson der Server haben die Client-Verbindung, wenn der Client CONNECT Anfrage senden, so nach der Serverantwort 200 OK, tun Sie einfach alles Raw-Socket kann mit der TCP-Verbindung tun. – schemacs

1

Ich bin mir nicht sicher über verdreht, aber ich möchte Sie warnen, dass ein Webbrowser, wenn Sie einen HTTPS-Proxy implementieren, das SSL-Zertifikat des Servers mit dem Domänennamen in der URL (Adressleiste) erwarten. Der Webbrowser wird andernfalls Sicherheitswarnungen ausgeben.

Es gibt verschiedene Möglichkeiten, z. B. das Erstellen von Zertifikaten im laufenden Betrieb, aber Sie müssen das Stammzertifikat als vertrauenswürdig im Browser verwenden.

+0

Dies gilt für einen Reverse-Application-Layer-Proxy oder einen transparenten Proxy. Die Frage gibt nicht an, welche Art von Proxy er für welchen Zweck benötigt. – MattH

+0

Zur Klärung: Um zu beginnen, möchte ich einfach einen HTTPS-Proxy schreiben, der nur den gesamten Verkehr über die Verbindung abhören und ihn ausdrucken/protokollieren kann. Beispiel: Client -> Anfrage an SSL-verschlüsselte Site -> Proxy-Intercepts -> sendet an Ziel SSL-Server -> Antwort -> Proxy abfängt und liest -> Client – themaestro

+0

@MattH, das Beispiel zeigt deutlich ein Application-Layer-Proxy und kein umgekehrter. Sie können dies als transparenten Proxy bezeichnen oder nicht, je nachdem, wie das OP es verwendet. –