X11#

The X Window System is the legacy display server on Linux. A single Xorg (or Xwayland) process owns the framebuffer, input devices, and the client connections; every GUI app the operator runs is an X client talking to it over a Unix socket or TCP port.

X11’s design assumes mutual trust between clients on the same display. Any client can read any other client’s pixels, intercept its keystrokes, inject synthetic events, and grab the cursor without permission. For an operator on a defended host this is the single largest piece of attack surface above the kernel; for an operator running tooling on their own box it is what makes xdotool, scrot, and xrandr simple to script.

Anatomy#

        flowchart LR
    K[Kernel<br/>evdev / KMS] --> X[Xorg server<br/>:0]
    X --> WM[Window<br/>manager]
    X --> A1[Client app 1]
    X --> A2[Client app 2]
    X --> A3[Client app N]
    WM -.-> X
    A1 -.read/inject.-> A2
    A1 -.read/inject.-> A3
    

Piece

Role

Xorg server

Owns the framebuffer and input. One per session, listens on unix:/tmp/.X11-unix/X0 and (if enabled) TCP 6000+N.

Display number

DISPLAY=:0 names the local server. :0.1 selects the second screen on display 0.

Window manager

Decorates, places, and stacks top-level windows. Not the server; the operator can swap it without restarting Xorg.

Compositor

Optional. Composes window buffers into the final framebuffer. Provides transparency, shadows, smooth redraws. picom is the common standalone choice.

Clients

All GUI apps. Talk to the server over the X protocol; authentication via MIT-MAGIC-COOKIE-1 in ~/.Xauthority.

Tools#

xdpyinfo#

Identify the running X server, its resolution, extensions, and visual.

$ xdpyinfo | head -20
$ xdpyinfo | grep -E "dimensions|name of display"

xrandr#

List and configure outputs (monitors). Useful for triage on unfamiliar hosts and for scripting multi-monitor layouts.

$ xrandr                                       # list outputs
$ xrandr --output HDMI-1 --auto --right-of eDP-1
$ xrandr --output HDMI-1 --rotate left

xdotool#

Synthetic input. Move the pointer, type keystrokes, raise windows. Powerful for automation, dangerous as an attack primitive (works on any window because X11 has no isolation).

$ xdotool type "hello"
$ xdotool key ctrl+shift+t
$ xdotool search --name "Firefox" windowactivate

scrot#

Screen capture. No prompt, no isolation; an attacker with the same DISPLAY and cookie reads the screen freely.

$ scrot screen.png
$ scrot -s region.png                          # interactive region
$ scrot -u focused.png                         # focused window only

xev#

Show X events as they arrive at a window. The standard debugger for keybinding problems and input device behavior.

$ xev | grep -E "KeyPress|ButtonPress"

Constraints#

  • No client isolation. Anyone with DISPLAY=:0 and XAUTHORITY=~/.Xauthority can read pixels and inject input.

  • TCP listener disabled by default in modern distros (-nolisten tcp in the Xorg arguments). Re-enabling xhost + on a multi-user host is a vulnerability.

  • SUID and capability bits on the Xorg binary; check with getcap /usr/lib/xorg/Xorg after package upgrades.

Files#

Authentication#

Path

Purpose

~/.Xauthority

Per-user cookie file. Required to connect to :0.

/etc/X11/xorg.conf.d/

Drop-in configuration fragments (input, video, monitor).

/var/log/Xorg.0.log

Most recent X server log. (EE) lines are errors.

Display sockets#

Path

Purpose

/tmp/.X11-unix/X0

Local socket for display :0.

/tmp/.ICE-unix/

Inter-Client Exchange (ICE) sockets used by DE session managers.

Variables#

Session#

Variable

Purpose

DISPLAY

Target X server. Local is typically :0 or :1; remote tunnels (ssh -X) come out as localhost:10.0 or higher.

XAUTHORITY

Path to the cookie file. Override per process to use a different identity.

XDG_SESSION_TYPE

x11 confirms the operator is on X; wayland means this page does not apply.

Common Tasks#

Confirm the session is X11, not Wayland.

$ echo $XDG_SESSION_TYPE
$ loginctl show-session $(loginctl | awk '/'$USER'/{print $1}') -p Type

List every visible window and its PID.

$ wmctrl -lp

Disable TCP listening on Xorg (close the network attack surface).

# /etc/X11/xinit/xserverrc starts X with -nolisten tcp on most distros.
# Verify:
$ ss -ltnp | grep -E ':60[0-9]{2}'

Audit who can connect to the display.

$ xhost                                        # any '+' line is a hole

References#