.titleBar { margin-bottom: 5px!important; }

[Info] modfs-Starter - "Einmal-Impfung" mit ShellInABox für VR9-Boxen

Dieses Thema im Forum "FRITZ!Box Fon: Modifikationen" wurde erstellt von PeterPawn, 16 Dez. 2015.

  1. PeterPawn

    PeterPawn IPPF-Urgestein

    Registriert seit:
    10 Mai 2006
    Beiträge:
    11,793
    Zustimmungen:
    666
    Punkte für Erfolge:
    113
    Beruf:
    IT-Freelancer
    Ort:
    Berlin
    #1 PeterPawn, 16 Dez. 2015
    Zuletzt bearbeitet: 9 März 2018
    EDIT 09.03.2018:
    Ich habe einen anderen Weg für den Start der ersten Shell-in-a-Box-Instanz auf ansonsten "jungfräulicher Firmware" von AVM umgesetzt, dazu muß die betreffende Box einmalig mit einem speziellen Firmware-Image gestartet werden. Dieses Image installiert dann die notwendigen Dateien in der "wrapper"-Partition einer VR9-Box und fügt entsprechende Aufrufe von Skript-Dateien zum Startprozess des FRITZ!OS hinzu. Von diesem Moment an, steht dann - bis zum nächsten Update der Firmware in der gerade aktuellen Partition - bei jedem Start aus diesem System heraus (also aus der Partition, die zum Zeitpunkt der "Anwendung" dieses Images aktiv war) ein Shell-Zugriff auf dem Port 8010 bereit, der sich an dieselben "Regeln" bei der Anmeldung hält, wie jedes andere GUI-Login auch.

    Eine Beschreibung, wie das geschieht und wie man zu einem eigenen passenden Image kommt (ich selbst stelle das nur für die 7412 und die 7490 bereit), habe ich in diesem Thread schon niedergeschrieben ... der wird jetzt noch um die Details für genau dieses Skript in "toolbox" ergänzt.


    EDIT 19.07.2016:
    @qwertz.asdfgh hat das "modfs-Starter"-Image erfolgreich auf der 7430 getestet: http://www.ip-phone-forum.de/showthread.php?t=273304&p=2171420&viewfull=1#post2171420

    EDIT 17.02.2016:
    Seit Version 06.51 (gilt auch für die noch im Labor-Stadium gehandelten 06.36+ für andere Modelle) ist das Installieren von unsignierten Firmware-Images ja nicht mehr über das FRITZ!OS-GUI möglich, ebenso wie ein Downgrade auf frühere (potentiell verwundbare) Firmware-Versionen. Damit ist die einfache Installation über die "Datei-Update"-Funktion nicht mehr möglich, das Prinzip des Starts über die "inittab" in der wrapper-Partition bleibt jedoch verwendbar. Lediglich der Weg, auf dem man diese "inittab" jetzt ändert und wie man eine passende eigene Datei in diese Partition bekommt, ist jetzt eben ein anderer: http://www.ip-phone-forum.de/showthread.php?t=283039&p=2147416&viewfull=1#post2147416 (unter dem Ruler geht es erst los).
    Ende EDIT 17.02.2016

    Nachdem AVM ja nun die 06.50 für die 7490 freigegeben hat und man damit genau weiß, wie diese Firmware für die nächste Zeit aufgebaut sein wird, wird es auch Zeit für die bereits früher von mir versprochene relativ einfache Lösung zur dauerhaften Aktivierung von eigenen Zusätzen zur Firmware.

    Allerdings gleich vorweg die schlechte Nachricht ... das geht wieder (in der im Folgenden gezeigten Form) nur für FRITZ!Boxen, die zwei verschiedene Systeme im NAND-Flash verwalten (bzw. ein yaffs2-Dateisystem unter /wrapper gemountet haben) - ausdrücklich getestet habe ich selbst es nur auf der 7490.

    Es sollte aber zumindest theoretisch auf den folgenden Modellen funktionieren:

    [table="width: 500, class: grid"]
    [tr]
    [td]Modell[/td]
    [td]Firmware[/td]
    [td]getestet[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7490[/td]
    [td]06.50 + Labor ab 06.35[/td]
    [td]funktioniert, SquashFS4-Version verwenden[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7490[/td]
    [td]<= 06.30[/td]
    [td]funktioniert, getestet mit 06.30[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7430[/td]
    [td]06.30[/td]
    [td]funktioniert[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7430[/td]
    [td]06.50[/td]
    [td]SIAB funktioniert wohl, aber wegen der strikten Signaturprüfung ist keine einfache "Installation" möglich[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7412[/td]
    [td]06.30 + 06.32[/td]
    [td]ja, selbst getestet[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7362SL[/td]
    [td]Labor ab 06.36[/td]
    [td]teilweise getestet, 1 Meldung über Probleme ohne nähere Beschreibung (SIAB nicht benutzbar, Box startet aber normal), SquashFS4-Version verwenden[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7362SL[/td]
    [td]Release bis 06.30[/td]
    [td]ja[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 3490[/td]
    [td]?[/td]
    [td]nein[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 3390[/td]
    [td]?[/td]
    [td]nein[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 3370[/td]
    [td]?[/td]
    [td]nein[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 7272[/td]
    [td]?[/td]
    [td]nein, unklarer Aufbau des Flash, geht event. gar nicht[/td]
    [/tr]
    [tr]
    [td]FRITZ!Box 3272[/td]
    [td]?[/td]
    [td]nein, unklarer Aufbau des Flash, geht event. gar nicht[/td]
    [/tr]
    [/table]

    Für ShellInABox werden natürlich binäre Dateien benötigt ... in den bereitgestellten Update-Images sind sie in einer Version enthalten, die für FRITZ!Boxen mit einem VR9-Prozessor geeignet ist. Ob diese überhaupt auf ARX300 AR10 läuft (das wären die x272-Modelle), weiß ich genauso wenig wie ich Informationen über den Flash-Aufbau bei diesen Modellen habe - unter Umständen arbeitet da das FRITZ!OS auch vollkommen anders als bei den bekannten VR9-Modellen.

    Schon wegen der unterschiedlichen SquashFS-Versionen mußte ich zwei Archive bereitstellen, eines für Firmware mit 2.6.32-Kernel (SquashFS 3) und eines für neue Firmware mit 3.10.73-Kernel (SquashFS 4) - aber es gibt auch beim Starten der Erweiterung leichte Unterschiede zwischen der alten und der neuen Version.

    Um auch das ganz deutlich zu sagen ... das hier ist kein "Pseudo-Image", dessen Auswirkungen mit dem nächsten FRITZ!Box-Start wieder behoben sind - ganz im Gegenteil. Die FRITZ!Box legt sofort einen Neustart hin und die ausgeführten (permanenten) Änderungen starten beim nächsten Booten dann einen ShellInABox-Service.

    Ich würde Fragen und Diskussionen gerne aus diesem Thread heraushalten, damit der nicht auch schnell eine Länge erreicht, die niemand mehr lesen will ... wenn jemand Fragen dazu oder Probleme damit hat, bitte ich diese in dem anderen Thread zu diskutieren.
     
  2. PeterPawn

    PeterPawn IPPF-Urgestein

    Registriert seit:
    10 Mai 2006
    Beiträge:
    11,793
    Zustimmungen:
    666
    Punkte für Erfolge:
    113
    Beruf:
    IT-Freelancer
    Ort:
    Berlin
    #2 PeterPawn, 16 Dez. 2015
    Zuletzt bearbeitet: 20 Dez. 2015
    Anwendung

    Um die Leute, die nur damit arbeiten wollen, nicht schon wieder mit Details zu langweilen, kommen hier als erstes die URLs für den Download und die "Anleitung" zur Benutzung (und die ist ausnahmsweise mal wirklich kurz), bevor ich die Funktionsweise im Anschluß erläutere.

    Zu finden sind die Dateien unter:

    http://yourfritz.de/inject_shellinabox_vr9_nand_sqfs4.tar - derzeit nur für die 7490 mit 06.50 und die diversen Labor-Versionen mit 3.10.73-Kernel (Stand 20.12.2015) geeignet
    http://yourfritz.de/inject_shellinabox_vr9_nand_sqfs3.tar - für FRITZ!Boxen mit 2.6.32-Kernel und SquashFS-Version 3

    Die richtige Datei einfach irgendwo auf dem eigenen Rechner speichern, einige Browser gestatten auch direkt die Angabe einer HTTP-URL in einem Dateiauswahl-Dialog (z.B. Firefox), dann kann man sich das (explizite) Speichern sparen, der Browser lädt die Datei natürlich trotzdem und legt sie temporär ab.

    Wie man das machen kann, wenn man nur über ein SmartPhone oder ein Tablet gebietet (wo der Hersteller das lokale Speichern von Dateien nicht zuläßt - so etwas soll es ja geben), soll hier nicht das Thema sein.

    Anschließend ein dateibasiertes Firmware-Update der FRITZ!Box ausführen (der dazu benötigte Reiter erscheint ggf. erst nach dem Einschalten der Experten-Ansicht) und dabei die gespeicherte Datei verwenden (oder eben direkt die von oben kopierte URL angeben) - das "Image" ist natürlich nicht von AVM signiert und so mault die Firmware im ersten Anlauf erst einmal herum, das ist wie bei jedem "Pseudo-Image". Inzwischen ist es auch nicht mehr möglich, ein unsigniertes Update einzuspielen, wenn man keine Anmeldung aus dem Heimnetz verwendet oder noch kein Kennwort gesetzt hat ... das sollte auch immer der erste Schritt sein, weil die passende Fehlermeldung (obwohl vorhanden) wohl nicht immer korrekt erscheint und dann irgendwann sogar der Watchdog die Box neu startet.

    Nach dem anschließend folgenden Neustart sollte auf der FRITZ!Box eine ShellInABox-Instanz aktiv sein, die auf eingehende Verbindungen auf dem Port 8010 wartet und dasselbe Zertifikat verwendet wie das FRITZ!OS-GUI. Um das also noch einmal ganz platt zu schreiben, man startet dann einfach einen Browser und gibt in die Adresszeile "fritz.box:8010" ein. Die Redirection auf HTTPS sollte automatisch erfolgen, ein Zugriff ohne TLS funktioniert bei der von mir bereitgestellten Version absichtlich nicht.
    EDIT 20.12.2015: Wer ShellInABox mit dem IE11 aufrufen will, muß auf den "compatibility mode" zurückgreifen und ob ShellInABox mit Edge überhaupt funktioniert, habe ich bisher nicht getestet. Vermutlich müßte man etwas an den statischen Dateien herumdoktern, damit die XHTML-Ausgabe wieder "Edge-konform" ist.

    Die Anmeldung erfolgt (wie üblich) über /sbin/ar7login und damit kommen da die "normalen" Benutzerkonten des FRITZ!OS zum Einsatz. Welche Rechte so ein Konto auf der Box haben muß, interessiert mich dabei gar nicht ... das ist Sache des ar7login-Programms von AVM, da die richtigen Einschränkungen durchzusetzen. Solange niemand den Port 8010 nach extern freigibt, braucht es auch keine Unterscheidung zwischen ar7login und ar7login_frominternet - sollte jemand so etwas tatsächlich nach extern freigeben wollen, muß er den Start von ShellInABox entsprechend anpassen, wenn die Unterscheidung zwischen lokalem und externem Login erforderlich ist.

    So eine ShellInABox-Version hat natürlich auch ihre Nachteile (z.B. funktioniert dort kein Auto-Login, wenn die Box mit Benutzernamen und Kennwort gesichert ist, was natürlich unbedingt der Fall sein sollte - mit Leuten, die ihre Box mit "Keine Anmeldung aus dem Heimnetz" betreiben, rede ich gar nicht mehr) - sie ist eigentlich von mir auch eher als "Einstieg" in eine FRITZ!Box mit originaler AVM-Firmware und damit ohne Telnet-Zugang gedacht. Immerhin hat das gegenüber SSH den Vorteil, daß kein spezieller Client benötigt wird und ein Browser mit JavaScript-Unterstützung vollkommen ausreichend ist. Dieser "temporäre Charakter" ist auch der Grund, warum ich gar nicht in Erwägung gezogen habe, die ShellInABox-Instanz "nur bei Bedarf" zu starten, was ja als CGI auch problemlos möglich wäre oder sie gar in die Reste der ShellInABox-Integration von AVM wieder einzubetten.

    Für eine dauerhafte Verwendung (auch wenn diese Modifikation mit ShellInABox ebenfalls schon dauerhaft ist) empfehle ich nach wie vor die Verwendung von modfs, da gibt es irgendwann auch mal eine verbesserte Version von mir.

    Wer nur sehr selten mal einen Zugriff auf die Kommandozeile der FRITZ!Box benötigt und mit der ShellInABox-Lösung schon zufrieden ist, der braucht natürlich auch nichts weiter zu machen.

    Will man das installierte ShellInABox ohne Update oder Recovery wieder loswerden, ruft man in einer Shell-Session "sh /wrapper/remove_custom.sh" auf - dann wird ein Flag in der yaffs2-Partition gesetzt, anhand dessen beim nächsten Systemstart die Erweiterung nicht erneut initialisiert wird und damit dann auch gelöscht werden kann (und auch gelöscht wird). Im aktuell laufenden System müßte man da einiges aufräumen, das vermeiden wir durch das Entfernen beim nächsten Start.
     
  3. PeterPawn

    PeterPawn IPPF-Urgestein

    Registriert seit:
    10 Mai 2006
    Beiträge:
    11,793
    Zustimmungen:
    666
    Punkte für Erfolge:
    113
    Beruf:
    IT-Freelancer
    Ort:
    Berlin
    #3 PeterPawn, 16 Dez. 2015
    Zuletzt bearbeitet: 20 Dez. 2015
    Wie funktioniert's?

    Und nun kommen wir dazu, wie das Ganze am Ende funktioniert und warum da vollkommen ohne Auspacken, Modifizieren und wieder Einpacken des Root-Filesystems ein "bleibender Eindruck" im FRITZ!OS hinterlassen wird. Ab hier wird es technisch, weitere Informationen zum Einsatz kommen nicht mehr ... wer verstehen will, was beim "Update" passiert und das ggf. für eigene Zwecke anpassen will, der sollte aber weiterlesen.

    Die FRITZ!Boxen, über die wir hier reden, haben ja (m.W.) alle zwei verschiedene Systeme in ihrem NAND-Flash, für jedes System gibt es eine 4 MB große Kernel-Partition und eine 48 MB große Partition für das Dateisystem. Das ist ja jede Menge Platz ... und bei der 06.50 für die 7490 belegt das eigentliche Root-Filesystem als SquashFS-Image gerade mal 18,4 MB von diesen 48 vorhandenen - mit ein paar Files "außen herum" ergibt sich dann immer noch eine Belegung kleiner 22 MB in dieser Partition (das ist praktisch dieselbe Größe, wie sie die Datei "filesystem.image" in einem originalen Update-Image hat). Den schönen Platz in dieser Partition ungenutzt zu lassen, wäre ja fast sträflich - also nutzen wir ihn ab heute für die Speicherung unserer Erweiterungen.

    Wenn wir eigene Dateien in diese Partition schreiben, überleben die weder ein Firmware-Update (bzw. sie stehen dann nur noch in der inaktiven Partition) noch die Verwendung des Recovery-Programms für die FRITZ!Box (hier sind sie dann wirklich weg). Egal ob mit Freetz, dem AVM-Original oder "modfs", jedes Update löscht auch wieder den hier installierten Zusatz (und zwar absichtlich, das soll sich gar nicht "festkrallen" im System).

    Diese Dateisystem-Partition verwendet als Filesystem yaffs2, das ist ein Dateisystem extra für NAND-Flash ... aber eben eines, was auch Schreibzugriffe gestattet und genau das machen wir uns zunutze.

    Jetzt muß ich etwas ausholen und den Bootvorgang bei einer solchen Box erklären. Der Kernel wird "ganz normal" geladen und greift als erstes auf die yaffs2-Partition als root-Device zu. Dort liegt neben ein paar wenigen Dateien (in erster Linie eine Busybox mit benötigten Libraries) ein SquashFS-Image, das unterhalb des Wurzelverzeichnisses gemountet wird (als /core) und dann wird mit "pivot_root" auf dieses SquashFS-Filesystem umgeschaltet. In der /etc/inittab in der yaffs2-Partition sieht das so aus:
    Code:
    null::sysinit:/bin/mount -t squashfs /filesystem_core.squashfs /core -o loop [COLOR="#FF0000"]<=== neues root-Dateisystem mounten[/COLOR]
    null::sysinit:/sbin/pivot_root /core/ /core/wrapper/                         [COLOR="#FF0000"]<=== Umschalten auf dieses Dateisystem als neue Wurzel, das alte landet unterhalb von /wrapper[/COLOR]
    null::sysinit:/bin/mount /wrapper/dev /dev -o bind                           [COLOR="#FF0000"]<=== "Spiegelung" von /dev aus dem originalen Dateisystem unterhalb der neuen Wurzel mounten, ist nur bei 06.50 bisher so meines Wissens[/COLOR]
    null::sysinit:/wrapper/sbin/flash_update                                     [COLOR="#FF0000"]<=== darauf kommen wir gleich im Text zurück[/COLOR]
    #
    /dev/ttyS0::sysinit:/etc/init.d/rc.S                                         [COLOR="#FF0000"]<=== hier startet jetzt "init" die Initialisierung des FRITZ!OS[/COLOR]
    
    # Start an "askfirst" shell on ttyS0
    /dev/ttyS0::askfirst:-/bin/sh
    
    # Stuff to do before rebooting
    /dev/ttyS0::shutdown:/bin/sh -c /var/post_install
    
    Die Einträge in der "inittab" werden streng in dieser Reihenfolge abgearbeitet (für die jeweilige Aufrufbedingung, in diesem Falle eben "sysinit") - damit startet jedes folgende Kommando erst dann, wenn das vorhergehende beendet wurde.

    Das macht sich AVM an dieser Stelle auch bei Recovery zunutze, dort werden ein Kernel und ein Dateisystem ins RAM geladen und direkt von dort gestartet. Im Rahmen der Abarbeitung der /etc/inittab kommt dann irgendwann auch das Shell-Skript /sbin/flash_update an die Reihe, das nur dann eine echte Funktion erfüllt, wenn es von eben diesem System (nach Recovery) im RAM der Box aufgerufen wird. Dann beendet es sich nämlich nicht einfach, damit die Abarbeitung der "inittab" weitergehen kann ... nein, in diesem Falle schreibt es sowohl den Kernel als auch das Dateisystem aus dem RAM in die gerade aktiven Partitionen im Flash (deshalb wird bei Recovery auch immer die aktive Partition beschrieben) und startet anschließend die Box noch einmal neu, diesmal dann natürlich aus dem Flash-Speicher. Dieser Zwischenschritt ist auch der Grund, warum man eine solche Box nach dem Ende des Recovery-Programms erst einmal von selbst starten lassen muß und ihr nicht einfach den Stecker ziehen darf (z.B. um sie wieder vom PC an ihren eigentlichen Aufstellort zu schaffen) - solange das System nicht erfolgreich in den Flash-Speicher kopiert wurde, ist Recovery nicht abgeschlossen.

    Abseits von einem solchen Aufruf bei Recovery hat das Skript "flash_update" dann aber gar keine Funktion mehr und beendet sich unmittelbar wieder, wenn es feststellt, daß das System nicht aus dem RAM gestartet wurde. Man könnte also genauso gut hingehen und diese Zeile aus der /etc/inittab im Rahmen des Recovery-Laufs auch noch löschen, aber das wäre nur Kosmetik. Wenn so ein Eintrag aber schon mal existiert, können wir ja auch in diese Datei einfach unsere eigenen Befehle schreiben ... gäbe es den Eintrag in der "inittab" nicht, müßten wir halt einen eigenen anlegen.

    Genau so geht dieses "Update" jetzt auch vor ... es schreibt einfach eine neue Datei /sbin/flash_update in das yaffs2-Dateisystem, die dann im Rahmen der Initialisierung des Systems aufgerufen wird. Dort kann man natürlich jetzt nicht einfach eigene Programme starten, denn das FRITZ!OS ist zu diesem Zeitpunkt noch im Embryonal-Stadium und muß wenigstens erst mal bis zur Einschulung kommen, bevor wir mit ihm irgendetwas anfangen können. Daher wird die Datei mit folgendem Inhalt gefüllt:
    Code:
    #! /bin/sh
    #
    # version for kernel 3.10.73 - AVM firmware 06.50+ (assumption only)
    #
    # create a shell script to be called from a detached shell
    # only /dev is writable here, it's very early after kernel was loaded
    #
    cat >/dev/delayed_start.sh <<'EOT'
    [COLOR="#008000"]#
    # let the OS settle a bit
    #
    sleep 5
    #
    # wait until tmpfs is mounted on /var
    #
    while true; do
            grep -q "^tmpfs /var tmpfs" /proc/mounts 2>/dev/null && break
            sleep 2
    done
    #
    # check for "uninstall" request
    # wait until start has finished in this case, we'll use the running "run_clock"
    # as "decision helper"
    #
    if [ -f /wrapper/remove_custom.flag ]; then
            while true; do
                    pidof run_clock >/dev/null 2>&1 && break
            done
            mount -o remount,rw /wrapper
            rm /wrapper/remove_custom.flag
            rm /wrapper/remove_custom.sh
            rm /wrapper/filesystem_custom.squashfs
            echo "exit 0" >/wrapper/sbin/flash_update
            sync
            mount -o remount,ro /wrapper
            exit 0
    fi
    #
    # mount our additional SquashFS image to /var/custom
    #
    mkdir -p /var/custom
    mount -t squashfs /wrapper/filesystem_custom.squashfs /var/custom
    grep -q "^/dev/loop[0-9] /var/custom squashfs" /proc/mounts || exit 1
    #
    # wait until lan device was started
    #
    while true; do
            ifconfig lan 2>/dev/null | grep -q ".*UP.*RUNNING.*" && break
            sleep 2
    done
    #
    # start the init script (etc/init.d/rc.custom) of the mounted extension
    #
    nohup sh /var/custom/etc/init.d/rc.custom >/var/tmp/rc.custom.log 2>&1 &
    [/COLOR]EOT
    #
    # start a detached shell to execute the created script, we've to exit here
    # to let the init process continue
    #
    nohup sh /dev/delayed_start.sh >/dev/delayed_start.out 2>&1 &
    exit 0
    
    Das erste Problem ist es schon einmal, daß es zu diesem Zeitpunkt nur begrenzte Möglichkeiten gibt, irgendwo eigene Dateien zu erzeugen ... selbst das tmpfs unter /var ist noch nicht gemountet und kommt erst später im Rahmen der Initialisierung des Systems dazu. Gleichzeitig können wir aber nicht einfach abwarten, bis es soweit ist, denn - wir erinnern uns - die Abarbeitung erfolgt zu diesem Zeitpunkt streng sequentiell und das System wird erst initialisiert, wenn wir unser Skript beendet haben. Also müssen wir irgendwie einen gesonderten Prozess erstellen, der beim Ende unseres Skripts nicht ebenfalls abgeräumt wird. Dazu schreiben wir den grün markierten Teil in eine Datei unterhalb von /dev (da können wir nämlich schon hineinschreiben bei der 06.50) und starten eine weitere Shell-Instanz, die beim Beenden von "flash_update" nicht beendet wird (nohup), anschließend wird "flash_update" beendet, damit "init" weitermachen kann. Bei früheren Versionen ist /dev nicht beschreibbar, daher wird dort das Skript zum Starten nicht inline vorgehalten und dynamisch erzeugt, dort gibt es ein gesondertes Skript im yaffs2-Dateisystem, das dann gestartet wird. Da das "nohup"-Kommando einen sinnvollen File-Descriptor für stdout und stderr benötigt, werden diese beiden Kanäle bei der "vor 06.50"-Version nach /dev/null umgeleitet.

    Im grünen Teil (der steht bei < 06.50 als feste Datei "start_custom.sh" unterhalb von "/wrapper" und liegt nicht mehr inline vor) geben wir dann dem Initialisierungsprozess erst einmal 5 Sekunden Zeit, ein paar grundlegende Arbeiten zu verrichten und anschließend prüfen wir im Abstand von 2 Sekunden, ob inzwischen das tmpfs unterhalb von /var gemountet wurde (das sollte schon nach den 5 Sekunden Warten passiert sein, aber Testen schadet nicht). Haben wir dann ein beschreibbares Verzeichnis, legen wir uns einen Mount-Point /var/custom an und mounten dort ein weiteres SquashFS-Image, welches wir parallel zur Änderung der "flash_update" in das yaffs2-Dateisystem kopiert haben und das unsere zusätzlich benötigten Dateien enthält. Das müßte zwar kein SquashFS sein, aber erstens sind alle notwendigen "Zutaten" dafür bereits im FRITZ!OS vorhanden und zweitens kriegt man so wesentlich mehr in dieser Partition unter (auch wenn es in diesem konkreten Fall noch keine Rolle spielt). Nach einer Prüfung auf erfolgreiches Mounten unseres Zusatz-Images prüfen wir jetzt, ob das LAN-Interface der Box (genauer die "lan"-Bridge) initialisiert wurde - ansonsten warten wir in 2-Sekunden-Intervallen, bis es soweit ist. Auch das müßte eigentlich nicht sein ... aber ehe jetzt jemand auf die Idee kommt, gleich als erste Aktion im weiteren Verlauf irgendeinen Service zu starten, der ein funktionierendes lokales Netz braucht und das Warten darauf "vergißt", sorgen wir lieber gleich dafür, daß man da nichts falsch machen kann.
    Ach so ... innerhalb des Start-Skripts prüfen wir auch noch, ob vor dem letzten Neustart das Entfernen unserer Erweiterung angeordnet wurde. In diesem Fall installieren wir sie nicht, sondern löschen alle "Dateireste" aus dem yaffs2 und nach dem nächsten Neustart ist dann wirklich alles restlos entfernt und man sieht nur noch an der leeren "flash_update", daß da jemals etwas vorhanden war. Zurück zum "Normalfall" ...

    Steht dann irgendwann auch das Netzwerk zur Verfügung, wird ganz simpel (in einem weiteren "detached process") ein Initialisierungsskript aus unserem Zusatz-Image gestartet ... das ist dann - bis auf den etwas früheren Zeitpunkt - im Prinzip dasselbe wie die "rc.custom" im Freetz oder die "debug.cfg" in früherer Firmware. Die im verlinkten Archiv enthaltene Datei sieht ganz simpel so aus:
    Code:
    #! /bin/sh
    #
    # we need some additional libraries from our custom extension
    #
    export LD_LIBRARY_PATH=/var/custom/lib:/lib
    #
    # start a ShellInABox instance on Port 8010 only supporting TLS connections to establish a secure handling from LAN
    #
    /var/custom/usr/bin/shellinaboxd --port=8010 --user=0 --group=0 --cert-from-box --background --pidfile=/var/run/shellinaboxd.pid --no-sni --disable-ssl-menu --service=/:0:0:/var/media/ftp:/sbin/ar7login
    #
    # it's possible to start a telnet instance too, but we should avoid it due to password submission as clear-text
    # uncomment the lines below to establish a permanent telnet service, which isn't controlled by the 'telefon' daemon
    #
    #/var/custom/bin/busybox telnetd -l /sbin/ar7login
    
    Es wird also nur die vorliegende ShellInABox-Version gestartet, mehr soll dieses Image gar nicht leisten ... was man damit noch bauen kann/könnte, bleibt der Phantasie des Lesers überlassen. Daher gibt es in dem zusätzlichen SquashFS-Image auch nur folgende Dateien (hier aus der Variante für SquashFS 4):
    Code:
    -rwxr-xr-x 1 root root 917748 Dec 15 10:23 ./bin/busybox                    [COLOR="#0000FF"]eine besser ausgestattete Busybox[/COLOR]
    -rw-r--r-- 1 root root    727 Dec 15 13:37 ./etc/init.d/rc.custom           [COLOR="#0000FF"]das oben gezeigte Start-Skript[/COLOR]
    -rwxr-xr-x 1 root root   9298 Dec 15 10:27 ./lib/libprivatekeypassword.so   [COLOR="#0000FF"]wird für die Nutzung des FRITZ!Box-Zertifikats benötigt[/COLOR]
    -rwxr-xr-x 1 root root   4688 Dec 15 10:24 ./usr/bin/privatekeypassword     [COLOR="#0000FF"]ebenfalls für die Benutzung des Zertifikats, eigentlich aber sogar überflüssig, weil die lib reichen würde[/COLOR]
    -rwxr-xr-x 1 root root 339964 Dec 16 06:57 ./usr/bin/shellinaboxd           [COLOR="#0000FF"]das ShellInABox-Programm[/COLOR]
    
    Die Patches gegen den Freetz-Trunk zur Erzeugung meines privatekeypassword-Pakets in Version 0.5 und für die Verwendung des FRITZ!Box-Zertifikats mit ShellInABox habe ich schon früher hier irgendwo veröffentlicht, sie stehen aber auch noch einmal "frisch" auf dem Server unter der URL http://yourfritz.de/shellinabox_freetz_13504.patch - werden aber von mir an Änderungen der Basispakete im Freetz nicht mehr angepaßt. Die Konfiguration der Busybox ist "selbsterklärend", dort ist "bbconfig" als Applet enthalten und sie wurde extra mit dem Freetz-Trunk erstellt, damit die Build-Umgebung auch stimmt. Damit sind die Forderungen der GPLv2 hoffentlich auch erfüllt.

    Bleibt also nur noch die Frage, wie wir diese Änderungen jetzt in das yaffs2-Dateisystem bringen ... dazu enthält das Archiv das folgende "install"-Skript:
    Code:
    #! /bin/sh
    export INSTALL_SUCCESS_REBOOT=1
    export INSTALL_OTHER_ERROR=6
    wrapper=/wrapper
    custom=custom
    mount -o remount,rw $wrapper
    grep -q "^/dev/root $wrapper yaffs rw.*" /proc/mounts || exit $INSTALL_OTHER_ERROR
    [ -r /var/tmp/filesystem.image ] || exit $INSTALL_OTHER_ERROR
    cp -a /var/tmp/filesystem.image $wrapper/filesystem_$custom.squashfs
    [ $? -ne 0 ] && exit $INSTALL_OTHER_ERROR
    cat >$wrapper/sbin/flash_update <<ENDOFSCRIPT
    [COLOR=#008000]#! /bin/sh
    #
    # version for kernel 3.10.73 - AVM firmware 06.50+ (assumption only)
    #
    # create a shell script to be called from a detached shell
    # only /dev is writable here, it's very early after kernel was loaded
    #
    cat >/dev/delayed_start.sh <<'EOT'
    #
    # let the OS settle a bit
    #
    sleep 5
    #
    # wait until tmpfs is mounted on /var
    #
    while true; do
        grep -q "^tmpfs /var tmpfs" /proc/mounts 2>/dev/null && break
        sleep 2
    done
    #
    # check for "uninstall" request
    # wait until start has finished in this case, we'll use the running "run_clock"
    # as "decision helper"
    #
    if [ -f $wrapper/remove_$custom.flag ]; then
        while true; do
            pidof run_clock >/dev/null 2>&1 && break
        done
        mount -o remount,rw $wrapper
        rm $wrapper/remove_$custom.flag
        rm $wrapper/remove_$custom.sh
        rm $wrapper/filesystem_$custom.squashfs
        echo "exit 0" >/wrapper/sbin/flash_update
        sync
        mount -o remount,ro /wrapper
        exit 0
    fi
    #
    # mount our additional SquashFS image to /var/$custom
    #
    mkdir -p /var/$custom
    mount -t squashfs $wrapper/filesystem_$custom.squashfs /var/$custom
    grep -q "^/dev/loop[0-9] /var/$custom squashfs" /proc/mounts || exit 1
    #
    # wait until lan device was started
    #
    while true; do
        ifconfig lan 2>/dev/null | grep -q ".*UP.*RUNNING.*" && break
        sleep 2
    done
    #
    # start the init script (etc/init.d/rc.$custom) of the mounted extension
    #
    nohup sh /var/$custom/etc/init.d/rc.$custom >/var/tmp/rc.$custom.log 2>&1 &
    EOT
    #
    # start a detached shell to execute the created script, we've to exit here
    # to let the init process continue
    #
    nohup sh /dev/delayed_start.sh >/dev/delayed_start.out 2>&1 &
    exit 0[/COLOR]
    ENDOFSCRIPT
    cat >$wrapper/remove_$custom.sh <<ENDOFREMOVE
    [COLOR=#0000FF]mount -o remount,rw $wrapper
    touch $wrapper/remove_$custom.flag
    sync
    echo "The $custom extension will be removed during next restart."
    exit 0[/COLOR]
    ENDOFREMOVE
    sync
    mount -o remount,ro $wrapper
    exit $INSTALL_SUCCESS_REBOOT
    
    Der grüne Teil ist genau der gewünschte Inhalt der "flash_update"-Datei, der wird halt von "inline" in die Datei geschrieben im Rahmen der Installation, der blaue Part dient zur optionalen Deinstallation der gesamten Erweiterung (siehe weiter oben). Wichtiger ist aber der Beginn der /var/install ... wir müssen nämlich erst einmal das eigentlich nur read-only gemountete yaffs2-Dateisystem beschreibbar machen, das geht ganz einfach mit der "remount"-Option. Ergibt die anschließende Überprüfung, daß es jetzt beschreibbar ist und existiert die Datei /var/tmp/filesystem.image aus unserem Update-Image, wird diese unter dem Namen "filesystem_custom.squashfs" in die Wurzel des yaffs2-Filesystems kopiert. Anschließend noch den neuen Inhalt nach /sbin/flash_update geschrieben nebst dem Skript zum Entfernen der Erweiterung und - nach einem Schreiben der noch ausstehenden Buffer - wir versuchen das yaffs2-Dateisystem der Ordnung halber (eigentlich umsonst) noch zurück auf "read-only" zu mounten (der Erfolg ist uns aber egal). Anschließend startet dann das FRITZ!OS die Box neu.

    Das war dann auch schon die ganze Geschichte ... wie man beim "Mitdenken" sicherlich sofort erkennen konnte, ist das wieder eine Art "Framework" - was am Ende installiert und ausgeführt wird, entscheidet allein der Inhalt der Datei "filesystem.image" im tar-Archiv. Tauscht man das gegen eigene Sachen aus und paßt die rc.custom darin entsprechend an, kann man praktisch wieder alles machen, was einem so in den Sinn kommt - der Vorteil ggü. der Verwendung von /var/media/ftp (also des offiziell nach außen zur Verfügung gestellten internen Flash-Speichers) ist es für meinen Anwendungszweck gewesen, daß man systemspezifische Erweiterungen eben genau dem jeweiligen System zuordnen kann und unter /var/media/ftp dann eben nur das ablegt, was beide Versionen in der FRITZ!Box benutzen können und sollen ... bei mir waren es ja seit dem Erscheinen der 06.35-Laborreihe immer zwei verschiedene Systeme, damit ich ohne Reue testen konnte.

    Damit könnte man z.B. ein richtiges "install image" für den LCR bauen oder auch wieder Perl und FHEM auf die Box bringen, wobei für FHEM vielleicht der Platz im yaffs2 schon wieder etwas eng wird und man das ggf. teilen muß.
     
  4. Micha0815

    Micha0815 IPPF-Promi

    Registriert seit:
    25 Feb. 2008
    Beiträge:
    3,016
    Zustimmungen:
    110
    Punkte für Erfolge:
    63
    Beruf:
    Stauberater
    #4 Micha0815, 21 Jan. 2016
    Zuletzt bearbeitet: 20 Feb. 2016
    Wie zu Ewarten

    funktioniert es nicht mehr mit "FRITZ.Box_7490_Labor.113.06.51-32225" geupdated von 113.6.50 kommend.

    Screenshot folgt wg. "Image zu klein" ... muss ich erst nachlesen wegen Forensoft wie anhängen.

    Angehängt

    LG





    P.S.: Upps falls im falschen Thread und mein individuelles Problem, poste ich unter Löschung hier nochmals

    Anmerkung: Ein Downgrade via GUI von FW 6.51(-xxxxx) auf 6.50 - um dieses Pseudo-Image nutzen zu können, geht nur über die 6.50-Recovery. Für Schnelleinsteiger, die wie ich nicht ganz so bewandert, lass ich dies mal als Hinweis so Stehen.



     

    Anhänge: