Skip to content

Instantly share code, notes, and snippets.

@itxtoledo
Last active July 14, 2025 23:39
Show Gist options
  • Save itxtoledo/b43a9e61949b285efe1d4e269fd0f92a to your computer and use it in GitHub Desktop.
Save itxtoledo/b43a9e61949b285efe1d4e269fd0f92a to your computer and use it in GitHub Desktop.
Optimized automation script for installing xRDP and LXDE, a minimal desktop environment, on Ubuntu VPS systems, enabling remote desktop access with low resource usage.
#!/bin/bash
# Script for installing Lightweight Desktop (Xfce) + xRDP on Ubuntu/Debian
# Author: Gustavo Toledo (modified for X11 display and authorization fix)
set -e
# Global variables
GENERATED_PASSWORD=""
CREATED_USERNAME=""
# Redirect output to log file
exec > >(tee -a /var/log/xfce-xrdp-install.log) 2>&1
# Print functions
print_message() {
echo "[INFO] $1"
}
print_warning() {
echo "[WARNING] $1"
}
print_error() {
echo "[ERROR] $1"
exit 1
}
print_header() {
echo "==============================="
echo "$1"
echo "==============================="
}
check_root() {
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root (sudo)"
fi
}
detect_distro() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
DISTRO=$ID
VERSION=$VERSION_ID
else
print_error "Could not detect distribution. Ensure /etc/os-release exists."
fi
print_message "Detected distribution: $DISTRO $VERSION"
}
check_packages() {
print_header "CHECKING PACKAGE AVAILABILITY"
print_message "Updating package lists..."
apt update &>/dev/null
for pkg in xfce4 xrdp firefox xauth tigervnc-standalone-server; do
if ! apt-cache show "$pkg" &>/dev/null; then
print_error "Package $pkg not found in repositories"
fi
done
print_message "All required packages are available"
}
update_system() {
print_header "UPDATING SYSTEM"
DEBIAN_FRONTEND=noninteractive apt-get update &>/dev/null
DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y &>/dev/null
print_message "System updated successfully"
}
install_desktop() {
print_header "INSTALLING LIGHTWEIGHT DESKTOP (XFCE)"
print_message "Installing Xfce desktop environment..."
DEBIAN_FRONTEND=noninteractive apt install -y xfce4 xfce4-goodies &>/dev/null
print_message "Installing web browser (Firefox), xauth, and VNC server..."
DEBIAN_FRONTEND=noninteractive apt install -y firefox xauth tigervnc-standalone-server &>/dev/null
print_message "Installing fonts..."
DEBIAN_FRONTEND=noninteractive apt install -y fonts-liberation fonts-dejavu-core &>/dev/null
print_message "Xfce desktop installed successfully with Firefox and VNC support"
}
install_xrdp() {
print_header "INSTALLING AND CONFIGURING xRDP"
print_message "Installing xRDP package..."
DEBIAN_FRONTEND=noninteractive apt install -y xrdp &>/dev/null
print_message "Configuring xRDP service..."
usermod -a -G ssl-cert xrdp
if [[ -f /etc/xrdp/startwm.sh ]]; then
cp /etc/xrdp/startwm.sh /etc/xrdp/startwm.sh.bak
fi
cat > /etc/xrdp/startwm.sh << 'EOF'
#!/bin/sh
# Load system profile
if test -r /etc/profile; then
. /etc/profile
fi
# Load locale settings
if test -r /etc/default/locale; then
. /etc/default/locale
test -z "${LANG+x}" || export LANG
test -z "${LANGUAGE+x}" || export LANGUAGE
test -z "${LC_ALL+x}" || export LC_ALL
test -z "${LC_COLLATE+x}" || export LC_COLLATE
test -z "${LC_CTYPE+x}" || export LC_CTYPE
test -z "${LC_MESSAGES+x}" || export LC_MESSAGES
test -z "${LC_MONETARY+x}" || export LC_MONETARY
test -z "${LC_NUMERIC+x}" || export LC_NUMERIC
test -z "${LC_TIME+x}" || export LC_TIME
fi
# Set DISPLAY variable
export DISPLAY=:10.0
# Ensure .Xauthority exists and set up X11 authorization
if [ -z "$XAUTHORITY" ]; then
export XAUTHORITY=$HOME/.Xauthority
fi
touch $XAUTHORITY
chmod 600 $XAUTHORITY
# Add X11 authorization cookie
XAUTH_COOKIE=$(xauth -f /tmp/.xrdp_xauth generate $DISPLAY . trusted 2>/dev/null)
if [ -n "$XAUTH_COOKIE" ]; then
xauth add $DISPLAY . $XAUTH_COOKIE
else
echo "[ERROR] Failed to generate Xauth cookie" >> /var/log/xfce-xrdp-install.log
fi
# Log DISPLAY and XAUTHORITY for debugging
echo "[DEBUG] DISPLAY=$DISPLAY, XAUTHORITY=$XAUTHORITY" >> /var/log/xfce-xrdp-install.log
# Start Xfce desktop
exec startxfce4
EOF
chmod +x /etc/xrdp/startwm.sh
# Ensure xRDP uses VNC backend
print_message "Configuring xRDP to use VNC backend..."
echo "xrdp.ini configured with VNC backend" >> /var/log/xfce-xrdp-install.log
systemctl restart xrdp
systemctl enable xrdp
print_message "xRDP installed and configured successfully with X11 and VNC support"
}
configure_firewall() {
print_header "CONFIGURING FIREWALL"
print_warning "Exposing RDP (port 3389) to the public internet is insecure. Use VPN or SSH tunnel."
if command -v ufw &> /dev/null; then
ufw allow 3389/tcp
ufw reload
print_message "Port 3389 opened in UFW"
else
print_warning "UFW not installed. Configure firewall manually if needed."
fi
}
get_network_info() {
print_header "CONNECTION INFORMATION"
LOCAL_IP=$(hostname -I | awk '{print $1}')
PUBLIC_IP=$(curl -s ifconfig.me 2>/dev/null || curl -s api.ipify.org 2>/dev/null || echo "Could not obtain public IP")
print_message "Local IP: $LOCAL_IP"
print_message "Public IP: $PUBLIC_IP"
print_message "xRDP Port: 3389"
echo
print_warning "PORTS THAT MUST BE OPEN:"
echo " • Port 3389 (TCP) - RDP Protocol"
}
create_rdp_user() {
print_header "USER CONFIGURATION"
read -p "Do you want to create a new user for RDP? (y/n): " create_user < /dev/tty
if [[ $create_user =~ ^[Yy]$ ]]; then
read -p "Enter username: " username < /dev/tty
if [[ -z "$username" || "$username" =~ [^a-zA-Z0-9_-] ]]; then
print_error "Invalid username. Use only letters, numbers, underscores, or hyphens."
fi
password=$(openssl rand -base64 12 | tr -d "=+/" | cut -c1-12)
password="${password}A1!"
GENERATED_PASSWORD="$password"
CREATED_USERNAME="$username"
print_message "Generated secure password: $password"
print_warning "IMPORTANT: Save this password as it will be needed for RDP login!"
useradd -m -s /bin/bash "$username"
ENCRYPTED_PASSWORD=$(echo "$password" | openssl passwd -6 -stdin)
usermod -p "$ENCRYPTED_PASSWORD" "$username"
usermod -a -G video,ssl-cert "$username" # Add to video and ssl-cert groups
# Create and configure .Xauthority
touch /home/"$username"/.Xauthority
chown "$username":"$username" /home/"$username"/.Xauthority
chmod 600 /home/"$username"/.Xauthority
# Ensure user session loads DISPLAY
echo "export DISPLAY=:10.0" >> /home/"$username"/.bashrc
echo "export XAUTHORITY=/home/$username/.Xauthority" >> /home/"$username"/.bashrc
chown "$username":"$username" /home/"$username"/.bashrc
if id "$username" &>/dev/null; then
print_message "User '$username' created successfully with X11 permissions"
echo "RDP USER CREDENTIALS" > /root/rdp_credentials.txt
echo "===================" >> /root/rdp_credentials.txt
echo "Username: $username" >> /root/rdp_credentials.txt
echo "Password: $password" >> /root/rdp_credentials.txt
echo "Sudo privileges: No" >> /root/rdp_credentials.txt
echo "Created: $(date)" >> /root/rdp_credentials.txt
chmod 600 /root/rdp_credentials.txt
print_message "Credentials saved to /root/rdp_credentials.txt"
else
print_error "Failed to create user '$username'"
fi
else
print_message "You can use existing users to connect via RDP"
fi
}
show_rdp_clients() {
print_header "RDP CLIENTS FOR DOWNLOAD"
echo "Windows: Remote Desktop Connection (mstsc.exe)"
echo "macOS: Microsoft Remote Desktop (App Store)"
echo "Linux: Remmina, FreeRDP, Vinagre"
echo "Android/iOS: Microsoft Remote Desktop, RD Client"
}
show_connection_info() {
print_header "HOW TO CONNECT"
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo " • Server: $LOCAL_IP"
echo " • Port: 3389"
if [[ -n "$CREATED_USERNAME" && -n "$GENERATED_PASSWORD" ]]; then
echo " • Username: $CREATED_USERNAME"
echo " • Password: $GENERATED_PASSWORD"
else
echo " • Username: [your system username]"
echo " • Password: [your system password]"
fi
echo " • Desktop: Xfce will start automatically"
}
main() {
print_header "xRDP + XFCE INSTALLER"
echo "Author: Gustavo Toledo (modified for X11 display and authorization fix)"
echo
check_root
detect_distro
if [[ ! "$DISTRO" =~ ^(ubuntu|debian)$ ]]; then
print_warning "This script has been tested only on Ubuntu/Debian"
read -p "Continue anyway? (y/n): " continue_install < /dev/tty
if [[ ! $continue_install =~ ^[Yy]$ ]]; then
exit 1
fi
fi
check_packages
update_system
install_desktop
install_xrdp
configure_firewall
create_rdp_user
echo
get_network_info
echo
show_rdp_clients
echo
show_connection_info
print_header "INSTALLATION COMPLETED!"
print_message "System is ready to receive RDP connections"
print_warning "Restart the system to ensure everything works properly"
read -p "Do you want to restart now? (y/n): " reboot_now < /dev/tty
if [[ $reboot_now =~ ^[Yy]$ ]]; then
print_message "Restarting system in 10 seconds (press Ctrl+C to cancel)..."
sleep 10
reboot
fi
}
main "$@"
@itxtoledo
Copy link
Author

To run: curl -s RAW_URL | bash

Please copy the most recent raw URL from gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment