Skip to content

How to access X over TCP IP network

Martin Viereck edited this page Jul 12, 2022 · 9 revisions

How to access X over TCP/IP

In few cases it is desireable to access an X server with an IP adress over TCP/IP instead of using a unix socket.

ssh -X

One might want to access an X server on a remote system similar to ssh -X. In fact, for most remote cases ssh -X (or ssh -Y) is already a satisfying solution. Bonus: The connection is encrypted. ssh -X does not access a remote X server but provides the local X server to the remote system.

xpra, X2go, nx-libs

xpra is a great tool for remote access. Also have a look at X2go and nx-libs(https://github.com/ArcticaProject/nx-libs).

-listen tcp

Xorg and most other X servers provide deprecated option -listen tcp. With this option enabled an X server can be accessed with an address of the form IP:DISPLAYNUMBER. A notable exception that does not support -listen tcp is Xwayland. Example:

Xephyr :2 -listen tcp &
sleep 1
DISPLAY=127.0.0.1:2 xterm

Pitfall: This connection is not encrypted. A sniffer might read X content and inject X11 commands. This might be ok in a local network, but should not be exposed the outer world. For this reason -listen tcp is disabled by default in most X server setups.

socat

If you want to access an X server that does not provide -listen tcp (Xwayland) or just did not have enabled it during startup (like mostly your host Xorg), you can use socat to provide TCP/IP access. Example:

  • Check current DISPLAY:
$ echo $DISPLAY
:0.0

The number after : and before . is your display number, in this case 0.

  • The according X unix socket is located at /tmp/.X11-unix/X0.
$ ls -l /tmp/.X11-unix/X0
srwxrwxrwx 1 root root 0 12. Jul 09:15 /tmp/.X11-unix/X0
  • Create a TCP/IP connection with socat. Use a custom new display number:
Newdisplaynumber=111
socat -d TCP-LISTEN:$((6000+Newdisplaynumber)),fork,bind=127.0.0.1 UNIX-CONNECT:/tmp/.X11-unix/X0
  • Try to access X over TCP/IP with the new display number:
DISPLAY=127.0.0.1:111 xterm

xhost based access

At this point you might or might not get an X authentication issue. Don't let this happen randomly but check X access:

$ DISPLAY=:0 xhost
access control enabled, only authorized clients can connect
SI:localuser:lauscher

It seems my debian system has allowed X access for local user lauscher (me). You can use xhost to even allow non-local remote access. However, this would expose your local X server unencrypted to the world outside and is a major security risk. In worst case xhost + is set and would allow arbitrary access for everyone around the world.

# DEAR CHILDS, DON'T TRY THIS AT HOME
$ xhost +
access control disabled, clients can connect from any host

# revoke
$ xhost -
access control enabled, only authorized clients can connect
  • Let's disable this local user based access:
# disallow local user access
$ xhost -SI:localuser:lauscher
localuser:lauscher being removed from access control list

# check
$ xhost
access control enabled, only authorized clients can connect

# fails as intended
$ DISPLAY=:111 xterm
No protocol specified
xterm: Xt error: Can't open display: :111
  • At this point you might allow access for a remote system with something like xhost +inet:IP or xhost +SI:hostname:HOSTNAME. See man xhost for details. However, xhost based access is insecure and discouraged. I won't go further this way.

XAUTHORITY cookie based access

Better than using xhost is to set up an X authentication cookie. Some information is also given on wiki page X authentication with cookies and xhost ("No protocol specified" error).

  • Let's bake a cookie:
# remove cookie file if it exists
rm ~/mycookie

# Let Xorg generate a trusted cookie that has to be used within 3600 seconds the first time.
xauth -i -f ~/mycookie generate $DISPLAY . trusted timeout 3600

# Extract part of cookie without DISPLAY and hostname information
Cookie="$(xauth -i -f ~/mycookie list | awk '{print $3}')"

# delete new cookie file
rm ~/mycookie

# create new cookie file with our new custom display number and extracted cookie part
xauth -i -f ~/mycookie add :111 MIT-MAGIC-COOKIE-1 "$Cookie"

# replace host identification with ffff / family wild
Cookie="$(xauth -i -f ~/mycookie nlist | sed -e 's/^..../ffff/')"
echo "$Cookie" | xauth -i -f ~/mycookie nmerge -
  • Run with new cookie
DISPLAY=127.0.0.1:111 XAUTHORITY=~/mycookie xterm

Hurray, it works! However, this connection is still unencrypted and as insecure as a -listen tcp setup. A sniffer can still intercept the connection and even steal our cute cookie whenever an X client submits it to the X server.

Clone this wiki locally