Skip to content

X authentication with cookies and xhost ("No protocol specified" error)

mviereck edited this page Mar 26, 2021 · 27 revisions

X authentication

X servers normally run with enabled cookie authentication (X option -auth).

  • Only clients providing the cookie can access the X server.
  • Exceptions from mandatory cookie authentication can be declared with xhost.
  • If an X client is not allowed to access the X server, it throws errors like No protocol specified. Unable to init server: Could not connect: Connection refused or Couldn't connect to XServer.
    • This is different from error Cannot open display that indicates that either variable DISPLAY is not set correctly or the X server is not accessible for other reasons.

XAUTHORITY

The path to the cookie is stored in environment variable XAUTHORITY.

  • Normally the file is ~/.Xauthority or $XDG_RUNTIME_DIR/Xauthority.
  • The file can contain more than one cookie and for more than one X server.
  • X clients read this variable and authenticate themselves at the X server with the cookie.
  • Stored cookies can be seen with xauth list.

Cookies in a container

Access to the X server can be done sharing the X unix socket in /tmp/.X11-unix, e.g. with --volume /tmp/.X11-unix/X0:/tmp/.X11-unix/X0. The cookie from XAUTHORITY cannot be shared immediately but needs some preparation.

  • Cookies contain a server adress family code. That must be overwritten. A way to go:
  • Choose a new cookie file name, e.g. ~/mycookie.
  • Read the cookie from XAUTHORITY, adjust it, and store the result in ~/mycookie.
    Cookiefile=~/containercookie
    Cookie="$(xauth nlist ${DISPLAY} | sed -e 's/^..../ffff/')" 
    echo "$Cookie" | xauth -f "$Cookiefile" nmerge -
    
  • Share the new cookie with the container and set XAUTHORITY accordingly
    docker run --env XAUTHORITY=/cookie \
               --volume $Cookiefile:/cookie \
               --env DISPLAY=${DISPLAY} \
               --volume /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 \
               --ipc=host \
               [...]
    
    ( --ipc=host is added to avoid MIT-SHM issues.)

xhost

Exceptions to cookie authentication can be specified with xhost.

  • xhost weakens the X security setup. Prefer to work with cookies.
  • Check current xhost access rules with plain xhost command.
  • X authentication can be disabled entirely with xhost +. Don't do that. No access protection is left, and X can be abused horribly.
  • X access for single local users can be specified with:
    • xhost +SI:localuser:username (Replace username with desired user name).
    • xhost "+SI:localuser:#uid" (Replace uid with desired user uid).
    • This can be revoked with - instead of +, e.g. xhost -SI:localuser:username.
    • Often seen use case: Allow root access to X: xhost +SI:localuser:root

Cookie baking

If you want to run your own X server, provide it a cookie generated with xauth:

Cookiefile=~/mycookie
Displaynumber=100 
xauth -f $Cookiefile add :$Displaynumber . $(mcookie)

Run an X server with this cookie:

# $Displaynumber must not be in use in ~/tmp/.X11-unix
Xephyr :$Displaynumber -auth $Cookiefile

Run an application (here a window manager) on the new X server:

env DISPLAY=:$Displaynumber XAUTHORITY=$Cookiefile fluxbox

Additional note: If you want to provide the X server to a container, add option -extension MIT-SHM to the X server command. That avoids some memory access errors and graphical glitches. Otherwise you would need insecure docker run option --ipc=host.

Special case: Request cookie from X server

You can ask a running X server to generate a cookie for you:

xauth -f $Cookiefile generate $Displaynumber . trusted timeout 3600
  • An interesting use case is to replace trusted with untrusted. That generates a cookie that can be used for untrusted applications. The X server will deny applications that use this cookie some features that could be used for security leaks otherwise.
  • timeout 3600 means that the cookie must be used from a client within 3600 seconds, otherwise it will be discarded as invalid.
Clone this wiki locally