Externe Whitelist mit DNS-Auflösung für dynamische IPs (DynDNS)
This commit is contained in:
@@ -29,6 +29,7 @@ Wenn ein Client eine bestimmte Domain zu oft anfragt (z.B. >30x pro Minute), wir
|
|||||||
- Eigene iptables Chain — greift nicht in bestehende Regeln ein
|
- Eigene iptables Chain — greift nicht in bestehende Regeln ein
|
||||||
- Automatisches Entsperren nach konfigurierbarer Dauer
|
- Automatisches Entsperren nach konfigurierbarer Dauer
|
||||||
- **Externe Blocklisten** — IP-Adressen von externen Textdateien (URLs) laden und automatisch sperren
|
- **Externe Blocklisten** — IP-Adressen von externen Textdateien (URLs) laden und automatisch sperren
|
||||||
|
- **Externe Whitelisten** — Domains/IPs aus externen Listen laden und automatisch whitelisten (ideal für DynDNS)
|
||||||
- **AbuseIPDB Reporting** — permanent gesperrte IPs automatisch an AbuseIPDB melden
|
- **AbuseIPDB Reporting** — permanent gesperrte IPs automatisch an AbuseIPDB melden
|
||||||
- **E-Mail Reports** — periodische Statistik-Reports als HTML oder TXT (täglich, wöchentlich, zweiwöchentlich, monatlich)
|
- **E-Mail Reports** — periodische Statistik-Reports als HTML oder TXT (täglich, wöchentlich, zweiwöchentlich, monatlich)
|
||||||
- **Ban-History** — lückenlose Protokollierung aller Sperren/Entsperrungen mit Zeitstempel
|
- **Ban-History** — lückenlose Protokollierung aller Sperren/Entsperrungen mit Zeitstempel
|
||||||
@@ -90,6 +91,8 @@ sudo /opt/adguard-shield/adguard-shield.sh reset-offenses # Offense-Zähler
|
|||||||
sudo /opt/adguard-shield/adguard-shield.sh test # API-Verbindung testen
|
sudo /opt/adguard-shield/adguard-shield.sh test # API-Verbindung testen
|
||||||
sudo /opt/adguard-shield/adguard-shield.sh blocklist-status # Externe Blocklisten Status
|
sudo /opt/adguard-shield/adguard-shield.sh blocklist-status # Externe Blocklisten Status
|
||||||
sudo /opt/adguard-shield/adguard-shield.sh blocklist-sync # Blocklisten manuell synchronisieren
|
sudo /opt/adguard-shield/adguard-shield.sh blocklist-sync # Blocklisten manuell synchronisieren
|
||||||
|
sudo /opt/adguard-shield/adguard-shield.sh whitelist-status # Externe Whitelisten Status
|
||||||
|
sudo /opt/adguard-shield/adguard-shield.sh whitelist-sync # Whitelisten manuell synchronisieren
|
||||||
sudo /opt/adguard-shield/report-generator.sh send # Report jetzt senden
|
sudo /opt/adguard-shield/report-generator.sh send # Report jetzt senden
|
||||||
sudo /opt/adguard-shield/report-generator.sh status # Report-Status anzeigen
|
sudo /opt/adguard-shield/report-generator.sh status # Report-Status anzeigen
|
||||||
sudo /opt/adguard-shield/report-generator.sh install # Cron-Job einrichten
|
sudo /opt/adguard-shield/report-generator.sh install # Cron-Job einrichten
|
||||||
@@ -103,6 +106,7 @@ sudo journalctl -u adguard-shield -f # Logs live ver
|
|||||||
├── adguard-shield.conf # Konfiguration
|
├── adguard-shield.conf # Konfiguration
|
||||||
├── adguard-shield.service # systemd Unit
|
├── adguard-shield.service # systemd Unit
|
||||||
├── external-blocklist-worker.sh # Externer Blocklist-Worker
|
├── external-blocklist-worker.sh # Externer Blocklist-Worker
|
||||||
|
├── external-whitelist-worker.sh # Externer Whitelist-Worker (DynDNS-Auflösung)
|
||||||
├── iptables-helper.sh # Manuelle iptables-Verwaltung
|
├── iptables-helper.sh # Manuelle iptables-Verwaltung
|
||||||
├── unban-expired.sh # Cron-basiertes Entsperren
|
├── unban-expired.sh # Cron-basiertes Entsperren
|
||||||
├── report-generator.sh # E-Mail Report Generator
|
├── report-generator.sh # E-Mail Report Generator
|
||||||
|
|||||||
@@ -134,6 +134,20 @@ REPORT_MAIL_CMD="msmtp"
|
|||||||
# 0 = Nur innerhalb des Berichtszeitraums (altes Verhalten)
|
# 0 = Nur innerhalb des Berichtszeitraums (altes Verhalten)
|
||||||
REPORT_BUSIEST_DAY_RANGE=30
|
REPORT_BUSIEST_DAY_RANGE=30
|
||||||
|
|
||||||
|
# --- Externe Whitelist (optional) ---
|
||||||
|
# Ermöglicht das Einbinden externer Whitelist-Dateien mit Domains/IPs.
|
||||||
|
# Domains werden regelmäßig per DNS aufgelöst (ideal für dynamische IPs/DynDNS).
|
||||||
|
EXTERNAL_WHITELIST_ENABLED=false
|
||||||
|
|
||||||
|
# URL(s) zu externen Textdateien mit Domains/IPs (eine pro Zeile)
|
||||||
|
# Mehrere URLs kommagetrennt angeben
|
||||||
|
# Beispiel: "https://example.com/whitelist.txt,https://other.com/trusted-hosts.txt"
|
||||||
|
EXTERNAL_WHITELIST_URLS=""
|
||||||
|
|
||||||
|
# Wie oft die externe Whitelist geprüft und Domains neu aufgelöst werden (in Sekunden, 300 = 5 Minuten)
|
||||||
|
# Kürzere Intervalle empfohlen bei vielen DynDNS-Einträgen
|
||||||
|
EXTERNAL_WHITELIST_INTERVAL=300
|
||||||
|
|
||||||
# --- Externe Blocklist (optional) ---
|
# --- Externe Blocklist (optional) ---
|
||||||
# Aktiviert den externen Blocklist-Worker
|
# Aktiviert den externen Blocklist-Worker
|
||||||
EXTERNAL_BLOCKLIST_ENABLED=false
|
EXTERNAL_BLOCKLIST_ENABLED=false
|
||||||
|
|||||||
@@ -329,6 +329,7 @@ cleanup() {
|
|||||||
sleep 1
|
sleep 1
|
||||||
fi
|
fi
|
||||||
stop_blocklist_worker
|
stop_blocklist_worker
|
||||||
|
stop_whitelist_worker
|
||||||
rm -f "$PID_FILE"
|
rm -f "$PID_FILE"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@@ -356,6 +357,13 @@ is_whitelisted() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Externe Whitelist prüfen (aufgelöste IPs aus dem Whitelist-Worker)
|
||||||
|
local ext_wl_file="${EXTERNAL_WHITELIST_CACHE_DIR:-/var/lib/adguard-shield/external-whitelist}/resolved_ips.txt"
|
||||||
|
if [[ -f "$ext_wl_file" ]] && grep -qxF "$ip" "$ext_wl_file" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,6 +1179,39 @@ stop_blocklist_worker() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ─── Externer Whitelist-Worker starten ───────────────────────────────────────
|
||||||
|
start_whitelist_worker() {
|
||||||
|
if [[ "${EXTERNAL_WHITELIST_ENABLED:-false}" != "true" ]]; then
|
||||||
|
log "DEBUG" "Externer Whitelist-Worker ist deaktiviert"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local worker_script="${SCRIPT_DIR}/external-whitelist-worker.sh"
|
||||||
|
if [[ ! -f "$worker_script" ]]; then
|
||||||
|
log "WARN" "Whitelist-Worker Script nicht gefunden: $worker_script"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Starte externen Whitelist-Worker im Hintergrund..."
|
||||||
|
bash "$worker_script" start &
|
||||||
|
WHITELIST_WORKER_PID=$!
|
||||||
|
log "INFO" "Whitelist-Worker gestartet (PID: $WHITELIST_WORKER_PID)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Externer Whitelist-Worker stoppen ───────────────────────────────────────
|
||||||
|
stop_whitelist_worker() {
|
||||||
|
local worker_pid_file="/var/run/adguard-whitelist-worker.pid"
|
||||||
|
if [[ -f "$worker_pid_file" ]]; then
|
||||||
|
local wpid
|
||||||
|
wpid=$(cat "$worker_pid_file")
|
||||||
|
if kill -0 "$wpid" 2>/dev/null; then
|
||||||
|
log "INFO" "Stoppe Whitelist-Worker (PID: $wpid)..."
|
||||||
|
kill "$wpid" 2>/dev/null || true
|
||||||
|
rm -f "$worker_pid_file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# ─── Hauptschleife ──────────────────────────────────────────────────────────
|
# ─── Hauptschleife ──────────────────────────────────────────────────────────
|
||||||
main_loop() {
|
main_loop() {
|
||||||
log "INFO" "═══════════════════════════════════════════════════════════"
|
log "INFO" "═══════════════════════════════════════════════════════════"
|
||||||
@@ -1181,6 +1222,7 @@ main_loop() {
|
|||||||
log "INFO" " Dry-Run: ${DRY_RUN}"
|
log "INFO" " Dry-Run: ${DRY_RUN}"
|
||||||
log "INFO" " Whitelist: ${WHITELIST}"
|
log "INFO" " Whitelist: ${WHITELIST}"
|
||||||
log "INFO" " Externe Blocklist: ${EXTERNAL_BLOCKLIST_ENABLED:-false}"
|
log "INFO" " Externe Blocklist: ${EXTERNAL_BLOCKLIST_ENABLED:-false}"
|
||||||
|
log "INFO" " Externe Whitelist: ${EXTERNAL_WHITELIST_ENABLED:-false}"
|
||||||
if [[ "${PROGRESSIVE_BAN_ENABLED:-false}" == "true" ]]; then
|
if [[ "${PROGRESSIVE_BAN_ENABLED:-false}" == "true" ]]; then
|
||||||
log "INFO" " Progressive Sperren: AKTIV (×${PROGRESSIVE_BAN_MULTIPLIER:-2}, Max-Stufe: ${PROGRESSIVE_BAN_MAX_LEVEL:-0}, Reset: $(format_duration "${PROGRESSIVE_BAN_RESET_AFTER:-86400}"))"
|
log "INFO" " Progressive Sperren: AKTIV (×${PROGRESSIVE_BAN_MULTIPLIER:-2}, Max-Stufe: ${PROGRESSIVE_BAN_MAX_LEVEL:-0}, Reset: $(format_duration "${PROGRESSIVE_BAN_RESET_AFTER:-86400}"))"
|
||||||
else
|
else
|
||||||
@@ -1206,6 +1248,9 @@ main_loop() {
|
|||||||
# Blocklist-Worker als Hintergrundprozess starten
|
# Blocklist-Worker als Hintergrundprozess starten
|
||||||
start_blocklist_worker
|
start_blocklist_worker
|
||||||
|
|
||||||
|
# Whitelist-Worker als Hintergrundprozess starten
|
||||||
|
start_whitelist_worker
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
# Abgelaufene Sperren prüfen
|
# Abgelaufene Sperren prüfen
|
||||||
check_expired_bans
|
check_expired_bans
|
||||||
@@ -1272,6 +1317,33 @@ case "${1:-start}" in
|
|||||||
echo "Blocklist-Worker nicht gefunden"
|
echo "Blocklist-Worker nicht gefunden"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
whitelist-status)
|
||||||
|
init_directories
|
||||||
|
_worker_script="${SCRIPT_DIR}/external-whitelist-worker.sh"
|
||||||
|
if [[ -f "$_worker_script" ]]; then
|
||||||
|
bash "$_worker_script" status
|
||||||
|
else
|
||||||
|
echo "Whitelist-Worker nicht gefunden"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
whitelist-sync)
|
||||||
|
init_directories
|
||||||
|
_worker_script="${SCRIPT_DIR}/external-whitelist-worker.sh"
|
||||||
|
if [[ -f "$_worker_script" ]]; then
|
||||||
|
bash "$_worker_script" sync
|
||||||
|
else
|
||||||
|
echo "Whitelist-Worker nicht gefunden"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
whitelist-flush)
|
||||||
|
init_directories
|
||||||
|
_worker_script="${SCRIPT_DIR}/external-whitelist-worker.sh"
|
||||||
|
if [[ -f "$_worker_script" ]]; then
|
||||||
|
bash "$_worker_script" flush
|
||||||
|
else
|
||||||
|
echo "Whitelist-Worker nicht gefunden"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
status)
|
status)
|
||||||
init_directories
|
init_directories
|
||||||
show_status
|
show_status
|
||||||
@@ -1335,7 +1407,7 @@ Service-Steuerung (empfohlen):
|
|||||||
sudo systemctl restart adguard-shield
|
sudo systemctl restart adguard-shield
|
||||||
sudo systemctl status adguard-shield
|
sudo systemctl status adguard-shield
|
||||||
|
|
||||||
Nutzung: $0 {status|history|flush|unban|reset-offenses|test|dry-run|blocklist-status|blocklist-sync|blocklist-flush}
|
Nutzung: $0 {status|history|flush|unban|reset-offenses|test|dry-run|blocklist-status|blocklist-sync|blocklist-flush|whitelist-status|whitelist-sync|whitelist-flush}
|
||||||
|
|
||||||
Verwaltungsbefehle:
|
Verwaltungsbefehle:
|
||||||
status Zeigt aktive Sperren, Regeln und Wiederholungstäter
|
status Zeigt aktive Sperren, Regeln und Wiederholungstäter
|
||||||
@@ -1348,6 +1420,9 @@ Verwaltungsbefehle:
|
|||||||
blocklist-status Zeigt Status der externen Blocklisten
|
blocklist-status Zeigt Status der externen Blocklisten
|
||||||
blocklist-sync Einmalige Synchronisation der externen Blocklisten
|
blocklist-sync Einmalige Synchronisation der externen Blocklisten
|
||||||
blocklist-flush Entfernt alle Sperren der externen Blocklisten
|
blocklist-flush Entfernt alle Sperren der externen Blocklisten
|
||||||
|
whitelist-status Zeigt Status der externen Whitelisten
|
||||||
|
whitelist-sync Einmalige Synchronisation der externen Whitelisten
|
||||||
|
whitelist-flush Entfernt alle aufgelösten Whitelist-IPs
|
||||||
|
|
||||||
Interne Befehle (nicht direkt verwenden — nur über systemd):
|
Interne Befehle (nicht direkt verwenden — nur über systemd):
|
||||||
start Startet den Monitor im Vordergrund
|
start Startet den Monitor im Vordergrund
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ Das ermöglicht:
|
|||||||
├── adguard-shield.conf.old # Backup der Konfig nach Update
|
├── adguard-shield.conf.old # Backup der Konfig nach Update
|
||||||
├── iptables-helper.sh # iptables Verwaltung
|
├── iptables-helper.sh # iptables Verwaltung
|
||||||
├── external-blocklist-worker.sh # Externer Blocklist-Worker
|
├── external-blocklist-worker.sh # Externer Blocklist-Worker
|
||||||
|
├── external-whitelist-worker.sh # Externer Whitelist-Worker (DNS-Auflösung)
|
||||||
└── unban-expired.sh # Cron-basiertes Entsperren
|
└── unban-expired.sh # Cron-basiertes Entsperren
|
||||||
|
|
||||||
/etc/systemd/system/
|
/etc/systemd/system/
|
||||||
@@ -142,7 +143,8 @@ Das ermöglicht:
|
|||||||
/var/lib/adguard-shield/
|
/var/lib/adguard-shield/
|
||||||
├── *.ban # State-Dateien aktiver Sperren
|
├── *.ban # State-Dateien aktiver Sperren
|
||||||
├── *.offenses # Offense-Zähler (Progressive Sperren)
|
├── *.offenses # Offense-Zähler (Progressive Sperren)
|
||||||
└── external-blocklist/ # Cache für externe Blocklisten
|
├── external-blocklist/ # Cache für externe Blocklisten
|
||||||
|
└── external-whitelist/ # Cache für externe Whitelisten + aufgelöste IPs
|
||||||
|
|
||||||
/var/log/
|
/var/log/
|
||||||
├── adguard-shield.log # Laufzeit-Log
|
├── adguard-shield.log # Laufzeit-Log
|
||||||
|
|||||||
@@ -158,6 +158,40 @@ sudo /opt/adguard-shield/iptables-helper.sh save
|
|||||||
sudo /opt/adguard-shield/iptables-helper.sh restore
|
sudo /opt/adguard-shield/iptables-helper.sh restore
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Externer Whitelist-Worker
|
||||||
|
|
||||||
|
Der Whitelist-Worker löst Domains aus externen Listen regelmäßig per DNS auf und stellt die IPs als dynamische Whitelist bereit:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status anzeigen (aufgelöste IPs, konfigurierte Listen)
|
||||||
|
sudo /opt/adguard-shield/adguard-shield.sh whitelist-status
|
||||||
|
|
||||||
|
# Einmalige Synchronisation (z.B. nach Konfigurationsänderung)
|
||||||
|
sudo /opt/adguard-shield/adguard-shield.sh whitelist-sync
|
||||||
|
|
||||||
|
# Alle aufgelösten Whitelist-IPs entfernen
|
||||||
|
sudo /opt/adguard-shield/adguard-shield.sh whitelist-flush
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Worker kann auch standalone gesteuert werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Worker manuell starten (normalerweise automatisch per Hauptscript)
|
||||||
|
sudo /opt/adguard-shield/external-whitelist-worker.sh start
|
||||||
|
|
||||||
|
# Worker stoppen
|
||||||
|
sudo /opt/adguard-shield/external-whitelist-worker.sh stop
|
||||||
|
|
||||||
|
# Einmalige Synchronisation
|
||||||
|
sudo /opt/adguard-shield/external-whitelist-worker.sh sync
|
||||||
|
|
||||||
|
# Status anzeigen
|
||||||
|
sudo /opt/adguard-shield/external-whitelist-worker.sh status
|
||||||
|
|
||||||
|
# Aufgelöste IPs entfernen
|
||||||
|
sudo /opt/adguard-shield/external-whitelist-worker.sh flush
|
||||||
|
```
|
||||||
|
|
||||||
## Externer Blocklist-Worker
|
## Externer Blocklist-Worker
|
||||||
|
|
||||||
Der Worker kann auch standalone gesteuert werden:
|
Der Worker kann auch standalone gesteuert werden:
|
||||||
|
|||||||
@@ -150,6 +150,60 @@ Regelmäßige Statistik-Reports per E-Mail. Voraussetzung ist ein funktionierend
|
|||||||
| `STATE_DIR` | `/var/lib/adguard-shield` | Verzeichnis für State-Dateien |
|
| `STATE_DIR` | `/var/lib/adguard-shield` | Verzeichnis für State-Dateien |
|
||||||
| `PID_FILE` | `/var/run/adguard-shield.pid` | PID-Datei |
|
| `PID_FILE` | `/var/run/adguard-shield.pid` | PID-Datei |
|
||||||
| `DRY_RUN` | `false` | Testmodus — nur loggen, nicht sperren |
|
| `DRY_RUN` | `false` | Testmodus — nur loggen, nicht sperren |
|
||||||
|
|
||||||
|
### Externe Whitelist
|
||||||
|
|
||||||
|
Ermöglicht das Einbinden externer Whitelist-Dateien mit Domains und IP-Adressen. Der Worker löst Domains regelmäßig per DNS auf — ideal für DynDNS-Einträge mit wechselnden IP-Adressen. Aufgelöste IPs werden automatisch zur Whitelist hinzugefügt und bei jeder Prüfung aktualisiert.
|
||||||
|
|
||||||
|
| Parameter | Standard | Beschreibung |
|
||||||
|
|-----------|----------|--------------|
|
||||||
|
| `EXTERNAL_WHITELIST_ENABLED` | `false` | Aktiviert den externen Whitelist-Worker |
|
||||||
|
| `EXTERNAL_WHITELIST_URLS` | *(leer)* | URL(s) zu Whitelist-Textdateien (kommagetrennt). Unterstützt IPv4, IPv6, CIDR und Hostnamen |
|
||||||
|
| `EXTERNAL_WHITELIST_INTERVAL` | `300` | Prüfintervall in Sekunden (300 = 5 Min.). Bei DynDNS-Einträgen ggf. kürzer wählen |
|
||||||
|
| `EXTERNAL_WHITELIST_CACHE_DIR` | `/var/lib/adguard-shield/external-whitelist` | Lokaler Cache für heruntergeladene Listen und aufgelöste IPs |
|
||||||
|
|
||||||
|
#### Externe Whitelist einrichten
|
||||||
|
|
||||||
|
1. Erstelle eine Textdatei auf einem Webserver. Pro Zeile ein Eintrag — Domain, IPv4, IPv6 oder CIDR:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# Domains (werden regelmäßig per DNS aufgelöst — ideal für DynDNS)
|
||||||
|
mein-router.dyndns.org
|
||||||
|
homeserver.example.com
|
||||||
|
|
||||||
|
# Feste IPs
|
||||||
|
192.168.1.100
|
||||||
|
10.0.0.0/24
|
||||||
|
2001:db8::1
|
||||||
|
|
||||||
|
# Kommentare und Inline-Kommentare werden unterstützt
|
||||||
|
192.168.1.200 # Backup-Server
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Aktiviere die Whitelist in der Konfiguration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EXTERNAL_WHITELIST_ENABLED=true
|
||||||
|
EXTERNAL_WHITELIST_URLS="https://example.com/whitelist.txt"
|
||||||
|
EXTERNAL_WHITELIST_INTERVAL=300
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Mehrere Listen können kommagetrennt angegeben werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EXTERNAL_WHITELIST_URLS="https://example.com/trusted.txt,https://other.com/whitelist.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Service neustarten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart adguard-shield
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Hinweis:** Da Domains bei jedem Prüfintervall neu aufgelöst werden, eignet sich diese Funktion besonders für DynDNS-Einträge. Ändert sich die IP eines DynDNS-Hostnamens, wird die neue IP beim nächsten Sync automatisch erkannt und in die Whitelist aufgenommen.
|
||||||
|
|
||||||
|
> **Wichtig:** Wird eine bereits gesperrte IP durch eine Whitelist-Aktualisierung gewhitelistet, wird sie **automatisch entsperrt**.
|
||||||
|
|
||||||
### Externe Blocklist
|
### Externe Blocklist
|
||||||
|
|
||||||
Ermöglicht das Einbinden externer Blocklisten, die IPv4-Adressen, IPv6-Adressen und Hostnamen enthalten können. Der Worker läuft als Hintergrundprozess, prüft periodisch auf Änderungen und löst Hostnamen automatisch über den lokalen DNS-Resolver auf.
|
Ermöglicht das Einbinden externer Blocklisten, die IPv4-Adressen, IPv6-Adressen und Hostnamen enthalten können. Der Worker läuft als Hintergrundprozess, prüft periodisch auf Änderungen und löst Hostnamen automatisch über den lokalen DNS-Resolver auf.
|
||||||
@@ -339,3 +393,7 @@ Beispiel:
|
|||||||
```
|
```
|
||||||
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.10,fd00::1"
|
WHITELIST="127.0.0.1,::1,192.168.1.1,192.168.1.10,fd00::1"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Externe Whitelist für dynamische IPs
|
||||||
|
|
||||||
|
Für Clients mit wechselnden IP-Adressen (z.B. DynDNS) kann eine **externe Whitelist** genutzt werden. Der Whitelist-Worker löst Domains regelmäßig per DNS auf und fügt die aktuellen IPs automatisch zur Whitelist hinzu. Siehe [Externe Whitelist](#externe-whitelist) für die Konfiguration.
|
||||||
|
|||||||
@@ -82,6 +82,13 @@ is_whitelisted() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Externe Whitelist prüfen (aufgelöste IPs aus dem Whitelist-Worker)
|
||||||
|
local ext_wl_file="${EXTERNAL_WHITELIST_CACHE_DIR:-/var/lib/adguard-shield/external-whitelist}/resolved_ips.txt"
|
||||||
|
if [[ -f "$ext_wl_file" ]] && grep -qxF "$ip" "$ext_wl_file" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
532
external-whitelist-worker.sh
Normal file
532
external-whitelist-worker.sh
Normal file
@@ -0,0 +1,532 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
###############################################################################
|
||||||
|
# AdGuard Shield - Externer Whitelist-Worker
|
||||||
|
# Lädt externe Whitelist-Dateien herunter, löst Domains zu IPs auf und
|
||||||
|
# stellt diese dem Hauptscript als dynamische Whitelist zur Verfügung.
|
||||||
|
# Ideal für DynDNS-Domains mit wechselnden IP-Adressen.
|
||||||
|
# Wird als Hintergrundprozess vom Hauptscript gestartet.
|
||||||
|
#
|
||||||
|
# Autor: Patrick Asmus
|
||||||
|
# E-Mail: support@techniverse.net
|
||||||
|
# Datum: 2026-04-04
|
||||||
|
# Lizenz: MIT
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
CONFIG_FILE="${SCRIPT_DIR}/adguard-shield.conf"
|
||||||
|
|
||||||
|
# ─── Konfiguration laden ───────────────────────────────────────────────────────
|
||||||
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||||
|
echo "FEHLER: Konfigurationsdatei nicht gefunden: $CONFIG_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# shellcheck source=adguard-shield.conf
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
|
||||||
|
# ─── Standardwerte ────────────────────────────────────────────────────────────
|
||||||
|
EXTERNAL_WHITELIST_CACHE_DIR="${EXTERNAL_WHITELIST_CACHE_DIR:-/var/lib/adguard-shield/external-whitelist}"
|
||||||
|
EXTERNAL_WHITELIST_RESOLVED_FILE="${EXTERNAL_WHITELIST_CACHE_DIR}/resolved_ips.txt"
|
||||||
|
|
||||||
|
# ─── Worker PID-File ──────────────────────────────────────────────────────────
|
||||||
|
WORKER_PID_FILE="/var/run/adguard-whitelist-worker.pid"
|
||||||
|
|
||||||
|
# ─── Logging (eigene Funktion, nutzt gleiche Log-Datei) ───────────────────────
|
||||||
|
declare -A LOG_LEVELS=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3)
|
||||||
|
|
||||||
|
log() {
|
||||||
|
local level="$1"
|
||||||
|
shift
|
||||||
|
local message="$*"
|
||||||
|
local configured_level="${LOG_LEVEL:-INFO}"
|
||||||
|
|
||||||
|
if [[ ${LOG_LEVELS[$level]:-1} -ge ${LOG_LEVELS[$configured_level]:-1} ]]; then
|
||||||
|
local timestamp
|
||||||
|
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
local log_entry="[$timestamp] [$level] [WHITELIST-WORKER] $message"
|
||||||
|
echo "$log_entry" | tee -a "$LOG_FILE" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Verzeichnisse erstellen ──────────────────────────────────────────────────
|
||||||
|
init_directories() {
|
||||||
|
mkdir -p "$EXTERNAL_WHITELIST_CACHE_DIR"
|
||||||
|
mkdir -p "$(dirname "$LOG_FILE")"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Eintrag-Validierung ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Prüft IPv4-Adresse mit optionalem CIDR
|
||||||
|
_is_valid_ipv4() {
|
||||||
|
local ip="$1" addr="$1" prefix=""
|
||||||
|
if [[ "$ip" == */* ]]; then
|
||||||
|
addr="${ip%/*}"
|
||||||
|
prefix="${ip#*/}"
|
||||||
|
{ [[ "$prefix" =~ ^[0-9]+$ ]] && [[ "$prefix" -le 32 ]]; } || return 1
|
||||||
|
fi
|
||||||
|
local IFS='.'
|
||||||
|
read -ra _octets <<< "$addr"
|
||||||
|
[[ ${#_octets[@]} -eq 4 ]] || return 1
|
||||||
|
local o
|
||||||
|
for o in "${_octets[@]}"; do
|
||||||
|
[[ "$o" =~ ^[0-9]+$ ]] || return 1
|
||||||
|
[[ "$o" -le 255 ]] || return 1
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prüft IPv6-Adresse mit optionalem CIDR
|
||||||
|
_is_valid_ipv6() {
|
||||||
|
local ip="$1" addr="$1"
|
||||||
|
if [[ "$ip" == */* ]]; then
|
||||||
|
addr="${ip%/*}"
|
||||||
|
local prefix="${ip#*/}"
|
||||||
|
{ [[ "$prefix" =~ ^[0-9]+$ ]] && [[ "$prefix" -le 128 ]]; } || return 1
|
||||||
|
fi
|
||||||
|
[[ "$addr" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9] ]] && return 1
|
||||||
|
[[ "$addr" == *:* ]] || return 1
|
||||||
|
[[ "$addr" =~ ^[0-9a-fA-F:\.]+$ ]] || return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prüft ob ein Hostname syntaktisch plausibel ist
|
||||||
|
_is_valid_hostname() {
|
||||||
|
local host="$1"
|
||||||
|
host="${host%.}" # trailing dot entfernen
|
||||||
|
[[ -z "$host" ]] && return 1
|
||||||
|
[[ ${#host} -gt 253 ]] && return 1
|
||||||
|
[[ "$host" =~ ^[a-zA-Z0-9._-]+$ ]] || return 1
|
||||||
|
[[ "$host" =~ ^[.\-] ]] && return 1
|
||||||
|
[[ "$host" == *.* ]] || return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Externe Whitelist herunterladen ─────────────────────────────────────────
|
||||||
|
download_whitelist() {
|
||||||
|
local url="$1"
|
||||||
|
local index="$2"
|
||||||
|
local cache_file="${EXTERNAL_WHITELIST_CACHE_DIR}/whitelist_${index}.txt"
|
||||||
|
local etag_file="${EXTERNAL_WHITELIST_CACHE_DIR}/whitelist_${index}.etag"
|
||||||
|
local tmp_file="${EXTERNAL_WHITELIST_CACHE_DIR}/whitelist_${index}.tmp"
|
||||||
|
|
||||||
|
log "DEBUG" "Prüfe externe Whitelist: $url"
|
||||||
|
|
||||||
|
local -a curl_args=(
|
||||||
|
-s
|
||||||
|
-L
|
||||||
|
--connect-timeout 10
|
||||||
|
--max-time 30
|
||||||
|
-o "$tmp_file"
|
||||||
|
-w "%{http_code}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ -f "$etag_file" ]]; then
|
||||||
|
local stored_etag
|
||||||
|
stored_etag=$(cat "$etag_file")
|
||||||
|
curl_args+=(-H "If-None-Match: ${stored_etag}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
local http_code
|
||||||
|
http_code=$(curl "${curl_args[@]}" -D "${tmp_file}.headers" "$url" 2>/dev/null) || {
|
||||||
|
log "WARN" "Fehler beim Download der Whitelist: $url"
|
||||||
|
rm -f "$tmp_file" "${tmp_file}.headers"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$http_code" == "304" ]]; then
|
||||||
|
log "DEBUG" "Whitelist nicht geändert (HTTP 304): $url"
|
||||||
|
rm -f "$tmp_file" "${tmp_file}.headers"
|
||||||
|
# Auch bei 304 müssen wir DNS neu auflösen (dynamische IPs!)
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$http_code" != "200" ]]; then
|
||||||
|
log "WARN" "Whitelist Download fehlgeschlagen (HTTP $http_code): $url"
|
||||||
|
rm -f "$tmp_file" "${tmp_file}.headers"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "${tmp_file}.headers" ]]; then
|
||||||
|
local new_etag
|
||||||
|
new_etag=$(grep -i '^etag:' "${tmp_file}.headers" | head -1 | sed 's/^[^:]*: *//;s/\r$//')
|
||||||
|
if [[ -n "$new_etag" ]]; then
|
||||||
|
echo "$new_etag" > "$etag_file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rm -f "${tmp_file}.headers"
|
||||||
|
|
||||||
|
if [[ -f "$cache_file" ]]; then
|
||||||
|
if diff -q "$tmp_file" "$cache_file" &>/dev/null; then
|
||||||
|
log "DEBUG" "Whitelist Inhalt unverändert: $url"
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv "$tmp_file" "$cache_file"
|
||||||
|
log "INFO" "Whitelist aktualisiert: $url"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Einträge aus Whitelist-Datei parsen und IPs auflösen ───────────────────
|
||||||
|
# Gibt pro Zeile eine IP-Adresse aus (aufgelöste Domains + direkte IPs)
|
||||||
|
parse_whitelist_entries() {
|
||||||
|
local cache_file="$1"
|
||||||
|
|
||||||
|
[[ -f "$cache_file" ]] || return
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
line="${line%$'\r'}"
|
||||||
|
line="${line#$'\xef\xbb\xbf'}"
|
||||||
|
|
||||||
|
[[ -z "$line" ]] && continue
|
||||||
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
|
||||||
|
line=$(echo "$line" | xargs)
|
||||||
|
line=$(echo "$line" | sed 's/[[:space:]]*[#;].*$//' | xargs)
|
||||||
|
[[ -z "$line" ]] && continue
|
||||||
|
|
||||||
|
# URLs ablehnen
|
||||||
|
if [[ "$line" =~ ^[a-zA-Z][a-zA-Z0-9+.-]*:// ]]; then
|
||||||
|
log "WARN" "Whitelist-Eintrag übersprungen (URL nicht erlaubt): $line"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Hosts-Datei-Format erkennen
|
||||||
|
if [[ "$line" =~ ^[^[:space:]]+[[:space:]]+[^[:space:]] ]]; then
|
||||||
|
local _first="${line%% *}"
|
||||||
|
local _rest="${line#* }"
|
||||||
|
local _second="${_rest%% *}"
|
||||||
|
if [[ "$_first" == "0.0.0.0" || "$_first" =~ ^127\. ||
|
||||||
|
"$_first" == "::1" || "$_first" == "::0" ||
|
||||||
|
"$_first" == "::" ]]; then
|
||||||
|
log "DEBUG" "Whitelist Hosts-Format erkannt, extrahiere: $_second"
|
||||||
|
line="$_second"
|
||||||
|
else
|
||||||
|
log "WARN" "Whitelist-Eintrag übersprungen (unbekanntes Format): $line"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Klassifizieren und validieren
|
||||||
|
if [[ "$line" == *:* ]]; then
|
||||||
|
# IPv6
|
||||||
|
if _is_valid_ipv6 "$line"; then
|
||||||
|
echo "$line"
|
||||||
|
else
|
||||||
|
log "WARN" "Whitelist-Eintrag übersprungen (ungültige IPv6): $line"
|
||||||
|
fi
|
||||||
|
|
||||||
|
elif [[ "$line" =~ ^[0-9] ]]; then
|
||||||
|
# IPv4
|
||||||
|
[[ "$line" == "0.0.0.0"* ]] && continue
|
||||||
|
if _is_valid_ipv4 "$line"; then
|
||||||
|
echo "$line"
|
||||||
|
else
|
||||||
|
log "WARN" "Whitelist-Eintrag übersprungen (ungültige IPv4): $line"
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
# Hostname → DNS-Auflösung (wird bei jedem Durchlauf neu aufgelöst!)
|
||||||
|
if ! _is_valid_hostname "$line"; then
|
||||||
|
log "WARN" "Whitelist-Eintrag übersprungen (kein gültiger Hostname): $line"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
local resolved
|
||||||
|
resolved=$(getent ahosts "$line" 2>/dev/null | awk '{print $1}' | sort -u) || resolved=""
|
||||||
|
if [[ -z "$resolved" ]]; then
|
||||||
|
log "WARN" "Whitelist-Hostname konnte nicht aufgelöst werden: $line"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
local resolved_count=0
|
||||||
|
while IFS= read -r resolved_ip; do
|
||||||
|
[[ -z "$resolved_ip" ]] && continue
|
||||||
|
[[ "$resolved_ip" == "0.0.0.0" ]] && continue
|
||||||
|
[[ "$resolved_ip" == "::" ]] && continue
|
||||||
|
[[ "$resolved_ip" == "::0" ]] && continue
|
||||||
|
echo "$resolved_ip"
|
||||||
|
resolved_count=$((resolved_count + 1))
|
||||||
|
done <<< "$resolved"
|
||||||
|
if [[ $resolved_count -gt 0 ]]; then
|
||||||
|
log "DEBUG" "Whitelist-Hostname aufgelöst: $line → $resolved_count IP(s)"
|
||||||
|
else
|
||||||
|
log "WARN" "Whitelist-Hostname lieferte nur ungültige Adressen: $line"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < "$cache_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Whitelisten synchronisieren ─────────────────────────────────────────────
|
||||||
|
sync_whitelists() {
|
||||||
|
# Alle URLs herunterladen
|
||||||
|
IFS=',' read -ra urls <<< "$EXTERNAL_WHITELIST_URLS"
|
||||||
|
local index=0
|
||||||
|
|
||||||
|
for url in "${urls[@]}"; do
|
||||||
|
url=$(echo "$url" | xargs)
|
||||||
|
[[ -z "$url" ]] && continue
|
||||||
|
|
||||||
|
download_whitelist "$url" "$index" || true
|
||||||
|
index=$((index + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
# Alle Einträge aus Cache-Dateien parsen und IPs auflösen
|
||||||
|
local all_ips_file="${EXTERNAL_WHITELIST_CACHE_DIR}/.all_ips.tmp"
|
||||||
|
> "$all_ips_file"
|
||||||
|
|
||||||
|
for cache_file in "${EXTERNAL_WHITELIST_CACHE_DIR}"/whitelist_*.txt; do
|
||||||
|
[[ -f "$cache_file" ]] || continue
|
||||||
|
parse_whitelist_entries "$cache_file" >> "$all_ips_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Duplikate entfernen und in die resolved-Datei schreiben
|
||||||
|
local unique_count
|
||||||
|
sort -u "$all_ips_file" > "${EXTERNAL_WHITELIST_RESOLVED_FILE}.tmp"
|
||||||
|
mv "${EXTERNAL_WHITELIST_RESOLVED_FILE}.tmp" "$EXTERNAL_WHITELIST_RESOLVED_FILE"
|
||||||
|
unique_count=$(wc -l < "$EXTERNAL_WHITELIST_RESOLVED_FILE" | xargs)
|
||||||
|
|
||||||
|
rm -f "$all_ips_file"
|
||||||
|
|
||||||
|
log "DEBUG" "Externe Whitelist: $unique_count eindeutige IPs aufgelöst"
|
||||||
|
|
||||||
|
# Prüfe ob gesperrte IPs jetzt auf der Whitelist stehen und entsperrt werden müssen
|
||||||
|
check_banned_whitelist_ips
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Gesperrte IPs prüfen die jetzt gewhitelistet sind ──────────────────────
|
||||||
|
# Wenn eine IP nach einer Whitelist-Aktualisierung nun auf der externen
|
||||||
|
# Whitelist steht, wird sie automatisch entsperrt.
|
||||||
|
check_banned_whitelist_ips() {
|
||||||
|
local state_dir="${STATE_DIR:-/var/lib/adguard-shield}"
|
||||||
|
[[ -d "$state_dir" ]] || return
|
||||||
|
[[ -f "$EXTERNAL_WHITELIST_RESOLVED_FILE" ]] || return
|
||||||
|
|
||||||
|
for state_file in "${state_dir}"/*.ban "${state_dir}"/ext_*.ban; do
|
||||||
|
[[ -f "$state_file" ]] || continue
|
||||||
|
local client_ip
|
||||||
|
client_ip=$(grep '^CLIENT_IP=' "$state_file" | cut -d= -f2)
|
||||||
|
[[ -z "$client_ip" ]] && continue
|
||||||
|
|
||||||
|
if grep -qxF "$client_ip" "$EXTERNAL_WHITELIST_RESOLVED_FILE" 2>/dev/null; then
|
||||||
|
log "INFO" "Gesperrte IP $client_ip ist jetzt auf externer Whitelist – entsperre automatisch"
|
||||||
|
|
||||||
|
# iptables-Regel entfernen
|
||||||
|
if [[ "$client_ip" == *:* ]]; then
|
||||||
|
ip6tables -D "$IPTABLES_CHAIN" -s "$client_ip" -j DROP 2>/dev/null || true
|
||||||
|
else
|
||||||
|
iptables -D "$IPTABLES_CHAIN" -s "$client_ip" -j DROP 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$state_file"
|
||||||
|
|
||||||
|
# Ban-History Eintrag
|
||||||
|
if [[ -f "${BAN_HISTORY_FILE:-/var/log/adguard-shield-bans.log}" ]]; then
|
||||||
|
local timestamp
|
||||||
|
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
printf "%-19s | %-6s | %-39s | %-30s | %-8s | %-10s | %-10s | %s\n" \
|
||||||
|
"$timestamp" "UNBAN" "$client_ip" "-" "-" "-" "-" "external-whitelist" \
|
||||||
|
>> "${BAN_HISTORY_FILE:-/var/log/adguard-shield-bans.log}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── PID-Management ──────────────────────────────────────────────────────────
|
||||||
|
write_pid() {
|
||||||
|
echo $$ > "$WORKER_PID_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
log "INFO" "Externer Whitelist-Worker wird beendet..."
|
||||||
|
rm -f "$WORKER_PID_FILE"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
check_already_running() {
|
||||||
|
if [[ -f "$WORKER_PID_FILE" ]]; then
|
||||||
|
local old_pid
|
||||||
|
old_pid=$(cat "$WORKER_PID_FILE")
|
||||||
|
if kill -0 "$old_pid" 2>/dev/null; then
|
||||||
|
log "DEBUG" "Whitelist-Worker läuft bereits (PID: $old_pid)"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
rm -f "$WORKER_PID_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Status anzeigen ─────────────────────────────────────────────────────────
|
||||||
|
show_status() {
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " Externer Whitelist-Worker - Status"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$EXTERNAL_WHITELIST_ENABLED" != "true" ]]; then
|
||||||
|
echo " ⚠️ Externer Whitelist-Worker ist deaktiviert"
|
||||||
|
echo " Aktivieren: EXTERNAL_WHITELIST_ENABLED=true in $CONFIG_FILE"
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Worker-Prozess Status
|
||||||
|
if [[ -f "$WORKER_PID_FILE" ]]; then
|
||||||
|
local pid
|
||||||
|
pid=$(cat "$WORKER_PID_FILE")
|
||||||
|
if kill -0 "$pid" 2>/dev/null; then
|
||||||
|
echo " ✅ Worker läuft (PID: $pid)"
|
||||||
|
else
|
||||||
|
echo " ❌ Worker nicht aktiv (veraltete PID-Datei)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " ❌ Worker nicht aktiv"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Konfigurierte URLs
|
||||||
|
echo " Konfigurierte Whitelisten:"
|
||||||
|
IFS=',' read -ra urls <<< "$EXTERNAL_WHITELIST_URLS"
|
||||||
|
local index=0
|
||||||
|
for url in "${urls[@]}"; do
|
||||||
|
url=$(echo "$url" | xargs)
|
||||||
|
[[ -z "$url" ]] && continue
|
||||||
|
local cache_file="${EXTERNAL_WHITELIST_CACHE_DIR}/whitelist_${index}.txt"
|
||||||
|
if [[ -f "$cache_file" ]]; then
|
||||||
|
local entry_count
|
||||||
|
entry_count=$(grep -cv '^\s*#\|^\s*$' "$cache_file" 2>/dev/null || echo "0")
|
||||||
|
local last_modified
|
||||||
|
last_modified=$(date -r "$cache_file" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "unbekannt")
|
||||||
|
echo " [$index] $url"
|
||||||
|
echo " Einträge: $entry_count | Zuletzt aktualisiert: $last_modified"
|
||||||
|
else
|
||||||
|
echo " [$index] $url (noch nicht heruntergeladen)"
|
||||||
|
fi
|
||||||
|
index=$((index + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Aufgelöste IPs
|
||||||
|
if [[ -f "$EXTERNAL_WHITELIST_RESOLVED_FILE" ]]; then
|
||||||
|
local resolved_count
|
||||||
|
resolved_count=$(wc -l < "$EXTERNAL_WHITELIST_RESOLVED_FILE" | xargs)
|
||||||
|
local last_resolved
|
||||||
|
last_resolved=$(date -r "$EXTERNAL_WHITELIST_RESOLVED_FILE" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "unbekannt")
|
||||||
|
echo " Aufgelöste IPs: $resolved_count"
|
||||||
|
echo " Letzte Auflösung: $last_resolved"
|
||||||
|
|
||||||
|
if [[ "$resolved_count" -gt 0 && "$resolved_count" -le 20 ]]; then
|
||||||
|
echo ""
|
||||||
|
echo " Aktuelle IPs:"
|
||||||
|
while IFS= read -r ip; do
|
||||||
|
echo " ✅ $ip"
|
||||||
|
done < "$EXTERNAL_WHITELIST_RESOLVED_FILE"
|
||||||
|
elif [[ "$resolved_count" -gt 20 ]]; then
|
||||||
|
echo ""
|
||||||
|
echo " Erste 20 IPs:"
|
||||||
|
head -20 "$EXTERNAL_WHITELIST_RESOLVED_FILE" | while IFS= read -r ip; do
|
||||||
|
echo " ✅ $ip"
|
||||||
|
done
|
||||||
|
echo " ... ($((resolved_count - 20)) weitere)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " Aufgelöste IPs: 0 (noch keine Synchronisation durchgeführt)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " Prüfintervall: ${EXTERNAL_WHITELIST_INTERVAL}s"
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Einmalig synchronisieren ────────────────────────────────────────────────
|
||||||
|
run_once() {
|
||||||
|
init_directories
|
||||||
|
|
||||||
|
if [[ -z "${EXTERNAL_WHITELIST_URLS:-}" ]]; then
|
||||||
|
log "ERROR" "Keine externen Whitelist-URLs konfiguriert (EXTERNAL_WHITELIST_URLS)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Einmalige Whitelist-Synchronisation..."
|
||||||
|
sync_whitelists
|
||||||
|
log "INFO" "Whitelist-Synchronisation abgeschlossen"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Hauptschleife ──────────────────────────────────────────────────────────
|
||||||
|
main_loop() {
|
||||||
|
init_directories
|
||||||
|
|
||||||
|
if [[ -z "${EXTERNAL_WHITELIST_URLS:-}" ]]; then
|
||||||
|
log "ERROR" "Keine externen Whitelist-URLs konfiguriert (EXTERNAL_WHITELIST_URLS)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "═══════════════════════════════════════════════════════════"
|
||||||
|
log "INFO" "Externer Whitelist-Worker gestartet"
|
||||||
|
log "INFO" " URLs: ${EXTERNAL_WHITELIST_URLS}"
|
||||||
|
log "INFO" " Prüfintervall: ${EXTERNAL_WHITELIST_INTERVAL}s"
|
||||||
|
log "INFO" "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
sync_whitelists
|
||||||
|
sleep "$EXTERNAL_WHITELIST_INTERVAL"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── Signal-Handler ──────────────────────────────────────────────────────────
|
||||||
|
trap cleanup SIGTERM SIGINT SIGHUP
|
||||||
|
|
||||||
|
# ─── Kommandozeilen-Argumente ────────────────────────────────────────────────
|
||||||
|
case "${1:-start}" in
|
||||||
|
start)
|
||||||
|
if ! check_already_running; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
write_pid
|
||||||
|
main_loop
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
if [[ -f "$WORKER_PID_FILE" ]]; then
|
||||||
|
kill "$(cat "$WORKER_PID_FILE")" 2>/dev/null || true
|
||||||
|
rm -f "$WORKER_PID_FILE"
|
||||||
|
echo "Whitelist-Worker gestoppt"
|
||||||
|
else
|
||||||
|
echo "Whitelist-Worker läuft nicht"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
sync)
|
||||||
|
run_once
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
init_directories
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
flush)
|
||||||
|
init_directories
|
||||||
|
echo "Entferne aufgelöste externe Whitelist-IPs..."
|
||||||
|
rm -f "$EXTERNAL_WHITELIST_RESOLVED_FILE"
|
||||||
|
echo "Externe Whitelist-IPs entfernt"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cat << USAGE
|
||||||
|
AdGuard Shield - Externer Whitelist-Worker
|
||||||
|
|
||||||
|
Nutzung: $0 {start|stop|sync|status|flush}
|
||||||
|
|
||||||
|
Befehle:
|
||||||
|
start Startet den Worker (Dauerbetrieb)
|
||||||
|
stop Stoppt den Worker
|
||||||
|
sync Einmalige Synchronisation (DNS-Auflösung)
|
||||||
|
status Zeigt Status und aufgelöste IPs
|
||||||
|
flush Entfernt alle aufgelösten Whitelist-IPs
|
||||||
|
|
||||||
|
Konfiguration: $CONFIG_FILE
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -103,6 +103,11 @@ print_help() {
|
|||||||
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh test${NC} # API-Verbindung testen"
|
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh test${NC} # API-Verbindung testen"
|
||||||
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh dry-run${NC} # Testmodus (nur loggen)"
|
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh dry-run${NC} # Testmodus (nur loggen)"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo -e "${BOLD}Externe Whitelist-Befehle:${NC}"
|
||||||
|
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh whitelist-status${NC} # Status der externen Whitelisten"
|
||||||
|
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh whitelist-sync${NC} # Einmalige Synchronisation"
|
||||||
|
echo -e " ${CYAN}sudo /opt/adguard-shield/adguard-shield.sh whitelist-flush${NC} # Aufgelöste IPs entfernen"
|
||||||
|
echo ""
|
||||||
echo -e "${BOLD}iptables-Befehle:${NC}"
|
echo -e "${BOLD}iptables-Befehle:${NC}"
|
||||||
echo -e " ${CYAN}sudo /opt/adguard-shield/iptables-helper.sh status${NC} # Firewall-Regeln anzeigen"
|
echo -e " ${CYAN}sudo /opt/adguard-shield/iptables-helper.sh status${NC} # Firewall-Regeln anzeigen"
|
||||||
echo -e " ${CYAN}sudo /opt/adguard-shield/iptables-helper.sh ban IP${NC} # IP manuell sperren"
|
echo -e " ${CYAN}sudo /opt/adguard-shield/iptables-helper.sh ban IP${NC} # IP manuell sperren"
|
||||||
@@ -241,6 +246,7 @@ install_files() {
|
|||||||
cp "$SCRIPT_DIR/iptables-helper.sh" "$INSTALL_DIR/"
|
cp "$SCRIPT_DIR/iptables-helper.sh" "$INSTALL_DIR/"
|
||||||
cp "$SCRIPT_DIR/unban-expired.sh" "$INSTALL_DIR/"
|
cp "$SCRIPT_DIR/unban-expired.sh" "$INSTALL_DIR/"
|
||||||
cp "$SCRIPT_DIR/external-blocklist-worker.sh" "$INSTALL_DIR/"
|
cp "$SCRIPT_DIR/external-blocklist-worker.sh" "$INSTALL_DIR/"
|
||||||
|
cp "$SCRIPT_DIR/external-whitelist-worker.sh" "$INSTALL_DIR/"
|
||||||
cp "$SCRIPT_DIR/report-generator.sh" "$INSTALL_DIR/"
|
cp "$SCRIPT_DIR/report-generator.sh" "$INSTALL_DIR/"
|
||||||
cp "$SCRIPT_DIR/uninstall.sh" "$INSTALL_DIR/"
|
cp "$SCRIPT_DIR/uninstall.sh" "$INSTALL_DIR/"
|
||||||
|
|
||||||
@@ -254,6 +260,7 @@ install_files() {
|
|||||||
chmod +x "$INSTALL_DIR/iptables-helper.sh"
|
chmod +x "$INSTALL_DIR/iptables-helper.sh"
|
||||||
chmod +x "$INSTALL_DIR/unban-expired.sh"
|
chmod +x "$INSTALL_DIR/unban-expired.sh"
|
||||||
chmod +x "$INSTALL_DIR/external-blocklist-worker.sh"
|
chmod +x "$INSTALL_DIR/external-blocklist-worker.sh"
|
||||||
|
chmod +x "$INSTALL_DIR/external-whitelist-worker.sh"
|
||||||
chmod +x "$INSTALL_DIR/report-generator.sh"
|
chmod +x "$INSTALL_DIR/report-generator.sh"
|
||||||
chmod +x "$INSTALL_DIR/uninstall.sh"
|
chmod +x "$INSTALL_DIR/uninstall.sh"
|
||||||
|
|
||||||
@@ -751,6 +758,7 @@ do_uninstall() {
|
|||||||
rm -f "$INSTALL_DIR/iptables-helper.sh"
|
rm -f "$INSTALL_DIR/iptables-helper.sh"
|
||||||
rm -f "$INSTALL_DIR/unban-expired.sh"
|
rm -f "$INSTALL_DIR/unban-expired.sh"
|
||||||
rm -f "$INSTALL_DIR/external-blocklist-worker.sh"
|
rm -f "$INSTALL_DIR/external-blocklist-worker.sh"
|
||||||
|
rm -f "$INSTALL_DIR/external-whitelist-worker.sh"
|
||||||
rm -f "$INSTALL_DIR/report-generator.sh"
|
rm -f "$INSTALL_DIR/report-generator.sh"
|
||||||
rm -rf "$INSTALL_DIR/templates"
|
rm -rf "$INSTALL_DIR/templates"
|
||||||
echo " ✅ Scripts entfernt (Konfiguration und Logs behalten)"
|
echo " ✅ Scripts entfernt (Konfiguration und Logs behalten)"
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ do_uninstall() {
|
|||||||
rm -f "$INSTALL_DIR/iptables-helper.sh"
|
rm -f "$INSTALL_DIR/iptables-helper.sh"
|
||||||
rm -f "$INSTALL_DIR/unban-expired.sh"
|
rm -f "$INSTALL_DIR/unban-expired.sh"
|
||||||
rm -f "$INSTALL_DIR/external-blocklist-worker.sh"
|
rm -f "$INSTALL_DIR/external-blocklist-worker.sh"
|
||||||
|
rm -f "$INSTALL_DIR/external-whitelist-worker.sh"
|
||||||
rm -f "$INSTALL_DIR/report-generator.sh"
|
rm -f "$INSTALL_DIR/report-generator.sh"
|
||||||
rm -f "$INSTALL_DIR/uninstall.sh"
|
rm -f "$INSTALL_DIR/uninstall.sh"
|
||||||
rm -rf "$INSTALL_DIR/templates"
|
rm -rf "$INSTALL_DIR/templates"
|
||||||
|
|||||||
Reference in New Issue
Block a user