Laisser Xorg écouter sur TCP, mais uniquement sur localhost?

12

J'ai un programme client X qui a besoin d'accéder à un serveur X. Il ne peut accéder au serveur X que par TCP, pas par d'autres méthodes comme les sockets de domaine Unix. Il fonctionnera sur le même hôte que le serveur, pour faciliter les choses.

Alors, comment puis-je faire en sorte que mon serveur Xorg écoute sur le port TCP 6000, mais uniquement pour les connexions de l'hôte local?

J'ai trouvé Comment faire pour que X.org écoute les connexions à distance sur le port 6000? , ce qui explique comment activer l'accès pour les hôtes distants, mais je ne veux pas vraiment l'accès à distance (pour des raisons de sécurité, principalement).

J'ai pensé à transférer le transport par défaut vers TCP, mais je n'ai pas vraiment trouvé d'informations sur le transport par défaut.

(J'utilise kdm comme gestionnaire d'affichage ici, mais je pense que je peux transférer des solutions pour le gestionnaire d'affichage, ou même changer de gestionnaire d'affichage.)

Des idées?

C'est le 11.04 sur une installation mixte Kubuntu-Ubuntu-XUbuntu (à l'origine Kubuntu, mais j'ai ajouté ubuntu-desktop et xubuntu-desktop. Au démarrage, il est maintenant dit Xubuntu 11.04). J'utilise maintenant le bureau gnome-classic, je pense, de KDM.

Paŭlo Ebermann
la source
Pour tous ceux qui se demandent ce qu'est ce client X: il s'agit en fait d'une implémentation Java SSH ( JSch ) qui essaie de faire le transfert X vers un autre hôte. Java ne peut pas vraiment accéder aux sockets de domaine Unix, je pense. Le même problème s'appliquerait également à un autre projet (maintenant en pause), où je voulais implémenter un client X en Java pur (par exemple en lisant / écrivant un socket, sans utiliser de bibliothèque de fenêtrage).
Paŭlo Ebermann
@Paulo, java peut en fait utiliser des sockets de domaine Unix (vous pouvez écrire une bibliothèque native qui donnera accès aux appels système nécessaires, ou tout simplement trouver déjà écrite). Mais alors, fwiw, vous perdez effectivement le principal avantage de java: une portabilité élevée. Donc, si vous aviez vraiment besoin de dur, vous pourriez assez facilement écrire la bibliothèque client X en java qui fonctionnerait sur PF_LOCAL. Notez également que l'interface TCP over loopback a une surcharge beaucoup plus élevée que le socket Unix standard.
ulidtko
Oui, j'ai trouvé des bibliothèques, mais cela ne m'aidera pas tant que je ne connais pas l'adresse UDS réelle. Est-ce documenté quelque part?
Paŭlo Ebermann
1
@Paulo, les sockets de domaine Unix utilisent généralement l'espace de noms du système de fichiers. Leurs adresses sont des noms de fichiers . Les nœuds de fichiers respectifs sont des "fichiers socket spéciaux". Sur mon système, j'ai de nombreuses connexions /tmp/.X11-unix/X0- c'est un exemple d'adresse AF_UNIX (utilisez netstat -xpour voir la vôtre). La spécification du protocole X11 doit déterminer les adresses exactes auxquelles se connecter. Et vous DEVEZ vraiment le lire si vous écrivez une bibliothèque cliente pour ce protocole.
ulidtko
1
/tmp/.X11-unix/X0existe aussi comme socket ici (OpenSUSE), je vais vérifier à nouveau à la maison (sur le système Ubuntu nommé dans la question). Maintenant, je n'ai plus qu'à voir comment transmettre cela à un socket TCP à 6000.
Paŭlo Ebermann

Réponses:

8

On dirait qu'une solution de contournement serait l'utilisation de socat. Voici une ligne de commande qui semble fonctionner, si le serveur X ne fonctionne pas déjà sur TCP:

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

Alors je peux faire

xlogo -display localhost:0

Étrangement, cela ne semble pas fonctionner si je le laisse écouter sur 6001, puis spécifie l'affichage localhost:1au lieu de localhost:0- je comprends No protocol specified. On dirait que je vais devoir relire le protocole X. (Et sur JSch, il s'arrête alors avec Invalid MIT-MAGIC-COOKIE-1 key, mais c'est un autre problème.)

Paŭlo Ebermann
la source
Oui!! Je cherchais un moyen de faire xserver-allow-tcp=true après que X ait déjà été démarré avec -nolisten tcp in /etc/X11/xinit/xserverrcsans redémarrer. Seulement dans mon cas, bind=0.0.0.0pour autoriser mes hôtes externes.
Marcos
5

Le code Xorg n'a actuellement aucune option pour contrôler les interfaces sur lesquelles écouter. Il ne devrait pas être difficile à ajouter, mais il devrait être encore plus facile de simplement configurer votre pare-feu pour bloquer les connexions entrantes vers le port 6000 à partir d'autres machines.

alanc
la source
2

Juste quelques autres réflexions ...

  1. Autoriser mais bloquer avec xhost (et / ou filtrage réseau)

La méthode traditionnelle consiste à écouter le serveur X sur le socket TCP et à utiliser xhost pour déterminer les hôtes autorisés à se connecter. Voir la page de manuel de xhost (1). (En outre, bien sûr, le filtrage des adresses IP et des ports aiderait ici aussi, comme l'ont noté les suggestions précédentes.)

  1. Écoute uniquement sur l'interface locale

Selon le commentaire d'Alanc ci-dessus, il n'y a pas de code maintenant, mais presque!

Rappelez-vous que (presque) tous les hôtes ont au moins deux interfaces, l'interface de bouclage lo0 (toujours 127.0.0.1) et l'étheth Ethernet normal (ou wlan0 ou autre, qui est disons 192.168.0.128) et beaucoup en ont plus. Habituellement, les serveurs TCP / IP (c'est-à-dire le serveur X) autorisent les connexions entrantes vers n'importe laquelle de leurs adresses IP sur n'importe laquelle de leurs interfaces, mais la plupart des logiciels vous permettent de spécifier une adresse IP si vous le souhaitez. Le travail réel est effectué par bind (2), qui prend INADDR_ANY (0.0.0.0) ou une véritable adresse IP.

Le serveur Xorg implémente -name local-address mais malheureusement ce n'est que pour XDMCP (voir le fichier os / xdmcp.c qui l'implémente correctement pour autant que je sache.) La connexion réelle pour le protocole X, je crois, est effectuée par SocketINETCreateListener dans le fichier /usr/include/X11/Xtrans/Xtranssock.c, qui définit l'adresse sur INADDR_ANY, puis s'y lie sans autre traitement. Ce qui serait nécessaire est le drapeau -from (qui est traité par os / xdmcp.c comme FromAddress) pour se connecter en quelque sorte à la variable 'sockname' juste avant SocketCreateListener () dans Xtranssock.c. Le problème, bien sûr, est que toutes les opérations de transport sont réellement effectuées de manière neutre pour le transport, il est donc un peu délicat d'entrer les informations dans Xtranssock.c.

Les chemins de fichiers et ainsi de suite peuvent varier, a été examiné avec Ubuntu 10.04 LTS, et notez que les noms de fonction dans Xtranssock.c ont été modifiés par une macro TRANS. http://cgit.freedesktop.org/xorg/xserver/tree/os/xdmcp.c

J'espère que cela vous sera utile.

Sincères amitiés

Jonathan.

Jonathan
la source
Pour l'instant, j'utilise l'authentification par cookie magique, donc même les connexions du même hôte ne seront pas autorisées. xhostélargirait l'accès, ne le rétrécirait pas.
Paŭlo Ebermann
Et je ne pense pas que je vais pirater mon serveur X, mais merci pour la suggestion sur où le faire.
Paŭlo Ebermann
9 ans plus tard et cela n'a pas changé. gitlab.freedesktop.org/xorg/lib/libxtrans/blob/master/…
daveloyall