mirror of https://github.com/Zelo72/rpi
348 lines
14 KiB
Bash
Executable File
348 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Script: updatePihole.sh - https://github.com/Zelo72/rpi (/pihole/)
|
|
#
|
|
# Beschreibung: Das Script aktualisiert bei jedem Lauf die Pi-hole Gravity auf Basis der in Pi-hole
|
|
# konfigurierten Blocklisten. Zusaetzlich werden, wenn das Script an einem Sonntag ausgefuehrt
|
|
# wird, Raspberry Paketupdates simuliert.
|
|
# Bei Bedarf wird ein Gravity-Update Bericht als Mail versendet. Dieser beinhaltet neben einem Pi-Hole
|
|
# Gesundheitstatus auch die Statistik für das Pi-Hole und Gravity Update.
|
|
# Das Script ist mit Pi-hole 4.x und 5.x kompatibel.
|
|
#
|
|
# Aufruf: sudo ./updatePihole.sh name@domain.xy <-- mit Mailversand
|
|
# sudo ./updatePihole.sh <-- ohne Mailversand
|
|
#
|
|
# Ausgabedateien: /var/log/pihole/Ymd_updatePihole.sh.log --> taegliches Logfile
|
|
# /var/log/pihole/updatePihole.stats.log --> Pi-hole Gravity Update Bericht/Statistik
|
|
# /var/var/log/pihole/updatePihole.cron.log --> Logifile des Cron-Jobs
|
|
#
|
|
# Installation: 1. Script downloaden:
|
|
# wget -N https://raw.githubusercontent.com/Zelo72/rpi/master/pihole/updatePihole.sh
|
|
# 2. Script mittels sudo chmod +x updatePihole.sh ausführbar machen.
|
|
#
|
|
# Installation: 1. Script mittels sudo cp updatePihole.sh /root nach /root kopieren.
|
|
# (als Cron-Job) 2. Script mittels sudo chmod +x /root/updatePihole.sh ausfuehrbar machen.
|
|
# 3. Cron-Job mit sudo crontab -e erstellen
|
|
# Am Ende der Datei z.B. folgendes einfuegen um das Script taeglich um 03:00 Uhr zu starten
|
|
# und eine Mail mit dem Gravity Update Bericht an "name@domain.xy" zu schicken:
|
|
#
|
|
# 0 3 * * * /root/updatePihole.sh name@domain.xy > /var/log/pihole/updatePihole.cron.log 2>&1
|
|
#
|
|
# 4. Datei speichern und schliessen. (im nano Editor: Strg+o/Enter/Strg+x).
|
|
#
|
|
# -------
|
|
# :HINWEIS: Damit der Mailversand funktioniert, muss msmtp und mailutils installiert und konfiguriert
|
|
# ------- sein. Eine Anleitung dazu ist hier zu finden:
|
|
# https://github.com/Zelo72/rpi/blob/master/tutorials/Mailversand-RPi-einrichten.md
|
|
#
|
|
# Versionshistorie:
|
|
# Version 1.0.0 - [Zelo72] - initiale Version
|
|
# 1.0.1 - [Zelo72/AleksCee] - Umstellung von wc -l auf grep -Evc '^#|^$' um auskommentierte und leere Zeilen
|
|
# beim Zählen herauszufiltern.
|
|
# - Damit die Mail mit dem Abschlussbericht nicht vom Mailserver des Empfaengers
|
|
# als Spam eingestuft wird, wurde die Ausgabe der Top 50 hinzugefuegten und
|
|
# geloeschten Domains auskommentiert.
|
|
# - Gesundheitsstatus von JA/NEIN/UNDEFINIERT auf OK/FEHLER/NICHT DURCHGEFUEHRT
|
|
# umgestellt.
|
|
# - Von Gesamtlogfile auf taegliche Logs umgestellt
|
|
# - Delimiter in der Ausgabe entfernt
|
|
# 1.0.2 - [Zelo72/AleksCee] - n Sekunden warten bevor der DNS Check nach dem Pi-hole Update durchgefuehrt
|
|
# wird. Der Pi-Hole DNS Service braucht manchmal etwas bis er verfuegbar ist.
|
|
# - Versuch von RestartDNS wenn der DNS Service nach dem Pi-hole Update nicht
|
|
# mehr reagiert.
|
|
# - Möglicher Fehler Exitcode 127 bei Aufruf des pihole binaries aus einem Cron
|
|
# Job heraus behoben: von pihole -u/-g auf /usr/local/bin/pihole ... umgestellt.
|
|
# 1.0.3 - [Zelo72] - Beschreibung, Aufruf, Ausgabedateien und Installation beschrieben.
|
|
# 1.0.4 - [Zelo72] - Logverzeichnis bereinigen, Logs aelter als 7 Tage werden geloescht.
|
|
# 1.0.5 - [Zelo72/AleksCee] - Logbereinigung von Minuten auf Tage umgestellt und Unterscheidung zwischen
|
|
# Startpunkt und Suchmuster
|
|
# 1.0.6 - [Zelo72] - Gravity Update Bericht erweitert: Hostname, CPU Temperatur, RAM Nutzung,
|
|
# HDD Nutzung, Pi-hole Status (aktiv/offline)
|
|
# - Fehler behoben: Nach waitfordns und anschliessend fehlgeschlagenem DNS-Test
|
|
# wurde der Code im If-Zweig zum erneuten DNS-Test nicht
|
|
# ausgefuehrt.
|
|
# 1.0.7 - [Zelo72] - Kompatiblitaet fuer Pihole 5.x
|
|
# 1.0.8 - [Zelo72] - Auf Update nur simulieren nicht automatisch durchführen umgestellt.
|
|
# Betrifft Raspberry Pakete und das Pi-hole Softwareupdate.
|
|
# 1.0.9 - [Zelo72] - Lokalen Blocklisten-Cache vor Gravity-Update bereinigen.
|
|
# 1.1.0 - [Zelo72] - Internetverbindungs-/DNS-Test um Cloudflare erweitert.
|
|
#
|
|
|
|
# Prüfen ob das Script als root ausgefuehrt wird
|
|
if [ "$(id -u)" != "0" ]; then
|
|
echo "Das Script muss mit Rootrechten ausgeführt werden!"
|
|
exit 1
|
|
fi
|
|
|
|
# *** Initialisierung ***
|
|
|
|
# Logging initialisieren
|
|
logDir=/var/log/pihole
|
|
log=$logDir/$(date +'%Y%m%d')_updatePihole.sh.log
|
|
mkdir -p $logDir
|
|
|
|
# Hilfsfunktion zum loggen
|
|
writeLog() {
|
|
echo -e "[$(date +'%Y.%m.%d-%H:%M:%S')]" "$*" | tee -a "$log"
|
|
}
|
|
writeLog "[I] Start | Logfile: $log"
|
|
|
|
# Tempverzeichnis initialisieren
|
|
tmp=/tmp/pihole
|
|
writeLog "[I] Initialisiere Tempverzeichnis $tmp ..."
|
|
mkdir -p $tmp
|
|
cd $tmp || exit
|
|
|
|
# Logverzeichnis bereinigen, Logs aelter als 7 Tage werden geloescht.
|
|
writeLog "[I] Bereinige Logverzeichnis $logDir ..."
|
|
find $logDir -daystart -type f -mtime +7 -name \*updatePihole\*.log -exec rm -v {} \;
|
|
writeLog "[I] Logverzeichnis $logDir bereinigt."
|
|
|
|
# Variablen fuer Dateien
|
|
piholeDir=/etc/pihole
|
|
piholeBinDir=/usr/local/bin
|
|
gravityDB=$piholeDir/gravity.db
|
|
gravListPihole=$piholeDir/gravity.list
|
|
gravListBeforeUpdate=$tmp/gravity_before_update.list
|
|
gravListDiff=$tmp/gravity_diff.list
|
|
logStats=$logDir/updatePihole.stats.log
|
|
|
|
# Pihole 5.x?
|
|
[ -f $gravityDB ] && pihole5=1 || pihole5=0
|
|
|
|
# Variablen fuer "Gesundheitsstatus": -1: Undefiniert / 0: true / >0: false
|
|
rpiUpdateStatus=-1
|
|
piholeGravUpdateStatus=-1
|
|
dnsTestStatus=-1
|
|
inetTestStatus=-1
|
|
|
|
# *** Hilfsfunktionen ***
|
|
|
|
status() {
|
|
case "$*" in
|
|
-3)
|
|
echo "|> UPDATES VERFUEGBAR! <|"
|
|
;;
|
|
-2)
|
|
echo "KEINE UPDATES VERFUEGBAR"
|
|
;;
|
|
-1)
|
|
echo "NICHT UEBERPRUEFT"
|
|
;;
|
|
0)
|
|
echo "OK"
|
|
;;
|
|
1 | *)
|
|
echo "FEHLER #Exitcode:$*"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Internetverbindung testen
|
|
checkinet() {
|
|
writeLog "[I] Teste Internetverbindung ..."
|
|
if ! (ping -c1 -w1 8.8.8.8 >/dev/null) && ! (ping -c1 -w1 1.1.1.1 >/dev/null); then
|
|
writeLog "[E] Keine Internetverbindung! Das Script wird beendet!"
|
|
inetTestStatus=1
|
|
exit 1
|
|
fi
|
|
writeLog "[I] Internetverbindungstest erfolgreich."
|
|
inetTestStatus=0
|
|
return 0
|
|
}
|
|
|
|
# DNS-Namensaufloesung testen
|
|
checkdns() {
|
|
writeLog "[I] Teste DNS Namensaufloesung ..."
|
|
if ! (ping -c1 -w2 google.de >/dev/null) && ! (ping -c1 -w2 cloudflare.com >/dev/null); then
|
|
writeLog "[E] Keine DNS Namensaufloesung moeglich!"
|
|
dnsTestStatus=1
|
|
return 1
|
|
fi
|
|
writeLog "[I] DNS Namensaufloesung erfolgreich."
|
|
dnsTestStatus=0
|
|
return 0
|
|
}
|
|
|
|
# Auf DNS Service warten
|
|
waitfordns() {
|
|
writeLog "[I] Warte $1 Sek. auf DNS Service ..."
|
|
sleep "$1"
|
|
}
|
|
|
|
# *** Pi-hole Update ***
|
|
|
|
# Internetverbindung / DNS testen
|
|
checkinet # besteht keine Internetverbindung wird das Script mit exitcode 1 beendet
|
|
checkdns
|
|
|
|
# Nur wenn dieses Script Sonntags am Wochentag 0 ausgeführt wird:
|
|
# das Raspberry Paket Update simulieren.
|
|
if test "$(date "+%w")" -eq 0; then # Sonntags = Wochentag 0
|
|
# Raspberry Paketequellen updaten
|
|
writeLog "[I] Raspberry Paket Update simulieren ..."
|
|
echo ""
|
|
apt-get update
|
|
echo ""
|
|
|
|
# Raspberry Paketupdate simulieren
|
|
writeLog "[I] Ermitteln ob Paketupdates vorliegen ..."
|
|
tst=$(apt-get --simulate upgrade | grep ^Inst)
|
|
[ -n "$tst" ] && rpiUpdateStatus=-3 || rpiUpdateStatus=-2
|
|
|
|
# Raspberry Pakete bereinigen
|
|
writeLog "[I] Raspberry Pakete bereinigen ..."
|
|
echo ""
|
|
apt-get -y autoremove
|
|
apt-get -y clean
|
|
echo ""
|
|
fi
|
|
|
|
# *** Pi-hole Gravity Update ***
|
|
|
|
# AKtuelle Gravity Liste vom Pi-hole zwischenspeichern und
|
|
# Pi-hole Gravity aktualisieren
|
|
# Kompatiblitaet fuer Pihole 5.x
|
|
if [ "$pihole5" -eq 1 ]; then
|
|
writeLog "[I] Exportiere Domains aus $gravityDB nach $gravListBeforeUpdate ..."
|
|
sqlite3 "$gravityDB" "select distinct domain from gravity;" >$gravListBeforeUpdate
|
|
else
|
|
writeLog "[I] Kopiere $gravListPihole nach $gravListBeforeUpdate ..."
|
|
cp $gravListPihole $gravListBeforeUpdate
|
|
fi
|
|
writeLog "[I] Bereinge lokalen Pi-hole Blocklisten-Cache ..."
|
|
echo ""
|
|
ls $piholeDir/list.*.domains
|
|
rm $piholeDir/list.*.domains
|
|
echo ""
|
|
writeLog "[I] Aktualisiere Pi-hole Gravity ..."
|
|
echo ""
|
|
$piholeBinDir/pihole -g # Pi-hole Gravity aktualisieren
|
|
piholeGravUpdateStatus=$?
|
|
echo ""
|
|
writeLog "[I] Pi-hole Gravity Update exitcode: $piholeGravUpdateStatus"
|
|
|
|
# DNS nach Gravity Update testen
|
|
[ "$pihole5" -eq 0 ] && waitfordns 30 #waitfordns nach pihole -g nur bei Pihole Versionen < 5.x notwendig
|
|
if ! checkdns; then
|
|
waitfordns 30
|
|
if ! checkdns; then
|
|
writeLog "[E] Pi-hole DNS Service reagiert nicht, versuche RestartDNS ..."
|
|
$piholeBinDir/pihole restartdns
|
|
waitfordns 90
|
|
checkdns
|
|
fi
|
|
fi
|
|
|
|
# Aktualisierte Pi-hole Gravityliste mit Gravityliste vor der Aktualisierung
|
|
# vergleichen und Aenderungen (hinzugefuegte/geloeschte Eintraege) in
|
|
# $gravListDiff Datei zur weiteren Auswertung speichern
|
|
writeLog "[I] Erstelle Aenderungs-Gravityliste $gravListDiff ..."
|
|
# Kompatiblitaet fuer Pihole 5.x
|
|
if [ "$pihole5" -eq 1 ]; then
|
|
writeLog "[I] Exportiere Domains aus $gravityDB nach $tmp/gravity.list ..."
|
|
sqlite3 "$gravityDB" "select distinct domain from gravity;" >$tmp/gravity.list
|
|
gravListPihole=$tmp/gravity.list
|
|
fi
|
|
diff $gravListPihole $gravListBeforeUpdate | grep '[><]' >$gravListDiff
|
|
writeLog "[I] Aenderungs-Gravityliste mit $(grep -Evc '^#|^$' $gravListDiff) Eintraegen erstellt."
|
|
|
|
# *** Pi-hole Gravity Update Bericht/Statistik ***
|
|
|
|
# Id für Pi-hole Gravity Update Bericht erzeugen
|
|
id=$(date +"%Y.%m.%d-%H%M%S")
|
|
|
|
# Ermittle Pi-hole Status
|
|
if [[ "$($piholeBinDir/pihole status web 2>/dev/null)" == "1" ]]; then
|
|
phStatus="AKTIV"
|
|
else
|
|
phStatus="OFFLINE!"
|
|
fi
|
|
# Kompatiblitaet fuer Pihole 5.x
|
|
if [ "$pihole5" -eq 1 ]; then
|
|
writeLog "[I] Exportiere Blacklist, RegExlisten, Whitelist und Adlists aus $gravityDB nach $tmp ..."
|
|
sqlite3 "$gravityDB" "select domain from vw_blacklist;" >$tmp/blacklist.txt
|
|
blacklist=$tmp/blacklist.txt
|
|
sqlite3 "$gravityDB" "select domain from vw_regex_blacklist;" >$tmp/regex_blacklist.txt
|
|
regexblacklist=$tmp/regex_blacklist.txt
|
|
sqlite3 "$gravityDB" "select domain from vw_regex_whitelist;" >$tmp/regex_whitelist.txt
|
|
regexwhitelist=$tmp/regex_whitelist.txt
|
|
sqlite3 "$gravityDB" "select domain from vw_whitelist;" >$tmp/whitelist.txt
|
|
whitelist=$tmp/whitelist.txt
|
|
sqlite3 "$gravityDB" "select address from vw_adlist;" >$tmp/adlists.txt
|
|
adlists=$tmp/adlists.txt
|
|
else
|
|
blacklist=$piholeDir/blacklist.txt
|
|
regexblacklist=$piholeDir/regex.list
|
|
whitelist=$piholeDir/whitelist.txt
|
|
adlists=$piholeDir/adlists.list
|
|
fi
|
|
|
|
# Gravity Update Bericht erzeugen und in die unter $logStats angegebene Datei schreiben.
|
|
writeLog "[I] Erstelle Pi-hole Gravity Update Bericht/Statistik $id ..."
|
|
echo ""
|
|
(
|
|
echo "# Raspberry Info #"
|
|
echo ""
|
|
echo "Hostname: $(hostname)"
|
|
echo "RAM Nutzung: $(awk '/^Mem/ {printf("%.2f%%", 100*($2-$4-$6)/$2);}' <(free -m))"
|
|
echo "HDD Nutzung: $(df -B1 / 2>/dev/null | awk 'END{ print $5 }')"
|
|
echo "Paket Updates?: $(status $rpiUpdateStatus)"
|
|
echo ""
|
|
echo "# Pi-hole Info #"
|
|
echo ""
|
|
echo "Pi-hole Status: $phStatus"
|
|
echo "Internet: $(status $inetTestStatus)"
|
|
echo "DNS-Test: $(status $dnsTestStatus)"
|
|
echo "Gravity Update: $(status $piholeGravUpdateStatus)"
|
|
echo ""
|
|
echo "# Pi-hole Update Status #"
|
|
echo ""
|
|
$piholeBinDir/pihole -up --check-only
|
|
echo ""
|
|
echo "# Pi-hole Statistik #"
|
|
echo ""
|
|
echo "Domains Gravitylist: $(grep -Evc '^#|^$' $gravListPihole)"
|
|
echo "Domains Blacklist: $(grep -Evc '^#|^$' $blacklist)"
|
|
echo "RegEx Blacklist: $(grep -Evc '^#|^$' $regexblacklist)"
|
|
echo "Domains Whitelist: $(grep -Evc '^#|^$' $whitelist)"
|
|
# Kompatiblitaet fuer Pihole 5.x
|
|
if [ "$pihole5" -eq 1 ]; then
|
|
echo "RegEx Whitelist: $(grep -Evc '^#|^$' $regexwhitelist)"
|
|
fi
|
|
echo "Aktive Blocklisten: $(grep -Evc '^#|^$' $adlists)"
|
|
echo ""
|
|
echo "# Pi-hole Gravity Updatestatistik #"
|
|
echo ""
|
|
echo "(+): $(grep -c '<' $gravListDiff) Domains hinzugefuegt"
|
|
echo "(-): $(grep -c '>' $gravListDiff) Domains geloescht"
|
|
echo "(S): $(grep -Evc '^#|^$' $gravListDiff) Domains geaendert"
|
|
) | tee $logStats #Ausgaben innerhalb von () in die $logStats Datei schreiben
|
|
echo ""
|
|
writeLog "[I] Pi-hole Gravity Update Bericht/Statistik $logStats erstellt."
|
|
|
|
# *** E-Mail Versand des Update Berichtes ***
|
|
|
|
# Aufrufparameter 1: sudo ./updatePihole.sh name@domain.xy
|
|
email="$1"
|
|
|
|
# Mail mit Gravity Update Bericht wird nur versendet wenn beim Aufruf des Scriptes eine
|
|
# Mailadresse mit uebergeben wurde!
|
|
if [ -n "$email" ]; then
|
|
writeLog "[I] E-Mail Pi-hole Gravity Update Bericht $id wird an $email versendet ..."
|
|
mail <$logStats -s "Pi-hole Gravity Update Bericht $id" "$email"
|
|
|
|
# Pruefen ob der E-Mailversand fehlgeschlagen ist
|
|
if [ $? -ne 0 ]; then
|
|
writeLog "[E] E-Mailversand an $email fehlgeschlagen!"
|
|
else
|
|
writeLog "[I] E-Mailversand an $email erfolgreich."
|
|
fi
|
|
fi
|
|
|
|
# Temp-Verzeihnis bereinigen
|
|
writeLog "[I] Bereinige $tmp"
|
|
rm -rf $tmp
|
|
|
|
writeLog "[I] Ende | Logfile: $log"
|