Freetz-NG: Mail-basierte Alarmierung und Fernsteuerung mit checkmaild, stunnel und BusyBox-Scripten incl Versand von Videos einer WebCam

John Paden

Neuer User
Mitglied seit
4 Dez 2018
Beiträge
47
Punkte für Reaktionen
1
Punkte
8
Preface:

Die Umsetzung und alle Tests wurden auf einer realen FB4050 mit Freetz-NG durchgeführt.

ChatGPT wurde zur Strukturierung, Dokumentation, Fehlersuche und Code-Unterstützung verwendet.

Die ersten Beiträge dieses Threads wurden zu 100% von ChatGPT formuliert und fassen (hoffentlich vollständig) zusammen, was in etwa zwei Tagen Entwicklungs- und Testarbeit entstanden ist.

Das Ergebnis läuft produktiv und ist für mich sehr zufriedenstellend. Es gibt aber sicherlich noch Möglichkeiten zur Verbesserung und Weiterentwicklung.

Tippfehler, Copy-&-Paste-Fehler und kleine Unstimmigkeiten sind natürlich von mir. ;-)

======================

Freetz-NG: Kamera-Videoclips automatisch per Mail versenden mit checkmaild und stunnel​

Ziel​

Ich wollte eine Freetz-NG-Fritzbox dazu verwenden, automatisch Videoclips einer IP-Kamera per E-Mail zu versenden.

Randbedingungen:

  • kein <span>ffmpeg</span>
  • keine zusätzliche Mailsoftware
  • möglichst wenig Ressourcenverbrauch
  • kompatibel mit BusyBox-Umgebung
  • Versand über verschlüsseltes SMTP
  • bei erfolgreichem Versand Datei löschen
  • bei Fehler Datei behalten und später erneut versuchen
Getestet wurde das Setup mit:

  • Fritzbox FB4050
  • Freetz-NG
  • BusyBox
  • USB-Speicher über FritzNAS/FTP
  • SMTP-Anbieter mit Port 465
Andere Fritzbox-Modelle sollten prinzipiell funktionieren, benötigen aber eventuell angepasste Pfade oder Pakete.


Architektur​

Die Kamera schreibt ihre Clips auf den USB-Speicher der Fritzbox.

Beispiel:

<span>/var/mod/root/usbdevice/ftp/<br><br>└── 20260716/<br> └── record/<br> ├── A260716_092128_092142.264<br> └── A260716_092303_092317.264</span>
Ein Cronjob startet regelmäßig ein Script:

<span>IP-Kamera<br> |<br> v<br>USB-Speicher Fritzbox<br> |<br> v<br>cammail.sh<br> |<br> v<br>stunnel<br> |<br> v<br>SMTP Server<br> |<br> v<br>E-Mail mit Videoanhang</span>

Warum stunnel?​

Die vorhandene Freetz-NG-Umgebung konnte SMTP nicht direkt mit SSL/TLS.

Deshalb wurde stunnel als lokaler TLS-Wrapper verwendet:

<span>cammail.sh<br> |<br> | SMTP Klartext lokal<br> |<br>127.0.0.1:1465<br> |<br> | TLS<br> |<br>smtp.provider.de:465</span>
Das Script selbst benötigt dadurch keine TLS-Funktionalität.


Verzeichnisstruktur​

Alle dauerhaften Dateien liegen unter <span>/tmp/flash</span>.

Beispiel:

<span>/tmp/flash/<br><br>├── checkmaild/<br>│ └── smtp.conf<br>│<br>└── cammail/<br> ├── cammail.sh<br> └── sent.log</span>
Wichtig:

<span>/var/mod</span> ist bei Freetz-NG nicht der richtige Ort für dauerhafte Dateien.


SMTP-Konfiguration​

Datei:

<span>/tmp/flash/checkmaild/smtp.conf</span>
Beispiel:

<span>SMTP_USER="[email protected]"<br>SMTP_PASS_B64="Base64Passwort"<br>BOX_MAIL="[email protected]"<br>ADMIN_MAIL="[email protected]"</span>
Das Passwort liegt nicht direkt im Script.


cammail.sh​

Das Script macht:

  1. Lock setzen
  2. SMTP-Konfiguration laden
  3. fertige Kamera-Clips suchen
  4. Clip als MIME-Mail versenden
  5. bei Erfolg löschen
  6. Fehler über Syslog melden

Lock-Mechanismus​

Der Lock wird absichtlich unter <span>/tmp</span> angelegt.

Beispiel:

<span>/tmp/flash/cammail.lock</span>
Der Lock wird nicht persistent gespeichert.

Grund:

Ein Stromausfall oder Neustart darf keinen alten Lock hinterlassen.

Verwendet wird:

<span>mkdir "$LOCKDIR"</span>
weil <span>mkdir</span> atomar ist.

Wenn bereits ein Prozess läuft:

<span>cammail: already running - exit</span>

Auswahl der Videodateien​

Gesucht werden:

<span>*.264<br>*.265</span>
Nur Dateien, die älter als eine definierte Zeit sind, werden verarbeitet.

Beispiel:

<span>MAX_AGE=120</span>
Damit wird verhindert, dass gerade noch geschriebene Dateien verschickt werden.


Versand​

Die Datei wird nicht konvertiert.

Der Originalclip bleibt erhalten:

<span>264<br>265</span>
und wird direkt als MIME-Anhang verschickt:

<span>Content-Type:<br>application/octet-stream<br><br>Content-Transfer-Encoding:<br>base64</span>
Damit entstehen keine zusätzlichen CPU-Lasten durch Video-Konvertierung.


Erfolgs- und Fehlerverhalten​

Erfolgreicher Versand​

Beispiel Log:

<span>cammail: sent A260716_092128_092142.264<br>cammail: deleted A260716_092128_092142.264</span>
Danach wird die Datei gelöscht.


Fehler​

Beispiel:

  • SMTP nicht erreichbar
  • TLS Fehler
  • Netzwerkproblem
Dann:

<span>cammail: send failed A260716_092128_092142.264</span>
Die Datei bleibt erhalten.

Beim nächsten Cron-Lauf wird erneut versucht.


Cronjob​

Beispiel:

Alle 5 Minuten:

<span>*/5 * * * * nice -n 10 /tmp/flash/cammail/cammail.sh</span>
<span>nice</span> reduziert die CPU-Priorität.

Die Fritzbox soll weiterhin bevorzugt:

  • Routing
  • WLAN
  • Telefonie
bedienen.


Logging​

Es wird kein eigenes Debug-Log geführt.

Alle Meldungen gehen über:

<span>logger -t cammail</span>
Anzeige:

<span>logread | grep cammail</span>
Vorteile:

  • zentrale Fritzbox-Logs
  • keine zusätzlichen Dateien
  • einfache Integration in weitere Überwachungsfunktionen

Sicherheit gegen Datenverlust​

Die wichtigste Designentscheidung:

Eine Datei wird erst gelöscht, wenn der SMTP-Server den Versand bestätigt.

Ablauf:

<span>Datei vorhanden<br><br> |<br> v<br><br>SMTP Versand<br><br> |<br> +---- Fehler<br> | |<br> | v<br> | Datei bleibt<br> |<br> v<br><br>250 OK vom SMTP Server<br><br> |<br> v<br><br>Datei löschen</span>

Mögliche Erweiterungen​

Noch nicht umgesetzt:

  • automatische Bereinigung leerer Kamera-Tagesordner
  • Statusmail bei Fehlern
  • mehrere Kameras
  • maximale Mailgröße
  • Überwachung des USB-Mounts
  • Alarmprioritäten

Erfahrungen​

Die wichtigsten Punkte bei diesem Projekt:

  • Freetz-NG-Pfade beachten:
    • persistent: <span>/tmp/flash</span>
    • flüchtig: <span>/var/mod</span>
  • Locks nicht persistent machen
  • Fehlerfälle zuerst planen
  • keine Datei löschen, bevor der Erfolg sicher ist
  • Syslog statt eigener Logdateien verwenden
  • möglichst kleine BusyBox-kompatible Shell-Scripte einsetzen
Das Ergebnis ist eine kleine, ressourcenschonende Kamera-Alarmierung direkt auf der Fritzbox ohne zusätzlichen Server.
 

Anhänge

Zuletzt bearbeitet:

Integration in checkmaild und stunnel​

Warum checkmaild?​

Freetz-NG bringt mit checkmaild einen einfachen Mechanismus mit, um eingehende Mails zu überwachen und Aktionen auszuführen.
In diesem Projekt wurde checkmaild ursprünglich verwendet für:
  • Statusabfragen der Fritzbox
  • Fernsteuerung (z.B. Reboot)
  • Ausführen definierter Aktionen über Mailbefehle
Die vorhandene Infrastruktur wurde erweitert, so dass dieselbe SMTP-Konfiguration auch für den Versand von Kamera-Clips genutzt werden kann.
Beispiel:
Code:
E-Mail an Fritzbox
        |
        v
checkmaild
        |
        v
Aktion ausführen
        |
        v
Statusmail / Alarmfunktion

SMTP-Versand über stunnel​

Problem​

Viele Mailprovider erlauben keinen unverschlüsselten SMTP-Versand.
Typische Anforderungen:
  • SMTP Submission
  • TLS
  • Authentifizierung
Die BusyBox-Umgebung der Fritzbox bietet dafür keine komfortable Mailsoftware.
Deshalb übernimmt stunnel die TLS-Schicht.

Aufbau​

Die Lösung verwendet zwei lokale Ports:
Code:
checkmaild / cammail.sh

        |
        | SMTP lokal ohne TLS
        |
        v

127.0.0.1:1465

        |
        | stunnel
        |
        v

smtp.provider.de:465
        |
        v

Mailserver
Der Vorteil:
  • cammail.sh bleibt sehr klein
  • keine TLS-Bibliothek im Script notwendig
  • vorhandene Freetz-NG-Komponenten werden genutzt

stunnel-Konfiguration​

Beispiel:
Code:
[cammail-smtp]

accept  = 127.0.0.1:1465
connect = smtp.provider.de:465

client = yes

verifyChain = yes
checkHost = smtp.provider.de
CAfile = /etc/ssl/certs/ca-bundle.crt
Der genaue Mailservername muss natürlich an den eigenen Provider angepasst werden.

POP3/SMTP-Konfiguration von checkmaild​

Für den Mailabruf kann ebenfalls stunnel verwendet werden.
Beispiel:
Code:
lokal:

127.0.0.1:1110

        |
        v

POP3 SSL Port 995
Damit kann checkmaild POP3 verwenden, obwohl der Provider nur verschlüsselte Verbindungen erlaubt.

Gemeinsame SMTP-Konfiguration​

Damit nicht mehrere Stellen gepflegt werden müssen, verwenden beide Funktionen dieselben Zugangsdaten:
Datei:
/tmp/flash/checkmaild/smtp.conf
Beispiel:
Code:
SMTP_USER="[email protected]"
SMTP_PASS_B64="Base64Passwort"

BOX_MAIL="[email protected]"
ADMIN_MAIL="[email protected]"
Diese Datei wird geladen von:
  • checkmaild-Aktionen
  • cammail.sh

SMTP-Dialog in cammail.sh​

Das Script spricht absichtlich nur SMTP:
Code:
EHLO
AUTH LOGIN
MAIL FROM
RCPT TO
DATA
QUIT
und verbindet sich mit:
nc 127.0.0.1 1465
Die TLS-Verschlüsselung übernimmt vollständig stunnel.

Test und Fehlersuche​

stunnel prüfen:
logread | grep stunnel
SMTP-Verbindung prüfen:
nc 127.0.0.1 1465
Erwartete Antwort:
220 smtp.server ...
cammail prüfen:
logread | grep cammail
checkmaild prüfen:
logread | grep CheckMailD

Warum diese Trennung sinnvoll ist​

Die Aufgaben bleiben getrennt:
AufgabeKomponente
Mail empfangencheckmaild
Mailbefehle auswertencheckmaild
TLS-Verschlüsselungstunnel
Kamera-Dateien findencammail.sh
Video-Mail erzeugencammail.sh
SMTP-Versandstunnel + SMTP-Server
Dadurch kann jede Komponente einzeln getestet werden.
 

Anhänge

Besonderheit bei Freetz-NG: stunnel Start über rc.custom​

Bei Freetz-NG kann es vorkommen, dass die automatisch erzeugte stunnel-Konfiguration Einträge für ein Server-Zertifikat enthält:

<span>cert = ...<br>key = ...</span>
Diese Einstellungen sind für einen stunnel-Server gedacht.

Für den hier verwendeten Fall arbeitet stunnel jedoch als Client:

<span>Fritzbox<br> |<br> | TLS Client<br> |<br>stunnel<br> |<br> |<br>SMTP Server</span>
Dafür werden keine lokalen Zertifikate benötigt.

Die vorhandenen Zeilen müssen deshalb vor dem Start entfernt werden.

Beispiel <span>rc.custom</span>:

<span>logger -t rc.custom "START"<br><br>logger -t rc.custom "Removing stunnel cert/key"<br><br>sed -i '/^cert = /d;/^key = /d' \<br> /var/mod/etc/stunnel.conf<br><br>logger -t rc.custom "Starting stunnel manually"<br><br>stunnel /var/mod/etc/stunnel.conf<br><br>logger -t rc.custom "FINISHED"</span>
Nach dem Start kann geprüft werden:

<span>logread | grep rc.custom</span>
Beispiel:

<span>rc.custom: START<br>rc.custom: Removing stunnel cert/key<br>rc.custom: Starting stunnel manually<br>rc.custom: FINISHED</span>
Wichtig:

Der Start muss nach der Freetz-NG-Initialisierung erfolgen, da die stunnel-Konfiguration erst dann vorhanden ist.

Zusätzlich muss bei USB-basierten Anwendungen berücksichtigt werden, dass USB-Mounts und Dienste eventuell noch nicht vollständig verfügbar sind. Deshalb können bei Bedarf Wartezeiten bzw. Prüfungen ergänzt werden.
 
rc.custom

logger -t rc.custom "START"
logger -t rc.custom "Removing stunnel cert/key"
sed -i '/^cert = /d;/^key = /d' /var/mod/etc/stunnel.conf

logger -t rc.custom "Starting stunnel manually"
stunnel /var/mod/etc/stunnel.conf

logger -t rc.custom "FINISHED"


logger -t rc.custom "Waiting for USB storage"

(
for i in 1 2 3 4 5 6 7 8 9 10
do
if [ -d /var/media/ftp/Intenso-PremiumLine-01/ftp ]
then
break
fi

sleep 5
done

if [ -d /var/media/ftp/Intenso-PremiumLine-01/ftp ]
then
ln -sf /var/media/ftp/Intenso-PremiumLine-01 /var/mod/root/usbdevice
logger -t rc.custom "usbdevice link created"
else
logger -t rc.custom "USB storage not found"
fi
) &


logger -t rc.custom "FINISHED"
 
Erweiterung: Fritzbox-Fernsteuerung mit checkmaild und sicheren Mailaktionen

Ergänzung zu den vorherigen Beiträgen:

Nachdem die Mail-Infrastruktur mit checkmaild und stunnel aufgebaut war, wurde dieselbe Basis auch für eine einfache Fernsteuerung der Fritzbox verwendet.

Die Idee:

Die Fritzbox kann über eine normale E-Mail kontrollierte Aktionen ausführen, ohne dass ein zusätzlicher Server oder eine Cloud-Lösung notwendig ist.

Die Umsetzung läuft vollständig auf der Fritzbox mit Freetz-NG.

====================================

Ziel​

Mögliche Aktionen:

  • Statusinformationen abrufen
  • definierte Wartungsaktionen ausführen
  • kontrolliert einen Neustart auslösen
Die Mail dient dabei nur als Transportweg.

Es werden keine freien Shell-Befehle per Mail ausgeführt.

====================================

Architektur​

Aufbau:

<span>E-Mail<br> |<br> v<br>Mailserver<br> |<br> v<br>checkmaild<br> |<br> v<br>mailactions<br> |<br> +---- definierte Aktion<br> |<br> +---- optional Antwortmail</span>
Die bestehende stunnel-Konfiguration wird weiter verwendet:

<span>checkmaild / cammail.sh<br><br> |<br> | lokales SMTP / POP3<br> |<br> v<br><br> stunnel<br><br> |<br> | TLS<br> |<br> v<br><br> Mailprovider</span>
Damit bleiben die Anwendungen selbst klein und müssen keine TLS-Funktionalität enthalten.

====================================

Warum checkmaild?​

Freetz-NG bringt mit checkmaild bereits einen Mechanismus mit, um Mailkonten zu überwachen und Aktionen auszuführen.

Dadurch kann eine vorhandene Mailbox als Steuerkanal genutzt werden.

Vorteile:

  • kein zusätzlicher Server notwendig
  • keine Portfreigabe zur Fritzbox erforderlich
  • geringer Ressourcenverbrauch
  • vorhandene Freetz-NG-Komponenten werden genutzt
====================================

Sicherheitsprinzip​

Eine Mailsteuerung muss verhindern, dass Nachrichten mehrfach verarbeitet werden.

Beispiel:

Eine Reboot-Mail darf nicht bei jedem weiteren Mailabruf erneut einen Neustart auslösen.

Daher wird die Verarbeitung bereits bearbeiteter Nachrichten gespeichert:

<span>/tmp/flash/checkmaild/processed.uid</span>
Ablauf:

<span>Neue Mail<br> |<br> v<br>UID prüfen<br> |<br> +---- bereits verarbeitet<br> | |<br> | v<br> | ignorieren<br> |<br> +---- neu<br> |<br> v<br> Aktion ausführen<br> |<br> v<br> UID speichern</span>
Damit bleibt die Aktion auch nach Neustarts nachvollziehbar.

====================================

Beispiel: Neustart per Mail​

Eine definierte Mailaktion kann beispielsweise einen Neustart auslösen.

Ablauf:

<span>E-Mail mit definiertem Kommando<br><br> |<br> v<br><br>checkmaild erkennt Nachricht<br><br> |<br> v<br><br>UID-Prüfung<br><br> |<br> v<br><br>mailactions führt definierte Aktion aus<br><br> |<br> v<br><br>Fritzbox startet neu</span>
Wichtig:

Die Aktion ist fest im Script hinterlegt.

Es gibt keine direkte Ausführung von Mailinhalt als Shell-Kommando.

====================================

Gemeinsame Konfiguration​

Die Mailzugänge werden zentral gehalten:

<span>/tmp/flash/checkmaild/smtp.conf</span>
Beispiel:

<span>SMTP_USER="[email protected]"<br>SMTP_PASS_B64="BASE64_ENCODED_PASSWORD"<br><br>BOX_MAIL="[email protected]"<br>ADMIN_MAIL="[email protected]"</span>
Diese Konfiguration kann von mehreren Funktionen verwendet werden:

  • checkmaild
  • cammail.sh
  • weitere Mailaktionen
====================================

Logging​

Wie bei der Kamera-Funktion werden keine eigenen Logdateien erzeugt.

Die Ausgabe läuft über Syslog:

<span>logger -t checkmaild</span>
bzw.

<span>logread | grep checkmaild</span>
Vorteile:

  • zentrale Freetz-NG-Logs
  • keine zusätzlichen Dateien
  • einfache Fehlersuche
====================================

Typische Fehlerfälle​

Bei Mailsteuerungen sind insbesondere diese Punkte wichtig:

  • Mail wird mehrfach abgeholt
  • Aktion wird doppelt ausgeführt
  • Mailserver hält Nachrichten zurück
  • Netzwerkverbindung bricht während der Verarbeitung ab
Die UID-Verarbeitung verhindert dabei Mehrfachausführung.

====================================

Warum diese Lösung interessant ist​

Die Kombination aus:

  • Freetz-NG
  • checkmaild
  • stunnel
  • BusyBox-Shell
  • Syslog
ergibt eine einfache, aber flexible Steuerplattform.

Die gleiche Infrastruktur kann genutzt werden für:

  • Kameraalarme
  • Statusmeldungen
  • Wartungsaktionen
  • kontrollierte Fernsteuerung
ohne zusätzlichen Rechner im Netzwerk.

====================================

Erfahrungen​

Die wichtigsten Punkte:

  • Mail als Steuerkanal ist überraschend robust
  • TLS sollte von stunnel übernommen werden
  • Aktionen sollten immer explizit definiert sein
  • Wiederholungsschutz ist zwingend notwendig
  • Syslog erleichtert die Fehlersuche erheblich
Damit wird die Freetz-NG-Fritzbox nicht nur zum Mailversender für Kameraalarme, sondern zu einem kleinen eigenständigen Überwachungs- und Wartungssystem.
 
Die BusyBox-Umgebung der Fritzbox bietet dafür keine komfortable Mailsoftware.
Das muss sie auch nicht - es gibt ein AVM-Binary für diese Aufgaben, welches auch bei den ganzen Pushmail-Services des FRITZ!OS zum Einsatz kommt.

Zu finden ist dieses unter dem Pfad /sbin/mailer und welche Parameter es kennt, verrät ein Aufruf mit dem (bei AVM üblichen) -? - das Binary versteht sich sowohl auf Mails mit "attachments" (also auch auf die dazu notwendigen "boundaries" in "multipart/mixed"-Messages), als auch auf die Authentifizierung bei einem Mail-Server, auch mit TLS.

Und es wird auch von den AVM-Komponenten selbst genutzt, sowie es um den SMTP-Versand geht, von Fax-Dokumenten über AB-Nachrichten bis zu den Status-Mails und zu der Zustellung gesicherter Einstellungen per Mail:
Rich (BBCode):
# grep -r "/sbin/mailer"
grep: lib/libfaxsend.so.1.0.0: binary file matches
grep: lib/libmailbuilder.so.0.0.0: binary file matches
grep: lib/libemailservice.so.0.0.0: binary file matches
grep: usr/share/ctlmgr/libconfigd.so: binary file matches
grep: usr/share/telefon/libtam.so.1.0.0: binary file matches
grep: usr/bin/faxd: binary file matches
grep: usr/bin/telefon: binary file matches
grep: usr/bin/dect_manager: binary file matches
Daher kann man auch davon ausgehen, dass dieses Binary bei AVM/FRITZ! nicht so ohne weiteres verschwinden wird - man kann also die gesamte Logik in der Funktion send_video_mail() in cammail.sh noch deutlich vereinfachen und vor allem reagiert m.W. das mailer-Binary auch direkt auf Protokoll-Fehler in der SMTP-Konversation, während hier die verwendete Logik mit printf und netcat (bzw. nc) lediglich irgendwann das Ergebnis auswerten kann - und auch da ist das vorliegende Skript (nach meiner Meinung, die man nicht teilen muss) nicht ganz korrekt.

Nach SMTP-RFC können auch andere im Rahmen eines SMTP-Dialogs ausgeführte Kommandos mit "250 OK" quittiert werden (https://www.rfc-editor.org/rfc/rfc5321.html - siehe Anhang D.1. für einen Beispiel-Dialog) - auch ein simples "RCTP TO" oder ein "MAIL FROM", so dass die Existenz einer solchen Zeile eben KEIN (sicheres) Anzeichen dafür ist, dass die Mail tatsächlich gesendet wurde. Wenn ich das richtig sehe, würde aber das verwendete grep-Kommando nach dem nc-Aufruf auch darauf "anspringen" und von einem erfolgreichen Versand ausgehen.

Diese "Fehlerbehandlung" dürfte also nur bei ganz bestimmten Fehlern überhaupt funktionieren - nämlich dann, wenn da gar kein wirklicher Dialog zustande kommt, weil z.B. der Mail-Server gar nicht erreichbar ist. Auch muss eine positive Quittung für den Erhalt einer Nachricht (und damit die Übernahme der Verantwortung für deren Weitertransport durch den Server-MTA) nicht zwingend mit "250" beginnen (s. RFC Abschnitt 4.2.5) und schon gar nicht muß jeder(!) Server den gesuchten Text Requested mail action okay, completed ... in einer positiven Quittung auf DATA verwenden. Das Skript mag also gegen den hier zum Test verwendeten SMTP-Server funktionieren (der stunnel ist ja lediglich ein Wrapper, die Kommunikation erfolgt mit dem SMTP-Server), aber es ist damit ziemlich sicher nicht universell einsetzbar, mal ganz abgesehen von den zusätzlich vorhandenen 250 OK-Quittungen in einem "normalen" SMTP-Dialog.

So mag das zwar eine "quick & dirty"-Umsetzung einer (blinden) Kommunikation mit einem SMTP-Server sein, aber von einer echten Fehlerbehandlung kann kaum die Rede sein - außerdem dürfte diese ohne eine passende State-Machine (Du kannst ja mal mit
Code:
Generiere mir eine "state machine" (aka finiter Automat) für einen SMTP-Client zum Versand von Mail-Inhalten per SMTP. 
Zeige alle verwendeten Kommandos, vom HELO bzw. EHLO bis zum Senden per DATA und dem Verarbeiten der Quittung
nach dem Ende der Übertragung der Daten.
in Deinem KI-Tool Dir eine Vorstellung verschaffen, wie so etwas aussehen sollte - dabei wirst Du bemerken, dass die Quittungen des Servers immer nur im Kontext des damit quittierten Kommandos einen Sinn ergeben) auch nur sehr "stümperhaft" bleiben (und das beziehe bitte nicht auf Dich, eher auf die KI, die bei der Implementierung geschlampt hat).

Meines Wissens kann man mit dem AVM-Utility all diesen Problemen aus dem Weg gehen - ja, es kann (aus dem Gedächtnis und nicht zwingend auch noch für aktuelle Versionen gültig) sogar jedes der gängigen Verfahren (ohne TLS, mit TLS und mit STARTTLS zum Umschalten auf eine verschlüsselte Verbindung nach Kontaktaufnahme im Klartext - basierend auf dem angesprochenen Port am Server) verwenden und man ist nicht per se auf SMTPS bzw. "submissions" (well known port 465 nach RFC 8314 - https://datatracker.ietf.org/doc/html/rfc8314) festgelegt - nicht jedes SMTP-Relay unterstützt das auch für die Einlieferung von Mails durch Client-MTAs. Wenn man tatsächlich mit einem SMTP-Server umgehen muß, der Einlieferungen nur auf Port TCP 587 mit STARTTLS-Kommando akzeptiert, dann guckt man mit der vorhandenen Implementierung auch schon in die Röhre - alles nur deshalb, weil man den Dialog und die Fehlerbehandlung nicht jemandem überläßt, der sich damit deutlich besser auskennt und obendrein auch noch andere AUTH-Verfahren als LOGIN beherrschen sollte (abgesehen davon, dass man in einer ohnehin per TLS gesicherten Verbindung auch gar kein LOGIN und damit keine Base64-Kodierung bräuchte und gleich PLAIN nehmen kann, wenn der Server das anbietet). Die (KI-)Feststellung:
Das Passwort liegt nicht direkt im Script.
ist ohnehin auch nur Augenwischerei - ob da etwas mit Base64-Kodierung gespeichert ist oder nicht, hat mit "direkt im Skript" nichts zu tun. Bei dem AVM-Binary kann das Kennwort für den SMTP-User tatsächlich verschlüsselt(!) in der ar7.cfg gespeichert werden (die anderen Daten natürlich auch) und man kann sie bei Bedarf dort mit ctlmgr_ctl auslesen (und im Falle eines Kennworts passend decodieren) lassen, wenn man sie nicht "direkt verdrahten" will - vorausgesetzt, der Pushmail-Versand ist konfiguriert über das AVM-GUI.

Auch der Locking-Mechanismus auf der Basis des mkdir-Kommandos ist (für mich) ein typischer KI-Vorschlag. Irgendwer hat mal verbreitet, mkdir als Shell-Kommando wäre per se atomar - aber dem ist (jedenfalls nach der (letzten?) POSIX-Spezifikation: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/mkdir.html) nicht so und das gilt eigentlich auch bei der dahinterliegenden C-Funktion mkdir() (https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdir.html) vielleicht für eine konkrete Implementierung einer solchen Library, aber nirgendwo ist spezifiert (so weit ich weiß jedenfalls, was ggf. zu kurz ist?), dass diese Operation atomar sein MÜSSE. Hinzu kommt noch, dass eigentlich nur der "richtige" Fehlercode (hier EEXIST) als (halbwegs) sicheres Anzeigen dafür verstanden werden darf, dass das anzulegende Verzeichnis bereits existiert. Gibt es z.B. einen Symlink mit diesem Namen, schlägt die Operation auch fehl und zwar sogar wieder mit EEXIST (s. Spec). Nur kriegt man so einen Symlink dann auch nicht mit einem rmdir-Aufruf wieder weg. An so einem Locking-Mechanismus scheiden sich also häufig auch die Geister der "Experten" - wobei bei solchen Semaphoren bzw. Mutexen (oder sind es doch eher Mutexes) auch immer eine Rolle spielt, was der Prozess, der nicht auf die verriegelte Ressource zugreifen darf, stattdessen machen soll und wie schnell er auf eine "Freigabe" reagieren können soll. Auch hier wieder als Q&D-Variante häufig mit mkdir zu sehen, aber nicht besonders robust (gegen Fehler und/oder Angriffe).

Wozu es beim Aufräumen der leeren Verzeichnisse zwei Schleifen über zwei Aufrufe von find braucht (einmal für Verzeichnisse mit Namen images und einmal für record), verstehe ich auch nicht - ich sehe jedenfalls keinen Unterschied (außer diesen beiden Verzeichnisnamen) in den beiden find-Kommandos und in den Kommandos in den Schleifen (wenn ich da falsch liege, kläre mich auf). Witzigerweise kommt dann später sogar noch ein find-Kommando (beim Suchen der Filmschnipsel), wo die passende Syntax für eine kombinierte Suche (name_A OR name_B) zu sehen ist.



Auch ist es eben recht fehleranfällig (auch wenn die Lock-Datei (bzw. das Verzeichnis) in volatilen Verzeichnissen liegen soll), wenn ein Angreifer den Versand ALLER Clips einfach dadurch wirksam verhindern kann, dass er selbst das Lockfile anlegt und es NICHT wieder löscht (bzw. wie oben erwähnt, einen Symlink gleichen Namens verwendet). Auf das Problem, dass vermutlich JEDER vernünftig geführte SMTP-Dialog hier als "erfolgreich" angesehen wird (es können nach dem ersten 250 OK noch so viele potentielle Fehler auftreten) und damit die angeblich gesendeten Dateien gelöscht werden, hatte ich ja schon hingewiesen. Dabei ist es noch ein glücklicher Umstand, dass die verwendeten Dateisysteme für /tmp im FRITZ!OS üblicherweise auf dem tmpfs-Treiber basieren - wäre das ein Dateisystem, in dem erweiterte Attribute unterstützt werden, könnte ein Angreifer mit root-Rechten (in einer FRITZ!Box eigentlich jeder) auch einfach eine Datei mit einer einzelnen Zeile 250 OK anlegen und diese vor weiteren Modifikationen schützen (chattr +a oder chattr +i). Das dazu erforderliche Binary /bin/chattr ist (oder war) zumindest in Inhouse-Versionen enthalten - ggf. existiert es sogar in irgendwelchen Freetz-(NG-)Paketen. Da die aufgerufenen Kommandos mit den Umleitungen in "Zwischendateien", die im Anschluß irgendwie ausgelesen und verarbeitet werden sollen, gar nicht wirklich prüfen, ob die Umleitungen erfolgreich waren und die Kommandos korrekt ausgeführt wurden, kann so eine "festgeklopfte" Datei mit ihrem Inhalt das ganze Skript ruinieren. Daher greift man am besten in solchen Fällen gleich auf "pipes" zurück - die muß man auch im Fehlerfall nicht löschen und ein potentieller Angreifer kann sie nicht einfach durch einen "festen" Inhalt in einer unveränderlichen Datei ersetzen.

Mein Fazit: Ein netter, aber "uninformierter" Versuch, mit/von einer KI, das gestellte Problem zu lösen. Das Ergebnis ist aber (zumindest in meinen Augen und warum, habe ich versucht zu erklären) eher suboptimal, angefangen beim doch sehr beschränkten, nachgebauten MTA (bzw. MUA) und der praktisch nicht existenten Fehlerbehandlung, bis hin zu den denkbaren Fallstricken, wenn man sich darauf verlassen sollte, dass diese Lösung die aufgenommenen Clips auch WIRKLICH korrekt per Mail archiviert. Ein lokales Bedienfeld einer Alarmanlage ist sicherlich schwerer zu "hacken", als so ein Skript in einer (ohnehin modifizierten und sicherlich per se mit Shell-Zugriff versehenen) FRITZ!Box, möglichst noch mit irgendwelchen Freigaben in Richtung Internet. Da wäre der entscheidende Vorteil vielleicht gewesen, dass ein Eindringling gar nicht mit einer solchen Möglichkeit rechnet - damit ist es jetzt aber auch vorbei. :)

Ich finde es ja auch immer gut, wenn jemand etwas "vom Blatt" implementieren kann und nicht einfach nur auf vorgefertigte (und ggf. gar nicht verfügbare) Bausteine zurückgreifen will - nur muß man das dann (nach meiner festen Überzeugung) auch "richtig" machen und für mich hat da die vorgestellte Lösung noch zu viele "Löcher". Das größte davon dürfte der falsch ausgewertete SMTP-Dialog sein - hast Du jemals den Fehlerfall getestet? Und zwar nicht nur mit einem "falschen" Server (der ggf. gar nicht reagiert), sondern auch mal mit falschen (Mail-)Adressen? Benutzername und Kennwort scheiden vermutlich auch aus als Fehlerquellen - ohne erfolgreiche Anmeldung kommt sicherlich auch kein 250 OK im Dialog vor. Und auch mit korrekten Mail-Adressen kann es immer noch (später) Probleme geben, z.B. wenn Quotas für die Mailbox (am finalen Speicherort, was noch gar nicht der Relay-Server sein muß) überschritten werden. Sind dann die Quelldateien schon weg (weil gelöscht) und irgendein MTA auf dem Weg zur finalen Mailbox kann die Mail nicht zustellen, guckt man auch in die Röhre. Die wenigsten MTA schicken im Fehlerfall die komplette(!) Mail mit allen Anhängen an den Absender zurück (i.d.R. gibt es nur eine Notiz, dass die Nachricht nicht zugestellt werden konnte und warum) - abgesehen davon, daß der hier vermutlich als "echte Mailbox" gar nicht existiert?

Wenn der Upload (bzw. der SMTP-Versand) tatsächlich dazu dienen soll, dass ein Eindringling (sagen wir mal ca. 30 Sekunden, nachdem eine Kamera mit autonomer Bewegungserkennung den Clip aufgezeichnet hat) auch durch die Mitnahme der FRITZ!Box samt USB-Stick nicht mehr verhindern kann, dass die Aufnahmen weiterhin zur Verfügung stehen, dann wäre ein cron-Job ohnehin die falsche Lösung (bei 5 Minuten Intervall hätte der Eindringling im schlechtesten Fall genau diese 5 Minuten Zeit, den Anschluß lahmzulegen) und man sollte eher auf die Aufzeichnung des Clips (sicherlich per FTP oder SMB?) reagieren, am besten schon auf das Anlegen der Datei, noch während der laufenden Aufzeichnung. Auch für eine "Türklingel" wäre ja ein Versand in 5-Minuten-Intervallen eher unpraktisch.

Dennoch noch einmal ganz deutlich: Danke für das Teilen dieses Vorschlags und seiner Implementierung - meine Einwände gegen die (derzeitige) Umsetzung haben nichts mit der Tatsache zu tun, dass Du dich überhaupt "getraut" hast, das für andere zu zeigen. Ich fände es gut, wenn es mehr Leute geben würde, die solche Sachen mit anderen teilen.

Wer jetzt noch Typos findet, darf sie (für sich) behalten ... ich habe fertig.
 
Hallo @erst_nachdenken,

vielen Dank für Deinen umfangreichen Kommentar. Das war mindestens 1.5 h Lebenszeit, aber bringt mich weiter.

Dieses Experiment war für mich auf mehreren Ebene spannend.

Einmal - ja, auch ein "nicht-so-profi" kann zusammen mit der KI so ein Projekt in 48 Stunden stemmen, bis 'was' tut.
Dabei nimmt einem die KI viel ab - z.B. gab es keinen einzigen Syntax Fehler.
Die KI hat auch die Einträge 1 2 und 6 vollständig verfaßt.
Manchmal zeigt die KI sogar Anzeichen von Humor a la "Ja, syntaktisch funktioniert das in crontab. Aber es macht wahrscheinlich nicht das, was Du erwartest."

Auch muss ich zugeben, daß so manche gute und schlechte Designentscheidung im Verlauf meine Verantwortung waren - wie z.B. die Verwendung von CheckmailD in Verbindung mit stunnel geht auf einen uralten Forumsbeitrag hier in IPPF Tools zurück.
Die Existenz von mailer war mir - und der KI ? - einfach nicht bekannt.

Die KI hat z.B. auch auf den suboptimalen Umgang mit SMTP hingewiesen, das ist eine technische Schuld auf dem Weg zur Erreichung einer zeitnahen V1.0 .

Es gab allerdings auch Probleme in der Arbeit mit der KI.
Einmal ist sie recht vergeßlich, insbesondere in der kostenfreien Variante, in der man nur eine email angeben muss. Nach einiger Zeit faßt sie ihr eigenes Gedächtnis zusammen, und dann fehlen für coding wesentliche Details - z.B. daß eine FB eine andere Filestruktur hat als ein generischer Linux Rechner. Ob KIs anderer Hersteller anders funktionieren oder die bezahlte Version das besser kann, würde mich interessieren.

Dann produziert sie doch sehr viel 'Textspam'. Eine Kommunikation, in der eine Frage gestellt wird, man immer eine Antwort mit zig Punkten bekommt ist einer linearen Abarbeitung nicht förderlich. Der primäre Zweck der KI, den Nutzer möglichst lange auf der Plattform zu halten und bestenfalls das Update zu verkaufen, schimmert manchmal durch - nervig und oft (aber auch nicht immer) hinderlich. Es bleibt durchgehend wichtig, im Hinterkopf zu haben, daß die KI Konversation macht, nicht Technikdesign, 80/20 statt 100/0 plus Vergeßlichkeit.


Aus technischer Sicht:
Einmal halte ich die Grundidee für viele Anwendungsfälle interessant. Ferienwohnung / Hotelzimmer mit Standleitung (ob LAN; DSL oder LTE) und eh-da Fritzbox. Eine Cam für 50€ - offen oder versteckt - und man hat eine minimale, erweiterbare (und gefrickelte) Überwachungsplattform.
Datenschutz mal beiseite - ich kann sehen ob ein gebetener oder ungebetener Besuch die Schubladen öffnet oder mir jemand die Scheiben einwirft.

Spannenderweise bekam die home FB (IP4 und Dyndns) während des Projekts plötzlich eine neue IP und dann war das vpn weg - daher der Bedarf die Box per mail zu resetten / den Status abzufragen.

Danke für den Hinweis auf mailer. Damit wird vermutlich sehr viel Code obsolet und extrem weniger fehleranfällig.
Falls es einen eingebauten - oder zumindest nicht depreciated - mail Client gibt, wäre ich auch interessiert.
Oder wie sonst sollte eine FB möglichst sicher proaktiv push kommunizieren?

Zum Thema Sicherheit - wenn ein Einbrecher die FB aus der Wand reißt - das kann ich kaum verhindern.
Daher war und ist mir zunächst wichtiger, daß die Box von aussen sicher bleibt.
Die Kommunikation Zentrale - Filiale läuft komplett (0.0.0.0) über ein Wireguard VPN. Keine Portöffnungen o.a.
Was kann hier gehärtet werden?

Tja, und der cron Job - da die Cam die Videos per ftp hochläd, wie anders als mit einem irgendwie getakteten Cron Job sollten der trigger kommen, damit sie auf die Reise gehen?

Und zum Thema "Locking-Mechanismus auf der Basis mkdir" da kam tatsächlich der Hinweis auf 'atomar', Posix usw.
Pragmatisch (48h Bauzeit) tut es so - und wer so weit drinnen ist, daß er den lock manipulieren kann, kann auch noch ne menge anderer Dinge kaputt machen ,-) .
 
ChatGPT bedankt sich mit:

FRITZ!Box Freetz-NG: CheckMailD und Kamera-Mailversand mit integriertem AVM-Mailer /sbin/mailer

Ausgangssituation​

Auf einer FRITZ!Box mit Freetz-NG sollten zwei eigene Funktionen umgesetzt werden:
  1. CheckMailD
    • Abrufen von POP3-Mails
    • Steuerung der FRITZ!Box per Mail
    • Statusinformationen per Mail zurücksenden
    • Reboot per Mail auslösen
  2. Kamera-Mailversand
    • Überwachung eines Verzeichnisses mit Kameraaufnahmen
    • Versand neuer Clips als Mail-Anhang
    • anschließendes Löschen erfolgreich versendeter Dateien
Die erste Implementierung verwendete eigene SMTP-Kommunikation über nc und einen lokalen Stunnel-Wrapper.
Das funktionierte grundsätzlich, war aber unnötig komplex:
  • eigener SMTP-Dialog
  • eigenes AUTH LOGIN
  • eigenes MIME-Handling
  • eigene Base64-Erzeugung für Attachments
  • eigene Auswertung der SMTP-Antworten
Bei einer Suche auf der FRITZ!Box wurde festgestellt, dass Freetz/AVM bereits einen Mailer bereitstellt:
/sbin/mailer
Dieser kann SMTP inklusive Authentifizierung, TLS und Attachments direkt erledigen.

Verwendete AVM/Freetz-Komponente​

Auf der FRITZ!Box:
/sbin/mailer
Ausgabe:
Code:
usage: mailer [-s subject] -f from -t to -m mailserver
              [-a authname [-w passwd]]
              -i file(s) [-r] [-d attachfile(s)]
              [-l] [-c charset]
Wichtige Optionen:
OptionBedeutung
-sBetreff
-fAbsender
-tEmpfänger
-mSMTP-Server
-aSMTP Benutzername
-wSMTP Passwort
-lSMTP über SSL/TLS
-iTextinhalt der Mail
-dDatei-Anhang

1. Umstellung von CheckMailD​

Vorher:
mailactions baute die komplette SMTP-Kommunikation selbst:
  • EHLO
  • AUTH LOGIN
  • MAIL FROM
  • RCPT TO
  • DATA
  • MIME Multipart
  • SMTP Antwortprüfung
Nach der Änderung übernimmt /sbin/mailer den Versand.
Die Statusmail wird jetzt als Textdatei erzeugt:
Beispiel:
Code:
FB4050 Status
==============================

Date:
2026-xx-xx xx:xx:xx

Uptime:
...

Memory:
...

Disk:
...

Processes:
...
Versand erfolgt anschließend über:
Code:
/sbin/mailer \
    -s "$SUBJECT" \
    -f "$BOX_MAIL" \
    -t "$ADMIN_MAIL" \
    -m smtp.provider.example:465 \
    -a "$SMTP_USER" \
    -w "$SMTP_PASSWORD" \
    -l \
    -i "$STATUS_FILE"
Ergebnis:
  • Statusmail kommt korrekt als normaler Mailtext an
  • kein eigener MIME-Code mehr erforderlich
  • deutlich weniger Scriptcode

2. Umstellung von cammail.sh​

Auch der Kamera-Mailversand wurde umgestellt.
Vorher:
  • eigener SMTP-Dialog
  • eigener MIME-Multipart-Aufbau
  • Base64-Codierung des Videoclips
  • Versand über lokale SMTP-Verbindung
Nach der Änderung:
  • Text wird als Mailinhalt erzeugt
  • Videodatei wird direkt als Attachment übergeben
Beispiel:
Code:
/sbin/mailer \
    -s "$SUBJECT" \
    -f "$BOX_MAIL" \
    -t "$ADMIN_MAIL" \
    -m smtp.provider.example:465 \
    -a "$SMTP_USER" \
    -w "$SMTP_PASSWORD" \
    -l \
    -i "$TEXT_FILE" \
    -d "$VIDEO_FILE"
Ergebnis:
  • Kamera-Clips werden weiterhin verschickt
  • Attachment bleibt erhalten
  • Mailformat wird vom AVM-Mailer erzeugt

3. Ergebnis​

Durch die Nutzung von /sbin/mailer ergeben sich folgende Vorteile:

Weniger eigener Code​

Entfallen sind:
  • SMTP-Protokollimplementierung
  • MIME-Erzeugung
  • Base64-Verarbeitung
  • Antwortanalyse des SMTP-Servers

Höhere Stabilität​

Der Mailversand nutzt jetzt die bereits vorhandene FRITZ!Box-Komponente.

Einfachere Wartung​

Eigene Scripts kümmern sich nur noch um:
  • Erkennen von Ereignissen
  • Erzeugen des Mailinhalts
  • Auswahl der Anhänge
Der eigentliche Mailtransport bleibt der AVM/Freetz-Komponente überlassen.

4. Hinweise​

Bei Verwendung von /sbin/mailer sollte man Dateiendungen verwenden.
Beispielsweise:
status.txt
statt:
status
Der Mailer verwendet die Endung zur Erkennung des Inhaltsformats.

Fazit​

Die Umstellung von selbst gebautem SMTP-Code auf den vorhandenen FRITZ!Box-Mailer /sbin/mailer reduziert die Komplexität erheblich.
Sowohl CheckMailD als auch der Kamera-Mailversand funktionieren nun mit derselben zentralen Mail-Komponente.


=====================
smtp.conf

SMTP_USER='[email protected]'
SMTP_PASS_B64='BASE64_PASSWORD'
POP3_PASS='PASSWORD'
BOX_MAIL='[email protected]'
ADMIN_MAIL='[email protected]'

================
mailactions
#!/bin/sh

UIDFILE="/tmp/flash/checkmaild/processed.uid"
SMTP_CONF="/tmp/flash/checkmaild/smtp.conf"

mkdir -p /tmp/flash/checkmaild
touch "$UIDFILE"

#####################################################################
# SMTP-Konfiguration laden
#####################################################################

if [ -f "$SMTP_CONF" ]; then
. "$SMTP_CONF"
fi


#####################################################################
# Status-Mail senden
#####################################################################

send_status_mail()
{
SUBJECT="$1"

if [ -z "$SMTP_USER" ] || [ -z "$SMTP_PASS_B64" ] ||
[ -z "$BOX_MAIL" ] || [ -z "$ADMIN_MAIL" ]
then
logger "CheckMailD: SMTP configuration incomplete"
return 1
fi


SMTP_PASS="$(printf '%s' "$SMTP_PASS_B64" | base64 -d)"


# STATUS_FILE="/tmp/checkmaild_status.$$"
STATUS_FILE="/tmp/checkmaild_status.$$.txt"


UPTIME="$(uptime)"
MEMORY="$(free)"
DISK="$(df -h)"
PROCESSES="$(ps | wc -l)"
DATE_NOW="$(date '+%Y-%m-%d %H:%M:%S')"


{
printf 'FB4050 Status\r\n'
printf '==============================\r\n'
printf '\r\n'

printf 'Date:\r\n%s\r\n\r\n' "$DATE_NOW"

printf 'Uptime:\r\n%s\r\n\r\n' "$UPTIME"

printf 'Memory:\r\n%s\r\n\r\n' "$MEMORY"

printf 'Disk:\r\n%s\r\n\r\n' "$DISK"

printf 'Processes:\r\n%s\r\n\r\n' "$PROCESSES"

} > "$STATUS_FILE"


logger "CheckMailD: sending status mail to $ADMIN_MAIL"


/sbin/mailer \
-s "$SUBJECT" \
-f "$BOX_MAIL" \
-t "$ADMIN_MAIL" \
-m "$SMTP_SERVER" \
-a "$SMTP_USER" \
-w "$SMTP_PASS" \
-l \
-i "$STATUS_FILE"


RESULT=$?
logger "CheckMailD: mailer return code=$RESULT"


rm -f "$STATUS_FILE"


if [ "$RESULT" -eq 0 ]
then
logger "CheckMailD: status mail sent successfully"
return 0
else
logger "CheckMailD: status mail failed"
return 1
fi

}


#####################################################################
# UID-Cleanup
#####################################################################

cleanup_uids()
{
POP3_REPLY="/tmp/checkmaild_pop3_uidl"
SERVER_UIDS="/tmp/checkmaild_server_uids"
TMPFILE="/tmp/checkmaild_processed.$$"

logger "CheckMailD: UID cleanup started"

rm -f "$POP3_REPLY" "$SERVER_UIDS" "$TMPFILE"

{
sleep 1
printf 'USER %s\r\n' "$SMTP_USER"
sleep 1
printf 'PASS %s\r\n' "$POP3_PASS"
sleep 1
printf 'UIDL\r\n'
sleep 2
printf 'QUIT\r\n'
sleep 1

} | nc 127.0.0.1 1110 > "$POP3_REPLY" 2>&1

if ! grep -q "^+OK" "$POP3_REPLY"
then
logger "CheckMailD: UID cleanup aborted - POP3 failed"
return 1
fi

grep -E "^[0-9]+ " "$POP3_REPLY" |
awk '{print $2}' > "$SERVER_UIDS"


MAILBOX_STATUS="$(grep 'mailbox' "$POP3_REPLY")"

if echo "$MAILBOX_STATUS" | grep -q 'has 0 messages'
then
POP3_EMPTY=1
else
POP3_EMPTY=0
fi


if [ "$1" -gt 0 ] 2>/dev/null && [ ! -s "$SERVER_UIDS" ]
then
logger "CheckMailD: UID cleanup aborted - empty UID list"
return 1
fi

: > "$TMPFILE"

while IFS=' ' read -r uid rest
do
[ -n "$uid" ] || continue

if grep -Fxq "$uid" "$SERVER_UIDS"
then
echo "$uid $rest" >> "$TMPFILE"
else
logger "CheckMailD: removing old UID $uid"
fi

done < "$UIDFILE"

if [ ! -s "$TMPFILE" ] && [ -s "$UIDFILE" ] && [ "$POP3_EMPTY" != "1" ]
then
logger "CheckMailD: UID cleanup aborted - would delete all processed UIDs"
rm -f "$TMPFILE"
return 1
fi

cp "$UIDFILE" "$UIDFILE.bak"

cat "$TMPFILE" > "$UIDFILE"
rm -f "$TMPFILE"

logger "CheckMailD: UID cleanup finished"
}


#####################################################################
# EVENT 0: Neue Mail
##########################################F###########################

if [ "$1" = "0" ]
then

logger "CheckMailD: New Mail detected"
logger "CheckMailD: UID=$5 From=$8 Subject=$9"

#################################################################
# Absender prüfen
#################################################################

case "$8" in

"$ADMIN_MAIL"|*"<$ADMIN_MAIL>"*)
;;

*)
logger "CheckMailD: rejected sender: $8"
exit 0
;;

esac

#################################################################
# UID bereits verarbeitet?
#################################################################

if grep -q "^$5 " "$UIDFILE" 2>/dev/null
then
logger "CheckMailD: UID $5 already processed - skip"
exit 0
fi

#################################################################
# UID vor Ausführung speichern
#################################################################

echo "$5 RECEIVED $9" >> "$UIDFILE"

#################################################################
# Befehle
#################################################################

case "$9" in

"FB4050 status")

logger "CheckMailD: status requested"

logger "CheckMailD: uptime:"
uptime | logger -t CheckMailD

logger "CheckMailD: memory:"
free | logger -t CheckMailD

if send_status_mail "FB4050 status"
then
sed -i "s/^$5 RECEIVED/$5 DONE/" "$UIDFILE"
else
sed -i "s/^$5 RECEIVED/$5 FAILED/" "$UIDFILE"
fi

;;

"FB4050 reboot")

logger "CheckMailD: reboot requested by $8"

if send_status_mail "FB4050 reboot"
then
logger "CheckMailD: reboot notification sent"
sed -i "s/^$5 RECEIVED/$5 DONE/" "$UIDFILE"
sync
modsave
else
logger "CheckMailD: reboot notification failed"
sed -i "s/^$5 RECEIVED/$5 FAILED/" "$UIDFILE"
exit 1
fi

sleep 10

logger "CheckMailD: rebooting now"

# Aktivieren, wenn getestet:
sync
cat "$UIDFILE" | logger -t CheckMailD
/sbin/reboot

;;


*)

logger "CheckMailD: unknown command '$9'"

sed -i "s/^$5 RECEIVED/$5 IGNORED/" "$UIDFILE"

;;

esac
f
fi


#####################################################################
# EVENT 1: Mail-Status / Cleanup
#####################################################################

if [ "$1" = "1" ]
then

logger "CheckMailD: Status unread=$2 new=$3"

cleanup_uids "$2"

fi

exit 0



==================

cammail.sh


#!/bin/sh

LOCKDIR="/tmp/cammail.lock"
SMTP_CONF="/tmp/flash/checkmaild/smtp.conf"
mkdir -p /tmp/flash/cammail
SENT_LOG="/tmp/flash/cammail/sent.log"

VIDEO_ROOT="/var/mod/root/usbdevice/ftp"

MAX_AGE=120

#####################################################################
# Lock
#####################################################################

cleanup()
{
rmdir "$LOCKDIR" 2>/dev/null
}

if ! mkdir "$LOCKDIR" 2>/dev/null
then
logger -t cammail "already running"
exit 0
fi

trap cleanup EXIT TERM INT HUP
logger -t cammail "started"

#####################################################################
# SMTP config
#####################################################################

if [ -f "$SMTP_CONF" ]
then
. "$SMTP_CONF"
else
logger -t cammail "missing smtp.conf"
exit 1
fi


if [ -z "$SMTP_USER" ] || [ -z "$SMTP_PASS_B64" ] ||
[ -z "$BOX_MAIL" ] || [ -z "$ADMIN_MAIL" ]
then
logger -t cammail "SMTP configuration incomplete"
exit 1
fi


#####################################################################
# Cleanup empty camera directories
#####################################################################

cleanup_empty_camera_dirs()
{
logger -t cammail "cleanup started"

find "$VIDEO_ROOT" \
-type d \
-name "images" |
while IFS= read -r DIR
do
if rmdir "$DIR" 2>/dev/null
then
logger -t cammail "removing $DIR"
fi
done


find "$VIDEO_ROOT" \
-type d \
-name "record" |
while IFS= read -r DIR
do
if rmdir "$DIR" 2>/dev/null
then
logger -t cammail "removing $DIR"
fi
done


find "$VIDEO_ROOT" \
-mindepth 1 \
-maxdepth 1 \
-type d |
while IFS= read -r DIR
do
if rmdir "$DIR" 2>/dev/null
then
logger -t cammail "removing $DIR"
fi
done

logger -t cammail "cleanup finished"
}


#####################################################################
# Send one video mail
#####################################################################

send_video_mail()
{
FILE="$1"
NAME="$(basename "$FILE")"

SUBJECT="Camera alarm $NAME"

TEXT_FILE="/tmp/cammail_text.$$.txt"


{
printf 'Camera alarm clip:\r\n'
printf '\r\n'
printf '%s\r\n' "$NAME"
printf '\r\n'
printf 'FB4050 camera notification\r\n'
printf 'Date:\r\n'
date
} > "$TEXT_FILE"


logger -t cammail "sending $NAME"


/sbin/mailer \
-s "$SUBJECT" \
-f "$BOX_MAIL" \
-t "$ADMIN_MAIL" \
-m "$SMTP_SERVER" \
-a "$SMTP_USER" \
-w "$(printf '%s' "$SMTP_PASS_B64" | base64 -d)" \
-l \
-i "$TEXT_FILE" \
-d "$FILE"


RESULT=$?


rm -f "$TEXT_FILE"


if [ "$RESULT" -eq 0 ]
then
logger -t cammail "sent $NAME"

echo "$(date '+%Y-%m-%d %H:%M:%S') $NAME" >> "$SENT_LOG"

if rm "$FILE"
then
logger -t cammail "deleted $NAME"
else
logger -t cammail "cannot delete $NAME"
fi

return 0

else
logger -t cammail "send failed $NAME"
return 1
fi
}


#####################################################################
# Find clips
#####################################################################

ERROR=0

TMP_FIND="/tmp/cammail_find.$$"

find "$VIDEO_ROOT" \
-type f \
\( -name '*.264' -o -name '*.265' \) \
2>/dev/null |
sort > "$TMP_FIND"


while IFS= read -r FILE
do

[ -f "$FILE" ] || continue


NOW=$(date +%s)
MTIME=$(stat -c %Y "$FILE" 2>/dev/null)

[ -n "$MTIME" ] || continue

AGE=$((NOW-MTIME))

if [ "$AGE" -lt "$MAX_AGE" ]
then
continue
fi


logger -t cammail "candidate $FILE"


if ! send_video_mail "$FILE"
then
ERROR=1
fi

done < "$TMP_FIND"


rm -f "$TMP_FIND"


if [ "$ERROR" -ne 0 ]
then
logger -t cammail "finished with errors"
exit 1
fi


cleanup_empty_camera_dirs


logger -t cammail "finished successfully"

exit 0
 
Kostenlos!

Neueste Beiträge

Statistik des Forums

Themen
248,907
Beiträge
2,304,706
Mitglieder
378,616
Neuestes Mitglied
Der_fragende_Unwissende