Back to Server Overview
Install FsRdpServer on Linux
A complete guide from a freshly installed Linux server to your first working client connection, for Ubuntu Server, Debian and Raspberry Pi OS (64-bit). Every command is explained individually.
Try It without a License:
You do not need a license to install the server. Without a license file, a server runs
as a trial installation for 30 days with full functionality; see
section 7 for details. We agree on the server name and license once it is running in your environment.
Need Help Setting Up?
Ask an AI chatbot of your choice using the following prompt:
Please help me set up my FSRdp server on Linux using this guide:
https://www.fssoft.de/FsRdp/en/InstallingServerLinux.md
Guide me step by step, only one step per response, and wait for my feedback after each command. Never ask me for a password.
The link points to the plain-text version of this page, which a chatbot can read in full rather than the shortened content it often retrieves from HTML pages.
1. What Should Be Running at the End
FsRdpServer is a relay server. It does not capture screens or store session content; it connects the participants in a room. All clients connect to the server, never directly to one another. Only the server needs to be reachable, rather than any client.
After installation, the service listens on these TCP ports:
| Also allow port | Purpose | Required? |
8888 | Main connection: control, screen content, files and remote control | yes |
8889 | Voice transmission (separate channel) | yes |
8890 | Browser viewer for viewers without an installed client | optional, requires a license (available during the trial) |
80 | Only for issuing and renewing Let's Encrypt certificates | optional |
The Linux package is self-contained ; no system-wide .NET runtime installation is required. Use:
linux-x64 for Ubuntu Server, Debian and similar 64-bit Intel/AMD systems;
linux-arm64 for Raspberry Pi OS (64-bit) and other ARM64 systems.
2. Prepare the Fresh Linux Server
Enter all following commands in a terminal, either directly on the device or via SSH. sudo means “run with administrative permissions”; Linux asks for your password the first time.
1
Update the System
sudo apt update
sudo apt full-upgrade -y
sudo reboot
Sign in again after restarting. A server that will be reachable from the internet should be up to date from the outset.
2
Install Required Utilities
sudo apt install -y unzip openssl
unzip extracts the server package; openssl
is needed later to inspect and create the PFX file.
3
Check Time and Time Zone
Certificates and licenses have validity periods. If the server clock is several minutes wrong, connections may fail with seemingly inexplicable errors.
timedatectl
sudo timedatectl set-timezone Europe/Berlin
The output of timedatectl should show
System clock synchronized: yes .
4
Assign a Fixed Local IP Address
The router must forward ports to a stable address. The simplest solution is a fixed DHCP assignment in the router (“always assign the same IPv4 address to this device”), so no Linux configuration change is required. View current addresses with:
ip -brief address show
5
IPv6: Keep the Last Part of the Address Fixed
An IPv6 address has two parts: the prefixassigned by your provider and the interface ID chosen by the device. Many systems choose a new interface ID whenever the prefix changes, which breaks DNS records and router access rules. With NetworkManager, the default on Raspberry Pi OS and current Ubuntu desktops, fix the interface ID as follows:
nmcli connection show
sudo nmcli connection modify "Wired connection 1" \
ipv6.addr-gen-mode eui64 ipv6.token ::159
sudo nmcli connection up "Wired connection 1"
The connection name comes from the first line;
::159 can be chosen freely. The server's IPv6 address will then always end in ::159regardless of the prefix. On servers using systemd-networkd or
netplan , achieve the same result with the parameter
Token= or a statically configured address.
3. Server Name: DNS with A and AAAA Records
3.1 Why a Name Rather than an IP Address?
Clients connect using a DNS name, for example server.ihrefirma.de, never an IP address. There are two essential reasons: the TLS certificate is issued for a name, and your license is tied to that exact same name.
Remember: Licensed host name = certificate name = name entered in the client. All three must match character for character.
3.2 What Are A and AAAA Records?
A DNS record translates a name into an address. There are two types because the internet uses two address types:
| Record | Points To | Example |
A | an IPv4 address | 203.0.113.45 |
AAAA | an IPv6 address | 2a02:810d:7087:8800::159 |
Pronounce AAAA as “quad A”. Both records may exist for the same name. Important: the AAAA record points to the IPv6 address of the server itself, rather than the router; every IPv6 device has its own globally valid address.
3.3 Find Your Public Addresses
Run on the server:
# Öffentliche IPv4-Adresse des Anschlusses
curl -4 https://api.ipify.org; echo
# Öffentliche IPv6-Adresse dieses Servers
curl -6 https://api6.ipify.org; echo
If the first command returns an answer, you have public IPv4; if the second does, you have IPv6.
3.4 DS-Lite: No Public IPv4 Address
Many cable and fiber connections in Germany use
DS-Lite. Your connection shares a public IPv4 address with many other customers rather than having its own. The consequences:
- IPv4 port forwarding has no effect. You can configure it, but it will never be reached.
- Only IPv6 works. The name therefore receives only an AAAA record.
- Clients on IPv4-only networks cannot connect ; this affects some company networks and mobile connections.
How to Recognize DS-Lite: The router shows no public IPv4 address or an address in the range 100.64.x.x–100.127.x.x; running curl -4 https://api.ipify.org fails, while the command using -6 succeeds.
Many providers will switch you to a connection with a real IPv4 address on request at no charge. If clients need to connect from any network, a call to your provider is the simplest solution.
3.5 Changing Addresses: Dynamic DNS
Residential connections usually have no fixed address: the public IPv4 address or IPv6 prefix changes. Eventually your DNS record points to an outdated address. Three options:
- Order a fixed address from your provider – the simplest arrangement, usually for a small additional charge.
- A dynamic DNS service (dynv6, deSEC, No-IP …), updated by your router whenever the address changes. Ensure the service also updates AAAA records , which is essential with DS-Lite.
- Run only on your local network – no dynamic DNS or port access required (see 3.8).
3.6 Create Records with Your DNS Provider
Create a record for the desired name with your domain's DNS provider: A with the connection's public IPv4 address and/or AAAA with the server's IPv6 address. During testing, use a short TTL (e.g. 600 seconds) and increase it once everything works.
3.7 Check Name Resolution
getent hosts server.ihrefirma.de
# Ausführlicher, falls installiert (sonst: sudo apt install -y dnsutils)
dig +short A server.ihrefirma.de
dig +short AAAA server.ihrefirma.de
A Pitfall on Your Own Network: Many routers, including FRITZ!Box, use DNS rebind protection
to filter responses pointing to the local network. The name may then fail to resolve specifically on your home network while working perfectly from outside. Add the host name as an exception under
Heimnetz → Netzwerk → Netzwerkeinstellungen → DNS-Rebind-Schutz (Home Network → Network → Network Settings → DNS Rebind Protection) . Then clear the test computers' DNS caches so they pick up the change.
3.8 Run Only on Your Local Network
If all participants are on the same network, no public DNS or port access is needed. The name must still exist because the certificate and license rely on it: use internal DNS or, for small tests only, an entry in
/etc/hosts on every client:
192.168.1.50 server.ihrefirma.de
4. Router, Port Access and Firewall
4.1 IPv4: Port Forwarding
With IPv4, all devices share a public address. The router must know where to forward incoming connections. Create TCP forwarding rules for 8888, 8889 and, if used,
8890 to the server. On a FRITZ!Box: Internet → Freigaben → Portfreigaben → Gerät für Freigaben hinzufügen (Internet → Permit Access → Port Sharing → Add Device for Sharing).
4.2 IPv6: Allow Access Rather than Forwarding
IPv6 connections are not redirected; each device already has an externally addressable IP. The router merely opens its firewall for that device and port. The interface usually still calls this “port sharing”, with an additional choice such as “internet access via IPv6”.
Create the access rule for the device rather than a manually entered address, so it survives a prefix change. With DS-Lite, only IPv6 access rules are effective.
4.3 Port 80: Only for Let's Encrypt
Let's Encrypt must verify that you control the name. The simplest method uses port 80, which needs to remain accessible because renewal runs automatically at regular intervals. Nothing listens on port 80 between renewals; router warnings here refer to a continuously running web server.
4.4 The Server's Own Firewall
First check whether a firewall is active:
sudo ufw status
If UFW is active, allow the ports:
sudo ufw allow 8888/tcp
sudo ufw allow 8889/tcp
sudo ufw allow 8890/tcp # nur bei Browser-Viewer
sudo ufw allow 80/tcp # nur bei Let's Encrypt
Take Care with Remote Servers: Never enable a firewall without first allowing sudo ufw allow OpenSSH
. Otherwise you lock yourself out and must use the provider's console to regain access.
5. The TLS Certificate (PFX File) in Detail
5.1 What Is a PFX File?
cert.pfx is a password-protected PKCS#12 container holding the server certificate for your server name, the corresponding private key and usually the issuing authority's intermediate certificates . FsRdpServer uses it to encrypt all connections. The service does not start without a valid certificate.
The PFX File Is a Secret. Anyone with the file and its password can impersonate your server. Do not send it by unencrypted email, put it in a repository or make it readable by all users.
The file must contain exactly one certificate with a private key and include the licensed server name as a Subject Alternative Name , either directly (server.ihrefirma.de) or through a wildcard certificate (*.ihrefirma.de).
5.2 Option A: Bundle a Purchased Certificate into a PFX File
Providers usually supply two or three files: the certificate, private key and intermediate certificates. Create a PFX file as follows:
openssl pkcs12 -export -out cert.pfx \
-inkey privkey.pem -in cert.pem -certfile chain.pem
OpenSSL asks for the password interactively. Do not put it on the command line using
-password pass:... , where it would be saved in your shell history.
5.3 Option B: Free with Let's Encrypt
This works once your server name is in public DNS and port 80 is reachable from outside. Two commonly used tools:
-
lego – a single program that can create the PFX file directly. This avoids conversion, so it is used here.
-
certbot – the best-known client. It creates PEM files that must be bundled as in 5.2. Note: Debian 13 (“trixie”) and Raspberry Pi OS versions based on it no longer include certbot as a package.
1
Install lego
sudo apt install -y lego
If apt cannot find the package, it may be available only through backports in your version (sudo apt install -y -t stable-backports lego), or you can download the prebuilt program from go-acme.github.io/lego
.
2
Try the Staging Environment First
Let's Encrypt limits failed attempts. First use the staging server to verify that port access actually works; this does not consume your production quota:
sudo lego --accept-tos --email ihre.adresse@example.com \
--domains server.ihrefirma.de \
--http --http.port :80 --path /etc/lego-staging \
--server https://acme-staging-v02.api.letsencrypt.org/directory run
3
Obtain the Real Certificate as PFX
If the test succeeds, obtain the real certificate. Choose a password for the PFX file:
sudo lego --accept-tos --email ihre.adresse@example.com \
--domains server.ihrefirma.de \
--http --http.port :80 --path /etc/lego \
--pfx --pfx.format SHA256 --pfx.pass 'IhrPasswort' run
The resulting file is at
/etc/lego/certificates/server.ihrefirma.de.pfx.
5.4 Option C: Your Company's Own CA
Only suitable for internal installations: every client must explicitly trust your company CA or all connections fail. This option is unsuitable for the browser viewer because every browser would show a warning page.
5.5 Check the PFX File before Installation
# Inhalt anzeigen (fragt nach dem Passwort)
openssl pkcs12 -info -in cert.pfx -nokeys
# Namen und Laufzeit des Zertifikats prüfen
openssl pkcs12 -in cert.pfx -clcerts -nokeys -passin pass: 2>/dev/null \
| openssl x509 -noout -subject -dates -ext subjectAltName
Ensure the licensed name appears in
subjectAltName and the date in
notAfter is in the future.
6. Install the Server Package
1
Copy the Package to the Server and Extract It
unzip FsRdpServer-linux-x64.zip -d FsRdpServer
cd FsRdpServer
ls
On Raspberry Pi, use
FsRdpServer-linux-arm64.zipinstead. The folder must contain, among other files, FsRdpServer, install.sh,
fsrdp-server.service and
README-LINUX.md .
2
Run the Installer
chmod +x FsRdpServer install.sh
sudo ./install.sh
On first installation, the service intentionally remains
stoppeduntil the certificate is configured. This is not an error. No license is needed to start; without one, the 30-day trial described in section 7.
What Is Created:
/opt/fsrdp-server/FsRdpServer | the program itself |
/opt/fsrdp-server/data/ | configuration, certificate, license, installation ID and logs |
/etc/fsrdp-server/fsrdp-server.env | secrets, readable only by root . |
/etc/systemd/system/fsrdp-server.service | the systemd service definition |
User fsrdp-server | dedicated restricted service account with no sign-in capability |
To use ports other than 8888/8889 , set them in
/opt/fsrdp-server/data/appsettings.json . Afterwards restore ownership and permissions:
sudo chown fsrdp-server:fsrdp-server … and
sudo chmod 0640 ….
7. Trial Period or License (Generate the Installation ID)
No License Needed for the First 30 Days
If there is no license file in the data directory, the server still starts and runs as a trial installation for 30 days. Nothing needs to be enabled: install the package, configure the certificate and PFX password (section 8), then start the service. The trial limits duration and capacity, not features:
| Trial Period | With a License |
| Concurrent Rooms | 1, fixed number 123456789 | as specified in the license |
| Session Duration | up to 24 hours | as specified in the license |
| Waiting Time Afterwards | none | as specified in the license |
| Participants per Room | 5 | as specified in the license |
| Room Features | all | all |
| Total Duration | 30 days from installation | license term |
| Watermark | yes | no |
“All features” means screen sharing, remote control, camera, voice, chat, file transfer, session recording, live captions and the browser viewer. Their technical requirements still apply: captions need your own API key, and the browser viewer needs its port and certificate (section 10).
During the trial, all participants see a Watermark
over the shared screen. This is intentional: an unlicensed server should be recognizable as such.
What the trial does not include is supporter key and the features tied to those keys: reserved room names and the room password with which a customer opens their permanent room in a browser. This is not a feature block; an unlicensed server simply does not issue keys.
The room number 123456789 is publicly known.
If your test server is reachable from the internet, set a
room PIN. The field is next to the room number in both desktop clients. The person opening the room sets it; everyone else needs it to join.
After 30 days, the service keeps running and listening but responds to every connection with a request for a license; it does not refuse not
to start. You can install a license file later at any time (section 12).
Request a License
For continued operation, you need a signed license file. It is tied to your
server name and a permanent
installation ID . Unlike Windows, on Linux you generate this ID yourself before requesting the license, exactly once:
sudo -u fsrdp-server env \
FSRDP_DATA_DIR=/opt/fsrdp-server/data \
/opt/fsrdp-server/FsRdpServer --installation-id
The command prints a long string and saves it in
/opt/fsrdp-server/data/server-instance-id.txt.
Send Me These Details for Issuing the License:
- the generated installation ID;
- the exact DNS name clients will use;
- the number of concurrent rooms and participants per room;
- the desired term;
- whether you want browser viewing, session recording or live captions; these features must be enabled in the license.
server-instance-id.txt must never be lost , including during updates or reinstallation. If the file is lost, your license no longer matches and must be reissued.
8. Install the Certificate, License and Password
1
Store Both Files with the Correct Permissions
Change to the folder containing license.fsrdp and
cert.pfx :
sudo install -o fsrdp-server -g fsrdp-server -m 0640 \
license.fsrdp /opt/fsrdp-server/data/license.fsrdp
sudo install -o fsrdp-server -g fsrdp-server -m 0640 \
cert.pfx /opt/fsrdp-server/data/cert.pfx
install copies the file and sets ownership and permissions in one step; the service account can read it, ordinary users cannot.
2
Store the PFX Password
The password belongs in the environment file readable only by root , rather than the configuration file:
sudoedit /etc/fsrdp-server/fsrdp-server.env
Enter these lines, replacing existing entries:
FSRDP_CERT_PASSWORD=hier-das-echte-passwort
Then ensure the correct permissions:
sudo chown root:root /etc/fsrdp-server/fsrdp-server.env
sudo chmod 0600 /etc/fsrdp-server/fsrdp-server.env
If the password contains spaces or special characters, quote it according to systemd syntax. The simplest approach is to avoid both and use a long password of letters and digits.
3
Check File Permissions
sudo stat -c '%U:%G %a %n' \
/opt/fsrdp-server/FsRdpServer \
/opt/fsrdp-server/data \
/opt/fsrdp-server/data/cert.pfx \
/opt/fsrdp-server/data/license.fsrdp \
/etc/fsrdp-server/fsrdp-server.env \
/etc/systemd/system/fsrdp-server.service
Expected values:
| Path | Owner | Permissions |
/opt/fsrdp-server/FsRdpServer | root:root | 0755 |
/opt/fsrdp-server/data | fsrdp-server:fsrdp-server | 0750 |
/opt/fsrdp-server/data/cert.pfx | fsrdp-server:fsrdp-server | 0640 |
/opt/fsrdp-server/data/license.fsrdp | fsrdp-server:fsrdp-server | 0640 |
/etc/fsrdp-server/fsrdp-server.env | root:root | 0600 |
/etc/systemd/system/fsrdp-server.service | root:root | 0644 |
9. Validate and Start the Service
9.1 Self-Check before the First Start
The following command looks complex for a reason: it lets systemd load the password file readable only by root while running validation under the service account. The PFX password never needs to appear on the command line.
sudo systemd-run \
--quiet --wait --pipe --collect \
--property=User=fsrdp-server \
--property=Group=fsrdp-server \
--property=EnvironmentFile=/etc/fsrdp-server/fsrdp-server.env \
--property=Environment=FSRDP_DATA_DIR=/opt/fsrdp-server/data \
/opt/fsrdp-server/FsRdpServer --validate-installation
Successful output confirms that the license, installation ID and certificate match. A DNS warning is acceptable only if you intentionally provide the name through internal DNS or hosts files; clients must still be able to resolve it. Fix every genuine error before starting.
9.2 Start the Service
sudo systemctl start fsrdp-server.service
systemctl is-active fsrdp-server.service
systemctl is-enabled fsrdp-server.service
is-active must report active , and
is-enabled must report enabled . The latter ensures the service starts automatically after a power failure.
9.3 Check
# Lauschen die Ports?
sudo ss -lntp | grep -E ':(8888|8889|8890)\b'
# Was sagt das Protokoll?
sudo journalctl -u fsrdp-server.service -n 50 --no-pager
# Lizenzstatus im Klartext
sudo -u fsrdp-server env FSRDP_DATA_DIR=/opt/fsrdp-server/data \
/opt/fsrdp-server/FsRdpServer --license-status
During the trial, you see this instead of customer details:
License state: trial
Trial state file: /opt/fsrdp-server/data/trial-state.json
Trial period: 2026-09-11 through 2026-10-11 (30 day(s) left)
Trial room: 123456789
The 30-day period is tied to the first start of this installation, recorded in trial-state.json. It is measured against the latest time ever observed; turning the system clock back does not extend it.
The startup log shows which certificate was loaded and its expiry date, among other details. This is a useful first place to look if something stops working later.
10. Browser Viewer on Port 8890 with Its Own Certificate
The browser viewer lets viewers participate without an installed client; they simply open
https://server.ihrefirma.de:8890/. It is disabled by default and requires two settings: permission
in the license and activation
in the configuration.
10.1 Why a Second Certificate Makes Sense
Any certificate trusted by native clients is sufficient for them, including one from your own company CA. A
Browser is stricter and shows visitors a warning if the certificate is not issued by a publicly recognized authority. The browser viewer can therefore have a separate certificate without changing the native channels' certificate. If left empty, cert.pfx
is used automatically.
10.2 Setup
1
Obtain a Publicly Trusted Certificate
Set up with lego as described in section 5.3. Remember the PFX password you chose.
2
Copy the Certificate to the Data Directory
sudo install -o fsrdp-server -g fsrdp-server -m 0640 \
/etc/lego/certificates/server.ihrefirma.de.pfx \
/opt/fsrdp-server/data/webgateway-cert.pfx
3
Add the Password to the Environment File
sudoedit /etc/fsrdp-server/fsrdp-server.env
Add this alongside the existing line:
FSRDP_WEB_CERT_PASSWORD=das-passwort-der-webgateway-pfx
4
Update Configuration
sudoedit /opt/fsrdp-server/data/appsettings.json
Set or add two values:
"WebGatewayEnabled": true,
"WebGatewayCertificatePath": "webgateway-cert.pfx",
A relative path is relative to the data directory. Afterwards restore permissions:
sudo chown fsrdp-server:fsrdp-server /opt/fsrdp-server/data/appsettings.json
and sudo chmod 0640 ….
5
Restart and Check
sudo systemctl restart fsrdp-server
sudo journalctl -u fsrdp-server -n 30 --no-pager | grep -i certificate
The log must now contain two certificate lines: one for the native channels and one for the browser viewer. Finally check the chain from outside:
echo | openssl s_client -connect server.ihrefirma.de:8890 \
-servername server.ihrefirma.de 2>&1 | grep -E 'Verify return code'
Verify return code: 0 (ok) means the browser will not show a warning.
10.3 Set Up Automatic Renewal
The server reads its certificates only at startup. Renewal takes effect after restarting the service, which disconnects all active sessions. The renewal script should therefore restart the service only when the certificate actually changes.
Have /usr/local/sbin/fsrdp-renew-webcert.sh :
#!/bin/bash
set -euo pipefail
domain=server.ihrefirma.de
email=ihre.adresse@example.com
env_file=/etc/fsrdp-server/fsrdp-server.env
lego_pfx="/etc/lego/certificates/${domain}.pfx"
pfx_pass=$(sed -n 's/^FSRDP_WEB_CERT_PASSWORD=//p' "$env_file")
[ -n "$pfx_pass" ] || { echo "Passwort fehlt in $env_file" >&2; exit 1; }
before=$(sha256sum "$lego_pfx" 2>/dev/null | cut -d' ' -f1 || true)
lego --accept-tos --email "$email" --domains "$domain" \
--http --http.port :80 --path /etc/lego \
--pfx --pfx.format SHA256 --pfx.pass "$pfx_pass" \
renew --days 30
after=$(sha256sum "$lego_pfx" | cut -d' ' -f1)
[ "$before" != "$after" ] || { echo "Zertifikat unveraendert."; exit 0; }
install -o fsrdp-server -g fsrdp-server -m 0640 \
"$lego_pfx" /opt/fsrdp-server/data/webgateway-cert.pfx
systemctl restart fsrdp-server
echo "Neues Zertifikat eingespielt, Dienst neu gestartet."
Make It Executable and Schedule It:
sudo chmod 0750 /usr/local/sbin/fsrdp-renew-webcert.sh
sudo systemctl edit --force --full fsrdp-webcert-renew.service
Service file contents:
[Unit]
Description=Zertifikat des FsRdp-Browser-Viewers erneuern
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/fsrdp-renew-webcert.sh
And the corresponding timer:
sudo systemctl edit --force --full fsrdp-webcert-renew.timer
[Unit]
Description=Zweimal taeglich pruefen, ob das Zertifikat erneuert werden muss
[Timer]
OnCalendar=*-*-* 03,15:00:00
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.target
Enable and test manually once:
sudo systemctl enable --now fsrdp-webcert-renew.timer
sudo systemctl start fsrdp-webcert-renew.service
sudo journalctl -u fsrdp-webcert-renew.service -n 20 --no-pager
11. Your First Connection Test
Do not test from the server itself, since this would miss router and firewall problems. Install the client on another device (see
Client Installation Guide), enter the licensed server name and connect two devices to the same room. Only with two participants can you verify that screen and audio are transmitted correctly.
Do not run telnet or nc in a loop. The server treats repeated connection attempts without a valid protocol as an attack and temporarily blocks the test computer's IP address.
12. Ongoing Operation
Backups
Back up /opt/fsrdp-server/data and
/etc/fsrdp-server/fsrdp-server.env to a location with equally restrictive access permissions, since they contain the PFX file and password. Most important is server-instance-id.txt: without it, your license is unusable for this installation.
Update the Server
unzip FsRdpServer-linux-x64.zip -d FsRdpServer-neu
cd FsRdpServer-neu
chmod +x FsRdpServer install.sh
sudo ./install.sh
If the service was running, the installer stops it, replaces the program and service definition, then restarts it. Certificate, password, license, installation ID, room reservations, configuration and logs remain unchanged.
A Deployment Pitfall: If
/etc/fsrdp-server/fsrdp-server.envis missing, the installer creates it from the template with a placeholder password. Since the environment variable takes precedence over the configuration file, the service will then fail to start. Restore the file with the real password before installing an update; the installer leaves an existing file unchanged.
Install or Replace the License
The same procedure applies to the first license after a trial and a renewed license. The license itself does not require restarting the service, which reloads it automatically. Browser viewing, captions and demo mode settings are read at startup and do require a restart.
sudo systemctl stop fsrdp-server.service
sudo install -o fsrdp-server -g fsrdp-server -m 0640 \
license.fsrdp /opt/fsrdp-server/data/license.fsrdp
# Danach die Selbstpruefung aus Abschnitt 9.1 wiederholen
sudo systemctl start fsrdp-server.service
Do not start the service if validation fails. If a license is regenerated with a different supporter count, all supporter keys may change; distribute new keys promptly.
Replace the Certificate
sudo install -o fsrdp-server -g fsrdp-server -m 0640 \
cert.pfx /opt/fsrdp-server/data/cert.pfx
# Falls sich das Passwort geaendert hat: fsrdp-server.env anpassen
sudo systemctl restart fsrdp-server.service
Connect the Pi only while it is needed
A server that is used now and then – a demo machine, a stand-by, a Pi that carries one support session a week – does not have to sit on the network for the rest of the time. Plug it in about two minutes beforehand; that is enough for it to boot, and the service starts on its own. What cannot be reached cannot be scanned or attacked, and the port forwarding for 8888, 8889 and 8890 exposes the Pi to the entire Internet for as long as it hangs on the cable.
What matters is how it goes off: by the button, not by the plug. A Raspberry Pi 5 has a button on the board – a short press shuts it down cleanly, and a press on a halted Pi starts it again. Older models get the same behaviour from dtoverlay=gpio-shutdown
in config.txt together with a momentary switch between pin 5 (GPIO3) and pin 6 (GND). Over SSH, sudo poweroff does the same. Pull the plug once the activity LED has gone quiet.
Why it matters:
Raspberry Pi OS journals its file system, so most abrupt power cuts pass without a trace. The risk per occurrence is small, but it accumulates – and it lands on the card that also carries the license, the certificate, the installation ID and the room reservations. Booting from a USB SSD instead of an SD card takes the weakest part out of the picture altogether.
13. Common Problems
The Service Does Not Start
First check the log:
sudo journalctl -u fsrdp-server -n 50 --no-pager. Common causes include an incorrect PFX password, a configuration syntax error (even a missing comma) and insufficient read permissions for the service account.
Permission Denied
Restore ownership and permissions from section 8. The PFX file and license must not be readable by all users, but the service account must be able to read them.
The Certificate Name Does Not Match
The client name, certificate name and licensed host name differ. Check all three using the command from 5.5 and always connect using the licensed name.
Every Client Reports “Trial Period Expired”
The 30 days have ended. The service keeps running but accepts no connections until a license is installed (section 12). --license-status shows trial-expired and the end date in this case.
The Server Remains in Trial Mode Despite an Installed License
The license file was not found or accepted. The startup banner in the journal shows both the expected path and the reason. Typical causes are an incorrect LicensePath, insufficient service account read permissions for license.fsrdp, a license for another installation ID or a manually edited and therefore invalid file.
The Service Runs, but No Clients Connect
- Does the client's name resolution return the correct address?
- Is the router's DNS rebind protection interfering (see 3.7)?
- Is router access enabled, including IPv6 with DS-Lite?
- Is the server listening?
sudo ss -lntp | grep 8888
- Is UFW blocking access?
sudo ufw status
The Browser Shows a Certificate Warning
The browser viewer is still using the native channels' certificate. Configure a publicly trusted certificate as described in section 10.
It Worked before, but Not Today
Two common causes: the certificate expired, or your connection's public address changed and the DNS record is outdated. An IPv6 prefix change affects both the DNS record and the router access rule.