XRDP Remote Desktop on Linux
XRDP enables Windows Remote Desktop Protocol (RDP) access to Linux servers, allowing users to connect with the standard Windows Remote Desktop Client or any RDP client without additional software. This guide covers installing XRDP on Linux, configuring desktop environments, managing sessions, and hardening the setup.
Prerequisites
- Ubuntu 22.04/Debian 12 or CentOS/Rocky 9 server
- Root or sudo access
- At least 1 GB RAM (2+ GB recommended with a desktop environment)
- Port 3389 (RDP) accessible from client machines
- Existing user account to connect with
Install a Desktop Environment
XRDP requires a desktop environment. XFCE is recommended for its low resource usage:
# Ubuntu/Debian - XFCE (recommended, lightweight)
sudo apt update
sudo apt install -y xfce4 xfce4-goodies
# Ubuntu/Debian - GNOME (heavier, more familiar)
sudo apt install -y ubuntu-desktop-minimal
# CentOS/Rocky - XFCE
sudo dnf groupinstall -y "Xfce" "Base X Window System"
sudo dnf install -y xfce4-session
# CentOS/Rocky - GNOME
sudo dnf groupinstall -y "Server with GUI"
# Prevent the display manager from starting (we use XRDP, not a physical display)
# Ubuntu with GDM:
sudo systemctl set-default multi-user.target
# (XRDP starts its own X sessions, no need for GDM at boot)
Install and Configure XRDP
# Ubuntu/Debian
sudo apt install -y xrdp
# CentOS/Rocky
sudo dnf install -y epel-release
sudo dnf install -y xrdp
# Enable and start XRDP
sudo systemctl enable --now xrdp
# Verify XRDP is running on port 3389
sudo ss -tlnup | grep 3389
# Add the xrdp user to the ssl-cert group (required for TLS)
sudo usermod -aG ssl-cert xrdp
# Check XRDP status
sudo systemctl status xrdp
Allow XRDP through the firewall:
# Ubuntu with UFW
sudo ufw allow from 192.168.1.0/24 to any port 3389 # Only from trusted network
# Or to allow from anywhere (less secure):
sudo ufw allow 3389/tcp
# CentOS/Rocky with firewalld
sudo firewall-cmd --permanent --add-port=3389/tcp
sudo firewall-cmd --reload
Configure XFCE for XRDP
Create per-user XFCE session configuration:
# For a specific user, create the .xsession file
# Run as the user (not root):
echo "startxfce4" > ~/.xsession
chmod +x ~/.xsession
# Or configure XRDP's default session manager
sudo nano /etc/xrdp/startwm.sh
Replace the contents of /etc/xrdp/startwm.sh:
#!/bin/sh
# XRDP session startup script
# Unset problematic environment variables
unset DBUS_SESSION_BUS_ADDRESS
unset XDG_RUNTIME_DIR
# Fix color issues in XFCE over RDP
export XDG_CURRENT_DESKTOP=XFCE
export DESKTOP_SESSION=xfce
# Start XFCE
test -x /etc/X11/Xsession && exec /etc/X11/Xsession
exec /bin/sh /etc/X11/Xsession
For a system-wide XFCE default:
sudo tee /etc/xrdp/startwm.sh << 'EOF'
#!/bin/sh
unset DBUS_SESSION_BUS_ADDRESS
unset XDG_RUNTIME_DIR
if [ -f /usr/bin/startxfce4 ]; then
exec startxfce4
elif [ -f /usr/bin/xterm ]; then
exec xterm
fi
EOF
sudo chmod +x /etc/xrdp/startwm.sh
sudo systemctl restart xrdp
Configure GNOME for XRDP
GNOME requires additional setup for XRDP compatibility:
# Install GNOME and XRDP
sudo apt install -y gnome-session gnome-shell gnome-terminal xrdp
# Configure XRDP to launch GNOME
sudo tee /etc/xrdp/startwm.sh << 'EOF'
#!/bin/sh
unset DBUS_SESSION_BUS_ADDRESS
unset XDG_RUNTIME_DIR
export GNOME_SHELL_SESSION_MODE=ubuntu
export XDG_CURRENT_DESKTOP=ubuntu:GNOME
export XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
export XDG_SESSION_TYPE=x11
exec /usr/lib/gnome-session/gnome-session-binary --session=ubuntu
EOF
sudo chmod +x /etc/xrdp/startwm.sh
# Fix GNOME Keyring issues over XRDP
sudo tee -a /etc/xrdp/sesman.ini << 'EOF'
[Sessions]
DefAddPolicy=DENY
MaxLoginRetry=4
TerminalServerUsers=tsusers
TerminalServerAdmins=tsadmins
EOF
sudo systemctl restart xrdp
Session Management
XRDP supports multiple session types visible on the login screen:
# Check available XRDP session types
cat /etc/xrdp/xrdp.ini | grep -A5 "\[Xorg\]"
# Configure session parameters in /etc/xrdp/xrdp.ini
sudo nano /etc/xrdp/xrdp.ini
[Globals]
; Maximum connections
max_bpp=32
xserverbpp=24
port=3389
; Session limits
max_connections=50
tcp_keepalive=yes
tcp_send_buffer_bytes=32768
tcp_recv_buffer_bytes=32768
; Encryption
security_layer=negotiate # negotiate, tls, or rdp
crypt_level=high # none, low, medium, high, fips
[Xorg]
name=Xorg
lib=libxup.so
username=ask
password=ask
width=1920
height=1080
code=20
Manage existing sessions:
# List active XRDP sessions
sudo xrdp-sesadmin list
# Kill a specific session
sudo xrdp-sesadmin kill <session-id>
# Check XRDP session logs
sudo tail -f /var/log/xrdp-sesman.log
sudo tail -f /var/log/xrdp.log
Security Hardening
Restrict XRDP access and improve security:
# 1. Limit XRDP to specific IP ranges (firewall)
sudo ufw delete allow 3389/tcp # Remove wide-open rule
sudo ufw allow from 192.168.1.0/24 to any port 3389/tcp # Internal network only
# 2. Enable TLS for XRDP connections
sudo openssl req -x509 -newkey rsa:4096 \
-keyout /etc/xrdp/key.pem \
-out /etc/xrdp/cert.pem \
-days 365 -nodes \
-subj "/CN=rdp.example.com"
sudo chown xrdp:xrdp /etc/xrdp/key.pem /etc/xrdp/cert.pem
sudo chmod 640 /etc/xrdp/key.pem
# Update xrdp.ini to use TLS
sudo sed -i 's/security_layer=negotiate/security_layer=tls/' /etc/xrdp/xrdp.ini
# 3. Require 2FA - install Google Authenticator PAM module
sudo apt install -y libpam-google-authenticator
# For each user who needs XRDP access:
google-authenticator # Run as the user
# Configure PAM for XRDP to require TOTP
sudo nano /etc/pam.d/xrdp-sesman
# Add at the top:
# auth required pam_google_authenticator.so
# 4. Disable root login via XRDP
sudo sed -i '/^\[Xorg\]/,/^\[/ s/username=ask/username=ask\nAllowRoot=false/' /etc/xrdp/sesman.ini
# 5. Restrict to specific users via group
sudo groupadd tsusers
sudo usermod -aG tsusers username
# In /etc/xrdp/sesman.ini:
# TerminalServerUsers=tsusers
# AllowRootLogin=false
sudo systemctl restart xrdp
Connect from Windows, macOS, and Linux
Windows:
- Press
Win + R, typemstscand press Enter - Enter the server IP and port:
192.168.1.100:3389 - Click Connect, enter credentials when prompted
macOS:
# Install Microsoft Remote Desktop from Mac App Store
# Or use free Remmina alternative via Homebrew:
brew install --cask microsoft-remote-desktop
Linux with Remmina:
# Install Remmina RDP client
sudo apt install -y remmina remmina-plugin-rdp
# Or use xfreerdp for command-line access
sudo apt install -y freerdp2-x11
# Connect with xfreerdp
xfreerdp /v:192.168.1.100:3389 \
/u:username \
/p:password \
/size:1920x1080 \
/bpp:32 \
/dynamic-resolution \
+clipboard \
+fonts
Troubleshooting
Black screen after connecting:
# Usually a desktop environment startup issue
# Check session startup script
cat /etc/xrdp/startwm.sh
# Try creating a user-level .xsession file
echo "startxfce4" > ~/.xsession && chmod +x ~/.xsession
# Check for errors in sesman log
sudo tail -50 /var/log/xrdp-sesman.log
Authentication failure / "Your session has ended":
# Check PAM configuration
sudo tail -20 /var/log/auth.log | grep xrdp
# Ensure user is in the tsusers group if TerminalServerUsers is set
groups username
# Verify the user's password works
su - username
Session is very slow or laggy:
# Lower the color depth in the RDP client (16-bit instead of 32-bit)
# In xrdp.ini, optimize network settings:
sudo nano /etc/xrdp/xrdp.ini
# Set: max_bpp=16
# Enable compression in the RDP client
# Or use xfreerdp with compression:
xfreerdp /v:server:3389 /u:user /p:pass /compression /bpp:16
Port 3389 already in use:
sudo ss -tlnup | grep 3389
# If another service is using it, change XRDP's port:
sudo sed -i 's/port=3389/port=3390/' /etc/xrdp/xrdp.ini
sudo systemctl restart xrdp
Conclusion
XRDP provides a practical way to access Linux desktops remotely using standard RDP clients available on Windows, macOS, and Linux without requiring VPN or additional client software. XFCE is the most reliable and lightweight desktop environment for XRDP sessions, offering a good balance of features and performance. For production deployments, always restrict RDP access to trusted IP ranges, enable TLS encryption, and consider requiring two-factor authentication to protect against brute-force attacks on exposed RDP ports.


