-------------------------------------------
* **rustdesk**
* **Jonathan Haack**
* **Haack's Networking**
* **webmaster@haacksnetworking.org**
-------------------------------------------
//rustdesk//
-------------------------------------------
This tutorial is for Debian users who want to create a self-hosted RustDesk instance manually. This covers installing the relay server (hbbr), the signaling server (hbbs), and the gohttp server (for client downloads and/or configs). After installing these services, I go through how to setup each systemd unit and, additionally, cover how to drop the gohttp server behind a reverse proxy. This tutorial assumes you have a hardened VM and/or VPS ready with a LAMP stack in place. If not, please head to [[https://wiki.haacksnetworking.org/doku.php?id=computing:apachesurvival|Apache Survival]] first. If you are ready to go, let's start by configuring the firewall:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 21114:21119/tcp
sudo ufw allow 21116/udp
sudo ufw enable
Let's now download the latest version of rustdesk, unzip it, and then copy the binaries into the standard location inside ''/opt/rustdesk'':
cd /tmp
wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.14/rustdesk-server-linux-amd64.zip
unzip rustdesk-server-linux-amd64.zip
sudo mkdir -p /opt/rustdesk /var/log/rustdesk
sudo cp amd64/hbbs amd64/hbbr amd64/rustdesk-utils /opt/rustdesk/
sudo chmod +x /opt/rustdesk/hbbs /opt/rustdesk/hbbr /opt/rustdesk/rustdesk-utils
After the relay and signaling servers are installed and copied to the standard locations, we can download and install the gohttp server:
sudo mkdir -p /opt/gohttp /var/log/gohttp
cd /tmp
wget https://github.com/codeskyblue/gohttpserver/releases/download/1.3.0/gohttpserver_1.3.0_linux_amd64.tar.gz
tar -xzf gohttpserver_1.3.0_linux_amd64.tar.gz
sudo cp gohttpserver /opt/gohttp/
sudo chmod +x /opt/gohttp/gohttpserver
We can now navigate to our dedicated rustdesk directory and generate our keypair:
cd /opt/rustdesk
sudo ./rustdesk-utils genkeypair
sudo chmod 600 id_ed25519
cat /opt/rustdesk/id_ed25519.pub
Make a note of the public key somewhere in your secure notes. That's your API key for configuring clients to use your self-hosted relay. We now need to create our systemd units for each of the three services. Let's start with hbbs, or the signaling server. Open up ''sudo nano /etc/systemd/system/rustdesksignal.service'' and drop inside:
[Unit]
Description=Rustdesk Signal Server
[Service]
Type=simple
LimitNOFILE=1000000
ExecStart=/opt/rustdesk/hbbs -r hackingclub.org:21117
WorkingDirectory=/opt/rustdesk/
User=root
Group=root
Restart=always
StandardOutput=append:/var/log/rustdesk/signalserver.log
StandardError=append:/var/log/rustdesk/signalserver.error
RestartSec=10
[Install]
WantedBy=multi-user.target
Next, let's configure the relay server, or hbbr. To do that, open up ''sudo nano /etc/systemd/system/rustdeskrelay.service'' and drop the following inside:
[Unit]
Description=Rustdesk Relay Server
[Service]
Type=simple
LimitNOFILE=1000000
ExecStart=/opt/rustdesk/hbbr
WorkingDirectory=/opt/rustdesk/
User=root
Group=root
Restart=always
StandardOutput=append:/var/log/rustdesk/relayserver.log
StandardError=append:/var/log/rustdesk/relayserver.error
RestartSec=10
[Install]
WantedBy=multi-user.target
Finally, let's create the systemd unit for the gohttp server. Please note that the unit contains a section to password protect the webroot so only authorized staff can access the client configs in the gohttp server. Adjust that to a secure value. Let's open up ''sudo nano /etc/systemd/system/gohttpserver.service'' and drop the following inside:
[Unit]
Description=Go HTTP Server
[Service]
Type=simple
LimitNOFILE=1000000
ExecStart=/opt/gohttp/gohttpserver -r ./public --port 8000 --auth-type http --auth-http admin:STRONG_PASSWORD_HERE
WorkingDirectory=/opt/gohttp/
User=root
Group=root
Restart=always
StandardOutput=append:/var/log/gohttp/gohttpserver.log
StandardError=append:/var/log/gohttp/gohttpserver.error
RestartSec=10
[Install]
WantedBy=multi-user.target
We can now enable all the units and start the services:
sudo systemctl daemon-reload
sudo systemctl enable rustdesksignal rustdeskrelay gohttpserver
sudo systemctl start rustdesksignal rustdeskrelay gohttpserver
sudo systemctl status rustdesksignal rustdeskrelay gohttpserver
We can now drop the gohttp server behind an apache reverse proxy. To do that, let's install certbot, cut a certificate, and enable the modules. To make things easier for yourself, open up ''/etc/apache2/sites-enabled/000-default.conf'' and uncomment and change ''ServerName'' to ''domain.com'' of your instance. Restart apache ''sudo systemctl restart apache2'' and then do the following:
sudo apt install certbot letsencrypt python3-certbot-apache
sudo certbot --authenticator standalone --installer apache -d domain.com --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"
sudo a2enmod proxy proxy_http proxy_wstunnel rewrite headers ssl
You will now have to enabled vhosts in apache, namely, ''000-default.conf'' and something like ''000-default-le-ssl.conf'' or something similar. These are running stock configurations, not reverse proxies, however. So, now that the certificate is cut, simply swap the contents with some reverse proxy configs instead. For http, use something like:
ServerName hackingclub.org
ServerSignature Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
Require all granted
ProxyPassReverse http://127.0.0.1:8000
ProxyPassReverse http://hackingclub.org
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/uploads/.*
RewriteRule .* http://127.0.0.1:8000%{REQUEST_URI} [P,QSA,NE]
ErrorDocument 404 /404.html
ErrorDocument 422 /422.html
ErrorDocument 500 /500.html
ErrorDocument 502 /502.html
ErrorDocument 503 /503.html
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common_forwarded
ErrorLog /var/log/apache2/hackingclub.org_error.log
CustomLog /var/log/apache2/hackingclub.org_forwarded.log common_forwarded
CustomLog /var/log/apache2/hackingclub.org_access.log combined env=!dontlog
CustomLog /var/log/apache2/hackingclub.org.log combined
RewriteCond %{SERVER_NAME} =hackingclub.org
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
For the https virtual host, use something like:
SSLEngine on
SSLProtocol all -SSLv2
SSLHonorCipherOrder on
SSLCipherSuite "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
Header add Strict-Transport-Security: "max-age=15768000;includeSubdomains"
SSLCompression Off
ServerName hackingclub.org
ServerSignature Off
ProxyPreserveHost On
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
AllowEncodedSlashes NoDecode
Require all granted
ProxyPassReverse http://127.0.0.1:8000
ProxyPassReverse http://hackingclub.org
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/uploads/.*
RewriteRule .* http://127.0.0.1:8000%{REQUEST_URI} [P,QSA,NE]
RequestHeader set X_FORWARDED_PROTO 'https'
RequestHeader set X-Forwarded-Ssl on
ErrorDocument 404 /404.html
ErrorDocument 422 /422.html
ErrorDocument 500 /500.html
ErrorDocument 502 /502.html
ErrorDocument 503 /503.html
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common_forwarded
ErrorLog /var/log/apache2/hackingclub.org_error.log
CustomLog /var/log/apache2/hackingclub.org_forwarded.log common_forwarded
CustomLog /var/log/apache2/hackingclub.org_access.log combined env=!dontlog
CustomLog /var/log/apache2/hackingclub.org.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/hackingclub.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/hackingclub.org/privkey.pem
Check your configs with ''apache2ctl configtest'' and then restart the service ''sudo systemctl restart apache2''. Once everything is working properly, we can now switch to setting up clients. On each RustDesk client, you go to Settings > Network > Unlock and edit the following:
* **ID Server**: hackingclub.org
* **Relay Server**: hackingclub.org
* **API Server**: https://hackingclub.org
* **Key**: API Key from above
Here's an example of what this section looks like. Note that entering a value in API Server is moot - that's only supported by the premium/paid version. It does not hurt anything to add the value there, however.
{{ :computing:screenshot_from_2024-11-02_11-12-52.png?direct&800 |}}
Enter the same values on your primary workstation. Once that's done for your workstation and at least one client, you can then specify the ID your "Control Remote Desktop" section and you are all set. Of course, there are many settings inside RustDesk, such as "Always connect via relay" and also how you choose to configure the "Password", i.e., whether it is permanent or one-time. These are decisions that will be decided by your use-case, as with others, but these are two good areas to look at post-installation. For updates, we do the following:
sudo systemctl stop rustdesksignal rustdeskrelay gohttpserver
cd /tmp
wget https://github.com/rustdesk/rustdesk-server/releases/download/NEW_VERSION/rustdesk-server-linux-amd64.zip
unzip -o rustdesk-server-linux-amd64.zip
sudo cp amd64/hbbs amd64/hbbr /opt/rustdesk/
sudo chmod +x /opt/rustdesk/hbbs /opt/rustdesk/hbbr
sudo systemctl start rustdesksignal rustdeskrelay gohttpserver
sudo systemctl status rustdesksignal rustdeskrelay gohttpserver
That's basically it. The new binaries are executed and controlled by the pre-established systemd units, so you merely replace the binaries and make them executable and you are good to go. If the gohttp server has been updated, similarly:
sudo systemctl stop gohttpserver
cd /tmp
wget https://github.com/codeskyblue/gohttpserver/releases/download/NEW_VERSION/gohttpserver_NEW_VERSION_linux_amd64.tar.gz
tar -xzf gohttpserver_NEW_VERSION_linux_amd64.tar.gz
sudo cp gohttpserver /opt/gohttp/
sudo chmod +x /opt/gohttp/gohttpserver
sudo systemctl start gohttpserver
sudo systemctl status gohttpserver
The password is specified in the systemd unit, which remains unchanged. Just make sure to restart the service as directed above and it will invoke that same value, but on the updated go server. You should now be fully up to date. Hope this helps others wanting to avoid using the automated script / understand all the moving parts of the instance. Happy hacking!
--- //[[alerts@haacksnetworking.org|oemb1905]] 2026/01/01 18:24//