Netzwerk Ausfallerkennung und automatischer Neustart
Im Beitrag VoIP Video Türsprechanlage mit dem Raspberry und DoorPI beschreibe ich bereits die Einrichtung eines Watchdogs, welcher autoamtisiert Dienste überwacht und eigenständig neu startet, sobald Probleme erkannt wurden.
Da unser DoorPI Raspberry jedoch per WLAN angebunden ist, hatte ich in den letzten Monaten vermehrt festgestellt, dass diese ab und an wegbrach.
Auch kam der Raspberry dann nicht mehr eigenständig ins Netzwerk zurück und somit war die komplette Türanlage offline.
Ohne irgendwelche Hinweise bekamen wir dadurch nicht mit, wenn jemand geläutet hatte.
Aus diesem Grund habe ich ein eigenes kleines Bash Skript network.sh mit folgendem Inhalt geschrieben:
#!/bin/bash
# Check if network is connected and restart if not.
# @author Roland Meier
today=`date +"%Y%m%d_%H%M"`
ping -c4 192.168.XXX.XXX > /dev/null
if [ $? != 0 ]
then
echo $today: "No network available... Reboot" >> /var/log/reboot.log
sudo /sbin/shutdown -r now
fi
Als erstes ermittle ich das aktuelle Datum und die Uhrzeit und schreibe dies in die Variable $today.
Anschließend folgen 4 Pings zur IP-Adresse meiner Fritzbox.
Bei fehlendem Netzwerk schreibt mir das Script diese Info in eine dafür erstellte reboot.log Datei im /var/log Verzeichnis.
Zuletzt führt es einen Neustart durch.
Das Skript habe ich mit:
chmod +x network.sh
ausführbar gemacht.
Anschließend noch einen Cronjob dafür erstellt, welcher alle 10 Minuten das Skript ausführt:
crontab -e
*/10 * * * * /usr/bin/sudo -H /PFAD-ZUM-SKRIPT/network.sh
service cron restart
Das Testen des Skripts ist etwas tricky, vor allem was den Neustart angeht, aber machbar. Eigentlich muss nur die IP-Adresse in eine nicht verfügbare Adresse geändert werden.
Dann auf die Uhr sehen wann der nächste Cronjob kommt, kurz nach diesem sollte die Konsole des Raspberries keine Reaktion mehr zeigen, schließlich ging er offline durch den Restart.
Benachrichtigung über Änderung der Logdatei
Damit ich über eventuelle Neustarts auch informiert werde, installiere ich Postfix und richte ihn ein, damit er vom lokalen Netzwerk aus eine Email senden kann:
apt install postfix
- Satellitensystem
- SMTP-Releay-Server eintragen z.B. smtp.gmail.de:587
Der vollständigkeit halber habe ich noch weitere Dateien erstellt:
/etc/postfix/recipient_bcc
# ohne Inhalt
/etc/postfix/recipient_canonical
root
/etc/postfix/sasl_passwd
smtp.gmail.de:587 :PASSWORT
/etc/postfix/sender_bcc
/etc/postfix/sender_canonical
/.+/
/etc/postfix/smtp_header_checks
# Append the hostname to the email subject
/^Subject: (.*)/ REPLACE Subject: [HOSTNAME-VOM-RASPBERRY] ${1}
/etc/postfix/transport
HOSTNAMEfilter:
Diese habe ich auch alle in die /etc/postfix/main.cf eingetragen:
relayhost = smtp.gmail.de:587
sender_canonical_maps = regexp:/etc/postfix/sender_canonical
sender_bcc_maps = hash:/etc/postfix/sender_bcc
recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_mechanism_filter =
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
transport_maps = hash:/etc/postfix/transport
Anschließend wurde Postfix neu gestartet und es konnte erfolgreich eine Testmailverschickt werden:
service postfix restart
echo "Dies ist ein Test." | mailx -s "Hallo Test"
Nun stellt sich natürlich die Frage, wann genau soll ich denn informiert werden?
Vom Skript, wenn keine Netzwerkverbindung erkannt wurde geht ja schlecht...
Eine Lösung wäre einfach eine Nachricht, wenn der Raspberry neu gestartet hat.
Dafür bearbeite ich die /etc/rc.local wie folgt:
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
printf "Raspberry rebooted..." | mailx -s "Raspberry Reboot"
fi
Die Abfrage selbst war bereits in der rc.local enthalten, sowie dem ersten Printf mit der IP-Adresse.
Ich habe lediglich den 2. Printf mit dem Mailversand hinzugefügt.
Durch die Abfrage wird die Mail erst verschickt, nachdem eine Verbindung vorhanden ist.
Ein Test mit einem Reboot hatte auch funktioniert.
SD-Karte durch Reduzierung der Schreibzugriffe entlasten
Es ist bekannt, dass SD Karten nur begrenzte Lese und vor allem Schreibzugriffe haben. Linux schreibt jedoch von sich aus unzählige Einträge ständig in seine Logdatein oder lagert Dateien in den Swap aus, sofern der RAM nicht mehr ausreicht.
Deshalb möchte ich hier einige Maßnahmen ergreifen, um die Schreibzugriffe zu reduzieren.
Linux Swap Partition deaktivieren
In meinem Fall ist Swap mit 99MB aktiv, zum aktuellen Status aber nicht genutzt und auch der RAM (Mem) ist noch weit von einem Überlauf entfernt:
Da bei mir ein Raspbian Jessie läuft, kann ich den Swap wie folgt deaktivieren:
dphys-swapfile swapoff
systemctl disable dphys-swapfile
apt-get purge dphys-swapfile
Nach einem Neustart ist der Swap Bereich deaktiviert:
Log & Run in den RAM verschieben
Die wohl wirksamere Methode ist jedoch das Log und Run Verzeichnis in den RAM zu verschieben. Da ich wie oben im Laufenden Betrieb über 800MB übrig habe, mounte ich die beiden Verzeichnisse mit je 20MB in den RAM:
mcedit /etc/fstab
none /var/log tmpfs size=20M,noatime 0 0
none /var/run tmpfs size=20M,noatime 0 0
Nach einem Neustart sollten die Dateien dann im Arbeitsspeicher sein, was natürlich auch zur Ursache hat, dass sie nach einem Raspberry Neustart weg sind!
SD-Karte einmalig auf der NAS Freigabe sichern
Als erstes möchte ich meine Backup-Freigabe vom NAS auf dem Raspberry per NFS einbinden.
Bei mir war der Dienst nfs-common bereits installiert, sollte dies nicht der Fall sein kann er wie folgt installiert werden:
apt install nfs-common
Anschließend habe ich im /media Ordner einen Freigabeordner erstellt, in welchem ich diese mounten möchte:
mkdir /media/nas
Mit folgendem Befehl kann ich die genauen Freigaben von der NAS-IP Adresse auslesen:
showmount -e 192.168.178.XXX
Dann kann der gewünschte Ordner eingehängt werden:
mount -t nfs -o rw,soft,nolock 192.168.178.XXX:/export/backup /media/nas
Natürlich könnt Ihr auch einen USB-Stick anhängen und hier das Backup draufspielen, da gibt es viele Wege.
Zuletzt kann dann mit folgendem Befehl die komplette SD Karte in eine IMG-Datei gesichert werden:
dd if=/dev/mmcblk0 of=/media/nas/meinbackup_$(date +%Y%m%d-%H%M%S).img bs=1MB
Wenn keine Fehler erscheinen sollte das Image korrekt angelegt worden sein:
Im Fall der Fälle kann dann diese Imagedatei auf eine neue SD Karte kopiert werden.
Sinnvoll ist es natürlich umgehend nach dem Backup dies auch zu überprüfen, um nicht im wirklichen Notfall dann feststellen zu müssen, dass während dem Backup und/oder der Wiederherstellung ein Fehler gemacht wurde und die Sicherung gar nicht funktioniert:
dd if=/PFAD-ZUM-BACKUP/BACKUPNAME.img of=/dev/sda bs=1MB
In der Regel wird die SD-Karte auf einem anderen PC wieder hergestellt, insofern wird es hier einen anderen Pfad zu dem Backup geben, auch könnte das Device, hier habe ich SDA verwendet je nach Geräte ein anderes sein!
Mit einem Cronjob und einer eigenen Skriptdatei, könnte der Sicherungsprozess auch automatisiert werden.
Hierfür ist natürlich zu Sorgen, dass die NAS-Freigabe fest eingebunden ist und nicht wie hier nach dem nächsten Neustart verschwindet.