Last active
July 14, 2025 23:39
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run:
curl -s RAW_URL | bash
Please copy the most recent raw URL from gist.