Ich habe mal etwas in mein GitHub-Repository eingecheckt, was ich bisher in leicht abgewandelter Form auf entfernten FRITZ!Boxen eingesetzt habe, um dort beim Neustart der Box auf dem internen NAS-Speicher (unter /var/media/ftp, ich habe nur noch Boxen "in Pflege", die dort einen Speicher haben - 7390, 7490, 6490) abgelegte neue Firmware zu installieren. Bisher habe ich das dazu genutzt, die von mir modifizierte Firmware einfach über den NAS-Zugriff dort abzulegen und bei der nächsten Gelegenheit (i.d.R. nachts, wenn in den betreffenden Filialen garantiert niemand das Telefon braucht) installieren zu lassen.
Das ist zwar alles weitgehend getestet, aber es ist in dieser Form auch aus vorhandenen Bausteinen neu zusammengesetzt und muß erst einmal ausgiebig unter verschiedenen Bedingungen seine Eignung unter Beweis stellen. Das "Abschalten" ist normalerweise sehr einfach ... auch im Fehlerfalle. Da vor jedem Aufruf einer Datei im Verzeichnis "/var/media/ftp" erst deren Existenz geprüft wird, führt bereits das Löschen einer falschen Datei per NAS-Zugriff (FTP, Samba, GUI) dazu, daß der Ablauf nicht geändert wird - es reicht also bereits, eine Datei zu löschen, um das Ganze wieder zu deaktivieren, wenn man die entfernte Firmware erfolgreich aktualisiert hat.
Der bisher realisierte Ablauf ist folgender ... beim Neustart der FRITZ!Box (noch einmal, ich rede eigentlich von anderen Modellen als der 6490, aber nach meinen Tests und ein paar ausgeführten Änderungen funktioniert es auch für diese) wird ja bekanntlich die "/var/post_install" abgearbeitet. Schaut man dort kurz hinein (hier in die 141.06.62), sieht der Beginn dort so aus:
Code:
## ! /bin/sh
## Skip Startup (on very early reboot-cmd)
if ps | grep -v grep | grep -q 'rc.S'; then
echo "rc.S is running - set 'skip init'"
touch /var/skip_init
[COLOR="#FF0000"]else
test -f /var/media/ftp/update_firmware && . /var/media/ftp/update_firmware
[/COLOR]fi
## AHA
if ps | grep -v grep | grep -q /usr/bin/aha ; then
Die roten Zeilen sind schon eine Ergänzung meinerseits, sie fügen die Kommandos aus der Datei "/var/media/ftp/update_firmware" ein, wenn diese Datei existieren sollte. In diesem Falle (bei der 6490) auch nur, wenn das kein "early reboot" ist, wie er z.B. bei Änderungen an der "featovl.cfg" über "docsis_feature_disable" auftritt, deshalb der "else"-Zweig bei der 6490 - bei anderen Modellen gibt es diese Abfrage gar nicht, dann läßt man das "else" einfach weg.
Die eingefügte Datei kann dann z.B.
so aussehen:
Code:
## Check semaphore to avoid 2nd call
if ! [ -f /var/run/post_install_2nd_run ]; then
if [ -f /var/media/ftp/run_update ]; then
touch /var/run/post_install_2nd_run
exec $SHELL /var/media/ftp/run_update
fi
fi
Hier wird beim ersten Aufruf (solange die Datei "/var/run/post_install_2nd_run" nicht existiert) die Abarbeitung der "/var/post_install" erst einmal beendet, wenn ein weiteres Skript "/var/media/ftp/run_update" existiert und stattdessen dieses Skript ausgeführt (über "exec", was in diesem Falle entscheidend ist).
Dieses Skript kann jetzt machen, was es für notwendig erachtet ... es muß nur bei jedem "Ausgang" dafür sorgen, daß es seinerseits wieder die "/var/post_install" erneut aufruft, woraufhin dann der Rest der Kommandos in dieser Datei abgearbeitet wird, weil die Datei als Semaphore beim zweiten Aufruf existiert. Das kann also durchaus auch die durch das "/var/install"-Skript aus einem AVM-Firmware-Image geänderte "/var/post_install" sein. Macht man das richtig, funktioniert das auch auf den DSL-Boxen, sogar auf den NOR-Modellen, mit denen "modfs" nichts am Hut hat (hier natürlich mit einem gewissen Risiko, deshalb teste ich solche "remote updates" bei mir auch immer vorher auf einer passenden Box).
Die eigentliche Arbeit übernimmt dann das Skript "
run_update", das ich für die Veröffentlichung noch etwas umgeschrieben habe.
Als erstes testet es, ob eine neue Firmware bereits auf dem NAS-Speicher vorhanden ist (als "newfirmware.image"). Findet es keine, versucht es im nächsten Schritt den AVM-Service zu befragen, ob es eine neuere Version gibt oder nicht. Wer diese Prüfung nicht haben will, entfernt einfach das "check_update"-Skript (oder stellt es gar nicht erst bereit) - wobei das Vorhandensein der "include"-Datei (update_firmware) bei Fehlen der Datei "newfirmware.image" eine etwas paradoxe Situation ergeben würde ... warum ist dann die "update_firmware" überhaupt existent?
Wer eigene Firmware installieren will (bei mir der Haupteinsatzzweck), der kann bzw. muß natürlich neben den Skript-Dateien auch noch die passende Datei "newfirmware.image" bereitstellen, das kann auch ein mit Freetz erstelltes Image sein.
Sollte eine neuere Version bei AVM existieren für die Box, wird diese heruntergeladen und so behandelt (sie bleibt auch gespeichert, solange man am Pfad "/var/media/ftp" nicht dreht - bei Boxen ohne (ausreichenden) internen NAS-Speicher muß man ohnehin das Basisverzeichnis (und ein paar weitere Zeilen) anpassen), als wäre sie von Beginn an vorhanden gewesen.
Jetzt wird die Firmware-Datei (nur überwindlich) geprüft ... sie muß eine Größe > 0 haben und die Dateien "var/tmp/filesystem.image", "var/tmp/kernel.image" und "var/install" enthalten. Hat sie diesen Test bestanden und existiert die Datei "
check_signed_image" (
hier beschrieben), dann wird versucht, die Signatur der Datei zu überprüfen.
Das setzt allerdings die Existenz einer passenden OpenSSL-Version als Binary auf der betreffenden Box voraus ... bei mir ist das "openssl" immer irgendwie erreichbar, daher werden in "check_signed_image" auch keine speziellen Vorkehrungen für den Aufruf mit absolutem Pfad getroffen. Für die MIPS-Boxen (NAND/VR9) gäbe es im "modfs"-Repository ein passendes Binary, für die 6490 muß man sich eben eines basteln, wenn man die Signaturprüfung überhaupt will. Ich habe die bei mir eingebaut, weil ich die Firmware für "remote install" eben auch passend signiere und damit erstens weiß, daß der Inhalt richtig übertragen wurde und zweitens sicher sein kann, daß keine manipulierte Firmware installiert wird.
Aber damit die Signaturprüfung nicht zum Stolperstein wird, ignoriere ich in der Version im Repository jeden Fehler, der nicht explizit sagt "falsche Signatur" - damit reicht auch das Fehlen des "openssl"-Binaries, damit die Signaturprüfung quasi übergangen wird.
Im Anschluß gibt es noch die Möglichkeit, die entpackten Firmware-Dateien durch den Aufruf eines passenden Kommandos/Skripts zu modifizieren - z.B. mit der (bisher unveröffentlichten) Batch-Version von "modfs". Aber hier kann sich auch jeder selbst seine Kommandos zurechtbasteln ... die Zutaten in Form von "unsquashfs" und "mksquashfs" für die Box, auf der das laufen soll, muß man sich eben vorher besorgen - für die 6490 stelle ich da (zumindest bisher) nichts weiter bereit, für MIPS-Boxen ist wieder alles Notwendige im "modfs"-Repo zu finden.
Ist bis hierhin alles fehlerfrei gelaufen, wird nun das Skript "/var/install" aufgerufen - das ist dann dafür verantwortlich, die Firmware zu installieren. Dabei kann es sich um das originale Skript von AVM handeln oder um ein beliebiges selbstgeschriebenes ... es muß sich nur wie das von AVM verhalten.
Die Arbeitsweise von "run_update" läßt sich noch an einigen Stellen modifizieren ... dazu gibt es in der Datei die folgenden Zeilen/Variablen, deren Bedeutung kurz erläutert wird:
Code:
exec_to=/var/post_install
[...]
log_ip="192.168.178.2"
log_port=514
[...]
basedir=/var/media/ftp
[...]
imagename=newfirmware.image
[...]
force_update=0
[...]
force_branding=1
[...]
modify_firmware=0
modify_command="$SHELL $basedir/modfs/modfs_batch unpacked /"
"exec_to" gibt den Namen des Skripts an, welches im Anschluß (ebenfalls mit "exec") aufgerufen werden soll.
"basedir" ist der Pfad, in dem nach den ganzen Bestandteilen dieses "autoupdate"-Mechanismus für Arme gesucht wird ... bei einer Box ohne internen NAS-Speicher muß das natürlich auf ein Verzeichnis auf einem USB-Stick geändert werden und gleichzeitig muß sichergestellt sein, daß der USB-Stack noch verfügbar ist, wenn "/var/post_install" aufgerufen wird (nach "prepare_fwupgrade" nur teilweise der Fall).
"imagename" enthält den Namen der Image-Datei, falls den jemand ändern möchte.
"force_update" kann man auf "1" setzen, wenn man dafür sorgen will, daß auch ältere Firmware installiert wird, die bei AVM durch die Versionsprüfung fällt (also ein Downgrade auszuführen ist). Dabei werden dann aber vom AVM-Code vorhandene Einstellungen gelöscht ... nur falls sich niemand mehr an diesen Mechanismus erinnern kann, seitdem AVM ihn abgeschafft hat.
"force_branding" sorgt dafür, daß ich auf einer internationalen 7390 auch die deutsche Version der Firmware installieren kann und umgekehrt. Dazu überprüft das Skript in der "/var/install" von AVM (das Entpacken von SquashFS-Images ist dafür zu mühsam und wenig platzsparend), welche Brandings enthalten sind ... das ist etwas fragiler Code, weil so ein Shell-Statement natürlich leicht zu ändern ist - andererseits editiert Freetz daran auch herum, wenn man dort ein Branding entfernen läßt. Ist das aktuelle Branding in der neuen Firmware nicht enthalten, wird die Variable "OEM" mit dem ersten Wert aus der Liste der Brandings exportiert, damit sich "/var/install" nicht am falschen Branding stört. Kommt es dann wirklich zur Installation, wird am Ende von "run_update" auch noch das Branding im Bootloader-Environment entsprechend gesetzt - damit ist der (automatisierte) Wechsel zwischen "avm" und "avme" möglich, aber es sollte theoretisch auch von "kdg" auf "avm" klappen. Den erhobenen Zeigefinger, daß man das nur auf der eigenen Box machen sollte, kann und will ich niemandem ersparen. Bei mir gibt es jedenfalls einen Kunden, der hat Anschlüsse in D und in A mit der 7390 und irgendwann hatte ich die Nase voll, die vorhandene Reserve-Box immer erst vom aktuellen Branding auf das benötigte umzuschalten - die wird nämlich auch für (kritische) Updates eingesetzt, wenn noch eine garantiert funktionsfähige Alternative benötigt wird.
"modify_firmware" und "modify_command" sind die beschriebenen Einstellungen für die Änderung der Firmware vor der Installation - kann man benutzen, muß man aber nicht; es hängt halt davon ab, ob man eine bereits modifizierte oder eine originale Firmware als Ausgangsmaterial hat.
Interessant ist vielleicht noch die Einstellung "log_ip" ... da ich keine Lust habe/hatte, so ein Update immer live zu überwachen, habe ich eine Möglichkeit der Protokollierung eingebaut, die auch über Netzwerk-Verbindungen arbeiten kann - sogar über das Internet, solange die WAN-Verbindung verfügbar ist. Dazu wird eine TCP-Verbindung zum angegebenen Host aufgebaut und sowohl die Standardausgabe als auch die Standardfehlerausgabe (STDOUT/STDERR) auf diese Verbindung umgeleitet ... parallel dazu wird der Debug-Modus der Shell aktiviert (set -x). Steht "nc" nicht zur Verfügung (bei originaler AVM-Firmware auf DSL-Boxen ist das der Fall), wird einfach nach "/dev/console" protokolliert, auch wenn das wohl nie jemand sehen wird (außer er hat eine serielle Schnittstelle oder eine Shell-Session mit "getcons" am Laufen). Weil auch AVM nach "/dev/console" protokolliert, wird das ggf. noch in der "/var/install" geändert (auf FD 6), bevor dieses Skript aufgerufen wird.
Wer die Protokollierung über das Netzwerk aktivieren will, muß also bei "log_ip" die IP-Adresse (oder den Namen) eines passenden Hosts eintragen und auf diesem dann einen entsprechenden "Empfänger" einrichten ... im einfachsten Falle ist das ein "nc -l <eigene IP-Adresse> 514" auf einem passenden Gerät (es gibt auch ein "netcat" für Windows, falls jemand keinen TCPClient mit PowerShell verwenden kann oder will). Gerade bei der Fehlersuche kann das gute Dienste leisten, wenn man ansonsten keinen Shell-Zugang hat (kann man auch als Beispiel nehmen, warum es einen solchen gar nicht immer braucht).
- - - Aktualisiert - - -
Falls es jemand noch als Zusammenfassung für das Update von kdg-06.31 (oder größer) auf avm-06.62 braucht: Einfach die vier Dateien (drei reichen auch, solange man kein "openssl"-Binary für dem Puma6 (ARM) hat - dann kann man "check_signed_image" auch weglassen) per NAS-Zugriff auf die Box bringen und dann in der "/var/post_install" die eine bzw. zwei Zeilen ergänzen.
Dann sollte beim nächsten Neustart (mit aktiver WAN-Verbindung) auch das Update anlaufen ... funktioniert das irgendwie nicht, kann man ja wieder per Bootloader auf die vorherige Version und das vorherige Branding zurückstellen.
Als Vorlage kann man auch die "/var/post_install" aus der 06.62 nehmen, so sehr unterscheiden die sich nicht - von der 06.24-30805 zur 06.50 ist dann nur das WLAN auf den x86-Core umgezogen (keine Ahnung, wo das bei der 06.31 läuft) und zwischen der 06.50 und der 06.62 (falls jemand kdg-06.50 auf avm-06.62 ändern will) gibt es gar keinen Unterschied.