Remote access with RustDesk
Recently I traveled abroad and need a solution to use my workstation. I tried the RustDesk remote desktop. It needs a self-hosted server if you don't want to use their cloud solution and yet I don't want to :) So after I created a virtual machine on my Proxmox host with the official suggested hardware capabilities and installed an OS (AlmaLinux), I went through the following steps described below: Create user for running the server I made a group and user named rustdesk on that system and created the /home/rustdesk/.config/containers/systemd/ path because I wanted to run the server containerized with Podman handled by Systemd. groupadd --gid 990 --system rustdesk useradd --system --create-home --gid 990 rustdesk sudo -u rustdesk mkdir -p /home/rustdesk/.config/containers/systemd/ Because the server have to be start at boot I enabled lingering for the rustdesk user so in this way it doesn't need an active session. loginctl enable-linger rustdesk Configure firewall Based on the official documentation RustDesk needs a couple port to communicate with clients. I created a service named rustdesk and add ports to it. Later assign the newly created service to the public zone. firewall-cmd --permanent --new-service=rustdesk firewall-cmd --permanent --service=rustdesk --set-description='Ports which are necessary to operate with rustdesk' firewall-cmd --permanent --service=rustdesk --add-port=21115/tcp firewall-cmd --permanent --service=rustdesk --add-port=21116/tcp firewall-cmd --permanent --service=rustdesk --add-port=21116/udp firewall-cmd --permanent --service=rustdesk --add-port=21118/tcp firewall-cmd --permanent --service=rustdesk --add-port=21117/tcp firewall-cmd --permanent --service=rustdesk --add-port=21119/tcp firewall-cmd --permanent --zone=public --add-service=rustdesk firewall-cmd --reload Check the firewall configuration If you want to check the completed settings you can list the services assigned to the public zone and list the opened ports of the service. firewall-cmd --zone=public --list-services firewall-cmd --service=rustdesk --get-ports Create systemd resources Podman has a great integration with systemd. You can create and configure containers, volumes and networking. I did not mind the networking in this configuration, but I wanted to persist the /root folder as the official documentation suggested. Because I only needed a simple volume I just created the rustdesk-hbbs.volume and rustdesk-hbbr.volume files under the /home/rustdesk/.config/containers/systemd/ with the following content: [Volume] Based on the configuration above the tool Quadlet - that installed alongside Podman - creates the appropriate systemd configurations and the end of the process a podman volume creates on the machine. In the next step I created the configuration for the server containers. It's like n ordinary systemd service file, but it has an extra section named [Container]. The possible configurations are described here: podman-systemd.unit (5). You can notice I used the standard Restart parameter under the [Service] section to configure when should the container restarts. You can find more information about the configurations here: systemd.service hbbs.container [Unit] Description=Rustdesk HBBS cotnainer After=local-fs.target [Container] AutoUpdate=registry Image=ghcr.io/rustdesk/rustdesk-server:latest ContainerName=hbbs PublishPort=21115:21115 PublishPort=21116:21116 PublishPort=21116:21116/udp PublishPort=21118:21118 Volume=rustdesk-hbbs.volume:/root Exec=hbbs [Service] Restart=on-failure [Install] WantedBy=multi-user.target default.target hbbr.container [Unit] Description=Rustdesk HBBR cotnainer After=local-fs.target [Container] AutoUpdate=registry Image=ghcr.io/rustdesk/rustdesk-server:latest ContainerName=hbbr PublishPort=21117:21117 PublishPort=21119:21119 Volume=rustdesk-hbbr.volume:/root Exec=hbbr [Service] Restart=on-failure [Install] WantedBy=multi-user.target default.target Start the application I struggled to start with the start of the application and then I found the following post on StackOverflow: systemd 248 (released March 2021) introduced support for the syntax -M myuser@ for specifying another user. sudo systemctl --user -M myuser@ start ap@inst1 A side-note: If you want to get an interactive login shell for the user myuser sudo machinectl shell myuser@ On my fresh installed AlmaLinux Podman complained about only few user namespaces were allowed, so I increased the number of the namespaces, and enabled IP forwarding for the containers. I edited directly the /etc/sysctl.conf file, and add / changed the following properties net.ipv4.ip_forward = 1 user.max_user_namespaces = 15000 After that I reloaded the settings and started the services in the name of the user rustdesk. systemctl --user -M rustdesk@ daemon-reload systemctl --u

Recently I traveled abroad and need a solution to use my workstation. I tried the RustDesk remote desktop. It needs a self-hosted server if you don't want to use their cloud solution and yet I don't want to :) So after I created a virtual machine on my Proxmox host with the official suggested hardware capabilities and installed an OS (AlmaLinux), I went through the following steps described below:
Create user for running the server
I made a group
and user
named rustdesk on that system and created the /home/rustdesk/.config/containers/systemd/
path because I wanted to run the server containerized with Podman handled by Systemd.
groupadd --gid 990 --system rustdesk
useradd --system --create-home --gid 990 rustdesk
sudo -u rustdesk mkdir -p /home/rustdesk/.config/containers/systemd/
Because the server have to be start at boot I enabled lingering for the rustdesk
user so in this way it doesn't need an active session.
loginctl enable-linger rustdesk
Configure firewall
Based on the official documentation RustDesk needs a couple port to communicate with clients. I created a service named rustdesk
and add ports to it. Later assign the newly created service to the public
zone.
firewall-cmd --permanent --new-service=rustdesk
firewall-cmd --permanent --service=rustdesk --set-description='Ports which are necessary to operate with rustdesk'
firewall-cmd --permanent --service=rustdesk --add-port=21115/tcp
firewall-cmd --permanent --service=rustdesk --add-port=21116/tcp
firewall-cmd --permanent --service=rustdesk --add-port=21116/udp
firewall-cmd --permanent --service=rustdesk --add-port=21118/tcp
firewall-cmd --permanent --service=rustdesk --add-port=21117/tcp
firewall-cmd --permanent --service=rustdesk --add-port=21119/tcp
firewall-cmd --permanent --zone=public --add-service=rustdesk
firewall-cmd --reload
Check the firewall configuration
If you want to check the completed settings you can list the services assigned to the public zone and list the opened ports of the service.
firewall-cmd --zone=public --list-services
firewall-cmd --service=rustdesk --get-ports
Create systemd resources
Podman has a great integration with systemd. You can create and configure containers, volumes and networking. I did not mind the networking in this configuration, but I wanted to persist the /root
folder as the official documentation suggested. Because I only needed a simple volume I just created the rustdesk-hbbs.volume
and rustdesk-hbbr.volume
files under the /home/rustdesk/.config/containers/systemd/
with the following content:
[Volume]
Based on the configuration above the tool Quadlet
- that installed alongside Podman - creates the appropriate systemd configurations and the end of the process a podman volume creates on the machine.
In the next step I created the configuration for the server containers. It's like n ordinary systemd service file, but it has an extra section named [Container]
. The possible configurations are described here: podman-systemd.unit (5). You can notice I used the standard Restart
parameter under the [Service]
section to configure when should the container restarts. You can find more information about the configurations here: systemd.service
hbbs.container
[Unit]
Description=Rustdesk HBBS cotnainer
After=local-fs.target
[Container]
AutoUpdate=registry
Image=ghcr.io/rustdesk/rustdesk-server:latest
ContainerName=hbbs
PublishPort=21115:21115
PublishPort=21116:21116
PublishPort=21116:21116/udp
PublishPort=21118:21118
Volume=rustdesk-hbbs.volume:/root
Exec=hbbs
[Service]
Restart=on-failure
[Install]
WantedBy=multi-user.target default.target
hbbr.container
[Unit]
Description=Rustdesk HBBR cotnainer
After=local-fs.target
[Container]
AutoUpdate=registry
Image=ghcr.io/rustdesk/rustdesk-server:latest
ContainerName=hbbr
PublishPort=21117:21117
PublishPort=21119:21119
Volume=rustdesk-hbbr.volume:/root
Exec=hbbr
[Service]
Restart=on-failure
[Install]
WantedBy=multi-user.target default.target
Start the application
I struggled to start with the start of the application and then I found the following post on StackOverflow:
systemd 248 (released March 2021) introduced support for the syntax -M myuser@ for specifying another user.
sudo systemctl --user -M myuser@ start ap@inst1
A side-note: If you want to get an interactive login shell for the user myuser
sudo machinectl shell myuser@
On my fresh installed AlmaLinux Podman complained about only few user namespaces were allowed, so I increased the number of the namespaces, and enabled IP forwarding for the containers. I edited directly the /etc/sysctl.conf
file, and add / changed the following properties
net.ipv4.ip_forward = 1
user.max_user_namespaces = 15000
After that I reloaded the settings and started the services in the name of the user rustdesk
.
systemctl --user -M rustdesk@ daemon-reload
systemctl --user -M rustdesk@ start hbbs.service
systemctl --user -M rustdesk@ start hbbr.service
Configure the clients
In the settings menu of the application use the hostname or IP address of the RustDesk service. For the ID Server
use the 21116 port and for the Relay server
the 21117 port. During the startup the HBBS service generate a keypair, and in the Key
field I inserted the content of the public key. It can be found under the path /home/rustdesk/.local/share/containers/storage/volumes/systemd-rustdesk-hbbs/_data/id_ed25519.pub
Additional Technical Notes:
- User Namespaces and Networking: I had to increase the maximum allowed user namespaces on my system. This is necessary for containers to run securely with their own isolated environments. If you’re not familiar with namespaces, they essentially provide a layer of isolation between processes, which is crucial for container security.
- Podman Networking: While I didn’t configure custom networking in this setup, it's an important aspect of containerized applications. You might want to define a specific network for your containers if you need them to communicate with other systems outside the host.