(Nur ein Konzept/"
RFC" bisher)
Es gibt ja diverse Umgebungen (Arbeit, Schule, Uni, blah), in denen man zwar sein eigenes Laptop anschließen kann, aber entweder aller Datenverkehr zu Ports außer 80/443 geblockt ist oder man gezwungen wird, über einen Squid o.ä. (womöglich noch mit Filter-Regeln) zu surfen. In der Regel ist im letzteren Fall auch die HTTP-Methode "CONNECT" deaktiviert oder wieder nur für Port 443 erlaubt, so dass man weitgehend chancenlos ist, wenn man ICQ,
IRC,
FTP,
SSH oder sonstwas benutzen will.
Wir gehen also mal davon aus, dass:
1. Wir uns in einer Umgebung befinden, in der die einzige Möglichkeit,
TCP-Verbindungen nach außen aufzubauen, im Senden von gültigen HTTP-Anforderungen an Port 80 eines beliebigen "entfernten" Servers besteht.
2. Wir die Möglichkeit haben, Programmcode (
PE/ELF Binary) lokal auszuführen und auf einem Port an 127.0.0.1 zu lauschen.
3. In der Anwendung, die wir gerne einsetzen würden (ICQ, Putty, whatever) die Möglichkeit besteht, einen Socks5-Proxy zu verwenden.
4. Wir eine zweite Maschine irgendwo "draußen" stehen haben, auf der wir auf einem Port auf Verbindungen aus dem Internet lauschen können und die sonst in ihrer Konnektivität bezüglich ausgehender Verbindungen nicht eingeschränkt ist.
Nun frage ich mich, was spricht dagegen folgende Lösung zu implementieren (d.h. warum hats noch niemand gemacht?).
Das Client-Programm
Das CP verhält sich allen Anwendungen gegenüber wie ein regulärer Socks5-Proxy, lauscht auf einem Port auf der lokalen Maschine und nimmt dort entsprechend sämtliche Verbindungswünsche von anderen Anwendungen entgegen.
Im CP ist die Adresse des Servers der "Gegenseite" (mehr dazu unten) eingestellt.
Das CP hält gemäß dem Socks5-Protokoll alle eingehenden Verbindungen solange offen, bis die Anwendung, die die Verbindung aufgebaut hat, diese wieder schließt (oder sie auf andere Art/Weise geschlossen wird, you get the idea).
Das Client-Server-Protokoll
Während
TCP-Verbindungen normalerweise natürlich stateful sind, müssen sie hier durch einen stateless HTTP-Proxy getunnelt werden. Zu diesem Zweck werden HTTP POST-Anforderungen verwendet, die an das Server-Programm (SP, siehe unten) gesendet werden. Dabei sind mindestens vier Typen zu unterscheiden: connect (neue Verbindung), disconnect (Verbindung schließen), data_send (Daten senden) und data_wait (auf eingehende Daten warten).
Da kommt auch schon der Knackpunkt: Wie kommen Daten vom Server zum Client? Dazu kann man sich etwas vom COMET-Prinzip abschauen. Das CP sollte versuchen, immer eine Verbindung zum SP offen zu halten, also eine HTTP-Anforderungen senden und auf Antwort warten. Hat das SP neue Daten, so wird es sie durch diese bestehende Verbindung zum Client senden (als HTTP Response natürlich). Nach einer bestimmten Zeit ohne Datenverkehr (o.ä.) sollte die Verbindung dann beendet werden und das CP eine neue mit dem selben Zweck aufbauen.
Die Synchronisation zwischen den verschiedenen Verbindungen geschieht über eine eindeutige ID, die beim Verbindungsaufbau vom CP vergeben, dem SP mitgeteilt und fortan zusammen mit jeder Anforderung und jeder Antwort gesendet wird.
Das Server-Programm
Das SP hält entsprechend dem bisher vorgestellten Prinzip die eigentlichen
TCP-Verbindungen, die vom CP angefordert wurden, offen. Kommen Daten an (vom
IRC/ICQ/
SSH/blubb-Server), so werden diese gepuffert und an das CP gesendet, sobald dieses eine Verbindung zum SP aufbaut (siehe Protokoll).
Dazu muss es natürlich als HTTP-Server auf einem passenden Port lauschen und dort die Anforderungen vom CP entgegennehmen.
Mögliche Erweiterungen
- Transparente Verschlüsselung (entweder über OpenSSL und Port 443 oder eine proprietäre Lösung, die nur die Nutzdaten verschlüsselt).
Das Ganze ist sicher nicht für online gaming o.ä. geeignet, da durch das "COMET like" Prinzip sicher einiges an Verzögerung entsteht, sollte aber für viele Anwendungen durchaus möglich sein. Problematisch könnte es werden, SSL-Verbindungen zu tunneln, mit ein bisschen Bastelei dürfte sich aber auch das bewerkstelligen lassen.
--
Soweit meine Spinnerei. Ist natürlich nicht einfach, das ganze zuverlässig zu implementieren, trotzdem wundert es mich, dass es sowas bisher noch nicht gibt. Qualifizierte Kommentare sind willkommen!