Lassen Sie Xorg auf TCP lauschen, aber nur auf localhost?

12

Ich habe ein X-Client-Programm, das Zugriff auf einen X-Server benötigt. Es kann nur über TCP auf den X-Server zugreifen, nicht über andere Methoden wie Unix-Domain-Sockets. Es wird auf demselben Host wie der Server ausgeführt, um die Arbeit zu vereinfachen.

Wie kann ich meinen Xorg-Server dazu bringen, den TCP-Port 6000 abzuhören, aber nur auf Verbindungen von localhost?

Ich habe gefunden, wie X.org Remoteverbindungen auf Port 6000 abhören kann. , in dem erklärt wird, wie der Zugriff für Remote-Hosts aktiviert wird, ich möchte jedoch keinen Remote-Zugriff (hauptsächlich aus Sicherheitsgründen).

Ich dachte darüber nach, den Standardtransport irgendwie an TCP weiterzuleiten, fand aber keine Informationen darüber, was der Standardtransport ist.

(Ich verwende hier kdm als Display-Manager, aber ich denke, ich kann Lösungen entweder für den Display-Manager übertragen oder sogar den Display-Manager wechseln.)

Irgendwelche Ideen?

Dies ist am 11.04 in einer gemischten Kubuntu-Ubuntu-XUbuntu-Installation (ursprünglich Kubuntu, aber ich habe ubuntu-desktop und xubuntu-desktop hinzugefügt. Beim Booten heißt es jetzt Xubuntu 11.04). Ich benutze jetzt den gnome-klassischen Desktop von KDM.

Paŭlo Ebermann
quelle
Für alle, die sich fragen, was dieser X-Client ist: Es handelt sich tatsächlich um eine Java-SSH-Implementierung ( JSch ), die versucht, X-Weiterleitungen an einen anderen Host durchzuführen . Ich denke, Java kann nicht wirklich auf Unix-Domain-Sockets zugreifen. Das gleiche Problem würde auch für ein anderes (jetzt angehaltenes) Projekt von mir gelten, bei dem ich einen X-Client in reinem Java implementieren wollte (z. B. durch Lesen / Schreiben eines Sockets, ohne eine Fensterbibliothek zu verwenden).
Paŭlo Ebermann
@Paulo, Java kann tatsächlich Unix-Domain-Sockets verwenden (Sie können eine native Bibliothek schreiben, die den Zugriff auf benötigte Syscalls ermöglicht, oder nur bereits geschriebene finden). Aber dann, fwiw, verlieren Sie effektiv den Hauptvorteil von Java: hohe Portabilität. Wenn Sie also wirklich viel Zeit benötigen, können Sie ganz einfach eine X-Client-Bibliothek in Java schreiben, die über PF_LOCAL funktioniert. Beachten Sie auch, dass die TCP-über-Loopback-Schnittstelle einen viel höheren Overhead als der Standard-Unix-Socket hat.
ulidtko
Ja, ich habe einige Bibliotheken gefunden, aber das hilft mir nicht, solange ich die aktuelle UDS-Adresse nicht kenne. Ist das irgendwo dokumentiert?
Paŭlo Ebermann
1
@Paulo, Unix-Domain-Sockets verwenden normalerweise den Namespace des Dateisystems. Ihre Adressen sind Dateinamen . Die jeweiligen Dateiknoten sind "spezielle Socket-Dateien". Auf meinem System habe ich zahlreiche Verbindungen zu /tmp/.X11-unix/X0- dies ist ein Beispiel für eine AF_UNIX-Adresse (verwenden Sie diese netstat -x, um Ihre eigene zu sehen). Die X11-Protokollspezifikation sollte die genauen Adressen bestimmen, mit denen eine Verbindung hergestellt werden soll. Und Sie MÜSSEN es wirklich lesen, wenn Sie eine Client-Bibliothek für dieses Protokoll schreiben.
ulidtko
1
/tmp/.X11-unix/X0Existiert hier auch ein Socket (OpenSUSE), werde ich zu Hause nochmal nachschauen (auf dem in der Frage genannten Ubuntu-System). Jetzt muss ich nur noch sehen, wie man das um 6000 an einen TCP-Socket weiterleitet.
Paŭlo Ebermann

Antworten:

8

Sieht aus wie eine Problemumgehung wäre die Verwendung von socat. Hier ist eine Befehlszeile, die zu funktionieren scheint, wenn der X-Server noch nicht auf TCP läuft:

socat -d -d TCP-LISTEN:6000,fork,bind=localhost UNIX-CONNECT:/tmp/.X11-unix/X0

Dann kann ich machen

xlogo -display localhost:0

Seltsamerweise scheint es nicht zu funktionieren, wenn ich es auf 6001 hören lasse und dann das Display spezifiziere localhost:1anstatt localhost:0- das bekomme ich No protocol specified. Scheint, ich muss das X-Protokoll noch einmal lesen. (Und über JSch hört es dann auf Invalid MIT-MAGIC-COOKIE-1 key, aber das ist ein anderes Problem.)

Paŭlo Ebermann
quelle
Ja!! Ich hatte nach einer Möglichkeit gesucht, xserver-allow-tcp=true nachdem X bereits ohne Neustart mit -nolisten tcp in gestartet worden war /etc/X11/xinit/xserverrc. Nur in meinem Fall, bind=0.0.0.0um meine externen Hosts zuzulassen.
Marcos
5

Der Xorg-Code hat derzeit keine Option zum Steuern, welche Schnittstellen abgehört werden sollen. Das Hinzufügen sollte nicht schwierig sein, aber es sollte noch einfacher sein, Ihre Firewall so zu konfigurieren, dass eingehende Verbindungen zu Port 6000 von anderen Computern blockiert werden.

alanc
quelle
2

Nur ein paar andere Gedanken ...

  1. Zulassen, aber mit xhost blockieren (und / oder Netzwerkfilterung)

Die herkömmliche Methode besteht darin, dass der X-Server den TCP-Socket überwacht und mit xhost ermittelt, welche Hosts eine Verbindung herstellen dürfen. Siehe Manpage für xhost (1). (Zusätzlich würde natürlich auch hier die IP-Adress- und Portfilterung helfen, wie frühere Vorschläge angemerkt haben.)

  1. Lauschen Sie nur auf der lokalen Schnittstelle

Laut dem obigen Kommentar von alanc gibt es derzeit keinen Code, aber fast!

Denken Sie daran, dass (fast) alle Hosts mindestens zwei Schnittstellen haben, die Loopback-Schnittstelle lo0 (immer 127.0.0.1) und die normale Ethernet-Schnittstelle eth0 (oder wlan0 oder was auch immer, sagen wir 192.168.0.128) und viele weitere. Normalerweise erlauben TCP / IP-Server (dh X-Server) eingehende Verbindungen zu einer ihrer IP-Adressen an einer ihrer Schnittstellen, aber die meisten Programme lassen Sie eine IP-Adresse angeben, wenn Sie möchten. Die eigentliche Arbeit erledigt bind (2), das entweder INADDR_ANY (0.0.0.0) oder eine echte IP-Adresse annimmt.

Der Xorg-Server implementiert -name local-address, aber leider nur für XDMCP (siehe Datei os / xdmcp.c, die es meines Wissens korrekt implementiert). Die eigentliche Verbindung für das X-Protokoll wird, glaube ich, von SocketINETCreateListener hergestellt in der Datei /usr/include/X11/Xtrans/Xtranssock.c, die die Adresse auf INADDR_ANY setzt und dann ohne weitere Verarbeitung daran bindet. Was benötigt wird, ist das Flag -from (das von os / xdmcp.c als FromAddress behandelt wird), um sich kurz vor SocketCreateListener () in Xtranssock.c mit der Variablen 'sockname' zu verbinden. Das Problem ist natürlich, dass alle Transportaufgaben wirklich transportneutral erledigt werden, so dass es ein bisschen schwierig ist, die Informationen in Xtranssock.c zu bekommen.

Dateipfade und so weiter können variieren. Dies wurde mit Ubuntu 10.04 LTS untersucht. Beachten Sie, dass sich die Funktionsnamen in Xtranssock.c durch ein Makro TRANS geändert haben. http://cgit.freedesktop.org/xorg/xserver/tree/os/xdmcp.c

Hoffe, das ist von Nutzen.

Mit freundlichen Grüßen

Jonathan.

Jonathan
quelle
Im Moment verwende ich die Magic Cookie-Authentifizierung, daher sind selbst Verbindungen von demselben Host nicht zulässig. xhostwürde den Zugang erweitern, nicht verkleinern.
Paŭlo Ebermann,
Und ich glaube nicht, dass ich mich in meinen X-Server hacken werde, aber danke für den Vorschlag, wo ich das machen soll.
Paŭlo Ebermann
9 Jahre später und das hat sich nicht geändert. gitlab.freedesktop.org/xorg/lib/libxtrans/blob/master/…
daveloyall