Connect X und Y über Z

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Zwei PCs X und Y sollen miteinander kommunizieren. Die Verbindung soll aber über einen zentralen Server Z initiiert werden, der zuvor beide PCs authentifiziert.

Ähnlich wie bei ICQ oder Skype also...

PC X verbindet sich zu Server Z und fordert einen Verbindungsaufbau mit PC Y an. Server Z authentifiziert beide PCs. Wenn beide die sind, wofür sie sich auszugeben scheinen, verbindet Server Z die PCs X und Y direkt und klinkt sich aus. Von nun an kommunizieren beide PCs direkt miteinander.

Wie könnte ich sowas in Python realisieren?
BlackJack

Im Grunde so wie Du's beschreibst. Du müsstest vielleicht noch mal genauer heraus arbeiten wer wen, wann kennt und wie genau die Reihenfolge der Kommunikation sein soll. Einfachstes Szenario:

X --- anmelden/authentifizieren ---> Z
Y --- anmelden/authentifizieren ---> Z
X --- Verbindungswunsch mit Y ---> Z
Z --- Adresse von Y ---> X
X --- Kontaktaufnahme --> Y
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Stellt euch das am besten als Client (X), Server (Y) und zentrale Vermittlung (Z) vor. Client und Server dürfen nicht direkt miteinander kommunizieren, weil beide nicht sicherstellen können, ob der Gegenpart authorisiert ist. X und Y vertrauen nur Z.

Üblicherweise möchte sich X mit Y verbinden. Dazu schickt X an Z die Message "Ich möchte mich mit Y verbinden!". Z prüft X auf seine Vertrauenswürdigkeit. Wenn OK, dann prüft Z auch die Vertrauenswürdigkeit von Y. Wenn beides OK ist, muss Z nun X und Y direkt miteinander verkuppeln und sich ausklinken.

Die Verbindung kam nur durch Z zustande, am Ende aber sind X und Y direkt miteinander verbunden. Wenn X ein Client und Y ein Server ist, fungiert Z zunächst als eine Art Proxy, der als Server für X und als Client für Y dient.

Verständlich, wie ich das meine?
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Puh, der Begriff "Kerberos" ist mir schon öfter über den Weg gelaufen, hab ihn aber immer als eigenständiges Produkt betrachtet. Es handelt sich also vielmehr um ein Netzwerkprotokoll? Und mit Python kann man einen Kerberos-Server erstellen?

Klinkt sich der Kerberos-Server nach der Verifizierung und Verbindungsaushandlung eigentlich aus und entsteht somit eine Direktverbindung zwischen Server und Client?

Puh, da das nun ein total neues Thema für mich ist: Gibt es Beispiele für Server, Client und Kerberos-Server basierend auf Python? Wäre super, danke!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

droptix hat geschrieben:Puh, der Begriff "Kerberos" ist mir schon öfter über den Weg gelaufen, hab ihn aber immer als eigenständiges Produkt betrachtet.
Hallo droptix!

Ich würde mit Python keinen Kerberos-Server schreiben wollen.

Du kannst aber eine Kerberos-Umgebung verwenden um dich gegenüber anderen Computern zu identifizieren.

Grob gesagt: Du authentifizierst dich gegenüber einem Kerberos-Server. Dieser gibt dir ein Ticket und mit diesem Ticket kannst du dich gegenüber einem anderen Programm/Server/Computer identifizieren. Du zeigst das passende Ticket vor und schon darfst du rein.

Kerberos ist allerdings ein recht komplexes Thema. Wenn dir Sicherheit nicht so wichtig ist, dann kannst du zumindest eine ähnliche Strategie in Python nachprogrammieren.

Du authentifizierst dich gegenüber einem Haupt-Serverprogramm und fragst nach, wen du kontaktieren darfst. Das Haupt-Serverprogramm gibt dir eine Zieladresse und ein Ticket -- z.B. eine GUID.

Mit dieser Zieladresse verbindest du dich zum Unter-Serverprogramm und gibst diesem deine soeben erhaltene GUID. Das Unter-Serverprogramm (da es ja nicht so kompliziert wie Kerberos ist) verbindet sich zum Haupt-Serverprogramm, übergibt diesem seine eigene GUID (zur Sicherheit) und fragt nach, ob jemand mit der IP-Adresse X und der GUID Y rein gelassen werden darf.

Das OK kommt vom Serverprogramm zurück und schon kann die Kommunikation beginnen. --- Alle paar Minuten fragt das Unter-Serverprogramm beim Haupt-Server nach, ob auch wirklich noch alles in Ordnung ist mit der GUID des Clients und ob dieser immer noch verbunden sein darf.

Das ist zwar nicht so sicher wie Kerberos, aber wenn die Verbindung zwischen den Programmen verschlüsselt abläuft -- z.B. per XMLRPC over HTTPS, SSH, OpenVPN,... -- dann ist es auf jeden Fall besser als wenn du nichts machst um die Sicherheit zu erhöhen.

Der Vorteil bei Kerberos wäre der, dass nur der identifizierte Client etwas mit dem Ticket anfangen kann. Auch wenn ich so ein Ticket abfange, kann ich nichts damit machen. Genaues kann ich dir leider nicht darüber sagen, da ich mich nie dafür interessiert habe.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Im Prinzip hatte ich genau das vor. Ich dachte jetzt nur, es gibt für Kerberos vielleicht entsprechende Python-Module. Da ich Standards mag, hätte ich das vorgezogen.

Die selbst-programmierte Routine kriege ich sicherlich hin. Über SSL/TLS ist das denke ich auch ausreichend sicher. Ich dachte aber eher daran, dass der Vermittlungsserver (Z) vom Client (X) angesprochen wird und Z anschließend eine Verbindung zum Server (Y) aufbaut.

Der Server (Y) soll jede unsichere Verbindung abweisen bzw. auch jede, die nicht mit dem Zertifikat des Vermittlungsservers (Z) übereinstimmt. Ein Client (X) soll also nicht die Verbindung initiieren…

Fragt sich natürlich ob das unbedingt nötig ist… das mit dem Ticket ist auch eine gute Idee. Dann brauch ich es auch nicht zu bewerkstelligen, dass sich Z ausklinkt, um X und Y direkt zu verkoppeln.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Ich muss hier doch nochmal nachhaken. Da es sein kann, dass der Server (Y) hinter einer Firewall steckt, kann sich der Client (X) nicht immer direkt mit Y verbinden. Einzig der Port für den Vermittlungsserver (Z) ist durch die Firewall freigegeben.

Somit geht die Idee von oben leider nicht auf. Daher sprach ich ganz am Anfang auch von ICQ und Skype, die sich ja durch die Firewall bohren können, weil die Firewall ausgehende Verbindungen zulässt. Die Server von ICQ und Skype halten irgendwie die Verbindung aufrecht und kehren sie um… Wie das genau funktioniert weiß ich nicht, aber es geht. Somit können sie zwei PCs direkt miteinander verbinden und sich anschließend ausklinken.

Wie kann man so etwas mit Python bauen?
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Bei Skype heisst das Stichwort UDP hole punching. Wie das genau funktioniert, weiss ich allerdings auch nicht...
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Wie ich dort nachlesen konnte, funktioniert das nicht ohne Einschränkungen, da NAT nicht standardisiert ist und es Abweichungen geben kann. Allerdings kenne ich niemanden, bei dem ICQ und Skype nicht funktionieren.

In meinem Fall ist die Vorgehensweise aber etwas anders als bei Wikipedia beschrieben, da sich nicht zwei Clients zum Vermittlungsserver verbinden, sondern nur einer. Der kommt mit der Bitte, sich zu einem Server verbinden zu dürfen. Der Vermittlungsserver initiiert die gewünschte Verbindung und verkoppelt dann. Es gibt dann also eine eingehende und eine ausgehende Verbindung. Damit der Vermittlungsserver nicht alle Daten durchschleifen muss und unnötig Last erzeugt, soll der die Kommunikationswege "verbinden" und sich dann ausklinken. Bildlich könnte man sich das so vorstellen:
1) X ---> Z ---> Y (durchschleifen)
2) X ------> Y (nach dem Ausklinken)
Bei ICQ und Skype sind es zwei eingehende Verbindungen, die der Vermittlungsserver verkoppeln muss. Das stelle ich mir schwieriger vor, weil ja irgendwie die Verbindungen auch umgekehrt werden müssen, damit eine bidirektionale Kommunikation möglich wird.
1) X ---> Z <--- Y (zwei eingehende Verbindungen)
2) X ---> Z ---> Y (Verbindungen wird umgekehrt)
3) X ------> Y (nach dem Ausklinken)
Antworten