Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ae37610ec0 | |||
| f685e7eb3e | |||
| 5f631ba858 |
@@ -146,6 +146,11 @@ EXTERNAL_BLOCKLIST_BAN_DURATION=0
|
||||
# Automatisch IPs entsperren die aus der externen Liste entfernt wurden?
|
||||
EXTERNAL_BLOCKLIST_AUTO_UNBAN=true
|
||||
|
||||
# Benachrichtigungen bei Blocklist-Sperren senden?
|
||||
# Bei Listen mit vielen IPs empfiehlt sich false, da sonst beim Sync
|
||||
# hunderte Benachrichtigungen auf einmal verschickt werden.
|
||||
EXTERNAL_BLOCKLIST_NOTIFY=false
|
||||
|
||||
# Lokaler Cache-Pfad für die heruntergeladene Blocklist
|
||||
EXTERNAL_BLOCKLIST_CACHE_DIR="/var/lib/adguard-shield/external-blocklist"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# Lizenz: MIT
|
||||
###############################################################################
|
||||
|
||||
VERSION="v0.5.0"
|
||||
VERSION="v0.5.1"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -101,6 +101,16 @@ Sendet einen POST mit JSON-Body:
|
||||
}
|
||||
```
|
||||
|
||||
## Benachrichtigungen und externe Blocklisten
|
||||
|
||||
Bei Sperren aus der **externen Blocklist** werden Benachrichtigungen separat über `EXTERNAL_BLOCKLIST_NOTIFY` gesteuert — unabhängig von `NOTIFY_ENABLED`.
|
||||
|
||||
| Parameter | Standard | Beschreibung |
|
||||
|-----------|----------|--------------|
|
||||
| `EXTERNAL_BLOCKLIST_NOTIFY` | `false` | Benachrichtigungen bei Blocklist-Sperren aktivieren |
|
||||
|
||||
> **Wichtig:** Bei großen Listen `EXTERNAL_BLOCKLIST_NOTIFY=false` belassen. Beim ersten Sync (oder nach einem `blocklist-flush`) werden alle IPs der Liste auf einmal gesperrt — mit `true` würde das zu einer Nachrichten-Flut im Notification-Channel führen. Nur auf `true` setzen, wenn die Liste sehr klein ist.
|
||||
|
||||
## Beispiel-Nachrichten
|
||||
|
||||
**Service gestartet:**
|
||||
|
||||
@@ -160,6 +160,7 @@ Ermöglicht das Einbinden externer Blocklisten, die IPv4-Adressen, IPv6-Adressen
|
||||
| `EXTERNAL_BLOCKLIST_INTERVAL` | `300` | Prüfintervall in Sekunden (300 = 5 Min.) |
|
||||
| `EXTERNAL_BLOCKLIST_BAN_DURATION` | `0` | Sperrdauer in Sekunden (0 = permanent bis IP aus Liste entfernt) |
|
||||
| `EXTERNAL_BLOCKLIST_AUTO_UNBAN` | `true` | IPs automatisch entsperren wenn aus Liste entfernt |
|
||||
| `EXTERNAL_BLOCKLIST_NOTIFY` | `false` | Webhook-Benachrichtigungen bei Blocklist-Sperren senden. Bei großen Listen unbedingt auf `false` lassen — beim ersten Sync kommen sonst hunderte Nachrichten auf einmal. |
|
||||
| `EXTERNAL_BLOCKLIST_CACHE_DIR` | `/var/lib/adguard-shield/external-blocklist` | Lokaler Cache für heruntergeladene Listen |
|
||||
### AbuseIPDB Reporting
|
||||
|
||||
@@ -227,6 +228,28 @@ malware.example.net
|
||||
|
||||
> **Hinweis zur Hostname-Auflösung:** Da AdGuard Shield idealerweise auf demselben Host wie der DNS-Resolver läuft, verwendet der Worker automatisch den lokalen Resolver. Hostnamen die bereits von AdGuard geblockt werden (Antwort `0.0.0.0`) werden übersprungen und nicht importiert.
|
||||
|
||||
#### Dateiformat der Blocklist
|
||||
|
||||
Beim Erstellen eigener Blocklisten müssen zwei Dinge beachtet werden:
|
||||
|
||||
- **Zeichenkodierung:** Datei in **UTF-8 ohne BOM** speichern. Dateien mit BOM (z.B. Standard-Einstellung in Notepad++) führen dazu, dass der erste Eintrag als ungültig erkannt wird.
|
||||
- **Zeilenenden:** Datei mit **Unix-Zeilenenden (LF)** speichern, nicht Windows (CRLF). CRLF-Zeilenenden führen dazu, dass alle Einträge als ungültig abgelehnt werden.
|
||||
|
||||
In **Notepad++:** Kodierung → „UTF-8 (ohne BOM)" und Bearbeiten → Zeilenende-Konvertierung → Unix (LF).
|
||||
In **VS Code:** Unten rechts auf `CRLF` klicken → `LF` auswählen; Zeichenkodierung ebenfalls unten rechts prüfen.
|
||||
|
||||
> **Empfehlung:** IP-Adressen und Hostnamen in **getrennten Listen** pflegen. Bei Hostname-Listen löst der Worker jeden Eintrag per DNS auf — das ist langsamer als direkte IP-Listen und liefert je nach DNS-Antwort mehrere IPs pro Eintrag. Getrennte Listen sind außerdem übersichtlicher und einfacher zu pflegen.
|
||||
|
||||
#### Synchronisierungsverhalten
|
||||
|
||||
Der Worker synchronisiert die Blocklisten:
|
||||
|
||||
- **Beim Service-Start:** Der erste Sync läuft **sofort** beim Start — ohne Wartezeit. Danach beginnt erst das periodische Intervall (`EXTERNAL_BLOCKLIST_INTERVAL`).
|
||||
- **Automatisch im Hintergrund:** Alle `EXTERNAL_BLOCKLIST_INTERVAL` Sekunden (Standard: 300s = 5 Min.) wird geprüft, ob sich die Liste geändert hat. Unveränderte Listen (HTTP 304 oder gleicher Inhalt) werden nicht erneut verarbeitet.
|
||||
- **Manuell:** `sudo adguard-shield.sh blocklist-sync` erzwingt sofort einen Sync, unabhängig vom laufenden Worker.
|
||||
|
||||
> **Nach einem Neustart** (Server oder Service) werden fehlende iptables-Regeln beim nächsten Sync automatisch nachgezogen.
|
||||
|
||||
2. Aktiviere die Blocklist in der Konfiguration:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -39,7 +39,7 @@ log() {
|
||||
local timestamp
|
||||
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
local log_entry="[$timestamp] [$level] [BLOCKLIST-WORKER] $message"
|
||||
echo "$log_entry" | tee -a "$LOG_FILE"
|
||||
echo "$log_entry" | tee -a "$LOG_FILE" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -115,6 +115,16 @@ ban_ip() {
|
||||
|
||||
# Bereits gesperrt?
|
||||
if [[ -f "$state_file" ]]; then
|
||||
# iptables-Regel prüfen und ggf. nachziehen (z.B. nach Neustart verloren gegangen)
|
||||
if [[ "$ip" == *:* ]]; then
|
||||
if ! ip6tables -C "$IPTABLES_CHAIN" -s "$ip" -j DROP 2>/dev/null; then
|
||||
ip6tables -I "$IPTABLES_CHAIN" -s "$ip" -j DROP 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
if ! iptables -C "$IPTABLES_CHAIN" -s "$ip" -j DROP 2>/dev/null; then
|
||||
iptables -I "$IPTABLES_CHAIN" -s "$ip" -j DROP 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
log "DEBUG" "IP $ip bereits über externe Blocklist gesperrt"
|
||||
return 0
|
||||
fi
|
||||
@@ -163,8 +173,8 @@ EOF
|
||||
|
||||
log_ban_history "BAN" "$ip" "external-blocklist"
|
||||
|
||||
# Benachrichtigung senden
|
||||
if [[ "$NOTIFY_ENABLED" == "true" ]]; then
|
||||
# Benachrichtigung senden (nur wenn EXTERNAL_BLOCKLIST_NOTIFY=true)
|
||||
if [[ "$NOTIFY_ENABLED" == "true" && "${EXTERNAL_BLOCKLIST_NOTIFY:-false}" == "true" ]]; then
|
||||
send_notification "ban" "$ip"
|
||||
fi
|
||||
}
|
||||
@@ -188,7 +198,7 @@ unban_ip() {
|
||||
rm -f "$state_file"
|
||||
log_ban_history "UNBAN" "$ip" "$reason"
|
||||
|
||||
if [[ "$NOTIFY_ENABLED" == "true" ]]; then
|
||||
if [[ "$NOTIFY_ENABLED" == "true" && "${EXTERNAL_BLOCKLIST_NOTIFY:-false}" == "true" ]]; then
|
||||
send_notification "unban" "$ip"
|
||||
fi
|
||||
}
|
||||
@@ -198,7 +208,10 @@ send_notification() {
|
||||
local action="$1"
|
||||
local ip="$2"
|
||||
|
||||
[[ -z "${NOTIFY_WEBHOOK_URL:-}" ]] && return
|
||||
# ntfy benötigt keine NOTIFY_WEBHOOK_URL, alle anderen schon
|
||||
if [[ "${NOTIFY_TYPE:-generic}" != "ntfy" && -z "${NOTIFY_WEBHOOK_URL:-}" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local message
|
||||
if [[ "$action" == "ban" ]]; then
|
||||
@@ -382,6 +395,9 @@ parse_blocklist_ips() {
|
||||
[[ -f "$cache_file" ]] || return
|
||||
|
||||
while IFS= read -r line; do
|
||||
line="${line%$'\r'}" # Windows-Zeilenenden (CRLF) entfernen
|
||||
line="${line#$'\xef\xbb\xbf'}" # UTF-8 BOM entfernen (erste Zeile)
|
||||
|
||||
# Leerzeilen und Kommentarzeilen überspringen
|
||||
[[ -z "$line" ]] && continue
|
||||
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
||||
@@ -439,7 +455,7 @@ parse_blocklist_ips() {
|
||||
continue
|
||||
fi
|
||||
local resolved
|
||||
resolved=$(getent ahosts "$line" 2>/dev/null | awk '{print $1}' | sort -u)
|
||||
resolved=$(getent ahosts "$line" 2>/dev/null | awk '{print $1}' | sort -u) || resolved=""
|
||||
if [[ -z "$resolved" ]]; then
|
||||
log "WARN" "Hostname konnte nicht aufgelöst werden: $line"
|
||||
continue
|
||||
@@ -537,8 +553,12 @@ sync_blocklists() {
|
||||
continue
|
||||
fi
|
||||
|
||||
local _state_file_before="${STATE_DIR}/ext_${ip//[:/]/_}.ban"
|
||||
local _was_new=false
|
||||
[[ ! -f "$_state_file_before" ]] && _was_new=true
|
||||
|
||||
ban_ip "$ip"
|
||||
new_bans=$((new_bans + 1))
|
||||
[[ "$_was_new" == "true" ]] && new_bans=$((new_bans + 1))
|
||||
done < "$unique_ips_file"
|
||||
|
||||
# ─── Entfernte IPs entsperren ────────────────────────────────────────────
|
||||
|
||||
32
install.sh
32
install.sh
@@ -6,7 +6,7 @@
|
||||
# Lizenz: MIT
|
||||
###############################################################################
|
||||
|
||||
VERSION="v0.5.0"
|
||||
VERSION="v0.5.1"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -139,7 +139,7 @@ show_menu() {
|
||||
echo -e " ${CYAN}5)${NC} Hilfe — Hilfe & Befehlsübersicht anzeigen"
|
||||
echo -e " ${CYAN}0)${NC} Beenden"
|
||||
echo ""
|
||||
read -rp " Auswahl [0-5]: " choice
|
||||
read -rep " Auswahl [0-5]: " choice
|
||||
echo ""
|
||||
|
||||
case "$choice" in
|
||||
@@ -350,7 +350,7 @@ install_service() {
|
||||
echo ""
|
||||
|
||||
# Interaktiv: Autostart beim Booten?
|
||||
read -rp " Soll AdGuard Shield beim Booten automatisch starten? [J/n]: " autostart
|
||||
read -rep " Soll AdGuard Shield beim Booten automatisch starten? [J/n]: " autostart
|
||||
if [[ "${autostart,,}" != "n" ]]; then
|
||||
systemctl enable adguard-shield.service
|
||||
echo -e " ✅ Autostart aktiviert"
|
||||
@@ -369,17 +369,17 @@ configure() {
|
||||
local conf="$INSTALL_DIR/adguard-shield.conf"
|
||||
|
||||
# AdGuard URL
|
||||
read -rp " AdGuard Home URL [http://127.0.0.1:3000]: " adguard_url
|
||||
read -rep " AdGuard Home URL [http://127.0.0.1:3000]: " adguard_url
|
||||
adguard_url="${adguard_url:-http://127.0.0.1:3000}"
|
||||
sed -i "s|^ADGUARD_URL=.*|ADGUARD_URL=\"$adguard_url\"|" "$conf"
|
||||
|
||||
# Benutzername
|
||||
read -rp " AdGuard Home Benutzername [admin]: " adguard_user
|
||||
read -rep " AdGuard Home Benutzername [admin]: " adguard_user
|
||||
adguard_user="${adguard_user:-admin}"
|
||||
sed -i "s|^ADGUARD_USER=.*|ADGUARD_USER=\"$adguard_user\"|" "$conf"
|
||||
|
||||
# Passwort
|
||||
read -rsp " AdGuard Home Passwort: " adguard_pass
|
||||
read -resp " AdGuard Home Passwort: " adguard_pass
|
||||
echo ""
|
||||
if [[ -n "$adguard_pass" ]]; then
|
||||
# Einfache Quotes damit $-Zeichen im Passwort nicht expandiert werden
|
||||
@@ -387,17 +387,17 @@ configure() {
|
||||
fi
|
||||
|
||||
# Rate Limit
|
||||
read -rp " Max. Anfragen pro Domain/Client pro Minute [30]: " rate_limit
|
||||
read -rep " Max. Anfragen pro Domain/Client pro Minute [30]: " rate_limit
|
||||
rate_limit="${rate_limit:-30}"
|
||||
sed -i "s|^RATE_LIMIT_MAX_REQUESTS=.*|RATE_LIMIT_MAX_REQUESTS=$rate_limit|" "$conf"
|
||||
|
||||
# Sperrdauer
|
||||
read -rp " Sperrdauer in Sekunden [3600]: " ban_duration
|
||||
read -rep " Sperrdauer in Sekunden [3600]: " ban_duration
|
||||
ban_duration="${ban_duration:-3600}"
|
||||
sed -i "s|^BAN_DURATION=.*|BAN_DURATION=$ban_duration|" "$conf"
|
||||
|
||||
# Whitelist
|
||||
read -rp " Whitelist IPs (kommagetrennt) [127.0.0.1,::1]: " whitelist
|
||||
read -rep " Whitelist IPs (kommagetrennt) [127.0.0.1,::1]: " whitelist
|
||||
whitelist="${whitelist:-127.0.0.1,::1}"
|
||||
sed -i "s|^WHITELIST=.*|WHITELIST=\"$whitelist\"|" "$conf"
|
||||
|
||||
@@ -575,7 +575,7 @@ do_install() {
|
||||
if [[ -d "$INSTALL_DIR" ]] && [[ -f "$INSTALL_DIR/adguard-shield.sh" ]]; then
|
||||
echo -e "${YELLOW}AdGuard Shield ist bereits installiert!${NC}"
|
||||
echo ""
|
||||
read -rp " Möchtest du stattdessen ein Update durchführen? [j/N]: " do_upd
|
||||
read -rep " Möchtest du stattdessen ein Update durchführen? [j/N]: " do_upd
|
||||
if [[ "${do_upd,,}" == "j" ]]; then
|
||||
do_update
|
||||
return
|
||||
@@ -600,7 +600,7 @@ do_install() {
|
||||
|
||||
# Interaktiv: Service jetzt starten?
|
||||
echo -e "${YELLOW}Service starten:${NC}"
|
||||
read -rp " Soll der AdGuard Shield Service jetzt gestartet werden? [J/n]: " start_now
|
||||
read -rep " Soll der AdGuard Shield Service jetzt gestartet werden? [J/n]: " start_now
|
||||
if [[ "${start_now,,}" != "n" ]]; then
|
||||
systemctl start adguard-shield
|
||||
echo -e " ✅ Service gestartet"
|
||||
@@ -644,7 +644,7 @@ do_update() {
|
||||
if systemctl is-enabled adguard-shield &>/dev/null; then
|
||||
echo -e " ℹ️ Autostart ist bereits aktiviert"
|
||||
else
|
||||
read -rp " Soll AdGuard Shield beim Booten automatisch starten? [J/n]: " autostart
|
||||
read -rep " Soll AdGuard Shield beim Booten automatisch starten? [J/n]: " autostart
|
||||
if [[ "${autostart,,}" != "n" ]]; then
|
||||
systemctl enable adguard-shield.service
|
||||
echo -e " ✅ Autostart aktiviert"
|
||||
@@ -661,7 +661,7 @@ do_update() {
|
||||
fi
|
||||
|
||||
if [[ "$service_was_active" == "true" ]]; then
|
||||
read -rp " Soll der Service jetzt neu gestartet werden? [J/n]: " restart_now
|
||||
read -rep " Soll der Service jetzt neu gestartet werden? [J/n]: " restart_now
|
||||
if [[ "${restart_now,,}" != "n" ]]; then
|
||||
systemctl restart adguard-shield
|
||||
echo -e " ✅ Service wurde neu gestartet"
|
||||
@@ -670,7 +670,7 @@ do_update() {
|
||||
echo -e " ${YELLOW}Bitte manuell neustarten: sudo systemctl restart adguard-shield${NC}"
|
||||
fi
|
||||
else
|
||||
read -rp " Soll der Service jetzt gestartet werden? [J/n]: " start_now
|
||||
read -rep " Soll der Service jetzt gestartet werden? [J/n]: " start_now
|
||||
if [[ "${start_now,,}" != "n" ]]; then
|
||||
systemctl start adguard-shield
|
||||
echo -e " ✅ Service gestartet"
|
||||
@@ -709,7 +709,7 @@ do_uninstall() {
|
||||
echo ""
|
||||
|
||||
# Sicherheitsabfrage
|
||||
read -rp " Wirklich deinstallieren? [j/N]: " confirm
|
||||
read -rep " Wirklich deinstallieren? [j/N]: " confirm
|
||||
if [[ "${confirm,,}" != "j" ]]; then
|
||||
echo -e "${GREEN}Deinstallation abgebrochen.${NC}"
|
||||
exit 0
|
||||
@@ -735,7 +735,7 @@ do_uninstall() {
|
||||
fi
|
||||
|
||||
# Dateien entfernen
|
||||
read -rp " Konfiguration und Logs behalten? [j/N]: " keep
|
||||
read -rep " Konfiguration und Logs behalten? [j/N]: " keep
|
||||
if [[ "${keep,,}" == "j" ]]; then
|
||||
rm -f "$INSTALL_DIR/adguard-shield.sh"
|
||||
rm -f "$INSTALL_DIR/iptables-helper.sh"
|
||||
|
||||
Reference in New Issue
Block a user