Chapter 5 — xRDP: Linux as an RDP Server
Windows ships with an RDP server built in. Linux does not — but
xRDP is an open-source package that adds one. Once
installed, any standard RDP client (mstsc, Remmina, the
Microsoft Store app, xfreerdp) can connect to a Linux desktop session
exactly as if it were a Windows machine, on port 3389.
Why xRDP instead of VNC? xRDP uses the RDP protocol,
which compresses well and supports clipboard, drive, and audio redirection
natively. VNC sends raw pixel data and is typically slower over the same
connection. If your client runs Windows, xRDP gives you a polished
experience without any extra client software.
How xRDP Works
RDP Client
mstsc / Remmina
any RDP client
→ port 3389 →
xRDP daemon
translates RDP
to X11/Wayland
→
Xvnc / X11
virtual display
(xrdp-sesman)
→
Desktop session
XFCE / MATE
GNOME / KDE
xRDP listens on port 3389, accepts the RDP connection, then spawns an
Xvnc (or X11rdp) virtual display and launches your chosen
desktop environment inside it. The desktop renders in that virtual display,
and xRDP streams the output back to the client as standard RDP.
Choosing a Desktop Environment
xRDP works with most Linux desktop environments, but some perform better
over RDP than others. For a remote connection, lighter is almost always better:
XFCE
Recommended
Lightweight, fast, stable over RDP. The de-facto standard recommendation for xRDP setups. Renders cleanly and uses very little CPU on the server.
MATE
Good choice
GNOME 2 fork. Slightly heavier than XFCE but familiar to Ubuntu users. Renders well over RDP and supports compositing.
LXDE / LXQt
Very light
Minimal resource use. Good for older hardware or very slow connections. Less polished than XFCE but responsive.
GNOME
Works, heavy
Full GNOME Shell works with xRDP but needs extra configuration to avoid black-screen issues. Uses significantly more CPU/RAM than lighter desktops.
KDE Plasma
Works, heavy
Fully functional but resource-intensive. Better suited to fast LAN connections. May show rendering glitches without GPU acceleration.
i3 / openbox
Power users
Tiling window managers work fine with xRDP and are extremely lightweight. Best for developers who prefer keyboard-driven workflows.
Installing xRDP on Debian / Ubuntu
debian — install xRDP + XFCE
philip@debian:~$ sudo apt update && sudo apt upgrade -y
# install a lightweight desktop if not already present
philip@debian:~$ sudo apt install -y xfce4 xfce4-goodies
# install xrdp
philip@debian:~$ sudo apt install -y xrdp
# xrdp is added to the ssl-cert group so it can use the machine cert
philip@debian:~$ sudo adduser xrdp ssl-cert
# start and enable the service
philip@debian:~$ sudo systemctl enable --now xrdp
philip@debian:~$ sudo systemctl status xrdp
● xrdp.service - xrdp daemon
Loaded: loaded (/lib/systemd/system/xrdp.service; enabled)
Active: active (running) since Wed 2026-06-18 09:14:05 BST
Tell xRDP to use XFCE for your session
Create a .xsession file in the home directory of each user
who will connect via RDP. This tells xRDP which desktop to launch:
debian — set session type
# write the session startup file
philip@debian:~$ echo xfce4-session > ~/.xsession
# alternative: use startxfce4 if xfce4-session is not found
philip@debian:~$ echo startxfce4 > ~/.xsession
# for MATE instead of XFCE:
philip@debian:~$ echo mate-session > ~/.xsession
# for GNOME (requires gnome-session):
philip@debian:~$ echo gnome-session > ~/.xsession
Open port 3389 in UFW (if active)
philip@debian:~$ sudo ufw allow 3389/tcp
philip@debian:~$ sudo ufw allow from 192.168.0.0/24 to any port 3389
# prefer the second form — restrict to your LAN only
Do not expose port 3389 to the internet. xRDP has no
built-in brute-force protection and RDP is a constant target for
automated attacks. If you need remote access from outside your LAN, put
xRDP behind an SSH tunnel (covered in Chapter 8) or a VPN. On the public
internet, a default RDP port will be found and attacked within minutes.
Connecting from Windows (mstsc)
Open mstsc, enter the Linux machine's IP address, log in
with your Linux username and password. That's it — the xRDP login screen
appears first (you can leave Session as Xorg or the auto-detected
default), then your XFCE desktop loads.
# Command-line shortcut from Windows
mstsc /v:192.168.0.24 /w:1920 /h:1080
# Or a saved .rdp file for the Linux box
full address:s:192.168.0.24
username:s:philip
screen mode id:i:2
authentication level:i:0 # xRDP has no NLA, so set to 0 (or 1 to warn)
redirectclipboard:i:1
audiomode:i:0
authentication level 0 vs 2: Windows may warn "The
identity of the remote computer cannot be verified." This is expected —
xRDP uses a self-signed certificate and does not support NLA (CredSSP).
Set authentication level:i:0 in the .rdp file to suppress the
warning, or click Yes once and tick Don't ask again.
Connecting from Another Linux Machine (Remmina)
linux client — xfreerdp to xRDP host
philip@laptop:~$ xfreerdp /v:192.168.0.24 /u:philip /p:password \
+clipboard /dynamic-resolution /cert:ignore
# /cert:ignore suppresses the self-signed cert warning
In Remmina, create a new connection with Protocol set to RDP,
enter the IP, username, and password. Under Advanced, set
Security to RDP (no NLA) if the connection is
refused or shows a certificate error.
Fixing Common xRDP Issues
Black / grey screen after login
The session started but the desktop environment didn't launch — missing or wrong .xsession file, or a desktop that isn't installed.
Check ~/.xsession exists and contains the right command (xfce4-session). Install the desktop: sudo apt install xfce4.
Authentication / certificate warning
xRDP uses a self-signed TLS certificate. Windows shows a warning before connecting.
Set authentication level:i:0 in the .rdp file, or click Yes on the prompt and tick "Don't ask again".
Colours look washed out / wrong
Colour depth mismatch. xRDP defaults to 24-bit; the client requests 32-bit.
In mstsc Display tab, set colour depth to 16-bit or 24-bit. In xfreerdp: /bpp:24. Also try disabling compositing in XFCE settings.
Session already logged in locally
If the user is already logged into the physical machine, xRDP creates a new separate session rather than attaching to the existing one.
Log out of the local session first, or use a different user account for RDP. xRDP cannot share an existing physical console session.
Connection refused / port not open
xRDP service not running, or UFW blocking port 3389.
sudo systemctl start xrdp and sudo ufw allow 3389/tcp. Check with ss -tlnp | grep 3389.
Clipboard not working
xrdp-chansrv process (the channel server for clipboard/audio) didn't start correctly.
Restart the session. Check journalctl -u xrdp for errors. Ensure xrdp is in the ssl-cert group: sudo adduser xrdp ssl-cert.
Useful xRDP Diagnostics
# service status
philip@debian:~$ sudo systemctl status xrdp xrdp-sesman
# confirm xRDP is listening on port 3389
philip@debian:~$ ss -tlnp | grep 3389
LISTEN 0 10 0.0.0.0:3389 0.0.0.0:* users:(("xrdp",pid=1234,fd=12))
# live connection log — watch this while connecting from the client
philip@debian:~$ sudo tail -f /var/log/xrdp.log
philip@debian:~$ sudo tail -f /var/log/xrdp-sesman.log
# check the per-session log if the desktop fails to start
philip@debian:~$ ls ~/.xorgxrdp.*.log
philip@debian:~$ cat ~/.xorgxrdp.10.log
# installed xRDP version
philip@debian:~$ xrdp --version
xrdp: A Remote Desktop Protocol Server
Version 0.9.21
Quick Reference — xRDP Configuration Files
# Main config — port, security, session limits
/etc/xrdp/xrdp.ini
# Session manager config — timeout, max sessions, X display range
/etc/xrdp/sesman.ini
# User session file — which desktop environment to launch
~/.xsession
# System-wide session file (fallback when no ~/.xsession)
/etc/xrdp/startwm.sh
# Connection and error logs
/var/log/xrdp.log
/var/log/xrdp-sesman.log
# Per-session Xorg log (NN = display number, typically 10)
~/.xorgxrdp.NN.log
Editing /etc/xrdp/startwm.sh lets you set the desktop
globally for all users without needing a .xsession file in
every home directory. Add exec xfce4-session before the
final test -x /etc/X11/Xsession ... line. This is useful
on a server where you control all the accounts.
Next — Chapter 6: VNC.
xRDP sits on top of VNC internally, but VNC can also run directly — giving
you access to a desktop without the RDP translation layer. Chapter 6 covers
TigerVNC and RealVNC: setting up a server on Linux, connecting from any OS,
and why you must always tunnel VNC over SSH rather than exposing it directly.