-
Notifications
You must be signed in to change notification settings - Fork 395
How to access X over TCP IP network
In few cases it is desireable to access an X server with an IP adress over TCP/IP instead of using a unix socket.
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
is a great tool for remote access.
Also have a look at X2go and nx-libs
(https://github.com/ArcticaProject/nx-libs).
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.
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
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
orxhost +SI:hostname:HOSTNAME
. Seeman xhost
for details. However,xhost
based access is insecure and discouraged. I won't go further this way.
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.