# FsRdpServer unter Linux installieren

Vollständige Anleitung von einem frisch aufgesetzten Linux-Server bis zur ersten
funktionierenden Client-Verbindung – für Ubuntu Server, Debian und Raspberry Pi OS
(64 Bit). Jeder Befehl ist einzeln erklärt.

> Reine Textfassung der Seite <https://www.fssoft.de/FsRdp/InstallingServerLinux.aspx>
> für KI-Assistenten und zum Ausdrucken. Inhaltlich identisch mit der HTML-Fassung;
> maßgeblich ist im Zweifel die Seite selbst.

**Entwicklungsversion:** Der Server richtet sich derzeit an ausgewählte Pilotkunden.
Bitte nehmen Sie vor der Installation Kontakt auf, damit Servername und Lizenz
gemeinsam abgestimmt werden können: <https://www.fssoft.de/Impressum.aspx>

## Inhalt

1. Was am Ende laufen soll
2. Den frischen Linux-Server vorbereiten
3. Der Servername: DNS mit A- und AAAA-Record
4. Router, Portfreigaben und Firewall
5. Das TLS-Zertifikat (PFX-Datei) im Detail
6. Das Serverpaket installieren
7. Installations-ID erzeugen und Lizenz anfordern
8. Zertifikat, Lizenz und Passwort einspielen
9. Validieren und den Dienst starten
10. Browser-Viewer auf Port 8890 mit eigenem Zertifikat
11. Der erste Verbindungstest
12. Laufender Betrieb: Backup, Update, Erneuerung
13. Häufige Probleme

---

## 1. Was am Ende laufen soll

FsRdpServer ist ein **Vermittlungsserver**. Er nimmt keine Bildschirminhalte auf und
speichert keine Sitzungsinhalte – er verbindet lediglich die Teilnehmer eines Raums
miteinander. Alle Clients verbinden sich zum Server, nie direkt zueinander. Deshalb
muss ausschließlich der Server erreichbar sein, kein einziger Client.

Nach der Installation lauscht der Dienst auf diesen TCP-Ports:

| Port | Wofür | Pflicht? |
|---|---|---|
| `8888` | Hauptverbindung: Steuerung, Bildschirmbild, Dateien, Fernsteuerung | ja |
| `8889` | Sprachübertragung (eigener Kanal) | ja |
| `8890` | Browser-Viewer für Zuschauer ohne installierten Client | optional, lizenzpflichtig |
| `80` | Nur für die Ausstellung und Erneuerung von Let's-Encrypt-Zertifikaten | optional |

Das Linux-Paket ist **eigenständig** – eine systemweit installierte
.NET-Laufzeitumgebung ist nicht nötig. Verwenden Sie:

- `linux-x64` für Ubuntu Server, Debian und vergleichbare 64-Bit-Systeme auf Intel/AMD;
- `linux-arm64` für Raspberry Pi OS (64 Bit) und andere ARM64-Systeme.

---

## 2. Den frischen Linux-Server vorbereiten

Alle folgenden Befehle geben Sie in einem Terminal ein – entweder direkt am Gerät oder
per SSH. `sudo` bedeutet „mit Verwaltungsrechten ausführen"; beim ersten Mal fragt
Linux nach Ihrem Passwort.

### Schritt 1: System aktualisieren

```bash
sudo apt update
sudo apt full-upgrade -y
sudo reboot
```

Nach dem Neustart melden Sie sich erneut an. Ein Server, der später aus dem Internet
erreichbar ist, sollte von Anfang an aktuell sein.

### Schritt 2: Benötigte Hilfsprogramme nachinstallieren

```bash
sudo apt install -y unzip openssl
```

`unzip` entpackt das Serverpaket, `openssl` brauchen Sie später zum Prüfen und
Erzeugen der PFX-Datei.

### Schritt 3: Uhrzeit und Zeitzone kontrollieren

Zertifikate und Lizenzen haben Gültigkeitszeiträume. Geht die Serveruhr mehrere
Minuten falsch, scheitern Verbindungen mit scheinbar unerklärlichen Fehlern.

```bash
timedatectl
sudo timedatectl set-timezone Europe/Berlin
```

In der Ausgabe von `timedatectl` sollte `System clock synchronized: yes` stehen.

### Schritt 4: Feste lokale IP-Adresse vergeben

Der Router muss die Ports später an eine gleichbleibende Adresse weiterleiten. Am
einfachsten richten Sie im Router eine feste DHCP-Zuordnung ein („diesem Gerät immer
dieselbe IPv4-Adresse zuweisen") – dann müssen Sie am Linux-System nichts ändern. Die
aktuellen Adressen sehen Sie mit:

```bash
ip -brief address show
```

### Schritt 5: Bei IPv6 den hinteren Adressteil festnageln

Eine IPv6-Adresse besteht aus zwei Hälften: dem *Präfix*, das Ihr Anbieter vergibt,
und der *Interface-ID* dahinter, die das Gerät selbst wählt. Viele Systeme würfeln die
Interface-ID bei jedem Präfixwechsel neu aus – dann zeigt Ihr DNS-Eintrag ins Leere
und die Router-Freigabe greift nicht mehr. Mit NetworkManager (Standard auf Raspberry
Pi OS und aktuellen Ubuntu-Desktops) legen Sie die Interface-ID fest:

```bash
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"
```

Der Name der Verbindung stammt aus der ersten Zeile; `::159` ist frei wählbar. Danach
endet die IPv6-Adresse des Servers immer auf `::159`, egal wie das Präfix lautet. Auf
Servern mit `systemd-networkd` oder `netplan` erreichen Sie dasselbe über den
Parameter `Token=` bzw. eine statisch konfigurierte Adresse.

---

## 3. Der Servername: DNS mit A- und AAAA-Record

### 3.1 Warum ein Name und keine IP-Adresse?

Clients verbinden sich **immer über einen DNS-Namen**, zum Beispiel
`server.ihrefirma.de`, niemals über eine IP-Adresse. Dafür gibt es zwei zwingende
Gründe: Das TLS-Zertifikat ist auf einen Namen ausgestellt, und Ihre Lizenz ist an
genau denselben Namen gebunden.

> **Merksatz:** Lizenzierter Hostname = Name im Zertifikat = Name, den der Client
> einträgt. Diese drei müssen zeichengenau übereinstimmen.

### 3.2 A-Record und AAAA-Record – was ist das?

Ein DNS-Eintrag übersetzt einen Namen in eine Adresse. Es gibt zwei Sorten, weil es
zwei Adressarten im Internet gibt:

| Eintrag | Zeigt auf | Beispiel |
|---|---|---|
| `A` | eine IPv4-Adresse | `203.0.113.45` |
| `AAAA` | eine IPv6-Adresse | `2a02:810d:7087:8800::159` |

Gesprochen wird `AAAA` als „Quad-A". Beide dürfen für denselben Namen gleichzeitig
existieren. Wichtig: Der AAAA-Record zeigt auf die IPv6-Adresse **des Servers selbst**,
nicht auf die des Routers – bei IPv6 hat jedes Gerät eine eigene, weltweit gültige
Adresse.

### 3.3 Ihre öffentlichen Adressen herausfinden

Auf dem Server ausführen:

```bash
# Öffentliche IPv4-Adresse des Anschlusses
curl -4 https://api.ipify.org; echo

# Öffentliche IPv6-Adresse dieses Servers
curl -6 https://api6.ipify.org; echo
```

Antwortet der erste Befehl, haben Sie öffentliches IPv4; antwortet der zweite, haben
Sie IPv6.

### 3.4 Sonderfall DS-Lite: kein öffentliches IPv4

Viele Kabel- und Glasfaseranschlüsse in Deutschland laufen mit **DS-Lite**. Dabei
bekommt Ihr Anschluss keine eigene öffentliche IPv4-Adresse mehr, sondern teilt sich
eine mit vielen anderen Kunden. Die Folgen:

- **Eine IPv4-Portweiterleitung bleibt wirkungslos.** Sie können sie einrichten, sie
  wird nie erreicht.
- **Nur IPv6 funktioniert.** Der Name bekommt also ausschließlich einen AAAA-Record.
- **Clients in reinen IPv4-Netzen kommen nicht heran** – das betrifft manche
  Firmennetze und einzelne Mobilfunkzugänge.

**So erkennen Sie DS-Lite:** Der Router zeigt keine öffentliche IPv4-Adresse oder eine
aus dem Bereich `100.64.x.x`–`100.127.x.x`; der Aufruf von
`curl -4 https://api.ipify.org` schlägt fehl, der mit `-6` gelingt.

Bei vielen Anbietern lässt sich auf Anfrage kostenlos auf einen Anschluss mit echter
IPv4-Adresse umstellen. Wenn Ihre Clients aus beliebigen Netzen kommen sollen, ist
dieser Anruf die einfachste Lösung.

### 3.5 Wechselnde Adressen: Dynamic DNS

Privatanschlüsse bekommen meist keine feste Adresse: Bei IPv4 ändert sich die
öffentliche Adresse, bei IPv6 das Präfix. In beiden Fällen zeigt Ihr DNS-Eintrag
irgendwann ins Leere. Drei Wege:

- **Feste Adresse beim Anbieter buchen** – der sauberste Weg, meist gegen kleinen
  Aufpreis.
- **Dynamic-DNS-Dienst** (dynv6, deSEC, No-IP …), den Ihr Router bei jeder Änderung
  aktualisiert. Achten Sie darauf, dass der Dienst auch **AAAA-Records** aktualisiert –
  bei DS-Lite ist das die entscheidende Fähigkeit.
- **Nur im lokalen Netz betreiben** – dann brauchen Sie weder Dynamic DNS noch
  Portfreigaben (siehe 3.8).

### 3.6 Die Einträge beim DNS-Anbieter setzen

Legen Sie bei der Stelle, die Ihre Domain verwaltet, einen Eintrag für den gewünschten
Namen an – `A` mit der öffentlichen IPv4-Adresse des Anschlusses und/oder `AAAA` mit
der IPv6-Adresse des Servers. Setzen Sie die TTL für die Testphase auf einen kleinen
Wert (z. B. `600` Sekunden) und erhöhen Sie sie erst, wenn alles läuft.

### 3.7 Kontrollieren, ob der Name stimmt

```bash
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
```

> **Stolperstein im eigenen Netz:** Viele Router – unter anderem die FRITZ!Box –
> filtern mit ihrem *DNS-Rebind-Schutz* Antworten heraus, die auf das eigene Netz
> zeigen. Der Name löst dann ausgerechnet **im Heimnetz** auf gar nichts auf, während
> er von außen einwandfrei funktioniert. Abhilfe: den Hostnamen unter
> **Heimnetz → Netzwerk → Netzwerkeinstellungen → DNS-Rebind-Schutz** als Ausnahme
> eintragen. Danach unbedingt den DNS-Zwischenspeicher der Testrechner leeren, sonst
> merken sie die Änderung nicht.

### 3.8 Nur im lokalen Netz betreiben

Sitzen alle Teilnehmer im selben Netz, brauchen Sie weder öffentliches DNS noch
Portfreigaben. Der Name muss aber trotzdem existieren, weil Zertifikat und Lizenz
daran hängen: entweder über Ihr internes DNS oder – nur für kleine Tests – über einen
Eintrag in `/etc/hosts` auf jedem Client:

```text
192.168.1.50    server.ihrefirma.de
```

---

## 4. Router, Portfreigaben und Firewall

### 4.1 IPv4: Portweiterleitung

Bei IPv4 teilen sich alle Geräte eine öffentliche Adresse. Der Router muss deshalb
wissen, wohin er ankommende Verbindungen weiterreicht. Legen Sie für `8888`, `8889`
und – falls genutzt – `8890` je eine TCP-Weiterleitung auf den Server an. In der
FRITZ!Box: **Internet → Freigaben → Portfreigaben → Gerät für Freigaben hinzufügen**.

### 4.2 IPv6: Freigabe statt Weiterleitung

Bei IPv6 wird nichts umgeleitet – jedes Gerät ist bereits von außen adressierbar. Der
Router öffnet lediglich seine Firewall für dieses Gerät und diesen Port. In der
Oberfläche heißt das trotzdem meist „Portfreigabe", mit einer zusätzlichen Auswahl wie
„Internetzugriff über IPv6".

> Legen Sie die Freigabe **am Gerät** an, nicht an einer eingetippten Adresse – nur
> dann übersteht sie einen Präfixwechsel. Bei DS-Lite ist ausschließlich die
> IPv6-Freigabe wirksam.

### 4.3 Port 80 – nur für Let's Encrypt

Beziehen Sie Ihr Zertifikat über Let's Encrypt, muss die Zertifizierungsstelle prüfen,
dass Ihnen der Name gehört. Der einfachste Weg läuft über Port 80, und zwar dauerhaft
freigegeben, weil die Erneuerung regelmäßig automatisch abläuft. Zwischen den
Erneuerungen lauscht auf Port 80 nichts – die Warnung, die Router an dieser Stelle
anzeigen, zielt auf einen dauerhaft laufenden Webserver.

### 4.4 Die Firewall auf dem Server selbst

Prüfen Sie zuerst, ob überhaupt eine Firewall aktiv ist:

```bash
sudo ufw status
```

Ist UFW aktiv, geben Sie die Ports frei:

```bash
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
```

> **Vorsicht bei entfernten Servern:** Aktivieren Sie eine Firewall niemals, ohne
> vorher `sudo ufw allow OpenSSH` freizugeben. Sonst sperren Sie sich selbst aus und
> kommen nur noch über die Konsole des Anbieters wieder hinein.

---

## 5. Das TLS-Zertifikat (PFX-Datei) im Detail

### 5.1 Was ist eine PFX-Datei?

`cert.pfx` ist ein passwortgeschützter Behälter im Format PKCS#12. Darin stecken das
**Serverzertifikat** für Ihren Servernamen, der zugehörige **private Schlüssel** und
meist die **Zwischenzertifikate** der ausstellenden Stelle. FsRdpServer verschlüsselt
damit alle Verbindungen. Ohne gültiges Zertifikat startet der Dienst nicht.

> **Die PFX-Datei ist ein Geheimnis.** Wer sie und ihr Passwort besitzt, kann sich als
> Ihr Server ausgeben. Nicht per unverschlüsselter E-Mail verschicken, nicht in ein
> Repository legen, nicht für alle Benutzer lesbar machen.

Die Datei muss **genau ein** Zertifikat mit privatem Schlüssel enthalten und den
lizenzierten Servernamen als *Subject Alternative Name* tragen – entweder direkt
(`server.ihrefirma.de`) oder über ein Wildcard-Zertifikat (`*.ihrefirma.de`).

### 5.2 Weg A: Gekauftes Zertifikat in eine PFX-Datei bündeln

Anbieter liefern meist zwei bis drei Dateien: das Zertifikat, den privaten Schlüssel
und die Zwischenzertifikate. So machen Sie daraus eine PFX-Datei:

```bash
openssl pkcs12 -export -out cert.pfx \
  -inkey privkey.pem -in cert.pem -certfile chain.pem
```

OpenSSL fragt das Passwort interaktiv ab – schreiben Sie es nicht als
`-password pass:...` in die Befehlszeile, sonst steht es in Ihrem Shell-Verlauf.

### 5.3 Weg B: Kostenlos über Let's Encrypt

Funktioniert, sobald Ihr Servername öffentlich im DNS steht und Port 80 von außen
erreichbar ist. Es gibt zwei gängige Werkzeuge:

- **`lego`** – ein einzelnes Programm, das die PFX-Datei direkt erzeugen kann. Damit
  entfällt der Umwandlungsschritt, deshalb wird es hier gezeigt.
- **`certbot`** – der bekannteste Client. Er erzeugt PEM-Dateien, die Sie anschließend
  wie in 5.2 bündeln müssen. Beachten Sie: In Debian 13 („trixie") und darauf
  aufbauenden Raspberry-Pi-OS-Versionen ist `certbot` nicht mehr als Paket enthalten.

#### Schritt 1: lego installieren

```bash
sudo apt install -y lego
```

Findet `apt` das Paket nicht, ist es in Ihrer Version eventuell nur über die Backports
verfügbar (`sudo apt install -y -t stable-backports lego`) oder Sie laden das fertige
Programm von `go-acme.github.io/lego` herunter.

#### Schritt 2: Erst mit der Testumgebung ausprobieren

Let's Encrypt begrenzt die Zahl der Fehlversuche. Prüfen Sie deshalb zuerst gegen den
Testserver, ob Ihre Portfreigabe wirklich greift – das kostet kein Kontingent:

```bash
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
```

#### Schritt 3: Das echte Zertifikat als PFX abholen

Hat der Testlauf funktioniert, holen Sie das richtige Zertifikat. Denken Sie sich ein
Passwort für die PFX-Datei aus:

```bash
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
```

Die fertige Datei liegt danach unter
`/etc/lego/certificates/server.ihrefirma.de.pfx`.

### 5.4 Weg C: Zertifikat der eigenen Firmen-CA

Nur für rein interne Installationen sinnvoll: Jeder Client muss Ihrer Firmen-CA
ausdrücklich vertrauen, sonst schlägt jede Verbindung fehl. Für den Browser-Viewer ist
dieser Weg unbrauchbar, weil jeder Browser eine Warnseite zeigen würde.

### 5.5 Die PFX-Datei vor der Installation prüfen

```bash
# 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
```

Achten Sie darauf, dass der lizenzierte Name in `subjectAltName` auftaucht und das
Datum in `notAfter` in der Zukunft liegt.

---

## 6. Das Serverpaket installieren

Das Paket erhalten Sie unter <https://www.fssoft.de/FsRdp/>.

### Schritt 1: Paket auf den Server kopieren und entpacken

```bash
unzip FsRdpServer-linux-x64.zip -d FsRdpServer
cd FsRdpServer
ls
```

Auf einem Raspberry Pi verwenden Sie stattdessen `FsRdpServer-linux-arm64.zip`. Im
Ordner müssen unter anderem `FsRdpServer`, `install.sh`, `fsrdp-server.service` und
`README-LINUX.md` liegen.

### Schritt 2: Installer ausführen

```bash
chmod +x FsRdpServer install.sh
sudo ./install.sh
```

Der Dienst bleibt bei der Erstinstallation absichtlich **gestoppt**, bis Zertifikat und
Lizenz eingerichtet sind. Das ist kein Fehler.

**Was dabei entsteht:**

| Pfad | Bedeutung |
|---|---|
| `/opt/fsrdp-server/FsRdpServer` | das Programm selbst |
| `/opt/fsrdp-server/data/` | Konfiguration, Zertifikat, Lizenz, Installations-ID, Protokolle |
| `/etc/fsrdp-server/fsrdp-server.env` | Geheimnisse, nur für `root` lesbar |
| `/etc/systemd/system/fsrdp-server.service` | die Dienstbeschreibung für systemd |
| Benutzer `fsrdp-server` | eigenes, eingeschränktes Dienstkonto ohne Anmeldemöglichkeit |

Andere Ports als `8888`/`8889` stellen Sie in
`/opt/fsrdp-server/data/appsettings.json` ein. Setzen Sie Eigentümer und Rechte
anschließend zurück: `sudo chown fsrdp-server:fsrdp-server …` und `sudo chmod 0640 …`.

---

## 7. Installations-ID erzeugen und Lizenz anfordern

FsRdpServer startet ausschließlich mit einer gültigen, signierten Lizenzdatei. Sie ist
an Ihren **Servernamen** und an eine dauerhafte **Installations-ID** gebunden. Anders
als unter Windows erzeugen Sie diese ID auf einem Linux-Server *vor* der Lizenzanfrage
selbst – genau einmal:

```bash
sudo -u fsrdp-server env \
  FSRDP_DATA_DIR=/opt/fsrdp-server/data \
  /opt/fsrdp-server/FsRdpServer --installation-id
```

Der Befehl gibt eine lange Zeichenkette aus und speichert sie in
`/opt/fsrdp-server/data/server-instance-id.txt`.

Teilen Sie für die Ausstellung mit:

- die ausgegebene Installations-ID;
- den exakten DNS-Namen, den die Clients verwenden werden;
- wie viele Räume gleichzeitig und wie viele Teilnehmer pro Raum;
- die gewünschte Laufzeit;
- ob Sie Browser-Viewer, Sitzungsaufnahme oder Live-Untertitel nutzen möchten – diese
  Funktionen müssen in der Lizenz freigeschaltet sein.

> **`server-instance-id.txt` darf niemals verloren gehen** – auch nicht bei einem
> Update oder einer Neuinstallation. Ist die Datei weg, passt Ihre Lizenz nicht mehr
> und muss neu ausgestellt werden.

---

## 8. Zertifikat, Lizenz und Passwort einspielen

### Schritt 1: Beide Dateien mit den richtigen Rechten ablegen

Wechseln Sie in den Ordner, in dem `license.fsrdp` und `cert.pfx` liegen:

```bash
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` kopiert die Datei und setzt Eigentümer und Rechte in einem Zug – das
Dienstkonto darf lesen, normale Benutzer nicht.

### Schritt 2: Das PFX-Passwort hinterlegen

Das Passwort gehört nicht in die Konfigurationsdatei, sondern in die nur für `root`
lesbare Umgebungsdatei:

```bash
sudoedit /etc/fsrdp-server/fsrdp-server.env
```

Tragen Sie dort ein (bestehende Zeilen ersetzen):

```ini
FSRDP_CERT_PASSWORD=hier-das-echte-passwort
```

Danach die Rechte sicherstellen:

```bash
sudo chown root:root /etc/fsrdp-server/fsrdp-server.env
sudo chmod 0600 /etc/fsrdp-server/fsrdp-server.env
```

Enthält das Passwort Leerzeichen oder Sonderzeichen, setzen Sie es nach der
systemd-Syntax in Anführungszeichen. Am einfachsten vermeiden Sie beides und verwenden
ein langes Passwort aus Buchstaben und Ziffern.

### Schritt 3: Die Dateirechte kontrollieren

```bash
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
```

Erwartet wird:

| Pfad | Eigentümer | Rechte |
|---|---|---|
| `/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. Validieren und den Dienst starten

### 9.1 Selbstprüfung vor dem ersten Start

Der folgende Befehl sieht sperrig aus, hat aber einen guten Grund: Er lässt systemd die
nur für `root` lesbare Passwortdatei laden und führt die Prüfung trotzdem unter dem
Dienstkonto aus. So muss das PFX-Passwort nirgends in die Befehlszeile.

```bash
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
```

Eine erfolgreiche Ausgabe bestätigt, dass Lizenz, Installations-ID und Zertifikat
zusammenpassen. Eine **DNS-Warnung** ist nur dann akzeptabel, wenn Sie den Namen
bewusst über internes DNS oder hosts-Dateien bereitstellen – die Clients müssen ihn
trotzdem auflösen können. Jeden echten Fehler beheben Sie vor dem Start.

### 9.2 Dienst starten

```bash
sudo systemctl start fsrdp-server.service
systemctl is-active fsrdp-server.service
systemctl is-enabled fsrdp-server.service
```

`is-active` muss `active` melden, `is-enabled` muss `enabled` melden – Letzteres sorgt
dafür, dass der Dienst nach einem Stromausfall von selbst wieder hochkommt.

### 9.3 Kontrollieren

```bash
# 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
```

Im Startprotokoll steht unter anderem, welches Zertifikat geladen wurde und bis wann es
gilt – ein guter erster Blick, wenn später etwas nicht funktioniert.

---

## 10. Browser-Viewer auf Port 8890 mit eigenem Zertifikat

Der Browser-Viewer erlaubt Zuschauern, ohne installierten Client teilzunehmen – sie
öffnen einfach `https://server.ihrefirma.de:8890/`. Die Funktion ist standardmäßig aus
und braucht zwei Schalter: die Freigabe **in der Lizenz** und die Aktivierung **in der
Konfiguration**.

### 10.1 Warum ein zweites Zertifikat sinnvoll ist

Für die nativen Clients genügt jedes Zertifikat, dem die Clients vertrauen – auch eines
aus Ihrer eigenen Firmen-CA. Ein **Browser** ist strenger: Er zeigt jedem Besucher eine
Warnseite, wenn das Zertifikat nicht von einer öffentlich anerkannten Stelle stammt.
Deshalb kann der Browser-Viewer ein eigenes Zertifikat bekommen, ohne dass Sie das der
nativen Kanäle anfassen müssen. Lassen Sie die Einstellung leer, wird automatisch
`cert.pfx` mitverwendet.

### 10.2 Einrichten

#### Schritt 1: Öffentlich vertrauenswürdiges Zertifikat holen

Mit `lego` wie in Abschnitt 5.3 beschrieben. Merken Sie sich das vergebene
PFX-Passwort.

#### Schritt 2: Zertifikat ins Datenverzeichnis kopieren

```bash
sudo install -o fsrdp-server -g fsrdp-server -m 0640 \
  /etc/lego/certificates/server.ihrefirma.de.pfx \
  /opt/fsrdp-server/data/webgateway-cert.pfx
```

#### Schritt 3: Passwort in der Umgebungsdatei ergänzen

```bash
sudoedit /etc/fsrdp-server/fsrdp-server.env
```

Zusätzlich zur bestehenden Zeile eintragen:

```ini
FSRDP_WEB_CERT_PASSWORD=das-passwort-der-webgateway-pfx
```

#### Schritt 4: Konfiguration anpassen

```bash
sudoedit /opt/fsrdp-server/data/appsettings.json
```

Zwei Werte setzen bzw. ergänzen:

```json
"WebGatewayEnabled": true,
"WebGatewayCertificatePath": "webgateway-cert.pfx",
```

Ein relativer Pfad bezieht sich auf das Datenverzeichnis. Danach die Rechte
wiederherstellen:
`sudo chown fsrdp-server:fsrdp-server /opt/fsrdp-server/data/appsettings.json` und
`sudo chmod 0640 …`.

#### Schritt 5: Neu starten und prüfen

```bash
sudo systemctl restart fsrdp-server
sudo journalctl -u fsrdp-server -n 30 --no-pager | grep -i certificate
```

Im Protokoll müssen jetzt **zwei** Zertifikatszeilen stehen – eine für die nativen
Kanäle, eine für den Browser-Viewer. Zum Abschluss prüfen Sie die Kette von außen:

```bash
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)` heißt: Der Browser wird keine Warnung zeigen.

### 10.3 Automatische Erneuerung einrichten

> Der Server liest seine Zertifikate **nur beim Start**. Eine Erneuerung wirkt erst
> nach einem Neustart des Dienstes – und der trennt alle laufenden Sitzungen. Deshalb
> sollte das Erneuerungsskript den Dienst nur dann neu starten, wenn sich das
> Zertifikat tatsächlich geändert hat.

Legen Sie `/usr/local/sbin/fsrdp-renew-webcert.sh` an:

```bash
#!/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."
```

Ausführbar machen und einen Zeitplan hinterlegen:

```bash
sudo chmod 0750 /usr/local/sbin/fsrdp-renew-webcert.sh
sudo systemctl edit --force --full fsrdp-webcert-renew.service
```

Inhalt der Dienstdatei:

```ini
[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
```

Und der zugehörige Zeitgeber:

```bash
sudo systemctl edit --force --full fsrdp-webcert-renew.timer
```

```ini
[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
```

Einschalten und einmal von Hand testen:

```bash
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. Der erste Verbindungstest

Testen Sie **nicht** vom Server selbst – damit übersehen Sie jedes Router- und
Firewall-Problem. Installieren Sie den Client auf einem anderen Gerät (siehe
<https://www.fssoft.de/FsRdp/InstallingClient.aspx>), tragen Sie dort den lizenzierten
Servernamen ein und verbinden Sie sich mit zwei Geräten in denselben Raum. Erst mit
zwei Teilnehmern zeigt sich, ob Bild und Ton wirklich durchlaufen.

> **Testen Sie nicht mit `telnet` oder `nc` in der Schleife.** Wiederholte
> Verbindungsversuche ohne gültiges Protokoll wertet der Server als Angriffsversuch und
> sperrt die IP-Adresse des Testrechners vorübergehend.

---

## 12. Laufender Betrieb

### Sicherung

Sichern Sie `/opt/fsrdp-server/data` und `/etc/fsrdp-server/fsrdp-server.env` – aber an
einen Ort mit ebenso engen Zugriffsrechten, denn dort liegen PFX-Datei und Passwort. Am
wichtigsten ist `server-instance-id.txt`: Ohne sie ist Ihre Lizenz für diese
Installation wertlos.

### Server aktualisieren

```bash
unzip FsRdpServer-linux-x64.zip -d FsRdpServer-neu
cd FsRdpServer-neu
chmod +x FsRdpServer install.sh
sudo ./install.sh
```

War der Dienst aktiv, stoppt der Installer ihn, tauscht Programm und
Dienstbeschreibung aus und startet ihn wieder. Zertifikat, Passwort, Lizenz,
Installations-ID, Raumreservierungen, Konfiguration und Protokolle bleiben unverändert.

> **Eine Falle beim Ausrollen:** Fehlt `/etc/fsrdp-server/fsrdp-server.env`, legt der
> Installer sie aus der Vorlage neu an – mit einem Platzhalter als Passwort. Und weil
> die Umgebungsvariable Vorrang vor der Konfigurationsdatei hat, startet der Dienst
> danach nicht mehr. Stellen Sie die Datei mit dem echten Passwort her, *bevor* Sie ein
> Update einspielen; danach lässt der Installer eine vorhandene Datei unangetastet.

### Lizenz austauschen

```bash
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
```

Starten Sie den Dienst nicht, wenn die Prüfung fehlschlägt. Wurde die Lizenz mit einer
geänderten Supporter-Anzahl neu erzeugt, können sich alle Supporter-Schlüssel geändert
haben – verteilen Sie die neuen Schlüssel dann zeitnah.

### Zertifikat austauschen

```bash
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
```

---

## 13. Häufige Probleme

### Der Dienst startet nicht

Sehen Sie zuerst in das Protokoll:
`sudo journalctl -u fsrdp-server -n 50 --no-pager`. Die häufigsten Ursachen sind ein
falsches PFX-Passwort, eine Konfigurationsdatei mit Syntaxfehler (ein fehlendes Komma
genügt) und fehlende Leserechte des Dienstkontos.

### Keine Berechtigung

Setzen Sie Eigentümer und Rechte aus Abschnitt 8 erneut. PFX-Datei und Lizenz dürfen
nicht für alle Benutzer lesbar sein, das Dienstkonto muss sie aber lesen können.

### Der Name im Zertifikat passt nicht

Client-Name, Zertifikatsname und lizenzierter Hostname sind unterschiedlich. Prüfen Sie
alle drei mit dem Befehl aus 5.5 und verbinden Sie sich immer mit dem lizenzierten
Namen.

### Der Dienst läuft, aber kein Client verbindet sich

1. Löst der Name beim Client zur richtigen Adresse auf?
2. Greift der DNS-Rebind-Schutz des Routers (siehe 3.7)?
3. Ist die Freigabe im Router aktiv – bei DS-Lite auch für IPv6?
4. Lauscht der Server? `sudo ss -lntp | grep 8888`
5. Blockiert UFW? `sudo ufw status`

### Der Browser zeigt eine Zertifikatswarnung

Der Browser-Viewer verwendet noch das Zertifikat der nativen Kanäle. Richten Sie ein
öffentlich vertrauenswürdiges Zertifikat nach Abschnitt 10 ein.

### Alles lief, seit heute nicht mehr

Zwei Klassiker: Das Zertifikat ist abgelaufen, oder die öffentliche Adresse Ihres
Anschlusses hat sich geändert und der DNS-Eintrag zeigt ins Leere. Bei IPv6 betrifft
ein Präfixwechsel beides gleichzeitig – den DNS-Eintrag und die Freigabe im Router.

---

## Weiterführend

- Vertiefung zum PFX-Zertifikat: <https://www.fssoft.de/FsRdp/HowToPFX.aspx>
- Dieselbe Anleitung für Windows-Server: <https://www.fssoft.de/FsRdp/InstallingServerWindows.aspx>
- Client installieren: <https://www.fssoft.de/FsRdp/InstallingClient.aspx>
- Lizenzbedingungen: <https://www.fssoft.de/FsRdp/Lizenz.aspx>

**Sie kommen an einer Stelle nicht weiter?** Melden Sie sich – Servername, Zertifikat
und Lizenz stimmen wir gerne gemeinsam ab: <https://www.fssoft.de/Impressum.aspx>
(Robert Fischbacher, Fischbacher Software)
