
Inhaltsverzeichnis
Heute geht es mal um die Verschlüsselung in meinem Homelab. In der heutigen digitalisierten Welt sollte Sicherheit für jeden wichtig sein. Besonders in einem Homelab, wo verschiedene Dienste und IoT-Geräte interagieren, ist es essenziell, sensible Daten vor neugierigen Blicken zu schützen. In diesem Artikel möchte ich meine Erfahrungen und Strategien teilen, wie ich in meinem Homelab eine sichere und vertrauenswürdige Umgebung geschaffen habe, indem ich SSL-Zertifikate und eine eigene PKI (Public Key Infrastructure) implementiert habe.
In diesem Artikel geht es weniger darum wie Verschlüsselung technisch funktioniert. Es geht um das Ausstellen von Zertifikaten was für manche Anwendungen eine Voraussetzung ist, damit diese die Daten überhaupt verschlüsseln. Es geht um die Vertrauensbasis in deinem Netzwerk.
Ein Start mit XCA
Die Idee, eine Root-CA (Certificate Authority) zu erstellen, fand ich schon immer sinnvoll. Früher hatte ich darauf keinen so großen Wert gelegt. Mit der wachsenden Anzahl an IoT Geräten (alles elektronische was so kommuniziert) zuhause, wollte ich aber irgendwann sicherstellen, dass der gesamte Netzwerkverkehr (insbesondere zwischen sensiblen Diensten und IoT-Geräten) verschlüsselt ist.
Anfangs habe ich ausschließlich mit dem sehr guten Tool XCA meine Root-CA verwaltet und eine Sub-CA erstellt, die von der Root signiert wird. Dadurch konnte ich die Verwaltung der Zertifikate zentralisieren und sicherstellen, dass nur vertrauenswürdige Zertifikate in meinem Netzwerk verwendet werden.
XCA nutze ich immer noch um meine Root-Zertfikate sicher abzulegen. Ich hatte auch überlegt ob ich hier ein Hashicorp Vault nutze.
LabCA (ACME)
Die manuelle Verwaltung meiner Zertifikate ging mir auf die Nerven; daher habe ich LabCA in mein Setup integriert. Mit Hilfe von step-ca zur Automatisierung der CA-Verwaltung bietet LabCA eine benutzerfreundliche Weboberfläche, die die Verwaltung erheblich vereinfacht. Ein Feature von LabCA ist die Möglichkeit, den Zertifikatsabruf über ACME (Automatic Certificate Management Environment) zu automatisieren. Damit werden die Zertifikate für unter anderem Proxmox, Webserver und PostgreSQL-Server automatisch aktualisiert.
Ein weiterer Pluspunkt von LabCA ist die Überwachung der Ablaufzeiten der Zertifikate. So werde ich über E-Mail informiert, wenn eines meiner Zertifikate kurz vor dem Ablauf steht. Dies gibt mir die Sicherheit, dass ich jedes Fehlverhalten mitbekomme und meine Dienste ohne Unterbrechung für die Nutzer (meine Familie und mich) zur Verfügung stehen.
Certbot und Nginx
In einigen meiner Setups habe ich den Nginx Server zur SSL-Terminierung eingesetzt. In meinem neuen Setup greife ich jedoch auf Certbot zurück, um die Zertifikate von meiner eigenen PKI zu beziehen. Diese Zertifikate sind standardmäßig 30 Tage gültig, und Certbot kümmert sich um die rechtzeitige Erneuerung. Durch das Montieren des Verzeichnisses /etc/letsencrypt
im Read-Only-Modus in meine Docker-Container kann ich die neu bezogenen Zertifikate nahtlos integrieren.
Wichtig ist, dass man das gesamte /etc/letsencrypt
einbindet damit die Symlinks die Certbot erstellt auch funktionieren.
Hier ist als vollständige Beispiel die Konfiguration meines NocoDB Servers:
services:
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
# Hier ist das SSL Zertifkat vom Certbot einbefunden.
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- nocodb
nocodb:
container_name: nocodb
image: nocodb/nocodb:0.258.10
env_file: .env
restart: always
ports:
- 80:8080
volumes:
- type: volume
source: data
target: /usr/app/data
volumes:
data:
Die Nginx Konfiguration ist hier sehr einfach gehalten:
events {}
http {
server {
listen 443 ssl;
server_name nocodb.muench.lan;
# Hier ist das SSL Zertifikat vom Certbot eingebunden
ssl_certificate /etc/letsencrypt/live/nocodb.muench.lan/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nocodb.muench.lan/privkey.pem;
client_max_body_size 200M;
location / {
proxy_pass http://nocodb:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Um sicherzustellen, dass alles reibungslos funktioniert, habe ich die pre_hook
und post_hook
von Certbot genutzt, um Skripte auszuführen, die relevante Docker-Container neu starten. Diese Automatisierung erspart mir viel manuelle Arbeit und sorgt dafür, dass ich mich auf wichtigere Aufgaben in meinem Homelab konzentrieren kann.
Vorteile des Caddy Servers
Besonders bei neuen Webserver-Setups kommt auch immer wieder der Caddy Server ins Spiel. Caddy unterstützt ACME out-of-the-box, was die Einrichtung und Verwaltung von SSL-Zertifikaten extrem vereinfacht. Ohne die Notwendigkeit von Certbot kann ich Zeit sparen und mich gleichzeitig um die Sicherheit meiner Anwendungen kümmern.
Hier ist ein Beispiel die Konfguration meines pgadmin Servers:
{
email christian@muench.dev
acme_ca https://pki.muench.lan/directory
acme_ca_root /usr/local/share/ca-certificates/muench-lan-root-ca.crt
}
pgadmin4.muench.lan {
tls {
ca_root /usr/local/share/ca-certificates/muench-lan-root-ca.crt
}
reverse_proxy pgadmin:80
}
Da hier kein Certbot im Spiel ist und der Caddyserver dies übernimmt, muss nur das Root-CA Zertifikat eingebunden werden. Da ich das schon im LXC Container liegen habe, wurde dies einfach in den Container gemounted.
Verschlüsselung zwischen Hosts und Containern
Obwohl ich theoretisch auch meinen Traefik Server so konfigurieren könnte, dass dieser die interne PKI nutzt, habe ich beschlossen, dies zunächst zu vermeiden. Ich will nicht den gesamten internen Traffic über Traefik routen, sondern stattdessen eine direkte Verschlüsselung zwischen den einzelnen Servern und LXC-Containern sicherstellen. Jedes System besitzt daher eigene Zertifikate, was die Sicherheit auf verschiedene Weise erhöht.
Generell muss man überall darauf achten, dass man die Connections innerhalb von Anwendungen auch mit SSL/TLS etc. konfiguriert.
Sehr oft ist das allerdings nicht gerade benutzerfreundlich gemacht. So ignorieren einige Anwendungen auch gerne das Root-CA.
Wenn es geht sollte man aber aber versuche die Verbindungen zu Datenbanken oder anderen Geräten über verschlüsselte Wege einzurichten.
Die Server konfigurieren
Damit jeder Server in meinen Netzwerk der neuen Root-CA vertraut, muss das Root Zertifikat in den jeweiligen Trust-Stores hinzugefügt werden.
Ich setze für meine Fedora Workstation Linux ein und die Proxmox Server nutzen Debian. Der Rest bei mir sind LXC Container (im Proxmox Server) die Ubuntu nutzen.
Das Root-CA Zertifikat habe ich auf einen Server gelegt der für alle Server erreichbar ist.
Das Root-CA kann man als Benutzer bequem (ohne Login) herunterladen.
Fedora
# Download Zertifikat (URL im Beispiel ist angepasst)
curl -O https://example.com/acme/muench_lan_2025_root.crt
sudo cp muench_lan_2025_root.crt /etc/pki/ca-trust/source/anchors
sudo update-ca-trust
Debian
(bei mir z.B. Proxmox Server)
mkdir -p /usr/local/share/ca-certificates/extra
cd /usr/local/share/ca-certificates/extra
# Download Zertifikat (URL im Beispiel ist angepasst)
curl -O https://example.com/acme/muench_lan_2025_root.crt
update-ca-certificates
Ubuntu
Meine LXC Container basieren alle auf Ubuntu 24.04.
Manuell kann man die Konfiguration so vornehmen:
sudo -s
mkdir -p /usr/local/share/ca-certificates/extra
cd /usr/local/share/ca-certificates/extra
# Download Zertifikat (url im Beispiel angepasst)
curl -O https://example.com/acme/muench_lan_2025_root.crt
sudo update-ca-certificates
Für die Server habe ich die Installation der Root-CA per Ansible automatisiert.
Das sieht ungefähr so aus:
---
- name: Install muench-dev root ca playbook
hosts: all
become: true
gather_facts: true
vars:
is_ubuntu: ""
tasks:
- name: Install pki.muench.lan CA
when: is_ubuntu
block:
- name: Download root-ca.pem
ansible.builtin.get_url:
url: https://example.com/acme/muench_lan_2025_root.crt
dest: /usr/local/share/ca-certificates/muench-lan-root-ca.crt
validate_certs: false
mode: "0644"
register: pki_muench_lan_ca_download
- name: Update CA trust
ansible.builtin.command: "update-ca-certificates"
when: pki_muench_lan_ca_download.changed
Anwendungen konfigurieren
Proxmox selbst
In Proxmox habe ich zudem meinen ACME-Server als Account hinterlegt, sodass Proxmox ebenfalls selbstständig die Zertifikate verwaltet. Das letztliche Ziel ist klar: Ich möchte die Automatisierung maximieren und die Eingriffe von meiner Seite minimieren.
Leider kann man aus der Proxmox UI nicht direkt den eigenen ACME Server hinterlegen. Über die Kommandozeile funktioniert dies aber.
# PVE Node
pvenode acme account register muench_lan "christian@muench.dev" --directory https://pki.muench.lan/directory
# Für dem PBS
proxmox-backup-manager acme account register default "christian@muench.dev" --directory https://pki.muench.lan/directory
Danach kann man in Proxmox sehr einfach das Zertifikat holen lassen.
Postgres Server
In meinem Docker-Setup habe ich die von Certbot geholten Zertifikate/Schlüssel über die Parameter ssl_cert_file
und ssl_key_file
eingebunden.
services:
postgres:
container_name: postgres
image: postgres:16
ports:
- 5432:5432
command:
- postgres
# .... weitere Konfiguration
- -c
- ssl_cert_file=/certs/live/postgres.muench.lan/fullchain.pem
- -c
- ssl_key_file=/certs/live/postgres.muench.lan/privkey.pem
restart: unless-stopped
env_file:
- postgres.env
volumes:
- postgres-data:/var/lib/postgresql/data
- ./certs:/certs
Leider passen die Rechte im Container nicht der Postgres User (im Container) darf die Zertifikate nicht lesen.
Aus diesem Grund habe ich in meiner Certbot Renewal Config /etc/letsencrypt/renewal/postgres.muench.lan.conf Datei folgendes eingeführt:
[renewalparams]
post_hook="/usr/local/bin/move-certificate.sh"
Das Script /usr/local/bin/move-certificate.sh verschiebt dann die Zertifikate in das Verzeichnis, was im Postgres Container gemounted wurde und setzt die Rechte für den Postgres User damit dieser zugreifen darf.
Danach wird die Datenbank (alle 30 Tage einmal) durchgestartet.
Ein Problem was ich entdeckt hatte war, dass Postgres keine Zertifikate aus Symlinks auflöst. Deswegen musste ich beim Kopieren der Dateien die Symlinks auflösen lassen.
#!/bin/bash
CERT_SRC=/etc/letsencrypt;
CERT_DEST=/srv/docker/postgres/certs;
# Resolve symlink -> Postgres cannot work with linked certs
cp -rL $CERT_SRC/* $CERT_DEST/;
# Postgres runs as user 1000 with group 100
chown -R 999 $CERT_DEST;
chmod -R 700 $CERT_DEST;
cd /srv/docker/postgres;
docker compose restart postgres;
Node-RED und n8n (Node-JS Anwendungen)
Damit Node-RED meine Root-CA nutzt, habe ich das zuvor über Ansible installierte Root-CA .crt File einfach in den Docker Container gemounted und der NodeJS Anwendung über die Env Variable NODE_EXTRA_CA_CERTS
gesagt, dass es die Datei nutzen soll.
services:
node-red:
container_name: node-red
# ... other configs
# Node sagen, dass es die Root-CA aus der Datei nutzt
environment:
- NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/muench-lan-root-ca.crt
volumes:
- ./data:/data:rw
# Zertifikat mounten
- /usr/local/share/ca-certificates/muench-lan-root-ca.crt:/usr/local/share/ca-certificates/muench-lan-root-ca.crt:ro
Bei n8n sieht das fast genauso aus da es auch eine Node Anwendung ist.
Die Variable NODE_EXTRA_CA_CERTS
kann hier auch gesetzt werden.
Testen muss sein
Im Browser lässt sich sehr einfach prüfen ob das Zertifikat genutzt wird.
Wenn alles passt, sollte man die ganze Kette aus Root-CA -> Sub-CA -> TLS Zertifikat sehen können.
Über OpenSSL lässt sich auch schnell prüfen ob ein Zertifikat passt.
Für meinen Postgres Server kann ich das so machen:
echo "" | openssl s_client -starttls postgres -connect postgres.muench.lan:5432 -showcerts
Dabei sollte sowas wie Verify return code: 0 (ok)
angezeigt werden.
Wichtig ist, dass man die Verbindungen prüft da einige Anwendungen nicht einen Fehler anzeigen sondern einen Fallback auf die nichtverschlüsselte Verbindung machen.
Fazit
Zusammenfassend lässt sich sagen, dass im Homelab die Implementierung von SSL und einer eigenen PKI nicht nur die Sicherheit erhöht, sondern auch den Alltag erheblich erleichtert. Durch die Automatisierung der Zertifikatsverwaltung mit Tools wie LabCA und Certbot, sowie der flexiblen Nutzung moderner Serverlösungen, habe ich eine Infrastruktur geschaffen, die sowohl sicher als auch benutzerfreundlich ist.
Was man bei mir sieht ist, dass so ein Homelab wirklich lebst. Es ist immer in der Umgestaltung. Aber das ist es ja was es ausmacht. Man kann viel Testen und dann vielleicht auch im beruflichen Leben nutzen.