Let Xorg listen on TCP, but only to localhost?

I have some X client program which needs access to an X server. It is only able to access the X server by TCP, not by other methods like unix domain sockets. It will run on the same host as the server, to make things easy.

So, how can I make my Xorg server to listen on TCP port 6000, but only for connections from localhost?

I found How to make X.org listen to remote connections on port 6000?, which explains how to enable access for remote hosts, but I don't really want remote access (for security reasons, mainly).

I thought about somehow forwarding the default transport to TCP, but I didn't really find information about what the default transport is.

(I'm using kdm as my display manager here, but I think I can transfer solutions for either display manager, or even switch the display manager.)

Any ideas?

This is on 11.04 on a mixed Kubuntu-Ubuntu-XUbuntu installation (originally Kubuntu, but I added ubuntu-desktop and xubuntu-desktop. On boot it is now saying Xubuntu 11.04). I'm now using the gnome-classic desktop, I think, from KDM.


Solution 1:

Looks like a workaround would be the use of socat. Here is a command line which seems to work, if the X server does not already run on TCP:

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

Then I can do

xlogo -display localhost:0

Strangely, it does not seem to work if I let it listen on 6001 and then specify the display localhost:1 instead of localhost:0 - I get No protocol specified. Seems I'll have to read the X protocol again. (And over JSch it then quits with Invalid MIT-MAGIC-COOKIE-1 key, but this is another problem.)

Solution 2:

The Xorg code currently doesn't have any option for controlling which interfaces to listen on. It shouldn't be hard to add, but it should be even easier to simply configure your firewall to block incoming connections to port 6000 from other machines.

Solution 3:

Just some other thoughts ...

  1. Allow it but block with xhost (and/or network filtering)

The traditional way to do this is for the X server to listen on the TCP socket and use xhost to determine which hosts are allowed to connect. See man page for xhost(1). (Additionally, of course, IP address and port filtering would help here too, as previous suggestions have noted.)

  1. Only listen on local interface

Per alanc's comment above, there's no code there now , but nearly!

Remember that (almost) all hosts have at least two interfaces, the loopback interface lo0 (always 127.0.0.1) and the normal ethernet eth0 (or wlan0 or whatever, which let's say is 192.168.0.128) and many have more. Usually TCP/IP servers (ie, X server) will allow incoming connections to any of their IP addresses on any of their interfaces, but most software will let you specify an IP address if you want. The actual work is done by bind(2), which takes either INADDR_ANY (0.0.0.0) or a real IP address.

The Xorg server implements -name local-address but unfortunately this is only for XDMCP (see file os/xdmcp.c which implements it correctly as far as I know.) The actual connection for the X protocol, I believe, is done by SocketINETCreateListener in the file /usr/include/X11/Xtrans/Xtranssock.c, which sets the address to INADDR_ANY and then binds to it without further processing. What would be needed is the -from flag (which is dealt with by os/xdmcp.c as FromAddress) to somehow connect through to variable 'sockname' just before SocketCreateListener() in Xtranssock.c. The problem, of course, is that all the transport things are really done in a transport-neutral way so it's a bit tricky to get the information into Xtranssock.c.

File paths and so on might vary, was looked at with Ubuntu 10.04 LTS, and note that the function names in Xtranssock.c changed by a macro TRANS. http://cgit.freedesktop.org/xorg/xserver/tree/os/xdmcp.c

Hope that's of some use.

Kind regards

Jonathan.