497 lines
16 KiB
Bash
497 lines
16 KiB
Bash
#!/bin/bash
|
|
|
|
# This script will do the following to install RustDesk Server Pro
|
|
# 1. Install some dependencies
|
|
# 2. Setup UFW firewall if available
|
|
# 3. Create 2 folders /var/lib/rustdesk-server and /var/log/rustdesk-server ("$RUSTDESK_INSTALL_DIR" and "$RUSTDESK_LOG_DIR")
|
|
# 4. Download and extract RustDesk Pro Services to the above folder
|
|
# 5. Create systemd services for hbbs and hbbr
|
|
# 6. If you choose Domain, it will install Nginx and Certbot, allowing the API to be available on port 443 (https) and get an SSL certificate over port 80, it is automatically renewed
|
|
|
|
# Please note; even if the script is run as root, you will still be able to choose a non-root user during setup.
|
|
|
|
##################################################################################################################
|
|
|
|
TLS=""
|
|
if command -v ldconfig &> /dev/null; then
|
|
if ldconfig -p | grep -q "libssl.so.3"; then
|
|
TLS="-nativetls"
|
|
fi
|
|
fi
|
|
|
|
# Install curl and whiptail if needed
|
|
if [ ! -x "$(command -v curl)" ] || [ ! -x "$(command -v whiptail)" ]
|
|
then
|
|
# We need curl to fetch the lib
|
|
# There are the package managers for different OS:
|
|
# osInfo[/etc/redhat-release]=yum
|
|
# osInfo[/etc/arch-release]=pacman
|
|
# osInfo[/etc/gentoo-release]=emerge
|
|
# osInfo[/etc/SuSE-release]=zypp
|
|
# osInfo[/etc/debian_version]=apt-get
|
|
# osInfo[/etc/alpine-release]=apk
|
|
NEEDED_DEPS=(curl whiptail)
|
|
echo "Installing these packages:" "${NEEDED_DEPS[@]}"
|
|
if [ -x "$(command -v apt-get)" ]
|
|
then
|
|
sudo apt-get install "${NEEDED_DEPS[@]}" -y
|
|
elif [ -x "$(command -v apk)" ]
|
|
then
|
|
sudo apk add --no-cache "${NEEDED_DEPS[@]}"
|
|
elif [ -x "$(command -v dnf)" ]
|
|
then
|
|
sudo dnf install "${NEEDED_DEPS[@]}"
|
|
elif [ -x "$(command -v zypper)" ]
|
|
then
|
|
sudo zypper install "${NEEDED_DEPS[@]}"
|
|
elif [ -x "$(command -v pacman)" ]
|
|
then
|
|
sudo pacman -S install "${NEEDED_DEPS[@]}"
|
|
elif [ -x "$(command -v yum)" ]
|
|
then
|
|
sudo yum install "${NEEDED_DEPS[@]}"
|
|
elif [ -x "$(command -v emerge)" ]
|
|
then
|
|
sudo emerge -av "${NEEDED_DEPS[@]}"
|
|
else
|
|
echo "FAILED TO INSTALL! Package manager not found. You must manually install:" "${NEEDED_DEPS[@]}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# We need to source directly from the Github repo to be able to use the functions here
|
|
# shellcheck disable=2034,2059,2164
|
|
true
|
|
SCRIPT_NAME="Install script"
|
|
export SCRIPT_NAME
|
|
# shellcheck source=lib.sh
|
|
source <(curl -sL https://raw.githubusercontent.com/rustdesk/rustdesk-server-pro/main/lib.sh)
|
|
# see https://github.com/koalaman/shellcheck/wiki/Directive
|
|
unset SCRIPT_NAME
|
|
|
|
##################################################################################################################
|
|
|
|
# Check if root
|
|
root_check
|
|
|
|
# Output debugging info if $DEBUG set
|
|
if [ "$DEBUG" = "true" ]
|
|
then
|
|
identify_os
|
|
print_text_in_color "$ICyan" "OS: $OS"
|
|
print_text_in_color "$ICyan" "VER: $VER"
|
|
print_text_in_color "$ICyan" "UPSTREAM_ID: $UPSTREAM_ID"
|
|
exit 0
|
|
fi
|
|
|
|
# We need the WAN IP
|
|
get_wanip4
|
|
|
|
# Automatic restart of services while installing
|
|
# Restart mode: (l)ist only, (i)nteractive or (a)utomatically.
|
|
if [ ! -f /etc/needrestart/needrestart.conf ]
|
|
then
|
|
install_linux_package needrestart
|
|
if ! grep -rq "{restart} = 'a'" /etc/needrestart/needrestart.conf
|
|
then
|
|
# Restart mode: (l)ist only, (i)nteractive or (a)utomatically.
|
|
sed -i "s|#\$nrconf{restart} =.*|\$nrconf{restart} = 'a'\;|g" /etc/needrestart/needrestart.conf
|
|
fi
|
|
fi
|
|
|
|
# Select user for installation
|
|
msg_box "Rustdesk can be installed as an unprivileged user, but we need root for everything else.
|
|
Running with an unprivileged user enhances security, and is recommended."
|
|
|
|
if yesno_box_yes "Do you want to use an unprivileged user for Rustdesk?"
|
|
then
|
|
while :
|
|
do
|
|
RUSTDESK_USER=$(input_box_flow "Please enter the name of your non-root user:")
|
|
if ! id "$RUSTDESK_USER"
|
|
then
|
|
msg_box "We couldn't find $RUSTDESK_USER on the system, are you sure it's correct?
|
|
Please try again."
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
run_as_non_root_user() {
|
|
sudo -u "$RUSTDESK_USER" "$@";
|
|
}
|
|
fi
|
|
|
|
# Install needed dependencies
|
|
install_linux_package unzip
|
|
install_linux_package tar
|
|
install_linux_package dnsutils
|
|
install_linux_package ufw
|
|
if ! install_linux_package bind9-utils
|
|
then
|
|
install_linux_package bind-utils
|
|
fi
|
|
if ! install_linux_package bind9
|
|
then
|
|
install_linux_package bind
|
|
fi
|
|
|
|
# Setting up firewall
|
|
ufw allow 21115:21119/tcp
|
|
ufw allow 22/tcp
|
|
ufw allow 21116/udp
|
|
|
|
# Download latest version of RustDesk
|
|
RDLATEST=$(curl https://api.github.com/repos/rustdesk/rustdesk-server-pro/releases/latest -s | grep "tag_name"| awk '{print substr($2, 2, length($2)-3) }')
|
|
|
|
# Download, extract, and move Rustdesk in place
|
|
if [ -n "${ARCH}" ]
|
|
then
|
|
# If not /var/lib/rustdesk-server/ ($RUSTDESK_INSTALL_DIR) exists we can assume this is a fresh install. If it exists though, we can't move it and it will produce an error
|
|
if [ ! -d "$RUSTDESK_INSTALL_DIR" ]
|
|
then
|
|
print_text_in_color "$IGreen" "Installing RustDesk Server..."
|
|
# Create dir
|
|
mkdir -p "$RUSTDESK_INSTALL_DIR"
|
|
if [ -d "$RUSTDESK_INSTALL_DIR" ]
|
|
then
|
|
cd "$RUSTDESK_INSTALL_DIR"
|
|
else
|
|
msg_box "It seems like the installation folder wasn't created, we can't continue.
|
|
Please report this to: https://github.com/rustdesk/rustdesk-server-pro/issues"
|
|
exit 1
|
|
fi
|
|
# Since the name of the actual tar files differs from the output of uname -m we need to rename acutal download file.
|
|
# Preferably we would instead rename the download tarballs to the output of uname -m. This would make it possible to run a single $VAR for ARCH.
|
|
if [ "${ARCH}" = "x86_64" ]
|
|
then
|
|
ACTUAL_TAR_NAME=amd64
|
|
elif [ "${ARCH}" = "armv7l" ]
|
|
then
|
|
ACTUAL_TAR_NAME=armv7
|
|
elif [ "${ARCH}" = "aarch64" ]
|
|
then
|
|
ACTUAL_TAR_NAME=arm64v8
|
|
fi
|
|
ACTUAL_TAR_NAME=${ACTUAL_TAR_NAME}${TLS}
|
|
# Download
|
|
if ! curl -fSLO --retry 3 https://github.com/rustdesk/rustdesk-server-pro/releases/download/"${RDLATEST}"/rustdesk-server-linux-"${ACTUAL_TAR_NAME}".tar.gz
|
|
then
|
|
msg_box "Sorry, the installation package failed to download.
|
|
This might be temporary, so please try to run the installation script again."
|
|
exit 1
|
|
fi
|
|
# Extract, move in place, and make it executable
|
|
tar -xf rustdesk-server-linux-"${ACTUAL_TAR_NAME}".tar.gz
|
|
# Set permissions
|
|
if [ -n "$RUSTDESK_USER" ]
|
|
then
|
|
chown "$RUSTDESK_USER":"$RUSTDESK_USER" -R "$RUSTDESK_INSTALL_DIR"
|
|
fi
|
|
# Move as root if RUSTDESK_USER is not set.
|
|
if [ -n "$RUSTDESK_USER" ]
|
|
then
|
|
run_as_non_root_user mv "${ACTUAL_TAR_NAME}"/static "$RUSTDESK_INSTALL_DIR"
|
|
else
|
|
mv "${ACTUAL_TAR_NAME}"/static "$RUSTDESK_INSTALL_DIR"
|
|
fi
|
|
mv "${ACTUAL_TAR_NAME}"/hbbr /usr/bin/
|
|
mv "${ACTUAL_TAR_NAME}"/hbbs /usr/bin/
|
|
mv "${ACTUAL_TAR_NAME}"/rustdesk-utils /usr/bin/
|
|
rm -rf "$RUSTDESK_INSTALL_DIR"/"${ACTUAL_TAR_NAME:?}"
|
|
rm -rf rustdesk-server-linux-"${ACTUAL_TAR_NAME}".tar.gz
|
|
chmod +x /usr/bin/hbbs
|
|
chmod +x /usr/bin/hbbr
|
|
chmod +x /usr/bin/rustdesk-utils
|
|
if [ -n "$RUSTDESK_USER" ]
|
|
then
|
|
chown "$RUSTDESK_USER":"$RUSTDESK_USER" -R /usr/bin/hbbr
|
|
chown "$RUSTDESK_USER":"$RUSTDESK_USER" -R /usr/bin/hbbs
|
|
chown "$RUSTDESK_USER":"$RUSTDESK_USER" -R /usr/bin/rustdesk-utils
|
|
fi
|
|
else
|
|
print_text_in_color "$IGreen" "Rustdesk server already installed."
|
|
fi
|
|
else
|
|
msg_box "Sorry, we can't figure out your distro, this script will now exit.
|
|
Please report this to: https://github.com/rustdesk/rustdesk-server-pro/issues"
|
|
exit 1
|
|
fi
|
|
|
|
# Make folder /var/log/rustdesk-server/
|
|
if [ ! -d "$RUSTDESK_LOG_DIR" ]
|
|
then
|
|
print_text_in_color "$IGreen" "Creating $RUSTDESK_LOG_DIR"
|
|
install -d -m 700 "$RUSTDESK_LOG_DIR"
|
|
# Set permissions
|
|
if [ -n "$RUSTDESK_USER" ]
|
|
then
|
|
chown -R "$RUSTDESK_USER":"$RUSTDESK_USER" "$RUSTDESK_LOG_DIR"
|
|
fi
|
|
fi
|
|
|
|
# Setup systemd to launch hbbs
|
|
if [ ! -f "/etc/systemd/system/rustdesk-hbbs.service" ]
|
|
then
|
|
touch "/etc/systemd/system/rustdesk-hbbs.service"
|
|
if [ -n "$RUSTDESK_USER" ]
|
|
then
|
|
cat << HBBS_RUSTDESK_SERVICE > "/etc/systemd/system/rustdesk-hbbs.service"
|
|
[Unit]
|
|
Description=RustDesk Signal Server
|
|
[Service]
|
|
Type=simple
|
|
LimitNOFILE=1000000
|
|
ExecStart=/usr/bin/hbbs
|
|
WorkingDirectory=$RUSTDESK_INSTALL_DIR
|
|
User=${RUSTDESK_USER}
|
|
Group=${RUSTDESK_USER}
|
|
Restart=always
|
|
StandardOutput=append:$RUSTDESK_LOG_DIR/hbbs.log
|
|
StandardError=append:$RUSTDESK_LOG_DIR/hbbs.error
|
|
# Restart service after 10 seconds if node service crashes
|
|
RestartSec=10
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
HBBS_RUSTDESK_SERVICE
|
|
else
|
|
cat << HBBS_RUSTDESK_SERVICE > "/etc/systemd/system/rustdesk-hbbs.service"
|
|
[Unit]
|
|
Description=RustDesk Signal Server
|
|
[Service]
|
|
Type=simple
|
|
LimitNOFILE=1000000
|
|
ExecStart=/usr/bin/hbbs
|
|
WorkingDirectory=$RUSTDESK_INSTALL_DIR
|
|
User=root
|
|
Group=root
|
|
Restart=always
|
|
StandardOutput=append:$RUSTDESK_LOG_DIR/hbbs.log
|
|
StandardError=append:$RUSTDESK_LOG_DIR/hbbs.error
|
|
# Restart service after 10 seconds if node service crashes
|
|
RestartSec=10
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
HBBS_RUSTDESK_SERVICE
|
|
fi
|
|
fi
|
|
|
|
# Setup systemd to launch hbbr
|
|
if [ ! -f "/etc/systemd/system/rustdesk-hbbr.service" ]
|
|
then
|
|
touch "/etc/systemd/system/rustdesk-hbbr.service"
|
|
if [ -n "$RUSTDESK_USER" ]
|
|
then
|
|
cat << HBBR_RUSTDESK_SERVICE > "/etc/systemd/system/rustdesk-hbbr.service"
|
|
[Unit]
|
|
Description=RustDesk Relay Server
|
|
[Service]
|
|
Type=simple
|
|
LimitNOFILE=1000000
|
|
ExecStart=/usr/bin/hbbr
|
|
WorkingDirectory=$RUSTDESK_INSTALL_DIR
|
|
User=${RUSTDESK_USER}
|
|
Group=${RUSTDESK_USER}
|
|
Restart=always
|
|
StandardOutput=append:$RUSTDESK_LOG_DIR/hbbr.log
|
|
StandardError=append:$RUSTDESK_LOG_DIR/hbbr.error
|
|
# Restart service after 10 seconds if node service crashes
|
|
RestartSec=10
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
HBBR_RUSTDESK_SERVICE
|
|
else
|
|
cat << HBBR_RUSTDESK_SERVICE > "/etc/systemd/system/rustdesk-hbbr.service"
|
|
[Unit]
|
|
Description=RustDesk Relay Server
|
|
[Service]
|
|
Type=simple
|
|
LimitNOFILE=1000000
|
|
ExecStart=/usr/bin/hbbr
|
|
WorkingDirectory=$RUSTDESK_INSTALL_DIR
|
|
User=root
|
|
Group=root
|
|
Restart=always
|
|
StandardOutput=append:$RUSTDESK_LOG_DIR/hbbr.log
|
|
StandardError=append:$RUSTDESK_LOG_DIR/hbbr.error
|
|
# Restart service after 10 seconds if node service crashes
|
|
RestartSec=10
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
HBBR_RUSTDESK_SERVICE
|
|
fi
|
|
fi
|
|
|
|
# Enable services
|
|
# HBBR
|
|
systemctl enable rustdesk-hbbr.service
|
|
systemctl start rustdesk-hbbr.service
|
|
# HBBS
|
|
systemctl enable rustdesk-hbbs.service
|
|
systemctl start rustdesk-hbbs.service
|
|
|
|
while :
|
|
do
|
|
if ! systemctl status rustdesk-hbbr.service | grep "Active: active (running)"
|
|
then
|
|
sleep 2
|
|
print_text_in_color "$ICyan" "Waiting for RustDesk Relay service to become active..."
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
while :
|
|
do
|
|
PUBKEYNAME=$(find "$RUSTDESK_INSTALL_DIR" -name "*.pub")
|
|
if [ -z "$PUBKEYNAME" ]
|
|
then
|
|
print_text_in_color "$ICyan" "Checking if public key is generated..."
|
|
sleep 5
|
|
else
|
|
print_text_in_color "$IGreen" "Public key path: $PUBKEYNAME"
|
|
PUBLICKEY=$(cat "$PUBKEYNAME")
|
|
break
|
|
fi
|
|
done
|
|
|
|
choice=$(whiptail --title "Rustdesk installation script" --menu \
|
|
"Choose your preferred option, IP or DNS/Domain:
|
|
|
|
DNS = Setup Rustdesk with TLS and your own domain
|
|
IP = You don't have a domain, only plain IP
|
|
$MENU_GUIDE\n\n$RUN_LATER_GUIDE" "$WT_HEIGHT" "$WT_WIDTH" 4 \
|
|
"DNS" "(e.g. rustdesk.example.com)" \
|
|
"IP" "($WANIP4)" 3>&1 1>&2 2>&3)
|
|
|
|
case "$choice" in
|
|
"DNS")
|
|
# Enter domain
|
|
while :
|
|
do
|
|
RUSTDESK_DOMAIN=$(input_box_flow "Please enter your domain, e.g. rustdesk.example.com")
|
|
DIG=$(dig +short "${RUSTDESK_DOMAIN}" @8.8.8.8)
|
|
if ! [[ "$RUSTDESK_DOMAIN" =~ ^[a-zA-Z0-9]+([a-zA-Z0-9.-]*[a-zA-Z0-9]+)?$ ]]
|
|
then
|
|
msg_box "$RUSTDESK_DOMAIN is an invalid domain/DNS address! Please try again."
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Check if DNS are forwarded correctly
|
|
if dig +short "$RUSTDESK_DOMAIN" @8.8.8.8 | grep -q "$WANIP4"
|
|
then
|
|
print_text_in_color "$IGreen" "DNS seems correct when checking with dig!"
|
|
else
|
|
msg_box "DNS lookup failed with dig. The external IP ($WANIP4) \
|
|
address of this server is not the same as the A-record ($DIG).
|
|
Please check your DNS settings! Maybe the domain hasn't propagated?
|
|
Please check https://www.whatsmydns.net/#A/${RUSTDESK_DOMAIN} if the IP seems correct."
|
|
exit 1
|
|
fi
|
|
|
|
# Install packages
|
|
print_text_in_color "$IGreen" "Installing Nginx and Cerbot..."
|
|
if yesno_box_yes "We use Certbot to generate the free TLS certificate from Let's Encrypt.
|
|
The default behavior of installing Certbot is to use the snap package which auto updates, and provides the latest version of Certbot. If you don't like snap packages, you can opt out now and we'll use regular (old) deb packages instead.
|
|
|
|
Do you want to install Certbot with snap? (recommended)"
|
|
then
|
|
install_linux_package nginx
|
|
if ! install_linux_package snapd
|
|
then
|
|
print_text_in_color "$IRed" "Sorry, snapd wasn't found on your system, using 'python3-certbot-nginx' instead."
|
|
install_linux_package python3-certbot-nginx
|
|
else
|
|
snap install certbot --classic
|
|
fi
|
|
else
|
|
install_linux_package nginx
|
|
install_linux_package python3-certbot-nginx
|
|
fi
|
|
|
|
# Add Nginx config
|
|
if [ -d "/etc/nginx/sites-available" ] && [ -d "/etc/nginx/sites-enabled" ]
|
|
then
|
|
SITES_CONF_DIR="sites-available"
|
|
elif [ -d "/etc/nginx/conf.d" ]
|
|
then
|
|
SITES_CONF_DIR="conf.d"
|
|
else
|
|
msg_box "Couldn't find the Nginx config directory. Please check your system!"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "/etc/nginx/$SITES_CONF_DIR/rustdesk.conf" ]
|
|
then
|
|
touch "/etc/nginx/$SITES_CONF_DIR/rustdesk.conf"
|
|
cat << NGINX_RUSTDESK_CONF > "/etc/nginx/$SITES_CONF_DIR/rustdesk.conf"
|
|
server {
|
|
server_name ${RUSTDESK_DOMAIN};
|
|
location / {
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
proxy_pass http://127.0.0.1:21114/;
|
|
}
|
|
}
|
|
NGINX_RUSTDESK_CONF
|
|
fi
|
|
|
|
# Enable the Nginx config file
|
|
if [ "$SITES_CONF_DIR" = "sites-available" ] && [ ! -f /etc/nginx/sites-enabled/rustdesk.conf ]
|
|
then
|
|
ln -s /etc/nginx/sites-available/rustdesk.conf /etc/nginx/sites-enabled/rustdesk.conf
|
|
fi
|
|
|
|
# Enable firewall rules for the domain
|
|
ufw allow 80/tcp
|
|
ufw allow 443/tcp
|
|
ufw --force enable
|
|
ufw --force reload
|
|
|
|
# Generate the certifictae
|
|
if ! certbot --nginx --cert-name "${RUSTDESK_DOMAIN}" --key-type ecdsa --renew-by-default --no-eff-email --agree-tos --server https://acme-v02.api.letsencrypt.org/directory -d "${RUSTDESK_DOMAIN}"
|
|
then
|
|
msg_box "Sorry, the TLS certificate for $RUSTDESK_DOMAIN failed to generate!
|
|
Please check that port 80/443 are correctly port forwarded, and that the DNS record points to this servers IP.
|
|
|
|
Please try again."
|
|
exit
|
|
fi
|
|
;;
|
|
"IP")
|
|
ufw allow 21114/tcp
|
|
ufw --force enable
|
|
ufw --force reload
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
# Display final info!
|
|
if [ -n "$RUSTDESK_DOMAIN" ]
|
|
then
|
|
msg_box "
|
|
Your Public Key is:
|
|
$PUBLICKEY
|
|
Your DNS Address is:
|
|
$RUSTDESK_DOMAIN
|
|
|
|
Please login at https://$RUSTDESK_DOMAIN
|
|
Default User/Pass: admin/test1234"
|
|
else
|
|
msg_box "
|
|
Your Public Key is:
|
|
$PUBLICKEY
|
|
Your IP Address is:
|
|
$WANIP4
|
|
|
|
Please login at http://$WANIP4:21114
|
|
Default User/Pass: admin/test1234"
|
|
fi
|
|
|
|
print_text_in_color "$IGreen" "Cleaning up..."
|
|
rm -f rustdesk-server-linux-"${ACTUAL_TAR_NAME}".zip
|
|
rm -rf "${ACTUAL_TAR_NAME}"
|