fix: verify AdGuard API TLS by default and pin Go toolchain

This commit is contained in:
Patrick Asmus
2026-10-11 13:37:03 +02:00
parent b22aa3c9c2
commit edc3ae626f
8 changed files with 15 additions and 10 deletions
+2
View File
@@ -79,6 +79,8 @@ cd adguard-shield
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o adguard-shield ./cmd/adguard-shieldd
```
Benötigt wird Go 1.26.9 oder neuer (ältere 1.26.x-Patchversionen enthalten bekannte Sicherheitslücken in der Standardbibliothek). `go.mod` gibt `toolchain go1.26.9` vor; bei älterem lokalem Go lädt `go` diese Toolchain automatisch nach, sofern `GOTOOLCHAIN` nicht auf `local` steht.
### Variante C: Ohne lokales Go per Docker bauen
```bash
+1 -1
View File
@@ -7,7 +7,7 @@
ADGUARD_URL="https://dns1.domain.com"
ADGUARD_USER="admin"
ADGUARD_PASS='changeme'
ADGUARD_TLS_INSECURE=true # TLS-Zertifikat der AdGuard-API nicht prüfen (selbstsigniert); gilt nur für die AdGuard-API
ADGUARD_TLS_INSECURE=false # true = TLS-Zertifikat der AdGuard-API nicht prüfen (nur selbstsigniert/intern)
# --- Rate-Limit ---
RATE_LIMIT_MAX_REQUESTS=30 # Max. Anfragen pro Domain/Client im Zeitfenster
+2 -2
View File
@@ -75,7 +75,7 @@ sudo adguard-shield dry-run
| `ADGUARD_URL` | `https://dns1.domain.com` | URL der AdGuard-Home-Weboberfläche/API |
| `ADGUARD_USER` | `admin` | Benutzername für die API-Authentifizierung |
| `ADGUARD_PASS` | `changeme` | Passwort für die API-Authentifizierung |
| `ADGUARD_TLS_INSECURE` | `true` | TLS-Zertifikat der AdGuard-Home-API nicht prüfen (z.B. selbstsigniert) |
| `ADGUARD_TLS_INSECURE` | `false` | `true` = TLS-Zertifikat der AdGuard-Home-API nicht prüfen (nur selbstsigniert/intern) |
### Beispiel: Lokale Instanz
@@ -99,7 +99,7 @@ AdGuard Shield ruft intern diesen Endpunkt ab:
/control/querylog?limit=<API_QUERY_LIMIT>&response_status=all
```
**Hinweis:** Mit `ADGUARD_TLS_INSECURE=true` (Standard) akzeptiert AdGuard Shield für die AdGuard-Home-API auch selbstsignierte TLS-Zertifikate. Das erleichtert lokale Setups, ersetzt aber keine saubere Absicherung der AdGuard-Home-Oberfläche. Hat AdGuard Home ein gültiges Zertifikat, sollte `ADGUARD_TLS_INSECURE=false` gesetzt werden. Benachrichtigungen prüfen Zertifikate standardmäßig; nur mit `NOTIFY_TLS_INSECURE=true` werden für das Benachrichtigungsziel auch selbstsignierte Zertifikate akzeptiert. AbuseIPDB, externe Listen und der MaxMind-Download prüfen Zertifikate immer.
**Hinweis:** Standardmäßig (`ADGUARD_TLS_INSECURE=false`) prüft AdGuard Shield das TLS-Zertifikat der AdGuard-Home-API. Nutzt AdGuard Home ein selbstsigniertes Zertifikat, schlägt die Verbindung fehl. Abhilfe: gültiges Zertifikat, die API lokal per `http://127.0.0.1:<port>` ansprechen oder `ADGUARD_TLS_INSECURE=true` setzen. Letzteres erlaubt Man-in-the-Middle-Angriffe auf die API-Verbindung (Zugangsdaten und Querylog) und sollte nur in vertrauenswürdigen Netzen genutzt werden. Benachrichtigungen prüfen Zertifikate standardmäßig; nur mit `NOTIFY_TLS_INSECURE=true` werden für das Benachrichtigungsziel auch selbstsignierte Zertifikate akzeptiert. AbuseIPDB, externe Listen und der MaxMind-Download prüfen Zertifikate immer.
---
+2 -1
View File
@@ -50,7 +50,8 @@ Was du prüfen solltest:
| Thema | Hinweis |
|---|---|
| TLS-Zertifikate | Benachrichtigungen (ntfy, Gotify, Webhooks) und externe Listen prüfen jetzt das TLS-Zertifikat. Nutzt du einen eigenen Server mit selbstsigniertem Zertifikat, schlagen Benachrichtigungen fehl (`Benachrichtigung fehlgeschlagen` im Log). Abhilfe: gültiges Zertifikat oder `NOTIFY_TLS_INSECURE=true`. Für externe Listen gibt es keine Ausnahme – bei Fehlern bleibt die bisherige Whitelist erhalten bzw. der Cache wird genutzt. Die AdGuard-API ist nicht betroffen (`ADGUARD_TLS_INSECURE=true`). |
| TLS-Zertifikate | Benachrichtigungen (ntfy, Gotify, Webhooks) und externe Listen prüfen jetzt das TLS-Zertifikat. Nutzt du einen eigenen Server mit selbstsigniertem Zertifikat, schlagen Benachrichtigungen fehl (`Benachrichtigung fehlgeschlagen` im Log). Abhilfe: gültiges Zertifikat oder `NOTIFY_TLS_INSECURE=true`. Für externe Listen gibt es keine Ausnahme – bei Fehlern bleibt die bisherige Whitelist erhalten bzw. der Cache wird genutzt. |
| AdGuard-API-Zertifikat | Auch das TLS-Zertifikat der AdGuard-Home-API wird jetzt geprüft (`ADGUARD_TLS_INSECURE=false`, wird beim Update ergänzt). Bis v1.1.x wurde es nie geprüft. Bei selbstsigniertem Zertifikat schlägt die Abfrage fehl (`sudo adguard-shield test` meldet einen Zertifikatsfehler). Abhilfe: gültiges Zertifikat, `ADGUARD_URL` auf `http://127.0.0.1:<port>` umstellen oder bewusst `ADGUARD_TLS_INSECURE=true` setzen. |
| Konfigurations-Warnungen | Ungültige, unbekannte oder veraltete Parameter werden beim Start und bei jedem CLI-Befehl als `WARNUNG` gemeldet (z. B. `BAN_HISTORY_FILE` aus der alten Shell-Version). Ungültige Werte werden durch den Standardwert ersetzt. Veraltete Zeilen kannst du aus der Konfiguration löschen. |
| Logrotation | `LOG_MAX_SIZE_MB` (Standard 50) wird jetzt ausgewertet: Das Log wird nach `adguard-shield.log.1` rotiert. |
| `BLOCKED_PORTS` | Kommas sind jetzt erlaubt, ungültige Ports werden mit Warnung ignoriert. Port-Namen wie `domain` werden nicht mehr akzeptiert – bitte Portnummern verwenden. |
+2
View File
@@ -2,6 +2,8 @@ module adguard-shield
go 1.26.0
toolchain go1.26.9
require (
github.com/oschwald/maxminddb-golang v1.13.1
golang.org/x/net v0.61.0
+1 -1
View File
@@ -140,7 +140,7 @@ func load(values map[string]string) (*Config, *reader) {
c.AdGuardURL = r.str("ADGUARD_URL", "")
c.AdGuardUser = r.str("ADGUARD_USER", "")
c.AdGuardPass = r.str("ADGUARD_PASS", "")
c.AdGuardTLSInsecure = r.bool("ADGUARD_TLS_INSECURE", true)
c.AdGuardTLSInsecure = r.bool("ADGUARD_TLS_INSECURE", false)
c.RateLimitMaxRequests = r.intMin("RATE_LIMIT_MAX_REQUESTS", 30, 1)
c.RateLimitWindow = r.intMin("RATE_LIMIT_WINDOW", 60, 1)
c.CheckInterval = r.intMin("CHECK_INTERVAL", 10, 1)
+4 -4
View File
@@ -71,8 +71,8 @@ func TestLoadDefaultsWithoutWarnings(t *testing.T) {
if len(c.Warnings) != 0 {
t.Fatalf("unexpected warnings: %v", c.Warnings)
}
if !c.AdGuardTLSInsecure {
t.Fatal("ADGUARD_TLS_INSECURE should default to true")
if c.AdGuardTLSInsecure {
t.Fatal("ADGUARD_TLS_INSECURE must default to false")
}
if c.HistoryRetentionDays != 0 {
t.Fatalf("BAN_HISTORY_RETENTION_DAYS default: %d", c.HistoryRetentionDays)
@@ -86,8 +86,8 @@ func TestLoadDefaultsWithoutWarnings(t *testing.T) {
}
func TestLoadNewKeys(t *testing.T) {
c := loadString(t, "ADGUARD_TLS_INSECURE=false\nBAN_HISTORY_RETENTION_DAYS=30\nLOG_MAX_SIZE_MB=0\n")
if c.AdGuardTLSInsecure || c.HistoryRetentionDays != 30 || c.LogMaxSizeMB != 0 {
c := loadString(t, "ADGUARD_TLS_INSECURE=true\nBAN_HISTORY_RETENTION_DAYS=30\nLOG_MAX_SIZE_MB=0\n")
if !c.AdGuardTLSInsecure || c.HistoryRetentionDays != 30 || c.LogMaxSizeMB != 0 {
t.Fatalf("unexpected values: tls=%v retention=%d logmax=%d", c.AdGuardTLSInsecure, c.HistoryRetentionDays, c.LogMaxSizeMB)
}
if len(c.Warnings) != 0 {
+1 -1
View File
@@ -663,7 +663,7 @@ const defaultConfig = `#########################################################
ADGUARD_URL="https://dns1.domain.com"
ADGUARD_USER="admin"
ADGUARD_PASS='changeme'
ADGUARD_TLS_INSECURE=true # TLS-Zertifikat der AdGuard-API nicht prüfen (selbstsigniert); gilt nur für die AdGuard-API
ADGUARD_TLS_INSECURE=false # true = TLS-Zertifikat der AdGuard-API nicht prüfen (nur selbstsigniert/intern)
# --- Rate-Limit ---
RATE_LIMIT_MAX_REQUESTS=30 # Max. Anfragen pro Domain/Client im Zeitfenster