Homeserver-Sicherheitsarchitektur: Unterschied zwischen den Versionen

Aus Tuxipedia
Zeile 3: Zeile 3:
Einen eigenen Server an's Internet zu bekommen, ist nicht allzu schwierig. Ein Dienst, der die eigene, vom Internet-Provider zugewiesene IP-Adresse in einen festen Domain-Namen umwandelt (siehe: [https://de.wikipedia.org/wiki/Dynamisches_DNS Dynamisches DNS]), wird im privaten Bereich die Voraussetzung sein.
Einen eigenen Server an's Internet zu bekommen, ist nicht allzu schwierig. Ein Dienst, der die eigene, vom Internet-Provider zugewiesene IP-Adresse in einen festen Domain-Namen umwandelt (siehe: [https://de.wikipedia.org/wiki/Dynamisches_DNS Dynamisches DNS]), wird im privaten Bereich die Voraussetzung sein.
Es gibt verschiedene Anbieter, oft auch kostenlose.
Es gibt verschiedene Anbieter, oft auch kostenlose.
Einmal eingerichtet,  
 
Beispiel: Der eigenen, von außen sichtbaren IP 78.123.234.45 wird vom DynDDS-Dienst die Domain <myhomeserver.dyndns.de> zugewiesen.
Einmal eingerichtet, wird der eigene Rechner antworten, wenn die Domain http://myhomeserver.dyndns.de in die Browser-Adressleiste einkopiert wird.


=== Ein Leitfaden für selbst gehostete Server mit OPNsense, Managed Switch und Docker ===
=== Ein Leitfaden für selbst gehostete Server mit OPNsense, Managed Switch und Docker ===


Die Kehrseite: Sowie der Server über's Internet erreichbar ist, ist er angreifbar. Das ist kein theoretisches Szenario. Meiner Erfahrung nach ist es eine Frage von Stunden, bis die ersten Bots "anklopfen", nach laufenden Diensten suchen, nach offenen Ports, nach Schwachstellen.
Die Kehrseite: Sowie der Server über's Internet erreichbar ist, ist er angreifbar.
Das ist kein theoretisches Szenario. Meiner Erfahrung nach ist es eine Frage von Stunden, bis die ersten Bots "anklopfen", nach laufenden Diensten suchen, nach offenen Ports, nach Schwachstellen.
Die öffentliche Erreichbarkeit des eigenen Servers über die ungesicherte Adresse...
* http://myhomeserver.dyndns.de
...ist fahrlässig.


Aufgrund einer mangelhaften Konfiguration (offener Samba-Port) hatte ich die sehr reale Erfahrung einer russischen Hackerbande, die einige Hundert Textdateien mit Zahlungsaufforderungen und einen Verschlüsselungstrojaner auf meinem Rechner hinterlassen hatte. Gerettet hatten mich damals die Dateirechte von Linux. Das fehlende E(x)ecutional-Flag und die eingeschränkten Benutzerrechte hatten den Trojaner ausgebremst.
Aufgrund einer mangelhaften Konfiguration (offener Samba-Port) hatte ich die sehr reale Erfahrung einer russischen Hackerbande, die einige Hundert Textdateien mit Zahlungsaufforderungen und einen Verschlüsselungstrojaner auf meinem Rechner hinterlassen hatte. Gerettet hatten mich damals die Dateirechte von Linux. Das fehlende E(x)ecutional-Flag und die eingeschränkten Benutzerrechte hatten den Trojaner ausgebremst.

Version vom 27. Mai 2026, 23:41 Uhr

Homeserver-Sicherheitsarchitektur: Aufbau, Funktionsweise und Diagnose

Einen eigenen Server an's Internet zu bekommen, ist nicht allzu schwierig. Ein Dienst, der die eigene, vom Internet-Provider zugewiesene IP-Adresse in einen festen Domain-Namen umwandelt (siehe: Dynamisches DNS), wird im privaten Bereich die Voraussetzung sein. Es gibt verschiedene Anbieter, oft auch kostenlose.

Beispiel: Der eigenen, von außen sichtbaren IP 78.123.234.45 wird vom DynDDS-Dienst die Domain <myhomeserver.dyndns.de> zugewiesen. Einmal eingerichtet, wird der eigene Rechner antworten, wenn die Domain http://myhomeserver.dyndns.de in die Browser-Adressleiste einkopiert wird.

Ein Leitfaden für selbst gehostete Server mit OPNsense, Managed Switch und Docker

Die Kehrseite: Sowie der Server über's Internet erreichbar ist, ist er angreifbar. Das ist kein theoretisches Szenario. Meiner Erfahrung nach ist es eine Frage von Stunden, bis die ersten Bots "anklopfen", nach laufenden Diensten suchen, nach offenen Ports, nach Schwachstellen. Die öffentliche Erreichbarkeit des eigenen Servers über die ungesicherte Adresse...

...ist fahrlässig.

Aufgrund einer mangelhaften Konfiguration (offener Samba-Port) hatte ich die sehr reale Erfahrung einer russischen Hackerbande, die einige Hundert Textdateien mit Zahlungsaufforderungen und einen Verschlüsselungstrojaner auf meinem Rechner hinterlassen hatte. Gerettet hatten mich damals die Dateirechte von Linux. Das fehlende E(x)ecutional-Flag und die eingeschränkten Benutzerrechte hatten den Trojaner ausgebremst.

Trotzdem: Nie wieder! Ein wenig von dem, was ich gelernt habe, gebe ich ich hier weiter.


Einleitung

Dieser Artikel beschreibt den Aufbau einer sicheren Netzwerkarchitektur für einen Homeserver, der über das öffentliche Internet erreichbar ist. Der Beitrag richtet sich an alle, die ihre Daten selbst kontrollieren wollen — und dabei nicht unfreiwillig Teil einer globalen Angriffs-Infrastruktur werden möchten. Er will zum Verständnis beitragen, wie die einzelnen Komponenten zusammenspielen — und wie man systematisch vorgeht, wenn etwas nicht funktioniert.

Der Fokus liegt nicht auf einer spezifischen Hardware-Konfiguration, sondern auf dem allgemeinen Prinzip: Wie kommt ein Request von außen sicher zu einem Docker-Container?


Annahmen / Szenario

Folgende Komponenten werden in diesem Artikel vorausgesetzt:

  • Homeserver (Raspberry Pi, Intel NUC, oder beliebiger Linux-Server)
    • Betriebssystem: Debian/Ubuntu oder vergleichbar
    • Docker mit mehreren Diensten (z.B. WordPress, Nextcloud, MediaWiki)
    • Caddy als Reverse Proxy (alternativ funktionieren nginx, Apache, oder (ggf. kostenpflichtige) proprietäre Lösungen. Caddy allerdings hat das für mich charmante Feature, sich eigenständig um die TSL-Zertifikate und ihre Verlängerung bei LetsEncrypt zu kümmern. Wer aufgrund "zu vieler" Fehlversuche bei der Zertifikats-Einrichtung von LetsEncrypt auf Tage gesperrt wurde, wird mein Faible über diesen Automatismus nachvollziehen oder teilen können.)
    • fail2ban als Brute-Force-Schutz
  • DynDNS-Dienst der dem Homeserver eine feste Domain zuweist
    • Beispiel: myhomeserver.dyndns.de
  • Router / Heimnetz-Gateway
    • Beispiel-IP: 192.168.2.1
    • Aufgabe: Portweiterleitung, WLAN, DynDNS-Aktualisierung
    • Typisch: FritzBox, aber jeder Router mit Portweiterleitung funktioniert
  • OPNsense Firewall (dedizierte Hardware-Firewall)
    • WAN-Interface: 192.168.2.2 (im Router-Netz)
    • LAN-Interface / Server-VLAN: 192.168.10.1
    • Aufgabe: Firewall, NAT, DHCP, IDS/IPS
  • Managed Switch (optional, für VLAN-Segmentierung)
    • Trennt Server-VLAN vom Rest des Netzes
  • Homeserver-IP: 192.168.10.100 (per DHCP-Reservation oder besser: Per statischer IP-Adresse fest)

Abschnitt 1: Wie funktionieren die Weiterleitungen? Wer macht was?

Die Kette von außen nach innen

Ein Request von außen (z.B. Browser ruft https://myhomeserver.dyndns.de auf) durchläuft folgende Stationen:

Internet
    ↓ DNS-Auflösung: dyndns.de → öffentliche IP des Heimnetzes
Router / Gateway (192.168.2.1)
    ↓ Portweiterleitung: :80 + :443 (und nur! diese!!) → 192.168.2.2
OPNsense WAN-Interface (192.168.2.2)
    ↓ Destination NAT: :80/:443 → 192.168.10.100
Homeserver eno1/eth0 (192.168.10.100)
    ↓ Docker-Port-Binding: 0.0.0.0:80 + 0.0.0.0:443
Caddy / Reverse Proxy (Docker-intern)
    ↓ Reverse Proxy anhand des Host-Headers
Ziel-Container (z.B. wordpress, nextcloud, ...)

Damit ist der Server auf der IP-Ebene (Layer 3 des OSI-Modells) von außen hin "unsichtbar": Die Firewall (OPNsense) lebt, mit dem Gateway, im 192.168.2-er Netz. Von dort routet sie alle Anfragen über die Ports 80 und 443 an das Interface 192.168.10.100. Dahinter, also im 192.168.10-er-Subnetz, residiert der Heimserver.

Am Ende dieses Beitrages gibt es Sicherheitshinweise. Bitte dringend beachten, dass der Router ausschließlich die Ports 80/TCP und 443/TCP nach außen frei gibt. Der Webserver wird dabei so konfiguriert, dass HTTP-Daten über Port 80 nach HTTPS auf Port 443 umgeleitet werden.

Die Idee, ausschließlich HTTPS zuzulassen, läge nahe. Damit bräuchte sich der Webserver nicht um die Weiterleitung auf Port 443 zu befassen. Bedauerlicherweise wird in diesem Fall der Umgang mit dem TLS-Zertifikat, das den HTTPS-Datenstrom verschlüsselt, scheitern. LetsEncrypt benötigt bei Einrichtung und Verlängerung seiner Zertifikate einen offenen 80-er Port.

Sollte es nötig sein, den Server von außen zu administrieren, wird man darüber nachdenken, einen VPN-Tunnel einzurichten. Sicherer jedoch - und einfacher - ist es dennoch, die Administration ausschließlich über einen zertifikats-geschützten SSH-Zugang im inneren 192.168.-er-Netz zuzulassen und, abgesehen von 80 und 443, auf jeden nach außen exponierten Port zu verzichten.

Wer macht was?

Komponente Aufgabe Konfigurationsort
Router / Gateway DynDNS-Aktualisierung, erste NAT-Stufe, WLAN Router Web-UI → Portfreigaben
OPNsense Firewall Firewall-Regeln, zweite NAT-Stufe (Destination NAT), DHCP für Server-VLAN OPNsense Web-UI (Standard: https://<wan-ip>:443 oder :8443)
Caddy / Reverse Proxy TLS-Terminierung, Let's Encrypt, Weiterleitung an Container Caddyfile auf dem Homeserver
Docker Container-Isolation, internes Netz (Standard: 172.18.0.0/16) docker-compose.yml pro Dienst
fail2ban Brute-Force-Schutz auf Applikationsebene Jail-Configs im fail2ban-Container

Wichtig: OPNsense hat ZWEI Firewall-Engines

OPNsense 26.x hat zwei parallele Regelwerke:

  • Rules [new] — neue API-basierte Engine
  • Rules — alte Engine (Legacy)

Neue Regeln immer in beiden anlegen! Bei Problemen immer beide prüfen.


Abschnitt 2: Wo steht was?

IP-Adressen (Beispiel-Setup)

Gerät Interface IP Bemerkung
Router / Gateway 192.168.2.1 Gateway, WLAN, DynDNS
OPNsense WAN wan-interface 192.168.2.2 Statisch konfiguriert
OPNsense LAN / Server-VLAN lan-interface 192.168.10.1 Gateway für Server-Netz
Homeserver eno1 / eth0 192.168.10.100 Fest per DHCP-Reservation (MAC-Adresse)
Client-Geräte WLAN 192.168.2.x Im Router-Netz, nicht im Server-VLAN

Homeserver: Netzwerk-Interface-Konfiguration

Der Homeserver bezieht seine IP per DHCP vom OPNsense-DHCP-Server. Bei Debian/Ubuntu mit systemd-networkd:

/etc/systemd/network/10-eth0.network

Korrekter Inhalt (DHCP):

[Match]
Name=eno1

[Network]
DHCP=ipv4

[DHCP]
RouteMetric=100

⚠️ Niemals eine statische IP oder einen Gateway manuell eintragen! Der Default-Gateway kommt immer vom DHCP-Server der OPNsense-Firewall (192.168.10.1).

Kea DHCP Lease-Datei (OPNsense)

/var/db/kea/kea-leases4.csv

Hier verwaltet Kea die aktiven Leases. Bei Problemen mit doppelten IPs kann diese Datei (nach configctl kea stop) auf den Header reduziert werden:

address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context,pool_id

Abschnitt 3: Systematische Diagnose — Schritt für Schritt

Grundprinzip: Von außen nach innen

Immer von außen nach innen vorgehen — nie raten, immer messen. Jede Schicht einzeln prüfen.

Schritt 1: Ist OPNsense überhaupt erreichbar?

# Vom Client-Rechner:
ping 192.168.2.2

⚠️ OPNsense antwortet standardmäßig nicht auf ICMP/Ping von außen — das ist korrekt!

Stattdessen prüfen:

# Web-UI erreichbar?
https://192.168.2.2:8443

# Router zeigt OPNsense als verbundenes Gerät?
http://192.168.2.1

Schritt 2: OPNsense intern prüfen

Per SSH oder serieller Konsole auf OPNsense:

# WAN-Interface OK?
ifconfig <wan-interface>
# Erwartete Ausgabe: inet 192.168.2.2, status: active

# LAN-Interface OK?
ifconfig <lan-interface>
# Erwartete Ausgabe: inet 192.168.10.1, status: active

# Router erreichbar?
ping -c 3 192.168.2.1

# Homeserver erreichbar?
ping -c 3 192.168.10.100

Schritt 3: Homeserver direkt prüfen

# SSH auf Homeserver:
ssh root@192.168.10.100

# Alle Container laufen?
docker ps

# Internet vom Homeserver aus erreichbar?
ping -c 3 9.9.9.9

# Routing-Tabelle korrekt?
ip route show
# Erwartete Default-Route: default via 192.168.10.1 dev eno1
# NICHT: default via 192.168.178.x — das wäre falsch!

# Welche IP hat das Interface?
ip addr show eno1
# Erwartete IP: 192.168.10.100

Schritt 4: Caddy / Reverse Proxy prüfen

# Läuft Caddy und antwortet er lokal?
curl -v http://localhost
# Erwartete Antwort: HTTP 308 Redirect → https://localhost/

# Caddy-Logs auf Fehler prüfen:
docker logs caddy --tail 50

Typische Fehler in den Caddy-Logs:

Fehlermeldung Bedeutung Lösung
dial tcp ...:443: connect: no route to host Caddy kommt nicht ins Internet (Let's Encrypt nicht erreichbar) Routing auf Homeserver prüfen (Schritt 3)
no route to host bei Ping auf 9.9.9.9 Falscher Default-Gateway ip route show prüfen, falsche Route entfernen

Schritt 5: NAT und Firewall-Regeln prüfen (OPNsense Shell)

# NAT-Regeln anzeigen:
pfctl -s nat | grep <PORT>

# Firewall-Regeln anzeigen:
pfctl -s rules | grep <PORT>

# Traffic auf WAN-Interface beobachten (kommt der Request an?):
tcpdump -i <wan-interface> port <PORT>

# Traffic auf LAN-Interface beobachten (wird er weitergeleitet?):
tcpdump -i <lan-interface> port <PORT>

Diagnose-Logik:

tcpdump WAN sieht Traffic, LAN nicht → NAT-Regel prüfen!
tcpdump WAN sieht keinen Traffic    → Portweiterleitung im Router prüfen!

Schritt 6: Bekannte Fallstricke

Problem Symptom Ursache Fix
Falsche statische Route ping 9.9.9.9 schlägt fehl Netzwerk-Config hat statischen Gateway eingetragen Auf DHCP umstellen, systemctl restart systemd-networkd
Homeserver hat falsche IP NAT-Regeln greifen nicht DHCP hat beim Neustart temporär andere IP vergeben DHCP-Reservation per MAC-Adresse einrichten
DHCP-Leases durcheinander Server taucht mit zwei IPs auf Neustart hat neuen Lease vor Ablauf des alten erzeugt configctl kea stop, Lease-CSV bereinigen, configctl kea start
OPNsense Firewall-Regel fehlt Dienste von außen nicht erreichbar, intern OK Regel nur in einer der beiden Engines angelegt Regel in beiden Engines anlegen (Rules [new] + Rules)
NAT-Regel ohne Subnetz-Maske Traffic kommt nicht an 192.168.178.0 statt 192.168.178.0/24 eingetragen Subnetz-Maske ergänzen — ohne /24 gilt nur die Netzadresse selbst!
Source/Destination Port vertauscht Verbindungen werden blockiert Bei Firewall-Regel Port unter "Source" statt "Destination" eingetragen Source Port: any / Destination Port: gewünschter Port

Notfall-Cheatsheet

# OPNsense: Firewall temporär deaktivieren (Notfall!)
pfctl -d

# OPNsense: Firewall wieder aktivieren
pfctl -e

# OPNsense: Kea DHCP stoppen/starten
configctl kea stop
configctl kea start

# Homeserver: Falsche Default-Route entfernen
ip route del default via <falsche-gateway-ip> dev eno1

# Homeserver: IP manuell setzen (Sofortlösung bei DHCP-Problemen)
ip addr add 192.168.10.100/24 dev eno1

# Homeserver: Netzwerk-Dienst neu starten (Verbindung kurz weg!)
systemctl restart systemd-networkd

# Homeserver: Docker-Logs prüfen
docker logs caddy --tail 50
docker ps

# OPNsense: Alias-Tabellen prüfen (Blocklisten)
pfctl -t <tabellenname> -T show | wc -l
pfctl -t <tabellenname> -T show | grep <IP>

Sicherheitshinweise

  • SSH-Ports nicht über das Internet freigeben — nur intern erreichbar lassen! Wenn das nicht geht: VPN-Tunnel!
  • Portweiterleitung im Router auf das Minimum beschränken (nur die Ports 80 + 443 öffnen)
  • Für interne Admin-Interfaces (OPNsense Web-UI, Monitoring) keine externen Freigaben
  • DHCP-Reservations per MAC-Adresse oder statische IP-Adressen verhindern IP-Wechsel nach Neustarts
  • Bei Firewall-Regeln: Block-Regeln immer vor Pass-Regeln platzieren

Abschließend eine absolute Regel, die immer und durch die Ewigkeiten gilt:

  • Dienste, die auf einem Rechner NICHT existieren, werden niemals angegriffen! Wenig ist hier mehr!

Dieser Artikel basiert auf praktischen Erfahrungen aus dem Betrieb eines selbst gehosteten Servers mit OPNsense, Cisco-Switch und Docker-Stack. Erstellt: Mai 2026