-
Notifications
You must be signed in to change notification settings - Fork 417
How to access X over TCP IP network
This article is currently work in progress. Hints and test reports are appreciated!
In few cases it is desireable to access an X server with an IP adress over TCP/IP instead of using a unix socket.
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
Pitfalls:
- 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 to the outer world. For this reason
-listen tcpis disabled by default in most X server setups. -
-listen tcpcannot be restricted to localhost but listens to all incoming connections with the mask0.0.0.0. So a proper authentication setup is needed.- To allow access restrictions at all, a Cookie must be created and specified with X option
-auth. - While there is basically no proper way to restrict access within localhost (except using cookies), it is possible to additionally allow remote access for specified IP addresses only using
xhost. - While remote clients cannot change
xhostsettings, every local client is able to allow access to X for everyone with e.g.xhost +.
- To allow access restrictions at all, a Cookie must be created and specified with X option
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 most likely your host Xorg), you can use socat to provide TCP/IP access.
- One advantage compared to
-listen tcpis that it can be restricted tolocalhostaccess by using IP127.0.0.1. - One disadvantage compared to
-listen tcpis that remote connection access cannot be configured withxhost. (The reason is that the X server is not aware of the TCP setup and believes that every client is a local one.) Instead, authentication cookies can be used. But if the cookie is given to third parties or stolen by a network sniffer, anyone could connect from anywhere if he provides the cookie.
Example for access to currently running X server:
- 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 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 authentication.
xhost does not restrict X access but allows additional access to an X server that is protected otherwise by cookie authentication.
It opens holes into X security settings.
- In general I recommend to use X cookie authentication only and to disable all
xhostbased access. This is especially true for all local setups. - In one setup
xhostis to be preferred over cookie authentication:- If a remote client is allowed to access the X server, the hostname or IP of the remote client should be allowed with
xhost. - If it would be authenticated with a cookie instead, the cookie could be (ab)used from other IP addresses, too.
- Remember that the traffic is unencrypted and a sniffer could extract the cookie.
- If a remote client is allowed to access the X server, the hostname or IP of the remote client should be allowed with
- Note that for a useful
xhostsetup the X server must be configured to use a cookie as well, even if the cookie is not provided to any client at all. Otherwise the X server would have no authentication setup that would cause him to refuse connections. - Local X clients can change
xhostsettings. Remote clients can not.- This is only true for
-listen tcpsetups. - With a
socatTCP/IP setup the X server is not aware that it is accessed over TCP and believes that every client is a local one.
- This is only true for
Now a follow-up for the socat TCP/IP setup to check and remove xhost based authentication:
$ # check current settings
$ 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). 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=127.0.0.1:111 xterm
No protocol specified
xterm: Xt error: Can't open display: 127.0.0.1:111
Below we'll set up a cookie to authenticate X access.
In worst case xhost + is set and would allow arbitrary access for everyone around the world. This is fatal for -listen tcp setups.
The socat TCP/IP setup is not affected but should be set up with localhost / 127.0.0.1 only.
$ # 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
Note that every local X client is allowed to set xhost +.
For local setups 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 for the localhost socat TCP setup:
Newdisplaynumber=111
# 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 :$Newdisplaynumber 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 -
# restrict access to cookie to current user only
chmod 600 ~/mycookie
- Run with new cookie
DISPLAY=127.0.0.1:111 XAUTHORITY=~/mycookie xterm
Hurray, it works! However, this connection is still unencrypted and almost 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. Only if using localhost / 127.0.0.1 this socat setup is more secure than a -listen tcp setup.
A cookie can also be used to authenticate remote connections. Issues:
- The remote client might give the cookie to a third party. Others could connect remotely, too.
- A sniffer might extract the cookie from the unencrypted connection and could use it to access the X server.
Unfortunately applications somehow freeze if they try to access the GPU through the socat connection. It seems they wait forever on some sort of event. Enable software rendering with LIBGL_ALWAYS_SOFTWARE=1. Example:
DISPLAY=127.0.0.1:111 XAUTHORITY=~/mycookie LIBGL_ALWAYS_SOFTWARE=1 glxgears
As long as socat binds the TCP socket to localhost / 127.0.0.1, there might be no way to access X from outside even if xhost + is set. At least in my test runs I could not access it even if trying to access with my local ethernet IP adress (e.g. DISPLAY=192.168.178.30:111).
However, if you set up an outgoing network connection with a public IP address, it will not be entirely secure even if you disable xhost settings and set up a cookie as described above.
The issue is: If an authorizied client accesses X over IP with the cookie, it is allowed to set xhost + and thus disabling authorization at all, exposing the X server to the entire world.
This is at least true for the socat setup where the X server itself is not aware that it is also accessed over TCP. If the setup is done with -listen tcp instead, the X server should deny xhost commands from outside and allow local clients only to change xhost settings.