Eine bzw. mehrere Lösungen, welche ich mit einem Rutsch erledige, möchte ich heute hier vor bzw. anderen Interessierten zur Verfügung stellen. Sicherlich wird es den einen oder anderen geben, der es besser machen würde.
Da ich Tailscale zwecks VPN Zugriff von außerhalb in mein gesamtes lokales Netzwerk im Prinzip gut finde, stört es mich grundlegend erst einmal an dem System, das ich von deren Servern abhängig bin. Zwar wurde mal hier erwähnt, das deren Server nur die Verbindung unter den jeweiligen Geräten herstellen, was aber so nicht ganz korrekt ist, wenn man sich das Thema "Tailscale DERP-Server" anschaut. Auch bin ich stets der Meinung, je größer ein Unternehmen wird, je anfälliger wird es stets für "Datenpannen" bezüglich der persönlichen Daten der Nutzer.
Auch bin skeptisch gegenüber den regulären Messenger-Diensten, welche ja trotz Ende-zu-Ende Verschlüsselungen und dem großen Versprechen nicht mitzulesen, da sehr interessante Dinge passieren. Unterhält man sich z.B. bei WhatsApp spaßeshalber über "Siemens Lufthaken", dann darf man sich am nächsten Tag in Facebook über die dort angepriesenen Befestigungssysteme in der Werbung nur wundern.
Kurzum, bin ich also daher gegangen und habe alternativen gesucht und bin fündig geworden, so das ich hier einmal eine Anleitung für all jene zur Verfügung stellen möchte, die es ggf. nutzen möchten.
Hardware Voraussetzung:
Im Prinzip wird ein kleiner vServer mit einem Core und max. 1GB RAM benötigt, findet man z.B. aktuell bei IONOS für 1€/Monat bei einer Laufzeit von mind. 12 Monaten (danach monatlich kündbar). So einen kleinen Vserver kann man immer gut für gewisse Dinge gebrauchen. Der Datentransfer ist bis 20TB/Monat kostenfrei, soviel produziert aber dieses Projekt nicht. Sollte man aber einen Tailscale Exit-Node zum verschleierten "surfen" im Internet benötigen, so wäre man z.B. bei BuyVM (1 Core/ 1 GB RAM / 20 GB SSD / Traffic Flatrate) für schlappe 3.50 USD/ Monat dabei. Die Wahl bleibt jedem aber letztendlich selbst überlassen. Wer jetzt aber sagt, das er das bei sich zu Hause auf einem Raspberry das ganze auch hosten kann, der wird spätestens beim ersten Aufruf und dem ungültigem SSL Zertifikat auf die Nase fallen. Zu dem brauchen wir einen vServer als Minimal-Rechner außerhalb unseres lokalen Netzwerkes um später außerhalb auf unser lokales Netzwerk zugreifen zu können, ohne irgend welche Firewallregeln mit Port-Weiterleitungen und anderem Sachen verbiegen zu müssen.
Grundlegende Absicherung des vServers unter Debian:
- Anmeldung auf de vServer als "root"
Code: Alles auswählen
ssh root@HOSTNAME/IP
- Server Softwaremäßig auf aktuellem Stand bringen
Code: Alles auswählen
sudo apt update && sudo apt upgrade -y && sudo apt autoremove
- Zeichensatz abändern
Code: Alles auswählen
sudo dpkg-reconfigure locales
Code: Alles auswählen
[*] de_DE.UTF-8 UTF-8
[*] en-GB.UTF-8 UTF-8
[*] en_US.UTF-8 UTF-8
- Zeitzone anpassen
Code: Alles auswählen
sudo timedatectl set-timezone "Europe/Berlin"
- Neuen Benutzer anlegen
Code: Alles auswählen
sudo adduser <DEIN_NAME>
- Neuen Nutzer zur Gruppe "sudo" hinzufügen
Code: Alles auswählen
sudo usermod -aG sudo <DEIN_GEWÄHLTER_NAME>
- Sicherheitskopie der "sshd_config" anlegen
Code: Alles auswählen
sudo cp /etc/ssh/sshd_config /home/<DEIN_GEWÄHLTER_NAME>/sshd_config.backup
- Root login per ssh verbieten
Code: Alles auswählen
sudo nano /etc/ssh/sshd_config
- SSH-Dienst neu starten und ausloggen
Code: Alles auswählen
sudo systemctl restart sshd && exit
- Anmelden auf dem vServer als Sudo-User mit neuem SSH Port
Code: Alles auswählen
ssh -p 2056 <DEIN_GEWÄHLTER_NAME>@HOSTNAME/IP
- Firewall installieren, für SSH und Headscale einrichten und prüfen
Code: Alles auswählen
sudo apt install ufw
sudo ufw allow 2056/tcp comment "SSH"
sudo ufw allow 80/tcp comment "Tailscale"
sudo ufw allow 443/tcp comment "Headscale-UI"
sudo ufw allow 443/udp comment "Headscale-UI"
sudo grep '^### tuple' /etc/ufw/user*.rules
- Firewall starten, wenn Ausgabe stimmt
Code: Alles auswählen
sudo ufw enable
- CrowdSec-Angriffe auf Systemanmeldung abwehren
Code: Alles auswählen
sudo apt install curl && curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec crowdsec-firewall-bouncer-iptables crowdsec-blocklist-mirror
Docker Installation vorbereiten und durchführen
Als nächstes benötigen wir Docker, und entfernen alle möglichen Pakete, die zu einem Konflikt führen könnten (was bei einer Neuinstallation eines vServers eigentlich unnötig ist, aber der Befehl kann nicht Schaden.
- Vorbeugende Konfliktlösung Docker
Code: Alles auswählen
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
- Benötigte Pakete für die Docker Installation
Code: Alles auswählen
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
- Docker’s offiziellen GPG key hinzufügen
Code: Alles auswählen
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
- Docker Repository zu APT hinzufügen
Code: Alles auswählen
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- APT Packet Index aktualisieren
Code: Alles auswählen
sudo apt-get update
- Docker installieren
Code: Alles auswählen
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- Nutzer zur Gruppe "docker" hinzufügen
Code: Alles auswählen
sudo usermod -aG docker <DEIN_GEWÄHLTER_NAME>
- Benötigte Verzeichnisse und Rechte für den oben angelegten Nutzer setzen
Code: Alles auswählen
sudo mkdir -p /srv/headscale
sudo chown <DEIN_GEWÄHLTER_NAME>:docker /srv/headscale
sudo chmod g+w /srv/headscale
- Docker-Compose Stack aufbauen
Code: Alles auswählen
cd /srv/headscale
sudo mkdir -p headscale/config headscale/data caddy/config caddy/data pg_data
sudo nano docker-compose.yml
- in dem geöffneten Editor nun folgenden Inhalt einfügen und entsprechende Variablen an eigene Umgebung anpassen:
Code: Alles auswählen
version: '3.5'
services:
headscale:
image: headscale/headscale:latest
container_name: headscale
command: headscale serve
restart: unless-stopped
volumes:
- ./headscale/config:/etc/headscale
- ./headscale/data:/var/lib/headscale
labels:
- "com.centurylinklabs.watchtower.enable=true"
depends_on:
- postgres
postgres:
image: postgres
container_name: postgres
restart: unless-stopped
volumes:
- ./pg_data:/var/lib/postgresql/data
labels:
- "com.centurylinklabs.watchtower.enable=true"
environment:
- POSTGRES_PASSWORD=<SUPER-GEHEIMES-PASSWORT-MIT-MIND.-30-ZEICHEN-LAENGE>
- POSTGRES_DB=headscale
- POSTGRES_USER=headscale
headscale-ui:
image: ghcr.io/gurucomputing/headscale-ui:latest
container_name: headscale-ui
restart: unless-stopped
labels:
- "com.centurylinklabs.watchtower.enable=true"
gotify:
image: gotify/server:latest
container_name: gotify
restart: unless-stopped
environment:
- TZ=Europe/Berlin
- GOTIFY_SERVER_PORT=8081
- GOTIFY_SERVER_KEEPALIVEPERIODSECONDS=0
- GOTIFY_SERVER_STREAM_PINGPERIODSECONDS=45
- GOTIFY_DATABASE_DIALECT=sqlite3
- GOTIFY_DATABASE_CONNECTION=data/gotify.db
- GOTIFY_DEFAULTUSER_NAME=admin
- GOTIFY_DEFAULTUSER_PASS=admin
- GOTIFY_PASSSTRENGTH=10
- GOTIFY_UPLOADEDIMAGESDIR=data/images
- GOTIFY_PLUGINSDIR=data/plugins
- GOTIFY_REGISTRATION=false
volumes:
- ./gotify/data:/app/data
labels:
- "com.centurylinklabs.watchtower.enable=true"
caddy:
image: caddy
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./caddy/config:/config
- ./caddy/data:/data
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
labels:
- "com.centurylinklabs.watchtower.enable=true"
watchdog:
image: containrrr/watchtower:latest
container_name: watchdog
restart: unless-stopped
environment:
- WATCHTOWER_NOTIFICATIONS_LEVEL=info
- WATCHTOWER_NOTIFICATIONS=gotify
- WATCHTOWER_NOTIFICATION_GOTIFY_URL=<url_deines_gotify_servers>
- WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN=<Token_der_gotify_app>
- WATCHTOWER_NOTIFICATIONS_HOSTNAME=<deine_domain.tld>
- WATCHTOWER_NO_STARTUP_MESSAGE=false
- WATCHTOWER_NOTIFICATION_REPORT:true
- WATCHTOWER_LABEL_ENABLE=true
- WATCHTOWER_POLL_INTERVAL=21600
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_TIMEOUT=30s
- WATCHTOWER_INCLUDE_RESTARTING=true
- WATCHTOWER_ROLLING_RESTART=true
- WATCHTOWER_INCLUDE_STOPPED=true
- WATCHTOWER_REMOVE_VOLUMES=false
- TZ=Europe/Berlin
labels:
- "com.centurylinklabs.watchtower.enable=true"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/localtime:/etc/localtime:ro
- /etc/TZ:/etc/timezone:ro
- Konfigurationsdatei für headscale erstellen
Code: Alles auswählen
cd /srv/headscale
sudo curl -o headscale/config/config.yml https://github.com/juanfont/headscale/raw/main/config-example.yaml
cd /srv/headscale/headscale/config
sudo nano config.yml
- in dem geöffneten Editor folgende Inhalte suchen und abändern
Code: Alles auswählen
server_url: https://tailscale.deine_domain.de
listen_addr: 0.0.0.0:8080
base_domain: tailscale.deine_domain.de
db_type: postgres
db_host: postgres
db_port: 5432
db_name: headscale
db_user: headscale
db_pass: <SUPER-GEHEIMES-PASSWORT-MIT-MIND.-30-ZEICHEN-LAENGE>
nameservers:
- 192.168.xxx.xxx
- folgende Zeilen noch vor dem speichern der Datei mit # auskommentieren, da wir kein SQLite mehr nutzen und auf Postgres umgestiegen sind
Code: Alles auswählen
#db_type: sqlite3
#db_path: /var/lib/headscale/db.sqlite
- Konfigurationsdatei für caddy erstellen
Code: Alles auswählen
cd /srv/headscale/caddy
sudo nano Caddyfile
- in dem geöffneten Editor nun folgenden Inhalt einfügen:
Code: Alles auswählen
tailscale.deine_domain.de {
reverse_proxy /web* http://headscale-ui:80
reverse_proxy * http://headscale:8080
}
gotify.deine_domain.de {
reverse_proxy * http://gotify:8081
}
Wer eine eigene Domain sein eigen nnen darf, kann die Subdomains nun als neue DNS-Zonen-Einträge vornehmen, andere können z.B. eigene Subdomains diverser DynDNS anbieter nutzen und zum vServer weiterleiten.
- In das Dockervereichnis zurückkehren und Stack starten
Code: Alles auswählen
cd /srv/headscale
docker compose up -d headscale
- Kontrolle der einzelnen Container
Code: Alles auswählen
docker logs headscale
docker logs headscale_ui
docker logs postgres
docker logs caddy
docker logs gotify
Da Caddy uns netterweise auch noch gleich für die in der Konfiguration genannten Domains/Sub-Domains automatisch gültige SSL Zertificate bei Let's Encrypt besorgt und installiert, sind wir so nett zu ihm und lassen ihm dafür ein bischen Zeit, so das wir erst einmal ein paarMinuten auf einen Aufruf über einen Webbrowser verzichten. Caddy sollte aber nach ~ 2-5 Minuten fertig damt sein beim erstmaligem Start des Containers.
Einrichtung und Anwendung von Gotify in der eigenen Umgebung
Die Gotify-Messenger-Server-UI ohne unnötigen Schnickschnack und völlig cloudfrei erreichen wir mittels unter der von uns verwendeten Domain/Sub-Domain https://gotify.deine_domain.de und loggen uns mit den im Docker Comose Stack genannten Admin Daten (admin/admin) ein. Erstelle dort dann unter dem Menüpunkt "Clients" einen neuen Admin Nutzer und entferne dann dort den Standard Admin (admin).
Danach eine neue App einrichten für die Homematic CCU. Sollte man eine Middleware benutzen, kann man für jene auch gleich eine seperate App zusätzlich erstellen. Im Google PlayStore oder im Apple App Store sucht man nach Gotify und wird dann auch schon für die passende App für das Smartphone fündig. Runterladen, installieren und beim ersten Start der App wird man nach der Server-URL gefragt, welche verständlicherweise "https://gotify.deine_domain.de" lautet, Benutzername und Passort sind identisch mit denen des Benutzers, den wir eben über die Weboberfläche neu angelegt haben.
In der Homematic CCU3 kann nun mit folgendem Script sich Nachrichten auf das Smartphone senden lassen:
Code: Alles auswählen
! Gotify Script für Nachrichtenversand
string titlemsg = "Nachrichtentitel";
string messagemsg = "Nachricht kommt hier rein und wird später UTF( Konform formatiert. Es sind keine Probleme mit Sonderzeichen zu erwarten!";
string TITLE = titlemsg.ToUTF8();
string MESSAGE = messagemsg.ToUTF8();
string TOKEN = "<GOTIFY-TOKEN AUS DER WEB-UI>";
! Priorität 0 = Normal (kein vibrieren oder Signalton vom Handy), 5 = Wichtig (Handy vibriert und gibt Signalton wieder)
string PRIORITY = "5";
system.Exec("curl 'https://gotify.deine_domain.de/message?token=" #TOKEN# "' -F 'title=" #TITLE# "' -F 'message=" #MESSAGE# "' -F 'priority=" #PRIORITY# "' > /dev/null");
Bilder können auch versandt werden über Gotify, wobei dann die Nachricht allerdings mittels POST im Json Format übergeben werden muss, weitere Info's zu den zusätzlich benötigten Variablen sind in der Gotify Dokumentation auf Github zu entnehmen. Damit wären wir erst einmal grundlegend von Benachrichtigungen per Messenger unabhängig (mal abgesehen vom angemieteten vServer) und dritte können nicht mitlesen, da die Übertagung trotz über URL stets abgesichert über SSL erfolgt.
Einrichtung und Anwendung von Tailscale/headscale in der eigenen Umgebung
Grundlegend sei erst einmal erwähnt, das wir hier nicht die luxuriöse Webumgebung wie man sie von Tailscale her kennt nicht haben werden, da die Webentwicklung für das Webfrontend erst noch in den "Kinderschuhen" steckt, jedoch der headscale-Server selber dem gewohnten in Sachen Produktivität Tailscale selber in nichts nachsteht, wenn er einmal grundlegend konfiguriert ist.
Um Zugriff auf das minimalistische Headscale Webinterface zu erhalten, benötigen wir noch einen API Key, welchen wir uns wie folgt vom headscale docker container generieren über die Konsole lassen:
Code: Alles auswählen
cd /srv/headscale
docker compose exec headscale headscale apikeys create
Wir nutzen die regulären Open_Source Tailscale Clients zum verbinden zu unserem Server, wobei eine Kleinigkeit beachtet werden muss.
Unter Linux wird der Tailscale Client nun gestartet mit der zusätzlichem Option "--login-server" gestartet, also
- als normaler Client
Code: Alles auswählen
sudo tailscale up --login-server https://tailscale.deine_domain.de
- als Exit-Node
Code: Alles auswählen
sudo tailscale up --login-server https://tailscale.deine_domain.de --advertise-exit-node --accept-routes
- als Subnet-Router
Code: Alles auswählen
sudo tailscale up --login-server https://tailscale.deine_domain.de --advertise-routes=192.168.0.0/24,fd00::/8,fe80::/10 --accept-routes
Sollte man nun erstmalig eines der o.g. Befehle absetzen, erscheint wie bei Tailscale üblich beim erstmaligem start
Code: Alles auswählen
https://tailscale.deine_domain.de/web/register/nodekey:[hexadezimal]
Beim Smartphone Client gelangt man über die drei Punkte oben rechts in das Menü, dort tippt man auf "Log out". Dieses Menü öffnen und schließen wir anschließend MEHRFACH hintereinander durch schnelles antippen, bis dort der Menüpunkt "Server URL" erscheint (sollte so nach 3-5 mal aufklappen des Menü's erscheinen) und geben dort als Server-URL https://tailscale.deine_domain.de ein. Auch dort erhalten wir die lange URL
Code: Alles auswählen
https://tailscale.deine_domain.de/web/register/nodekey:[hexadezimal]
Damit hat man nun einen eigenen VPN-Server und einen Messenger ohne das ein(e) Fremde Person oder Unternehmen die letztendliche Kontrolle darüber hat, sondern nur ihr selbst. Sollte ich etwas undokumentiert haben zur Inbetriebnahme, so sei hiermit der Verweis auf die jeweiligen Dokumentationen von Docker, Postgres, Caddy, Headscale, Headscale-UI und Gotify gegeben.
Hoffe, das diese "kleine" Anleitung dem einen oder anderem hilfreich ist, bei mir funktioniert es bisher tadellos. Rectschreibfehler sind gewollt und dienen der allgemeinen Belustigung, wer welche findet, darf sie auch gerne behalten.
Update vom 15.08.2023
- Gotify Messenger Test-Server unter https://hmip-gotify.dynv6.net eingerichtet.
- Nur zur Veranschaulichung und zum testen der Funktionalität von Gotify <-> Homematic!
- Nicht für den dauerhauften produktiven Einsatz gedacht!
- Dauerhafte Verfügbarkeit ohne jegliche Gewähr oder Garantie!
Update vom 11.08.2023
- In der "docker_compose.yml" einen zusätzlichen Conatiner "Watchtower" und Labels zu den vorhandenen Containern hinzugefügt. Damit werden nun alle vorhandenen Images der orhandenen Container automatisch alle 6 Stunden auf Updates geprüft. Sollte ein Update vorhanden sein, wird dieses automatisch aktuallisiert und eine Benachrichtigung über den vorhandenen Gotify-Server abgesetzt.