Merge pull request 'v0.5.2' (#6) from v0.5.2 into main

Reviewed-on: #6
This commit is contained in:
2026-03-06 12:14:05 +00:00
9 changed files with 219 additions and 32 deletions
+5 -1
View File
@@ -78,6 +78,9 @@ sudo bash install.sh --help # Hilfe anzeigen
sudo bash install.sh update # Update mit automatischer Konfigurations-Migration
sudo bash install.sh status # Installationsstatus prüfen
# Deinstallation (kein install.sh benötigt)
sudo bash /opt/adguard-shield/uninstall.sh # Direkt aus dem Installationsverzeichnis
# Monitor
sudo /opt/adguard-shield/adguard-shield.sh status # Aktive Sperren anzeigen
sudo /opt/adguard-shield/adguard-shield.sh history # Ban-History anzeigen
@@ -103,7 +106,8 @@ sudo journalctl -u adguard-shield -f # Logs live ver
├── iptables-helper.sh # Manuelle iptables-Verwaltung
├── unban-expired.sh # Cron-basiertes Entsperren
├── report-generator.sh # E-Mail Report Generator
├── install.sh # Installer / Updater / Uninstaller
├── install.sh # Installer / Updater
├── uninstall.sh # Uninstaller (wird ins Installationsverzeichnis kopiert)
├── templates/
│ ├── report.html # HTML-Report-Template
│ └── report.txt # TXT-Report-Template
+1 -1
View File
@@ -9,7 +9,7 @@
# Lizenz: MIT
###############################################################################
VERSION="v0.5.1"
VERSION="v0.5.2"
set -euo pipefail
+12 -1
View File
@@ -14,7 +14,7 @@ sudo bash install.sh install
# Update (mit automatischer Konfigurations-Migration)
sudo bash install.sh update
# Deinstallation
# Deinstallation (delegiert automatisch an den installierten Uninstaller)
sudo bash install.sh uninstall
# Installationsstatus anzeigen
@@ -24,6 +24,17 @@ sudo bash install.sh status
sudo bash install.sh --help
```
## Uninstaller (eigenständig)
Ab Version 0.6 wird bei der Installation ein eigenständiger Uninstaller nach `/opt/adguard-shield/uninstall.sh` kopiert. Die Deinstallation kann damit **ohne die originalen Installationsdateien** durchgeführt werden:
```bash
# Direkt aus dem Installationsverzeichnis — kein install.sh benötigt
sudo bash /opt/adguard-shield/uninstall.sh
```
Der Uninstaller kennt seinen Speicherort und leitet daraus automatisch das Installationsverzeichnis ab. `install.sh uninstall` delegiert intern ebenfalls dorthin — beide Wege führen zum selben Ergebnis.
### Update-Verhalten
Beim Update passiert automatisch:
+8 -1
View File
@@ -213,11 +213,18 @@ sudo bash install.sh update
## Deinstallation
Ab Version 0.6 gibt es einen eigenständigen Uninstaller im Installationsverzeichnis. Die Deinstallation kann daher jederzeit durchgeführt werden, **ohne die originalen Installationsdateien (install.sh) behalten zu müssen**:
```bash
# Über den Installer (interaktiv mit Menü)
# Empfohlen: direkt aus dem Installationsverzeichnis ausführen
sudo bash /opt/adguard-shield/uninstall.sh
# Alternativ: über den Installer (sofern noch vorhanden)
sudo bash install.sh uninstall
```
Beide Wege sind gleichwertig — `install.sh uninstall` delegiert intern an `/opt/adguard-shield/uninstall.sh`.
Oder manuell:
```bash
sudo systemctl stop adguard-shield
+19 -7
View File
@@ -6,7 +6,7 @@
# Lizenz: MIT
###############################################################################
VERSION="v0.5.1"
VERSION="v0.5.2"
set -euo pipefail
@@ -70,6 +70,9 @@ print_help() {
echo -e " ${GREEN}uninstall${NC} Vollständige Deinstallation"
echo -e " Stoppt den Service, entfernt iptables-Regeln und"
echo -e " löscht alle Dateien (optional Konfiguration behalten)."
echo -e " Delegiert automatisch an den im Installationsverzeichnis"
echo -e " liegenden Uninstaller — kein Behalten der Installationsdateien nötig."
echo -e " Direkt ausführbar: ${CYAN}sudo bash $INSTALL_DIR/uninstall.sh${NC}"
echo ""
echo -e " ${GREEN}status${NC} Installationsstatus anzeigen"
echo -e " Zeigt ob AdGuard Shield installiert ist, welche Version"
@@ -239,6 +242,7 @@ install_files() {
cp "$SCRIPT_DIR/unban-expired.sh" "$INSTALL_DIR/"
cp "$SCRIPT_DIR/external-blocklist-worker.sh" "$INSTALL_DIR/"
cp "$SCRIPT_DIR/report-generator.sh" "$INSTALL_DIR/"
cp "$SCRIPT_DIR/uninstall.sh" "$INSTALL_DIR/"
# Templates kopieren
mkdir -p "$INSTALL_DIR/templates"
@@ -251,6 +255,7 @@ install_files() {
chmod +x "$INSTALL_DIR/unban-expired.sh"
chmod +x "$INSTALL_DIR/external-blocklist-worker.sh"
chmod +x "$INSTALL_DIR/report-generator.sh"
chmod +x "$INSTALL_DIR/uninstall.sh"
echo -e " ✅ Dateien installiert"
echo ""
@@ -519,6 +524,9 @@ print_summary() {
echo " Hilfe anzeigen:"
echo " sudo bash install.sh --help"
echo ""
echo " Deinstallieren (auch ohne Installationsdateien):"
echo " sudo bash $INSTALL_DIR/uninstall.sh"
echo ""
}
# ─── Status anzeigen ─────────────────────────────────────────────────────────
@@ -705,10 +713,15 @@ do_uninstall() {
exit 1
fi
echo -e "${YELLOW}Deinstalliere AdGuard Shield...${NC}"
# An den im Installationsverzeichnis liegenden Uninstaller delegieren
if [[ -f "$INSTALL_DIR/uninstall.sh" ]]; then
exec bash "$INSTALL_DIR/uninstall.sh"
fi
# Fallback für ältere Installationen ohne uninstall.sh
echo -e "${YELLOW}Deinstalliere AdGuard Shield (Fallback-Modus)...${NC}"
echo ""
# Sicherheitsabfrage
read -rep " Wirklich deinstallieren? [j/N]: " confirm
if [[ "${confirm,,}" != "j" ]]; then
echo -e "${GREEN}Deinstallation abgebrochen.${NC}"
@@ -716,7 +729,6 @@ do_uninstall() {
fi
echo ""
# Service stoppen und deaktivieren
if systemctl is-active adguard-shield &>/dev/null; then
systemctl stop adguard-shield
echo " ✅ Service gestoppt"
@@ -729,18 +741,18 @@ do_uninstall() {
systemctl daemon-reload
echo " ✅ Service-Datei entfernt"
# iptables Chain aufräumen
if [[ -f "$INSTALL_DIR/iptables-helper.sh" ]]; then
bash "$INSTALL_DIR/iptables-helper.sh" remove || true
fi
# Dateien entfernen
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"
rm -f "$INSTALL_DIR/unban-expired.sh"
rm -f "$INSTALL_DIR/external-blocklist-worker.sh"
rm -f "$INSTALL_DIR/report-generator.sh"
rm -rf "$INSTALL_DIR/templates"
echo " ✅ Scripts entfernt (Konfiguration und Logs behalten)"
else
rm -rf "$INSTALL_DIR"
@@ -766,7 +778,7 @@ main() {
do_update
;;
uninstall)
print_header
# print_header wird vom delegierten uninstall.sh übernommen
do_uninstall
;;
status)
+43 -19
View File
@@ -62,35 +62,43 @@ log() {
local message="$*"
local timestamp
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
echo "[$timestamp] [$level] [REPORT] $message" | tee -a "$LOG_FILE"
echo "[$timestamp] [$level] [REPORT] $message" | tee -a "$LOG_FILE" >&2
}
# ─── Berichtszeitraum berechnen ───────────────────────────────────────────────
# Gibt Epoch-Wert für heute 00:00:00 (Mitternacht) zurück
get_today_midnight() {
date -d "today 00:00:00" '+%s' 2>/dev/null || date -v0H -v0M -v0S '+%s'
}
get_report_period() {
local now_epoch
now_epoch=$(date '+%s')
local today_midnight
today_midnight=$(get_today_midnight)
# Ende des Berichtszeitraums ist immer das Ende von gestern (23:59:59)
local end_epoch=$((today_midnight - 1))
local start_epoch
local period_label
case "$REPORT_INTERVAL" in
daily)
start_epoch=$((now_epoch - 86400))
start_epoch=$((today_midnight - 86400))
period_label="Tagesbericht"
;;
weekly)
start_epoch=$((now_epoch - 604800))
start_epoch=$((today_midnight - 7 * 86400))
period_label="Wochenbericht"
;;
biweekly)
start_epoch=$((now_epoch - 1209600))
start_epoch=$((today_midnight - 14 * 86400))
period_label="Zweiwochenbericht"
;;
monthly)
start_epoch=$((now_epoch - 2592000))
start_epoch=$((today_midnight - 30 * 86400))
period_label="Monatsbericht"
;;
*)
start_epoch=$((now_epoch - 604800))
start_epoch=$((today_midnight - 7 * 86400))
period_label="Bericht"
;;
esac
@@ -98,28 +106,40 @@ get_report_period() {
local start_date
start_date=$(date -d "@$start_epoch" '+%d.%m.%Y' 2>/dev/null || date -r "$start_epoch" '+%d.%m.%Y')
local end_date
end_date=$(date '+%d.%m.%Y')
end_date=$(date -d "@$end_epoch" '+%d.%m.%Y' 2>/dev/null || date -r "$end_epoch" '+%d.%m.%Y')
echo "${period_label}: ${start_date} ${end_date}"
if [[ "$REPORT_INTERVAL" == "daily" ]]; then
echo "${period_label}: ${start_date}"
else
echo "${period_label}: ${start_date} ${end_date}"
fi
}
get_period_start_epoch() {
local now_epoch
now_epoch=$(date '+%s')
local today_midnight
today_midnight=$(get_today_midnight)
case "$REPORT_INTERVAL" in
daily) echo $((now_epoch - 86400)) ;;
weekly) echo $((now_epoch - 604800)) ;;
biweekly) echo $((now_epoch - 1209600)) ;;
monthly) echo $((now_epoch - 2592000)) ;;
*) echo $((now_epoch - 604800)) ;;
daily) echo $((today_midnight - 86400)) ;;
weekly) echo $((today_midnight - 7 * 86400)) ;;
biweekly) echo $((today_midnight - 14 * 86400)) ;;
monthly) echo $((today_midnight - 30 * 86400)) ;;
*) echo $((today_midnight - 7 * 86400)) ;;
esac
}
get_period_end_epoch() {
# Ende des Berichtszeitraums = Ende von gestern (heute 00:00:00 minus 1 Sekunde)
local today_midnight
today_midnight=$(get_today_midnight)
echo $((today_midnight - 1))
}
# ─── Ban-History filtern nach Zeitraum ────────────────────────────────────────
# Gibt nur Zeilen zurück, deren Zeitstempel im Berichtszeitraum liegen
filter_history_by_period() {
local start_epoch="$1"
local end_epoch="$2"
if [[ ! -f "$BAN_HISTORY_FILE" ]]; then
return
@@ -141,7 +161,7 @@ filter_history_by_period() {
local line_epoch
line_epoch=$(date -d "$timestamp" '+%s' 2>/dev/null || date -j -f '%Y-%m-%d %H:%M:%S' "$timestamp" '+%s' 2>/dev/null || echo "0")
if [[ "$line_epoch" -ge "$start_epoch" ]]; then
if [[ "$line_epoch" -ge "$start_epoch" && "$line_epoch" -le "$end_epoch" ]]; then
echo "$line"
fi
done < "$BAN_HISTORY_FILE"
@@ -194,9 +214,11 @@ calculate_stats() {
local start_epoch
start_epoch=$(get_period_start_epoch)
local end_epoch
end_epoch=$(get_period_end_epoch)
local filtered_data
filtered_data=$(filter_history_by_period "$start_epoch")
filtered_data=$(filter_history_by_period "$start_epoch" "$end_epoch")
# Wenn keine Daten vorhanden, Standardwerte
if [[ -z "$filtered_data" ]]; then
@@ -373,6 +395,7 @@ generate_recent_bans_html() {
while IFS='|' read -r timestamp action ip domain count duration protocol reason; do
timestamp=$(echo "$timestamp" | xargs)
ip=$(echo "$ip" | xargs)
[[ -z "$timestamp" && -z "$ip" ]] && continue
domain=$(echo "$domain" | xargs)
reason=$(echo "$reason" | xargs)
[[ "$domain" == "-" ]] && domain=""
@@ -459,6 +482,7 @@ generate_recent_bans_txt() {
while IFS='|' read -r timestamp action ip domain count duration protocol reason; do
timestamp=$(echo "$timestamp" | xargs)
ip=$(echo "$ip" | xargs)
[[ -z "$timestamp" && -z "$ip" ]] && continue
domain=$(echo "$domain" | xargs)
reason=$(echo "$reason" | xargs)
[[ "$domain" == "-" ]] && domain=""
+1 -1
View File
@@ -311,7 +311,7 @@
<span class="separator">|</span>
<a href="https://git.techniverse.net/scriptos/adguard-shield.git">AdGuard Shield auf Gitea</a>
</div>
<div class="version-tag">AdGuard Shield v{{VERSION}} · {{HOSTNAME}}</div>
<div class="version-tag">AdGuard Shield {{VERSION}} · {{HOSTNAME}}</div>
</div>
</div>
</body>
+1 -1
View File
@@ -52,7 +52,7 @@
═══════════════════════════════════════════════════════════════
Dieser Report wurde automatisch von AdGuard Shield generiert.
AdGuard Shield v{{VERSION}}
AdGuard Shield {{VERSION}}
Web: https://www.patrick-asmus.de
Blog: https://www.cleveradmin.de
+129
View File
@@ -0,0 +1,129 @@
#!/bin/bash
###############################################################################
# AdGuard Shield - Uninstaller
# Autor: Patrick Asmus
# E-Mail: support@techniverse.net
# Lizenz: MIT
#
# Dieses Script befindet sich im Installationsverzeichnis und kann daher
# ohne die originalen Installationsdateien ausgeführt werden:
# sudo bash /opt/adguard-shield/uninstall.sh
###############################################################################
# INSTALL_DIR ergibt sich aus dem Verzeichnis, in dem dieses Script liegt
INSTALL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_FILE="/etc/systemd/system/adguard-shield.service"
# Farben
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
print_header() {
echo ""
echo -e "${BLUE}"
echo " ▄▄▄ ▓█████▄ ▄████ █ ██ ▄▄▄ ██▀███ ▓█████▄ ██████ ██░ ██ ██▓▓█████ ██▓ ▓█████▄ "
echo "▒████▄ ▒██▀ ██▌ ██▒ ▀█▒ ██ ▓██▒▒████▄ ▓██ ▒ ██▒▒██▀ ██▌ ▒██ ▒ ▓██░ ██▒▓██▒▓█ ▀ ▓██▒ ▒██▀ ██▌"
echo "▒██ ▀█▄ ░██ █▌▒██░▄▄▄░▓██ ▒██░▒██ ▀█▄ ▓██ ░▄█ ▒░██ █▌ ░ ▓██▄ ▒██▀▀██░▒██▒▒███ ▒██░ ░██ █▌"
echo "░██▄▄▄▄██ ░▓█▄ ▌░▓█ ██▓▓▓█ ░██░░██▄▄▄▄██ ▒██▀▀█▄ ░▓█▄ ▌ ▒ ██▒░▓█ ░██ ░██░▒▓█ ▄ ▒██░ ░▓█▄ ▌"
echo " ▓█ ▓██▒░▒████▓ ░▒▓███▀▒▒▒█████▓ ▓█ ▓██▒░██▓ ▒██▒░▒████▓ ▒██████▒▒░▓█▒░██▓░██░░▒████▒░██████▒░▒████▓ "
echo " ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒ ▒ ░▒▓▒ ▒ ▒ ▒▒ ▓▒█░░ ▒▓ ░▒▓░ ▒▒▓ ▒ ▒ ▒▓▒ ▒ ░ ▒ ░░▒░▒░▓ ░░ ▒░ ░░ ▒░▓ ░ ▒▒▓ ▒ "
echo " ▒ ▒▒ ░ ░ ▒ ▒ ░ ░ ░░▒░ ░ ░ ▒ ▒▒ ░ ░▒ ░ ▒░ ░ ▒ ▒ ░ ░▒ ░ ░ ▒ ░▒░ ░ ▒ ░ ░ ░ ░░ ░ ▒ ░ ░ ▒ ▒ "
echo " ░ ▒ ░ ░ ░ ░ ░ ░ ░░░ ░ ░ ░ ▒ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ "
echo " ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ "
echo " ░ ░ ░ "
echo -e "${NC}"
echo -e "${GREEN} Uninstaller${NC}"
echo -e "${BLUE} Autor: Patrick Asmus${NC}"
echo -e
echo -e "${BLUE} E-Mail: support@techniverse.net${NC}"
echo -e "${BLUE} Web: https://www.patrick-asmus.de${NC}"
echo ""
echo -e "${BLUE}───────────────────────────────────────────────────────────────────────────────────────────────────────────────${NC}"
echo ""
echo -e "${BLUE} Repo: https://git.techniverse.net/scriptos/adguard-shield${NC}"
echo ""
echo -e "${BLUE}═══════════════════════════════════════════════════════════════════════════════════════════════════════════════${NC}"
echo ""
}
check_root() {
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Dieses Script muss als root ausgeführt werden!${NC}" >&2
echo "Bitte mit 'sudo $0' ausführen."
exit 1
fi
}
do_uninstall() {
check_root
# Prüfen ob installiert
if [[ ! -d "$INSTALL_DIR" ]]; then
echo -e "${RED}AdGuard Shield ist nicht installiert (Verzeichnis nicht gefunden: $INSTALL_DIR)!${NC}"
exit 1
fi
echo -e "${YELLOW}Deinstalliere AdGuard Shield aus: ${BOLD}$INSTALL_DIR${NC}"
echo ""
# Sicherheitsabfrage
read -rep " Wirklich deinstallieren? [j/N]: " confirm
if [[ "${confirm,,}" != "j" ]]; then
echo -e "${GREEN}Deinstallation abgebrochen.${NC}"
exit 0
fi
echo ""
# Service stoppen und deaktivieren
if systemctl is-active adguard-shield &>/dev/null; then
systemctl stop adguard-shield
echo " ✅ Service gestoppt"
fi
if systemctl is-enabled adguard-shield &>/dev/null; then
systemctl disable adguard-shield
echo " ✅ Service deaktiviert"
fi
if [[ -f "$SERVICE_FILE" ]]; then
rm -f "$SERVICE_FILE"
systemctl daemon-reload
echo " ✅ Service-Datei entfernt"
fi
# iptables Chain aufräumen
if [[ -f "$INSTALL_DIR/iptables-helper.sh" ]]; then
bash "$INSTALL_DIR/iptables-helper.sh" remove || true
fi
# Dateien entfernen
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"
rm -f "$INSTALL_DIR/unban-expired.sh"
rm -f "$INSTALL_DIR/external-blocklist-worker.sh"
rm -f "$INSTALL_DIR/report-generator.sh"
rm -f "$INSTALL_DIR/uninstall.sh"
rm -rf "$INSTALL_DIR/templates"
echo " ✅ Scripts entfernt (Konfiguration und Logs behalten)"
echo ""
echo -e "${YELLOW} Konfiguration verbleibt in: $INSTALL_DIR/adguard-shield.conf${NC}"
echo -e "${YELLOW} Logs verbleiben in: /var/log/adguard-shield*.log${NC}"
else
rm -rf "$INSTALL_DIR"
rm -rf /var/lib/adguard-shield
rm -f /var/log/adguard-shield.log*
rm -f /var/log/adguard-shield-bans.log
echo " ✅ Alles entfernt"
fi
echo ""
echo -e "${GREEN}Deinstallation abgeschlossen.${NC}"
}
print_header
do_uninstall