Remove WireGuard integration from production deployment to simplify infrastructure: - Remove docker-compose-direct-access.yml (VPN-bound services) - Remove VPN-only middlewares from Grafana, Prometheus, Portainer - Remove WireGuard middleware definitions from Traefik - Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers All monitoring services now publicly accessible via subdomains: - grafana.michaelschiemer.de (with Grafana native auth) - prometheus.michaelschiemer.de (with Basic Auth) - portainer.michaelschiemer.de (with Portainer native auth) All services use Let's Encrypt SSL certificates via Traefik.
420 lines
13 KiB
Markdown
420 lines
13 KiB
Markdown
# WireGuard VPN Setup
|
|
|
|
WireGuard VPN-Server Installation und Konfiguration via Ansible.
|
|
|
|
## Übersicht
|
|
|
|
Dieses Ansible Setup installiert und konfiguriert einen WireGuard VPN-Server auf dem Production-Server, um sicheren Zugriff auf interne Services zu ermöglichen.
|
|
|
|
## Playbooks
|
|
|
|
### 1. setup-wireguard.yml
|
|
|
|
Installiert und konfiguriert den WireGuard VPN-Server.
|
|
|
|
**Features:**
|
|
- Installiert WireGuard und Tools
|
|
- Generiert Server-Keys (falls nicht vorhanden)
|
|
- Konfiguriert WireGuard-Server
|
|
- Aktiviert IP Forwarding
|
|
- Konfiguriert NAT (Masquerading)
|
|
- Öffnet Firewall-Port (51820/udp)
|
|
- Startet WireGuard-Service
|
|
|
|
**Verwendung:**
|
|
```bash
|
|
cd deployment/ansible
|
|
ansible-playbook -i inventory/production.yml playbooks/setup-wireguard.yml
|
|
```
|
|
|
|
**Variablen:**
|
|
- `wireguard_port`: Port für WireGuard (Standard: 51820)
|
|
- `wireguard_network`: VPN-Netzwerk (Standard: 10.8.0.0/24)
|
|
- `wireguard_server_ip`: Server-IP im VPN (Standard: 10.8.0.1)
|
|
|
|
**Beispiel mit Custom-Parametern:**
|
|
```bash
|
|
ansible-playbook -i inventory/production.yml playbooks/setup-wireguard.yml \
|
|
-e "wireguard_port=51820" \
|
|
-e "wireguard_network=10.8.0.0/24" \
|
|
-e "wireguard_server_ip=10.8.0.1"
|
|
```
|
|
|
|
### 2. add-wireguard-client.yml
|
|
|
|
Fügt einen neuen Client zum WireGuard-Server hinzu.
|
|
|
|
**Features:**
|
|
- Generiert Client-Keys
|
|
- Fügt Client zur Server-Config hinzu
|
|
- Erstellt Client-Konfigurationsdatei
|
|
- Generiert QR-Code (falls qrencode installiert)
|
|
- Restartet WireGuard-Service
|
|
|
|
**Verwendung:**
|
|
```bash
|
|
cd deployment/ansible
|
|
ansible-playbook -i inventory/production.yml playbooks/add-wireguard-client.yml \
|
|
-e "client_name=myclient"
|
|
```
|
|
|
|
**Optionale Parameter:**
|
|
- `client_ip`: Spezifische Client-IP (Standard: automatisch berechnet)
|
|
- `allowed_ips`: Erlaubte IP-Ranges (Standard: gesamtes VPN-Netzwerk)
|
|
|
|
**Beispiel mit spezifischer IP:**
|
|
```bash
|
|
ansible-playbook -i inventory/production.yml playbooks/add-wireguard-client.yml \
|
|
-e "client_name=myclient" \
|
|
-e "client_ip=10.8.0.2"
|
|
```
|
|
|
|
## Wichtige Sicherheitshinweise
|
|
|
|
### SSH-Zugriff bleibt verfügbar
|
|
|
|
**WICHTIG**: Die WireGuard-Konfiguration ändert NICHT die SSH-Zugriffsmöglichkeiten:
|
|
|
|
- ✅ SSH über die normale Server-IP bleibt vollständig funktionsfähig
|
|
- ✅ WireGuard routet standardmäßig nur das VPN-Netzwerk (10.8.0.0/24)
|
|
- ✅ Normale Internet-Routen werden nicht geändert
|
|
- ✅ Firewall-Regeln für SSH (Port 22) werden NICHT entfernt oder blockiert
|
|
|
|
Die Client-Konfiguration verwendet standardmäßig `AllowedIPs = 10.8.0.0/24`, was bedeutet, dass nur Traffic für das VPN-Netzwerk über WireGuard geroutet wird. Alle anderen Verbindungen (inkl. SSH) nutzen weiterhin die normale Internet-Verbindung.
|
|
|
|
**Um SSH komplett über VPN zu routen** (nicht empfohlen für die erste Installation):
|
|
```bash
|
|
ansible-playbook ... -e "allowed_ips=0.0.0.0/0"
|
|
```
|
|
|
|
## Verzeichnisstruktur
|
|
|
|
Nach der Installation:
|
|
|
|
```
|
|
/etc/wireguard/
|
|
├── wg0.conf # Server-Konfiguration
|
|
├── wg0_private.key # Server-Private-Key (600)
|
|
├── wg0_public.key # Server-Public-Key (644)
|
|
└── clients/ # Client-Konfigurationen
|
|
├── client1.conf # Client 1 Config
|
|
└── client2.conf # Client 2 Config
|
|
```
|
|
|
|
## Client-Konfiguration verwenden
|
|
|
|
### 1. Config-Datei auf Client kopieren
|
|
|
|
```bash
|
|
# Von Ansible Control Machine
|
|
scp -i ~/.ssh/production \
|
|
deploy@94.16.110.151:/etc/wireguard/clients/myclient.conf \
|
|
~/myclient.conf
|
|
```
|
|
|
|
### 2. WireGuard auf Client installieren
|
|
|
|
**Linux:**
|
|
```bash
|
|
sudo apt install wireguard wireguard-tools # Ubuntu/Debian
|
|
# oder
|
|
sudo yum install wireguard-tools # CentOS/RHEL
|
|
```
|
|
|
|
**macOS:**
|
|
```bash
|
|
brew install wireguard-tools
|
|
```
|
|
|
|
**Windows:**
|
|
Download von https://www.wireguard.com/install/
|
|
|
|
### 3. VPN verbinden
|
|
|
|
**Linux/macOS:**
|
|
```bash
|
|
sudo wg-quick up ~/myclient.conf
|
|
# oder
|
|
sudo wg-quick up myclient
|
|
```
|
|
|
|
**Windows:**
|
|
Importiere die `.conf`-Datei in die WireGuard-App.
|
|
|
|
### 4. Verbindung testen
|
|
|
|
```bash
|
|
# Ping zum Server
|
|
ping 10.8.0.1
|
|
|
|
# Status prüfen
|
|
sudo wg show
|
|
|
|
# VPN trennen
|
|
sudo wg-quick down myclient
|
|
```
|
|
|
|
## QR-Code für Mobile Client
|
|
|
|
Falls `qrencode` installiert ist, wird beim Hinzufügen eines Clients automatisch ein QR-Code angezeigt:
|
|
|
|
```bash
|
|
ansible-playbook -i inventory/production.yml playbooks/add-wireguard-client.yml \
|
|
-e "client_name=myphone"
|
|
```
|
|
|
|
Der QR-Code kann mit der WireGuard Mobile App (iOS/Android) gescannt werden.
|
|
|
|
## Firewall-Konfiguration
|
|
|
|
Das Playbook öffnet automatisch den WireGuard-Port (51820/udp) in UFW, falls installiert.
|
|
|
|
**Manuelle Firewall-Regeln:**
|
|
|
|
```bash
|
|
# UFW
|
|
sudo ufw allow 51820/udp comment 'WireGuard VPN'
|
|
|
|
# iptables direkt
|
|
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
|
|
```
|
|
|
|
## Split-Tunnel Routing & NAT Fix
|
|
|
|
### A. Quick Fix Commands (manuell auf dem Server)
|
|
```bash
|
|
WAN_IF=${WAN_IF:-eth0}
|
|
WG_IF=${WG_IF:-wg0}
|
|
WG_NET=${WG_NET:-10.8.0.0/24}
|
|
WG_PORT=${WG_PORT:-51820}
|
|
EXTRA_NETS=${EXTRA_NETS:-"192.168.178.0/24 172.20.0.0/16"}
|
|
|
|
sudo sysctl -w net.ipv4.ip_forward=1
|
|
sudo tee /etc/sysctl.d/99-${WG_IF}-forward.conf >/dev/null <<'EOF'
|
|
# WireGuard Forwarding
|
|
net.ipv4.ip_forward=1
|
|
EOF
|
|
sudo sysctl --system
|
|
|
|
# iptables Variante
|
|
sudo iptables -t nat -C POSTROUTING -s ${WG_NET} -o ${WAN_IF} -j MASQUERADE 2>/dev/null \
|
|
|| sudo iptables -t nat -A POSTROUTING -s ${WG_NET} -o ${WAN_IF} -j MASQUERADE
|
|
sudo iptables -C FORWARD -i ${WG_IF} -s ${WG_NET} -o ${WAN_IF} -j ACCEPT 2>/dev/null \
|
|
|| sudo iptables -A FORWARD -i ${WG_IF} -s ${WG_NET} -o ${WAN_IF} -j ACCEPT
|
|
sudo iptables -C FORWARD -o ${WG_IF} -d ${WG_NET} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null \
|
|
|| sudo iptables -A FORWARD -o ${WG_IF} -d ${WG_NET} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
|
for NET in ${EXTRA_NETS}; do
|
|
sudo iptables -C FORWARD -i ${WG_IF} -d ${NET} -j ACCEPT 2>/dev/null || sudo iptables -A FORWARD -i ${WG_IF} -d ${NET} -j ACCEPT
|
|
done
|
|
|
|
# nftables Variante
|
|
sudo nft list table inet wireguard_${WG_IF} >/dev/null 2>&1 || sudo nft add table inet wireguard_${WG_IF}
|
|
sudo nft list chain inet wireguard_${WG_IF} postrouting >/dev/null 2>&1 \
|
|
|| sudo nft add chain inet wireguard_${WG_IF} postrouting '{ type nat hook postrouting priority srcnat; }'
|
|
sudo nft list chain inet wireguard_${WG_IF} forward >/dev/null 2>&1 \
|
|
|| sudo nft add chain inet wireguard_${WG_IF} forward '{ type filter hook forward priority filter; policy accept; }'
|
|
sudo nft list chain inet wireguard_${WG_IF} postrouting | grep -q "${WAN_IF}" \
|
|
|| sudo nft add rule inet wireguard_${WG_IF} postrouting oifname "${WAN_IF}" ip saddr ${WG_NET} masquerade
|
|
sudo nft list chain inet wireguard_${WG_IF} forward | grep -q "iifname \"${WG_IF}\"" \
|
|
|| sudo nft add rule inet wireguard_${WG_IF} forward iifname "${WG_IF}" ip saddr ${WG_NET} counter accept
|
|
sudo nft list chain inet wireguard_${WG_IF} forward | grep -q "oifname \"${WG_IF}\"" \
|
|
|| sudo nft add rule inet wireguard_${WG_IF} forward oifname "${WG_IF}" ip daddr ${WG_NET} ct state established,related counter accept
|
|
for NET in ${EXTRA_NETS}; do
|
|
sudo nft list chain inet wireguard_${WG_IF} forward | grep -q "${NET}" \
|
|
|| sudo nft add rule inet wireguard_${WG_IF} forward iifname "${WG_IF}" ip daddr ${NET} counter accept
|
|
done
|
|
|
|
# Firewall Hooks
|
|
if command -v ufw >/dev/null && sudo ufw status | grep -iq "Status: active"; then
|
|
sudo sed -i 's/^DEFAULT_FORWARD_POLICY=.*/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
|
|
sudo ufw allow ${WG_PORT}/udp
|
|
sudo ufw route allow in on ${WG_IF} out on ${WAN_IF} to any
|
|
fi
|
|
if command -v firewall-cmd >/dev/null && sudo firewall-cmd --state >/dev/null 2>&1; then
|
|
sudo firewall-cmd --permanent --zone=${FIREWALLD_ZONE:-public} --add-port=${WG_PORT}/udp
|
|
sudo firewall-cmd --permanent --zone=${FIREWALLD_ZONE:-public} --add-masquerade
|
|
sudo firewall-cmd --reload
|
|
fi
|
|
|
|
sudo systemctl enable --now wg-quick@${WG_IF}
|
|
sudo wg show
|
|
```
|
|
|
|
### B. Skript: `deployment/ansible/scripts/setup-wireguard-routing.sh`
|
|
```bash
|
|
cd deployment/ansible
|
|
sudo WAN_IF=eth0 WG_IF=wg0 WG_NET=10.8.0.0/24 EXTRA_NETS="192.168.178.0/24 172.20.0.0/16" \
|
|
./scripts/setup-wireguard-routing.sh
|
|
```
|
|
*Erkennt automatisch iptables/nftables und konfiguriert optional UFW/Firewalld.*
|
|
|
|
### C. Ansible Playbook: `playbooks/wireguard-routing.yml`
|
|
```bash
|
|
cd deployment/ansible
|
|
ansible-playbook -i inventory/production.yml playbooks/wireguard-routing.yml \
|
|
-e "wg_interface=wg0 wg_addr=10.8.0.1/24 wg_net=10.8.0.0/24 wan_interface=eth0" \
|
|
-e '{"extra_nets":["192.168.178.0/24","172.20.0.0/16"],"firewall_backend":"iptables","manage_ufw":true}'
|
|
```
|
|
*Variablen:* `wg_interface`, `wg_addr`, `wg_net`, `wan_interface`, `extra_nets`, `firewall_backend` (`iptables|nftables`), `manage_ufw`, `manage_firewalld`, `firewalld_zone`.
|
|
|
|
### D. Beispiel `wg0.conf` Ausschnitt
|
|
```ini
|
|
[Interface]
|
|
Address = 10.8.0.1/24
|
|
ListenPort = 51820
|
|
PrivateKey = <ServerPrivateKey>
|
|
|
|
# iptables
|
|
PostUp = iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE 2>/dev/null || iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
|
|
PostUp = iptables -C FORWARD -i wg0 -s 10.8.0.0/24 -j ACCEPT 2>/dev/null || iptables -A FORWARD -i wg0 -s 10.8.0.0/24 -j ACCEPT
|
|
PostUp = iptables -C FORWARD -o wg0 -d 10.8.0.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || iptables -A FORWARD -o wg0 -d 10.8.0.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
|
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE 2>/dev/null || true
|
|
PostDown = iptables -D FORWARD -i wg0 -s 10.8.0.0/24 -j ACCEPT 2>/dev/null || true
|
|
PostDown = iptables -D FORWARD -o wg0 -d 10.8.0.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true
|
|
|
|
# nftables (stattdessen)
|
|
# PostUp = nft -f /etc/nftables.d/wireguard-wg0.nft
|
|
# PostDown = nft delete table inet wireguard_wg0 2>/dev/null || true
|
|
|
|
[Peer]
|
|
PublicKey = <ClientPublicKey>
|
|
AllowedIPs = 10.8.0.5/32, 192.168.178.0/24, 172.20.0.0/16
|
|
PersistentKeepalive = 25
|
|
```
|
|
|
|
### E. Windows Client (AllowedIPs & Tests)
|
|
```ini
|
|
[Interface]
|
|
Address = 10.8.0.5/32
|
|
DNS = 10.8.0.1 # optional
|
|
|
|
[Peer]
|
|
PublicKey = <ServerPublicKey>
|
|
Endpoint = vpn.example.com:51820
|
|
AllowedIPs = 10.8.0.0/24, 192.168.178.0/24, 172.20.0.0/16
|
|
PersistentKeepalive = 25
|
|
```
|
|
PowerShell:
|
|
```powershell
|
|
wg show
|
|
Test-Connection -Source 10.8.0.5 -ComputerName 10.8.0.1
|
|
Test-Connection 192.168.178.1
|
|
Test-NetConnection -ComputerName 192.168.178.10 -Port 22
|
|
```
|
|
Optional: `Set-DnsClientNrptRule -Namespace "internal.lan" -NameServers 10.8.0.1`.
|
|
|
|
### F. Troubleshooting & Rollback
|
|
- Checks: `ip r`, `ip route get <target>`, `iptables -t nat -S`, `nft list ruleset`, `sysctl net.ipv4.ip_forward`, `wg show`, `tcpdump -i wg0`, `tcpdump -i eth0 host 10.8.0.5`.
|
|
- Häufige Fehler: falsches WAN-Interface, Forwarding/NAT fehlt, doppelte Firewalls (iptables + nftables), Docker-NAT kollidiert, Policy-Routing aktiv.
|
|
- Rollback:
|
|
- `sudo rm /etc/sysctl.d/99-wg0-forward.conf && sudo sysctl -w net.ipv4.ip_forward=0`
|
|
- iptables: Regeln mit `iptables -D` entfernen (siehe oben).
|
|
- nftables: `sudo nft delete table inet wireguard_wg0`.
|
|
- UFW: `sudo ufw delete allow 51820/udp`, Route-Regeln entfernen, `DEFAULT_FORWARD_POLICY` zurücksetzen.
|
|
- Firewalld: `firewall-cmd --permanent --remove-port=51820/udp`, `--remove-masquerade`, `--reload`.
|
|
- Dienst: `sudo systemctl disable --now wg-quick@wg0`.
|
|
|
|
## Troubleshooting
|
|
|
|
### WireGuard startet nicht
|
|
|
|
```bash
|
|
# Status prüfen
|
|
sudo systemctl status wg-quick@wg0
|
|
|
|
# Logs anzeigen
|
|
sudo journalctl -u wg-quick@wg0 -f
|
|
|
|
# Manuell starten
|
|
sudo wg-quick up wg0
|
|
```
|
|
|
|
### Client kann nicht verbinden
|
|
|
|
1. **Firewall prüfen:**
|
|
```bash
|
|
sudo ufw status
|
|
sudo iptables -L -n | grep 51820
|
|
```
|
|
|
|
2. **Server-Logs prüfen:**
|
|
```bash
|
|
sudo journalctl -u wg-quick@wg0 -f
|
|
```
|
|
|
|
3. **Server-Status prüfen:**
|
|
```bash
|
|
sudo wg show
|
|
```
|
|
|
|
4. **Routing prüfen:**
|
|
```bash
|
|
sudo ip route show
|
|
```
|
|
|
|
### IP Forwarding nicht aktiv
|
|
|
|
```bash
|
|
# Manuell aktivieren
|
|
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
|
|
|
|
# Permanent machen
|
|
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
|
|
sudo sysctl -p
|
|
```
|
|
|
|
## Client entfernen
|
|
|
|
Um einen Client zu entfernen:
|
|
|
|
```bash
|
|
# Auf dem Server
|
|
sudo nano /etc/wireguard/wg0.conf
|
|
# Entferne den [Peer] Block für den Client
|
|
|
|
sudo wg-quick down wg0
|
|
sudo wg-quick up wg0
|
|
|
|
# Optional: Client-Config löschen
|
|
sudo rm /etc/wireguard/clients/clientname.conf
|
|
```
|
|
|
|
## Server-Public-Key abrufen
|
|
|
|
```bash
|
|
# Auf dem Server
|
|
cat /etc/wireguard/wg0_public.key
|
|
# oder
|
|
sudo cat /etc/wireguard/wg0_private.key | wg pubkey
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Backup der Keys**: Speichere Server-Keys sicher:
|
|
```bash
|
|
sudo tar czf wireguard-backup.tar.gz /etc/wireguard/
|
|
```
|
|
|
|
2. **Regelmäßige Updates:**
|
|
```bash
|
|
sudo apt update && sudo apt upgrade wireguard wireguard-tools
|
|
```
|
|
|
|
3. **Monitoring**: Überwache VPN-Verbindungen:
|
|
```bash
|
|
sudo wg show
|
|
```
|
|
|
|
4. **Sicherheit**:
|
|
- Verwalte Client-Keys sicher
|
|
- Entferne nicht genutzte Clients
|
|
- Nutze starke Passwörter für Server-Zugriff
|
|
|
|
## Support
|
|
|
|
Bei Problemen:
|
|
1. Prüfe Logs: `sudo journalctl -u wg-quick@wg0`
|
|
2. Prüfe Status: `sudo wg show`
|
|
3. Prüfe Firewall: `sudo ufw status`
|
|
4. Teste Connectivity: `ping 10.8.0.1` (vom Client)
|