Skip to content

Repository files navigation

WireHole: AdGuard Home + WireGuard (Zero-Log)

DNS-Filter + Full-Tunnel-VPN auf einem VPS. Upstream ist Cloudflare (DoH). Query-Log und Statistiken sind deaktiviert. Images: :latest.

Korrekturen gegenüber der Original-Anleitung: siehe NOTES.md.

Voraussetzungen

  • Linux-Host mit Docker + Compose-Plugin
  • perl (für Passwort-Hash beim Erstdeploy)
  • UDP-Port 51820 (oder SERVERPORT) in der Firewall offen
  • Root für den Deploy (Verzeichnis unter /opt)
  • Ideal: Kernel-Modul wireguard (sonst Fallback auf userspace)

Schnellstart

cd /path/to/dieses-repo
cp .env.example .env
# .env anpassen: SERVERURL, PEERS, ADMIN_PASSWORD, BLOCKLIST_LEVEL, optional DEPLOY_DIR
# Passwörter mit Sonderzeichen in Anführungszeichen: ADMIN_PASSWORD='P@ss$w0rd!'
# Blocklist: soft | medium | hard (Default: medium)

sudo ./deploy.sh
# optional Firewall: sudo ./deploy.sh --ufw

Standard-Ziel: /opt/wirehole-adguard. DEPLOY_DIR setzen per Umgebung (Vorrang) oder in .env (muss unter /opt liegen):

DEPLOY_DIR=/opt/mein-vpn sudo ./deploy.sh

Redeploy

sudo ./deploy.sh

Aktualisiert den Stack, ohne bestehende Config zu überschreiben:

  • .env, adguard-conf/AdGuardHome.yaml, adguard-data/
  • wireguard-config/ (Keys, Peer-Confs, vorhandenes templates/peer.conf)
  • docker-compose.yml nur wenn identisch oder mit --force-compose (legt .bak.<timestamp> an)
sudo ./deploy.sh --force-compose   # Compose aus dem Repo übernehmen
sudo ./deploy.sh --ufw             # UFW: SERVERPORT/udp erlauben (wenn ufw aktiv)

Dateien

├── deploy.sh
├── docker-compose.yml
├── .env.example
├── NOTES.md
├── adguard-conf/
│   └── AdGuardHome.yaml.example   # → AdGuardHome.yaml beim Erstdeploy
└── wireguard-config/
    └── templates/
        └── peer.conf                # inkl. MTU = 1360

Betrieb

Alle Compose-Befehle im Deploy-Verzeichnis:

cd /opt/wirehole-adguard

docker compose --env-file .env ps
docker compose --env-file .env logs -f adguardhome
docker compose --env-file .env restart
docker compose --env-file .env pull && docker compose --env-file .env up -d

WireGuard-Logs sind absichtlich deaktiviert (logging: driver: none). Diagnose über Peer-Configs und wg-Status im Container:

docker exec -it wireguard wg show

Clients anlegen und verwalten

Clients steuerst du über PEERS in der Deploy-.env (Standard: /opt/wirehole-adguard/.env). Namen nur alphanumerisch, kommagetrennt (z. B. myphone, nicht mein-laptop).

Neuen Client hinzufügen

sudo nano /opt/wirehole-adguard/.env
# z. B. PEERS=myphone,spousephone,tablet,laptop

cd /opt/wirehole-adguard
docker compose --env-file .env up -d

Das Image erkennt die geänderte Liste und erzeugt für neue Namen Keys + Config. Bestehende Peers behalten ihre Keys.

Anschließend QR oder Config holen (siehe unten), z. B.:

docker exec -it wireguard /app/show-peer laptop

Client entfernen

Namen aus PEERS streichen und Stack neu starten (docker compose --env-file .env up -d). Der Ordner unter wireguard-config/peer_… bleibt oft liegen — zum endgültigen Löschen Ordner manuell entfernen und erneut neu starten.

LOG_CONFS=false belassen (Default), damit beim Start keine QR-Codes in Logs landen.

Clients: Keys, Config und QR-Codes

Alles liegt unter dem Deploy-Verzeichnis (Standard: /opt/wirehole-adguard/wireguard-config/). Peer-Namen entsprechen den Einträgen in PEERS (z. B. myphone → Ordner peer_myphone).

QR-Code im Terminal

docker exec -it wireguard /app/show-peer myphone

Mehrere Peers auf einmal:

docker exec -it wireguard /app/show-peer myphone spousephone tablet

Config-Datei und PNG auf dem Host

Pro Peer:

/opt/wirehole-adguard/wireguard-config/peer_myphone/
  peer_myphone.conf          ← Client-Config (App-Import / QR)
  peer_myphone.png           ← QR als Bilddatei
  privatekey-peer_myphone
  publickey-peer_myphone
  presharedkey-peer_myphone

Anzeigen bzw. herunterladen:

cat /opt/wirehole-adguard/wireguard-config/peer_myphone/peer_myphone.conf

# vom lokalen Rechner:
scp user@VPS:/opt/wirehole-adguard/wireguard-config/peer_myphone/peer_myphone.conf .
scp user@VPS:/opt/wirehole-adguard/wireguard-config/peer_myphone/peer_myphone.png .

Die .conf reicht für die WireGuard-App. Einzelne Keys brauchst du nur für manuelle Setups.

Server-Keys

/opt/wirehole-adguard/wireguard-config/server/
  privatekey-server
  publickey-server

AdGuard-UI

Nur auf 127.0.0.1:8080 des VPS — per SSH-Tunnel:

ssh -N -L 8080:localhost:8080 user@DEINE_VPS_IP

Browser: http://localhost:8080 — Login: ADMIN_USER / Passwort aus der Erstinstallation.

Nach dem ersten Login ADMIN_PASSWORD aus der Deploy-.env entfernen oder auskommentieren (Klartext).

Blocklist (soft / medium / hard)

HaGeZi Multi über BLOCKLIST_LEVEL in der Deploy-.env:

Level HaGeZi-Liste Datei
soft Multi Light light.txt
medium (Default) Multi Normal multi.txt
hard Multi Pro pro.txt
sudo nano /opt/wirehole-adguard/.env
# BLOCKLIST_LEVEL=hard

sudo ./deploy.sh

deploy.sh schreibt die Filter-URL in AdGuardHome.yaml (Container wird dafür kurz gestoppt, falls nötig) und startet den Stack neu. In der UI unter Filter sollte die gewählte Liste erscheinen; einmal „Filter aktualisieren“ falls noch leer.

IPv4 / IPv6

Default: IPv4-only Full-Tunnel (ALLOWEDIPS=0.0.0.0/0).

AdGuard setzt dns.aaaa_disabled: true: keine AAAA-Antworten → Clients nutzen IPv4 über den VPN und umgehen ihn nicht über Handy-IPv6. (Bei echtem IPv6-Tunnel später wieder auf false setzen.)

Nur Link-Local (fe80::…) oder gar kein IPv6 am Host → ALLOWEDIPS so belassen. Mit ::/0 ohne vollständige IPv6-WG-Konfiguration drohen Timeouts.

Wenn der Host öffentliches IPv6 hat und du IPv6 mit tunneln willst (zusätzlicher Aufwand, siehe linuxserver-Limits):

ALLOWEDIPS='0.0.0.0/0, ::/0'   # Anführungszeichen Pflicht

Dann in AdGuardHome.yaml aaaa_disabled: false setzen, Stack/Peers neu laden.

Nach jeder ALLOWEDIPS-Änderung Stack neu starten und Peer-Configs neu importieren.

Bestehende Installation (YAML wird von deploy.sh nicht überschrieben): in der UI unter DNS-Einstellungen „IPv6 deaktivieren“, oder:

# AdGuard kurz stoppen, in AdGuardHome.yaml unter dns: ergänzen:
#   aaaa_disabled: true
cd /opt/wirehole-adguard
docker compose --env-file .env stop adguardhome
# YAML editieren, dann:
docker compose --env-file .env up -d

DNS-Upstream (Cloudflare)

AdGuard leitet Anfragen per DoH an Cloudflare weiter:

  • https://cloudflare-dns.com/dns-query
  • https://1.1.1.1/dns-query
  • Bootstrap: 1.1.1.1, 1.0.0.1
  • Fallback: tls://1.0.0.1

VPN-Clients nutzen PEERDNS=10.2.0.100 (AdGuard im Docker-Netz). Port 53 bleibt vom Host isoliert.

Troubleshooting

Symptom Prüfung
Kein Handshake Firewall UDP SERVERPORT; SERVERURL = öffentliche IP/DNS; docker exec wireguard wg show
Modul-Warnung beim Deploy modprobe wireguard bzw. wireguard/wireguard-tools installieren
DNS im VPN tot docker compose ps — AdGuard healthy?; Peer-DNS = ADGUARD_IP
UI nicht erreichbar SSH-Tunnel aktiv? Nur 127.0.0.1:8080 am VPS
Compose-Änderung greift nicht sudo ./deploy.sh --force-compose (legt Backup an)
Peer ohne MTU 1360 Template existiert schon — manuell MTU = 1360 in templates/peer.conf, dann Env-Änderung oder Peer-Conf neu erzeugen
Filter leer Ausgehendes HTTPS; in der UI Filter aktualisieren; BLOCKLIST_LEVEL prüfen
Langsame Apps / IPv6-Timeouts ALLOWEDIPS=0.0.0.0/0; aaaa_disabled: true in AdGuard; Peers neu importieren
compression cannot be enabled when max file count is 1 Compose aktualisieren (sudo ./deploy.sh --force-compose) — Logging-Fix

Hinweise

  • Zero-Log: Query-Log/Statistiken aus; WireGuard-Docker-Logs driver: none. Container-Logs (AdGuard), Filter-Downloads und Handshake-State können trotzdem anfallen.
  • Passwort: ADMIN_PASSWORD gilt nur beim ersten Anlegen von AdGuardHome.yaml. Sonderzeichen in .env quoten.
  • Rechte: Deploy setzt 700 auf Config-Dirs und 600 auf .env, YAML und Keys.
  • Peers: Anlegen/Entfernen siehe Abschnitt „Clients anlegen und verwalten“. Bei Endpoint-/DNS-Änderung Clients ggf. neu importieren.
  • MTU: Template setzt MTU = 1360 für Mobilfunk. Nur wirksam für neu generierte / regenerierte Peer-Confs.
  • Blocklist: BLOCKLIST_LEVEL=soft|medium|hard — Wechsel per .env + sudo ./deploy.sh.
  • IPv4/IPv6: Default ALLOWEDIPS=0.0.0.0/0 und aaaa_disabled: true. ::/0 nur mit echter IPv6-WG-Konfiguration; dann aaaa_disabled: false. Wert mit ::/0 immer quoten.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages