Headscale VPN Integration - Self-Hosted Tailscale Controler
Headscale VPN Integration
Self-Hosted Tailscale Control Server für sichere Server-zu-Client Verbindungen
1. Überblick & Architektur
Was ist Headscale?
Headscale ist eine Open-Source-Implementierung des Tailscale Control Servers. Es ermöglicht den Betrieb eines vollständig selbst gehosteten VPN-Netzwerks basierend auf WireGuard, ohne Abhängigkeit von Tailscale's Cloud-Diensten.
Anwendungsfall: n8n zu LiteLLM Verbindung
In unserer Infrastruktur verbinden wir einen Ubuntu Server (n8n Workflow-Automation) mit einem Windows Client (LiteLLM/Ollama LLM-Stack) über ein sicheres VPN-Netzwerk.
┌─────────────────────────────────────┐ ┌─────────────────────────────────────┐ │ Ubuntu Server (ssh2.matzka.cloud) │ │ Windows Client (Lokal) │ │ │ │ │ │ ┌─────────────┐ ┌──────────────┐ │ │ ┌──────────────┐ ┌─────────────┐ │ │ │ Headscale │ │ Traefik │ │ │ │ Tailscale │ │ Docker │ │ │ │ v0.27.1 │──│ (Reverse │ │ │ │ (Native) │ │ Stack: │ │ │ │ Port 8080 │ │ Proxy) │ │ │ │ │ │ │ │ │ └─────────────┘ └──────────────┘ │ │ └──────────────┘ │ ┌────────┐ │ │ │ │ │ │ │ │ │ │ Caddy │ │ │ │ ┌─────────────┐ │ │ │ │ │ │ :4000 │ │ │ │ │ Tailscale │ │ │ ◄─────VPN─────► │ │ └────────┘ │ │ │ │ (Client) │ │ │ │ │ │ ┌────────┐ │ │ │ │ 100.64.0.1 │ │ │ │ 100.64.0.3 │ │LiteLLM │ │ │ │ └─────────────┘ │ │ │ │ └────────┘ │ │ │ │ │ │ │ │ ┌────────┐ │ │ │ ┌─────────────┐ │ │ │ │ │ Ollama │ │ │ │ │ n8n │─────────┘ │ │ │ │ :11434 │ │ │ │ │ Workflows │ │ │ │ └────────┘ │ │ │ └─────────────┘ │ │ └─────────────┘ │ └─────────────────────────────────────┘ └─────────────────────────────────────┘Datenfluss: n8n → http://llm-client:4000 → Tailnet VPN → Windows Host → Docker Caddy → LiteLLM → Ollama
Komponenten-Übersicht
| Komponente | Funktion | Standort |
|---|---|---|
| Headscale | VPN Control Server (koordiniert Verbindungen) | Ubuntu Server |
| Traefik | Reverse Proxy mit SSL-Terminierung | Ubuntu Server |
| Tailscale (Server) | VPN Client auf dem Server | Ubuntu Server |
| Tailscale (Client) | VPN Client (Native Windows) | Windows Client |
| Caddy | Reverse Proxy für Docker Services | Windows Client |
| LiteLLM | LLM API Gateway | Windows Client |
| Ollama | LLM Runtime (Llama 3.1 8B) | Windows Client |
Netzwerk-Adressen
| Host | Tailnet IP | Hostname |
|---|---|---|
| Ubuntu Server | 100.64.0.1 |
server2 |
| Windows Client | 100.64.0.3 |
llm-client |
2. Voraussetzungen
Server-Anforderungen
- Ubuntu 22.04+ oder Debian 12+
- Docker & Docker Compose installiert
- Traefik als Reverse Proxy konfiguriert
- Domain mit DNS-Eintrag (z.B.
vpn.matzka.cloud) - Ports: 443 (HTTPS via Traefik)
Client-Anforderungen
- Windows 10/11 oder Linux
- Tailscale Client installiert
- Ausgehende HTTPS-Verbindungen erlaubt
DNS-Eintrag erstellen
Bevor Sie beginnen, erstellen Sie einen DNS A-Record:
vpn.matzka.cloud → [Server-IP]
Überprüfen Sie den DNS-Eintrag:
dig +short vpn.matzka.cloud AErwartete Ausgabe: 188.245.52.235
3. Server-Installation (Headscale)
3.1 Verzeichnisstruktur erstellen
ssh root@ssh2.matzka.cloudVerzeichnisse anlegen
sudo mkdir -p /opt/headscale/{config,data,scripts} cd /opt/headscale
3.2 Docker Compose Konfiguration
Erstellen Sie /opt/headscale/docker-compose.yml:
version: '3.8'services: headscale: image: headscale/headscale:latest container_name: headscale restart: unless-stopped volumes: - ./config/config.yaml:/etc/headscale/config.yaml:ro - ./data:/var/lib/headscale - ./data/acls.yaml:/etc/headscale/acls.yaml:ro command: serve environment: - TZ=Europe/Vienna healthcheck: test: ["CMD", "headscale", "health"] interval: 30s timeout: 10s retries: 3 networks: - frontend labels: # Traefik aktivieren - "traefik.enable=true" - "traefik.docker.network=frontend"
# HTTPS Router - "traefik.http.routers.headscale.rule=Host(
vpn.matzka.cloud)" - "traefik.http.routers.headscale.entrypoints=websecure" - "traefik.http.routers.headscale.tls=true" - "traefik.http.routers.headscale.tls.certresolver=letsencrypt" - "traefik.http.routers.headscale.service=headscale"# HTTP Redirect - "traefik.http.routers.headscale-http.rule=Host(
vpn.matzka.cloud)" - "traefik.http.routers.headscale-http.entrypoints=web" - "traefik.http.routers.headscale-http.middlewares=redirect-to-https@docker"# Service - "traefik.http.services.headscale.loadbalancer.server.port=8080"
# Redirect Middleware - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
networks: frontend: external: true
3.3 Headscale Konfiguration
Erstellen Sie /opt/headscale/config/config.yaml:
# Headscale ConfigurationDocs: https://headscale.net/ref/configuration/
Public URL (via Traefik)
server_url: https://vpn.matzka.cloud
Listen Adressen (intern)
listen_addr: 0.0.0.0:8080 metrics_listen_addr: 0.0.0.0:9090
Database
database: type: sqlite sqlite: path: /var/lib/headscale/db.sqlite
IP-Bereiche für Tailnet
prefixes: v4: 100.64.0.0/10 v6: fd7a:115c:a1e0::/48
DNS-Konfiguration
dns: magic_dns: true base_domain: matzka.internal nameservers: global: - 1.1.1.1 - 8.8.8.8
ACL Policy
policy: path: /etc/headscale/acls.yaml mode: file
Logging
log: level: info format: text
DERP Server (für Relay-Verbindungen)
derp: server: enabled: false urls: - https://controlplane.tailscale.com/derpmap/default auto_update_enabled: true update_frequency: 24h
Noise (WireGuard-basierte Verschlüsselung)
noise: private_key_path: /var/lib/headscale/noise_private.key
Unix Socket für CLI
unix_socket: /var/lib/headscale/headscale.sock unix_socket_permission: "0770"
TLS wird von Traefik terminiert
tls_cert_path: "" tls_key_path: ""
Ephemeral Nodes
ephemeral_node_inactivity_timeout: 30m
Update Check
disable_check_updates: false
3.4 ACL-Konfiguration (Access Control Lists)
Erstellen Sie /opt/headscale/data/acls.yaml:
{
// Headscale ACL Policy
// Format: HuJSON (JSON mit Kommentaren)
// Gruppen definieren
"groups": {
"group:admins": ["admin@matzka.cloud"]
},
// Tag-Besitzer (muss user@ oder group: sein)
"tagOwners": {
"tag:n8n-server": ["group:admins"],
"tag:llm-client": ["group:admins"]
},
// Access Control Rules
"acls": [
// Erlaubt allen Traffic innerhalb des Tailnets
{
"action": "accept",
"src": ["*"],
"dst": [":"]
}
],
// SSH-Regeln (optional)
"ssh": []
}
3.5 Headscale starten
# Container starten cd /opt/headscale docker compose up -dLogs prüfen
docker logs headscale
Erwartete Ausgabe:
INF Starting Headscale version=v0.27.1
INF listening and serving HTTP on: 0.0.0.0:8080
3.6 User erstellen
# User (Namespace) erstellen docker exec headscale headscale users create matzka-cloudUser auflisten
docker exec headscale headscale users list
Ausgabe:
ID | Name | Username | Email | Created
1 | | matzka-cloud | | 2026-01-10 18:55:36
3.7 Tailscale auf Server installieren
# Tailscale installieren curl -fsSL https://tailscale.com/install.sh | shPre-Auth Key für Server generieren (1 Stunde gültig)
docker exec headscale headscale preauthkeys create \ --user 1 \ --expiration 1h \ --reusable=false
Ausgabe: <YOUR_PREAUTH_KEY>
Server mit Headscale verbinden
tailscale up \ --login-server=https://vpn.matzka.cloud \ --authkey=<YOUR_PREAUTH_KEY> \ --accept-routes
Status prüfen
tailscale status
Ausgabe: 100.64.0.1 server2 matzka-cloud linux -
4. Traefik Integration
Warum Traefik?
- Automatisches SSL: Let's Encrypt Zertifikate werden automatisch generiert
- Standard-Port 443: Funktioniert auch aus restriktiven Netzwerken
- Konsistenz: Alle Services nutzen denselben Reverse Proxy
Routing-Architektur
Internet
│
▼
┌─────────────────────────────────────────────┐
│ Traefik (Port 443) │
│ │
│ vpn.matzka.cloud → headscale:8080 │
│ n8n.matzka.cloud → n8n:5678 │
│ auth.matzka.cloud → authentik:9000 │
│ ... │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ Headscale │
│ Port 8080 │
└─────────────────┘
Traefik Labels erklärt
| Label | Funktion |
|---|---|
traefik.enable=true |
Aktiviert Traefik für diesen Container |
traefik.docker.network=frontend |
Verwendet das frontend-Netzwerk |
traefik.http.routers.headscale.rule |
Routing-Regel (Host-basiert) |
traefik.http.routers.headscale.tls.certresolver |
Let's Encrypt Zertifikat-Resolver |
traefik.http.services.headscale.loadbalancer.server.port |
Interner Port des Containers |
5. Client-Setup (Tailscale)
5.1 Pre-Auth Key generieren
Auf dem Server ausführen:
# Pre-Auth Key für Client generieren (7 Tage gültig) docker exec headscale headscale preauthkeys create \ --user 1 \ --expiration 168h \ --reusable=falseAusgabe: <YOUR_PREAUTH_KEY>
5.2 Windows: Tailscale Installation
# PowerShell als AdministratorDownload Tailscale
$installerUrl = "https://pkgs.tailscale.com/stable/tailscale-setup-latest.exe" Invoke-WebRequest -Uri $installerUrl -OutFile "$env:TEMP\tailscale-setup.exe"
Installation
Start-Process -FilePath "$env:TEMP\tailscale-setup.exe" -Args "/quiet /norestart" -Wait
Mit Headscale verbinden
cd "C:\Program Files\Tailscale" .\tailscale.exe up ` --login-server=https://vpn.matzka.cloud ` --authkey=<YOUR_PREAUTH_KEY> ` --hostname=llm-client
Status prüfen
.\tailscale.exe status .\tailscale.exe ip -4
5.3 Linux: Tailscale Installation
# Tailscale installieren curl -fsSL https://tailscale.com/install.sh | shMit Headscale verbinden
sudo tailscale up \ --login-server=https://vpn.matzka.cloud \ --authkey=<YOUR_PREAUTH_KEY> \ --hostname=llm-client \ --accept-routes
Status prüfen
tailscale status tailscale ip -4
5.4 Server: /etc/hosts aktualisieren
Nach der Client-Verbindung die IP im Server eintragen:
# Client-IP ermitteln docker exec headscale headscale nodes list/etc/hosts aktualisieren
sudo nano /etc/hosts
Zeile hinzufügen:
100.64.0.3 llm-client litellm.matzka.cloud
Test
ping llm-client -c 4
5.5 Windows Firewall konfigurieren
# PowerShell als AdministratorPort 4000 (LiteLLM) erlauben
New-NetFirewallRule -DisplayName "Tailscale to LiteLLM" ` -Direction Inbound ` -Protocol TCP ` -LocalPort 4000 ` -Action Allow ` -Profile Any
ICMP (Ping) erlauben
New-NetFirewallRule -DisplayName "Tailscale ICMP" ` -Direction Inbound ` -Protocol ICMPv4 ` -Action Allow ` -Profile Any
Regeln prüfen
Get-NetFirewallRule | Where-Object {$_.DisplayName -like "Tailscale"}
6. Administration & Verwaltung
6.1 Nodes verwalten
# Alle Nodes auflisten docker exec headscale headscale nodes listBeispiel-Ausgabe:
ID | Hostname | Name | User | IP addresses | Connected
1 | server2 | server2 | matzka-cloud | 100.64.0.1 | online
2 | llm-client | llm-client | matzka-cloud | 100.64.0.3 | online
Node umbenennen
docker exec headscale headscale nodes rename -i 2 --name "windows-llm"
Node löschen
docker exec headscale headscale nodes delete -i 2 --force
Node-Details anzeigen
docker exec headscale headscale nodes show -i 1
6.2 Tags verwalten
# Tag zu Node hinzufügen docker exec headscale headscale nodes tag -i 1 -t tag:n8n-server docker exec headscale headscale nodes tag -i 2 -t tag:llm-clientTags prüfen
docker exec headscale headscale nodes list
Tags werden in der Ausgabe angezeigt
6.3 Pre-Auth Keys verwalten
# Alle Pre-Auth Keys auflisten docker exec headscale headscale preauthkeys list --user 1Neuen Key erstellen (verschiedene Optionen)
Standard (1 Stunde, einmalig)
docker exec headscale headscale preauthkeys create --user 1
7 Tage gültig
docker exec headscale headscale preauthkeys create --user 1 --expiration 168h
Wiederverwendbar (für mehrere Clients)
docker exec headscale headscale preauthkeys create --user 1 --expiration 168h --reusable
Ephemeral (Node wird nach Disconnect gelöscht)
docker exec headscale headscale preauthkeys create --user 1 --ephemeral
Key mit Tags
docker exec headscale headscale preauthkeys create --user 1 --tags tag:llm-client
Key ablaufen lassen
docker exec headscale headscale preauthkeys expire --user 1 <KEY>
6.4 User verwalten
# User auflisten docker exec headscale headscale users listNeuen User erstellen
docker exec headscale headscale users create development
User umbenennen
docker exec headscale headscale users rename -i 1 --new-name production
User löschen (VORSICHT: Löscht alle Nodes!)
docker exec headscale headscale users destroy --force <NAME>
6.5 API Keys (für externe Tools)
# API Key erstellen docker exec headscale headscale apikeys create --expiration 90dAPI Keys auflisten
docker exec headscale headscale apikeys list
API Key widerrufen
docker exec headscale headscale apikeys expire <PREFIX>
6.6 Routes verwalten
# Alle Routes auflisten docker exec headscale headscale routes listRoute aktivieren
docker exec headscale headscale routes enable -r <ROUTE_ID>
Route deaktivieren
docker exec headscale headscale routes disable -r <ROUTE_ID>
7. ACL-Konfiguration
ACL-Grundlagen
Access Control Lists (ACLs) definieren, welche Nodes miteinander kommunizieren dürfen. Headscale verwendet das HuJSON-Format (JSON mit Kommentaren).
Restriktive ACL (Produktion)
{
// Gruppen
"groups": {
"group:admins": ["admin@matzka.cloud"]
},
// Tag-Besitzer
"tagOwners": {
"tag:n8n-server": ["group:admins"],
"tag:llm-client": ["group:admins"]
},
// Regeln
"acls": [
// n8n → LiteLLM nur auf Port 4000
{
"action": "accept",
"src": ["tag:n8n-server"],
"dst": ["tag:llm-client:4000"]
},
// ICMP für Monitoring
{
"action": "accept",
"src": ["tag:n8n-server"],
"dst": ["tag:llm-client:*"],
"proto": "icmp"
},
// Rückweg für ICMP
{
"action": "accept",
"src": ["tag:llm-client"],
"dst": ["tag:n8n-server:*"],
"proto": "icmp"
}
]
}
Permissive ACL (Entwicklung)
{
"acls": [
// Alles erlauben (nur für Entwicklung!)
{
"action": "accept",
"src": ["*"],
"dst": [":"]
}
]
}
ACL-Syntax Referenz
| Element | Beispiel | Beschreibung |
|---|---|---|
| Wildcard | * |
Alle Nodes |
| Tag | tag:n8n-server |
Nodes mit diesem Tag |
| User | matzka-cloud |
Alle Nodes des Users |
| Gruppe | group:admins |
Alle Nodes der Gruppe |
| Port | tag:web:80,443 |
Spezifische Ports |
| Port-Range | tag:web:1000-2000 |
Port-Bereich |
| Alle Ports | tag:web:* |
Alle Ports |
ACL prüfen und anwenden
# ACL-Syntax prüfen docker exec headscale headscale policy checkAktuelle ACL anzeigen
docker exec headscale headscale policy get
ACL aus Datei laden
docker exec headscale headscale policy set --file /etc/headscale/acls.yaml
8. n8n Integration
HTTP Request Node Konfiguration
Für LLM Chat Completions:
Method: POST
URL: http://llm-client:4000/v1/chat/completions
Authentication: Header Auth
Name: Authorization
Value: Bearer sk-your-api-key-here
Body Content Type: JSON
Body:
{
"model": "llama3.1",
"messages": [
{"role": "user", "content": "{{ $json.prompt }}"}
],
"max_tokens": 500
}
Für Embeddings:
Method: POST
URL: http://llm-client:4000/v1/embeddings
Authentication: Header Auth (wie oben)
Body:
{
"model": "nomic-embed-text",
"input": "{{ $json.text }}"
}
Verfügbare Modelle
| Modell | Typ | Verwendung |
|---|---|---|
llama3.1 |
Chat | Chat Completions, Text-Generierung |
nomic-embed-text |
Embedding | RAG, Vektorsuche |
Test-Request
curl -X POST http://llm-client:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-matzka-..." \
-d '{"model":"llama3.1","messages":[{"role":"user","content":"Hello"}],"max_tokens":50}'
9. Sicherheit
Implementierte Sicherheitsmaßnahmen
| Ebene | Maßnahme | Status |
|---|---|---|
| API-Authentifizierung | LiteLLM API-Key | Aktiv |
| VPN-Verschlüsselung | WireGuard (Tailscale) | Aktiv |
| Netzwerk-ACLs | Headscale ACLs | Aktiv |
| Firewall | Windows Firewall (nur VPN) | Aktiv |
| Keine öffentliche Exposition | Nur VPN-Zugriff | Gesichert |
API-Key Management
Key-Rotation:
# 1. Neuen Key generieren openssl rand -base64 482. In .env aktualisieren
3. LiteLLM neu starten
docker-compose restart litellm
4. In n8n Workflows aktualisieren
Windows Firewall-Regeln
# Konfigurierte Regeln:- Port 4000/TCP - LiteLLM API
- Port 11434/TCP - Ollama API
- Port 80/TCP - Caddy HTTP
- Port 443/TCP - Caddy HTTPS
- ICMP - Ping
Regeln anzeigen (PowerShell)
Get-NetFirewallRule | Where-Object {$_.DisplayName -like "Docker -*"}
10. Performance
Erwartete Latenz
| Route | Latenz | Details |
|---|---|---|
| n8n → VPN | ~20-40ms | Über Tailscale/Headscale |
| VPN → Docker | <1ms | Lokal auf Windows |
| Docker → LLM | ~50-200ms | LLM Inference Zeit |
| Gesamt | ~100-250ms | Für erste Token |
Ressourcen-Nutzung
Windows Client:
- CPU: <5% (Tailscale minimal)
- RAM: +50MB (Tailscale Service)
- GPU: Unverändert (Ollama nutzt GPU)
Server:
- Headscale: ~50MB RAM, <1% CPU
Gemessene Werte (Ping-Test)
ping llm-client -c 464 bytes from llm-client (100.64.0.3): icmp_seq=1 ttl=128 time=87.3 ms
64 bytes from llm-client (100.64.0.3): icmp_seq=2 ttl=128 time=20.4 ms
64 bytes from llm-client (100.64.0.3): icmp_seq=3 ttl=128 time=20.2 ms
64 bytes from llm-client (100.64.0.3): icmp_seq=4 ttl=128 time=19.8 ms
--- 0% packet loss, avg ~37ms
11. Troubleshooting
Lessons Learned: Docker Netzwerk-Isolation
Problem: Tailscale als Docker Container konnte nicht auf andere Docker Container zugreifen. Server konnte VPN-Verbindung herstellen (Ping OK), aber Port 4000 war "Connection refused".
Ursache: Docker bridge network isoliert Container. Tailscale Container hatte IP im Tailnet, aber andere Container (LiteLLM, Caddy) waren nur im Docker bridge network erreichbar.
Lösung: Umstellung auf native Windows Tailscale Installation: Tailscale läuft als Windows-Dienst (nicht in Docker), Windows Host ist direkt im Tailnet, Docker Ports sind vom Host aus erreichbar.
11.1 Headscale startet nicht
# Logs prüfen docker logs headscaleHäufige Fehler:
- "Invalid Owner" → ACL-Syntax prüfen (user@, group:, tag:)
- "database locked" → Nur ein Headscale-Prozess erlaubt
- "bind: address already in use" → Port bereits belegt
Konfiguration testen
docker exec headscale headscale configtest
11.2 Client kann sich nicht verbinden
# Server-seitig prüfen docker exec headscale headscale nodes listDNS prüfen
dig +short vpn.matzka.cloud
HTTPS erreichbar?
curl -I https://vpn.matzka.cloud
Pre-Auth Key gültig?
docker exec headscale headscale preauthkeys list --user 1
Neuen Key erstellen falls abgelaufen
docker exec headscale headscale preauthkeys create --user 1 --expiration 168h
11.3 Ping funktioniert nicht
# Beide Nodes online? docker exec headscale headscale nodes listTailscale Status auf Server
tailscale status
Tailscale Status auf Client
tailscale status # Linux & "C:\Program Files\Tailscale\tailscale.exe" status # Windows
Firewall prüfen (Windows)
Get-NetFirewallRule | Where-Object {$_.DisplayName -like "Tailscale"}
Firewall prüfen (Linux)
sudo ufw status
11.4 Port nicht erreichbar
# Vom Server testen nc -zv llm-client 4000Direkt mit IP testen
nc -zv 100.64.0.3 4000
Wenn IP funktioniert aber Hostname nicht:
cat /etc/hosts | grep llm-client
Service auf Client läuft?
Windows:
netstat -an | findstr 4000
Linux:
ss -tulpn | grep 4000
Docker-Ports prüfen
docker port <container_name>
11.5 Node wechselt IP-Adresse
# Wenn ein Node eine neue IP bekommt:1. Alten Node löschen
docker exec headscale headscale nodes delete -i <ID> --force
2. Neuen Pre-Auth Key erstellen
docker exec headscale headscale preauthkeys create --user 1 --expiration 168h
3. Client neu verbinden
tailscale up --login-server=https://vpn.matzka.cloud --authkey=<NEW_KEY>
4. /etc/hosts aktualisieren
sudo sed -i 's/100.64.0.2/100.64.0.3/g' /etc/hosts
11.6 Headscale Logs analysieren
# Live-Logs docker logs -f headscaleLetzte 100 Zeilen
docker logs --tail 100 headscale
Fehler filtern
docker logs headscale 2>&1 | grep -E "(ERR|FTL|error)"
Verbindungsversuche
docker logs headscale 2>&1 | grep -i "register"
12. Befehlsreferenz
Headscale CLI Übersicht
| Befehl | Beschreibung |
|---|---|
| User-Verwaltung | |
users list |
Alle User auflisten |
users create <name> |
Neuen User erstellen |
users rename -i <id> --new-name <name> |
User umbenennen |
users destroy <name> |
User löschen |
| Node-Verwaltung | |
nodes list |
Alle Nodes auflisten |
nodes show -i <id> |
Node-Details anzeigen |
nodes delete -i <id> |
Node löschen |
nodes rename -i <id> --name <name> |
Node umbenennen |
nodes tag -i <id> -t <tag> |
Tag zu Node hinzufügen |
| Pre-Auth Keys | |
preauthkeys list --user <id> |
Keys auflisten |
preauthkeys create --user <id> |
Neuen Key erstellen |
preauthkeys expire --user <id> <key> |
Key ablaufen lassen |
| Policy (ACL) | |
policy get |
Aktuelle Policy anzeigen |
policy check |
Policy-Syntax prüfen |
policy set --file <path> |
Policy aus Datei laden |
| Routes | |
routes list |
Alle Routes auflisten |
routes enable -r <id> |
Route aktivieren |
routes disable -r <id> |
Route deaktivieren |
| System | |
health |
Health-Check |
version |
Version anzeigen |
configtest |
Konfiguration testen |
Tailscale CLI Übersicht
| Befehl | Beschreibung |
|---|---|
tailscale up |
Verbindung herstellen |
tailscale down |
Verbindung trennen |
tailscale status |
Status anzeigen |
tailscale ip |
IP-Adresse anzeigen |
tailscale ping <host> |
Tailscale-spezifischer Ping |
tailscale netcheck |
Netzwerk-Diagnose |
tailscale debug |
Debug-Informationen |
Schnellreferenz: Neue Verbindung einrichten
# 1. Pre-Auth Key auf Server erstellen ssh root@ssh2.matzka.cloud docker exec headscale headscale preauthkeys create --user 1 --expiration 168h2. Auf Client verbinden
Windows:
tailscale up --login-server=https://vpn.matzka.cloud --authkey=<KEY> --hostname=<NAME>
Linux:
sudo tailscale up --login-server=https://vpn.matzka.cloud --authkey=<KEY> --hostname=<NAME>
3. Node-Liste prüfen
docker exec headscale headscale nodes list
4. /etc/hosts auf Server aktualisieren
echo "<TAILSCALE_IP> <HOSTNAME>" | sudo tee -a /etc/hosts
5. Verbindung testen
ping <HOSTNAME> nc -zv <HOSTNAME> <PORT>
Zusammenfassung
Erreichtes Ziel
- Stabile VPN-Verbindung zwischen Ubuntu Server und Windows Client
- Unabhängig von dynamischen IPs (stabile Tailnet-IPs)
- Verschlüsselte Verbindung via WireGuard
- Netzwerk-Zugriffskontrolle via ACLs
- 100% Self-Hosted (keine Cloud-Abhängigkeit)
Aktuelle Konfiguration
| Komponente | Wert |
|---|---|
| Headscale URL | https://vpn.matzka.cloud |
| Server IP | 100.64.0.1 (server2) |
| Client IP | 100.64.0.3 (llm-client) |
| LiteLLM Endpoint | http://llm-client:4000 |
Weiterführende Links