-
Notifications
You must be signed in to change notification settings - Fork 71
/
install.sh
496 lines (456 loc) · 16 KB
/
install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
#!/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}" @resolver1.opendns.com)
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" @resolver1.opendns.com | 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}"