 So, dann sind wir bereit anzufangen. Der Titel dieses Vortrags lautet Go Crazy. Mein Name ist Michael Stapelberg. Schön, dass ich euch hier begrüßen kann zu diesem Vortrag. Zunächst mal gehen wir über die Agenda. Ich möchte zuerst mal motivieren, warum ich das Projekt angefangen habe. Und dann gebe ich ein Übersicht, warum es sich dabei eigentlich handelt. Ich werde eine Live-Demo vorführen, damit ihr ein besseres Verständnis davon bekommen, was es eigentlich ist. Denn ich kann ganz viel beschreiben, aber es ist einfacher, wenn man sieht, was da passiert. Nachdem das dann gründlich in die Hose gegangen ist, werde ich auf die unterstützte Hardware und die Cross-Compilation dafür eingehen. Ich werde euch erklären, was genau das Projekt mit Partitionen, Dateisystems, Updates und dergleichen zu tun hat. Dann werden wir auf die einzelnen Bestandteile eingehen, nämlich Firmware, Kernel und wie man die jeweils aktualisiert bei uns. Und dann werde ich ein paar Anwendungsfälle vorstellen, die ich tatsächlich mit dem Projekt betreibe, bevor wir letztendlich zu Fragen kommen. Wenn es irgendwelche superwichtigen Fragen gibt während des Vortrags, bei denen ihr denkt, dass ihr, wenn ihr die jetzt nicht sofort stellen könnt, abgehängt werdet, dann einfach die Hand heben, dann versuche ich sie dran zu nehmen, ansonsten gerne am Ende. Zunächst mal zur Motivation. Der Raspberry Pi ist jetzt schon seit einigen Jahren auf dem Markt. Vor fünf Jahren wurde er erstmals released. Damals 2012 war ich in einem Hackerspace namens Raumzeitlabor aktiv und wir hatten am Hausbusprojekt gearbeitet. Das war so ein ROS 485 basierter Verkabelungsding für verschiedene Geräte, die irgendwie miteinander sprechen sollten. Also man kennt das so aus seinem Lieblingshackerspace, hat man irgendwie eine Kasse und ein Musikplayer und ein Türschloss und alle diese heutzutage würde man fast sagen Internet of Things-Devices, die irgendwie miteinander reden sollen. Und wir hatten das so gebastelt auf Basis von Mikrocontrollern und ROS 485 und die Leute, die sich mit der Materie auskennen, werden feststellen, oh, ROS 485 ist echt kein Hexenwerk, aber es war damals trotzdem furchtbar frickelig und schwierig und kompliziert, vor allem weil wir diese Firmware eben von Grund auf neu schreiben wollten und in C und auf Mikrocontrollern und das ging mir furchtbar auf die Nerven. Und dann kam der Raspberry Pi und ich dachte, oh Gott, was für eine Erlösung. Auf einmal konnte man Hochsprachen verwenden auf einem einigermaßen gut ausgestatteten Computer für sehr wenig Geld, der auch noch in der Lage war, mit Low Level Hardware relativ einfach verbunden zu werden. Und seither habe ich Automatisierung sowohl bei mir zu Hause als auch wo auch immer ich sie gerade brauche, grundsätzlich nur noch in Hochsprachen geschrieben und lass sie auf Raspberry Pi laufen. Also Mikrocontroller sind für mich einfach komplett uninteressant geworden dadurch. Der Ansatz, den ich damals hatte, um die Images herzustellen, die ich auf dem Raspberry Pi betrieben habe, war, dass ich in ein eigenes Bildskript geschrieben habe. Man fragt sich vielleicht, warum überhaupt Images und die Antwort ist, dass wenn man sich Embedded Devices anschaut, die über längere Zeit laufen, also über einen Zeitraum von vielen Jahren, dann ist das erste Teil, was üblicherweise kaputt geht, ganz egal, was es für ein Gerät ist, das Speichermedium, wenn man die ganze Zeit da drauf schreibt. Also egal, ob man jetzt eine CF-Card irgendwie in seiner Firewall-Lösung hat, wie wir das damals im Raumzeitlabor hatten oder eine SD-Card im Raspberry Pi, wenn man da die ganze Zeit drauf schreibt, dann geht die irgendwann kaputt, die ist nicht dafür gedacht. Und deswegen hatte ich gedacht, dann mache ich einfach ein Betriebssystem Abbild, welches Read-Only ist, also keinerlei Schreibvorgänge macht und damit auch andere Leute nachverfolgen können und reproduzieren können, wie ich dieses Setup mache, sollte das auch irgendwie dokumentiert sein und das endete dann letztendlich in so einem kleinen Programm, welches, wenn man es ausführte, eben einen Raspberry Pi Abbild ausgespuckt hat. Soweit so gut, aber das Problem davon war, dass die Updates größere Blöcke an zusammenhängender Zeit erfordert haben. Das heißt, man musste sich irgendwie mehrere Stunden nehmen, bis man dann irgendwie das Skript aktualisiert hat, damit die neue Version von der speziellen Embedded Debian-Variante, die ich damals benutzt habe, dann irgendwie überhaupt erstmal durchläuft und dann hängt sich das auf und dann muss man das debaggen und dann verklemmt sich der Mount und man muss seinen Rechnerributen und so weiter und so weiter und dann flasht man das auf seinen Raspberry Pi und dann ist er erstmal kaputt und dann ist man frustriert und gibt vielleicht auf und dann ist alles schlecht. Und vor allem findet man Fehler dann vielleicht auch erst viel später und das Endresultat davon war dann, dass ich, nachdem ich 2013 angefangen habe, Vollzeit zu arbeiten, das letzte Image gebaut habe und bis 2017 im Einsatz gehabt habe. Das ist natürlich furchtbar schrecklich. Sicherheitslücken sammeln sich über vier Jahre an und man hat irgendwie in ein furchtbar unsicheres Gerät zu Hause rumstehen. Das will man natürlich nicht haben und nicht verantworten. Deswegen dachte ich mir, wie kann man das denn besser machen? Und dafür habe ich mir folgende Fragen gestellt. Frage Nummer eins. Kann man die Angriffsfläche von so einem typischen Raspberry Pi auf dem eigentlich nur vielleicht ein, zwei oder eine kleine Handvoll eigene Programme laufen, drastisch reduzieren? Also muss da überhaupt ein vollwertiges Linux laufen, muss da überhaupt eine Shell drauf sein, muss da überhaupt Image Magic drauf sein. All diese Programme, über die man täglich irgendwie neue Security Warnings in seiner Inbox hat. Der zweite Punkt. Kann man Updates komplett automatisieren? Nachdem ich die Modelle gesehen habe, wie zum Beispiel CoreOS oder den Tourist Omnia Router, die sich komplett selbstständig automatisieren, habe ich versucht, möglichst alle meine Geräte auf dieses Modell umzustellen. Weil ich gemerkt habe, dass ich persönlich einfach weder die Zeit noch die Motivation habe, seit irgendwelche blöden Updates einzuspielen. Ich will eigentlich Sachen machen und nicht Sachen aktualisieren. Die dritte Frage ist, kann man die Einrichtung eines Raspberry Pi drastisch vereinfachen? Also was ist eigentlich die Hürde, wenn man sagt, ich habe hier so eine coole Idee und ich möchte gerne umsetzen, aber da müsste ich diesen Raspberry Pi aufsetzen und warten und so weiter. Kann man da irgendwie was machen? Und wir kommen später noch darauf zurück und beantworten diese Fragen. Zunächst kurz als Übersicht über Go Crazy. Go Crazy beschreibt ein Projekt, welches Programme, die man in Go geschrieben hat, auf einem Raspberry Pi zu betreiben. Was braucht man dafür? Man braucht ein Kernel, das ist Linux. Was braucht man sonst noch? Naja, ein Innitsystem wäre wahrscheinlich auch ganz gut. Dann haben wir also eins in Go implementiert. Das Innitsystem ist stark integriert. Das heißt, das hat ein Webinterface gleich schon dabei. Es hat Logging dabei und es hat ein Updatemechanismus dabei. Da könnte man sagen, was bist du verrückt? Wieso kommt das alles in dein Innitsystem und das sind valide Punkte. Aber schauen wir es uns mal genauer an und dann können wir noch mal drüber reden. Zusätzlich zu dem Innitsystem, welches die einzelnen Prozesse startet, braucht man natürlich auch noch ein paar Userland Utilities. Wir haben ein sehr, sehr minimales Userland dabei. Wir haben derzeit einen NTP-Kleint und ein DHCP-Kleint. Und den ganzen Rest, z.B. sich um IPv6-Adressen zu kümmern, macht Linux selber. Jetzt wird es Zeit für eine Demo. Was ich vorbereitet habe hier, ich setze mich mal kurz hin. Für diese Demo ist an meinem Computer sind ganz viele USB-Geräte angeschlossen und Dongles und so weiter. Was ich hier habe, ist ein Cardreader, mit dem ich gleich die SD-Karte beschreiben werde für den Raspberry Pi. Der Raspberry Pi habe ich mit einem USB-2 Serial-Adapter an meinen Computer angeschlossen, damit wir sehen können, dass der auch wirklich bootet. Ansonsten ist es einfach ein ganz normaler, handelsüblicher Raspberry Pi 3, den ich mir bestellt habe. Und übers Netzwerk ist er an meinem Computer angeschlossen und deswegen brauche ich natürlich auch noch ein DHCP-Server. Ich simuliere also hier quasi wieder so, wenn mir zu Hause laufen würde, abgesehen natürlich von der serialen Schnittstelle, weil ich die nicht permanent dran lasse. So, was wir jetzt also zuerst mal machen können, ist, wir können schauen, dass der SD-Cardreader ordentlich erkannt wurde. Man sieht ja noch die alten Daten auf der SD-Karte. Da können wir einfach mal mit Def Zero die SD-Karte kurz löschen. So, jetzt ist die Partition Table weg und ihr könnt euch sicher sein, dass die Demo also ab jetzt nicht mehr gefaked ist, weil jetzt würde der Raspberry Pi gar nicht booten. So, was wir jetzt machen, ist, wir benutzen einen Tool namens Go Crazy Packer. Das ist das eigentliche Programm, mit dem man Go Crazy-Abbilder zusammenpackt und auf eine SD-Karte schreiben. Und da benutzen wir hier den ersten Use Case. Wir möchten nämlich eine komplette SD-Karte bespielen. Dann sagen wir hier also Def-SDB, die wir gerade leer gerannt haben. Und da müssen wir angeben, welche Go-Programme wir darauf haben wollen. Da sage ich github.com slash gocrazy slash hello. Das ist einfach ein Hello World. Dann sagt er, okay, was er im Hintergrund jetzt macht, ist, dass er es cross-compiled. Und dann schreibt er das auf Def-SDB, partitioniert das und so weiter und so weiter. Und jetzt sind wir fertig. So, jetzt sagt er, to boot Go Crazy, plug die SD-Karte into a Raspberry Pi 3. Das machen wir jetzt mal, ich steck sie hier raus. Dann nehme ich den Raspberry Pi und steck sie hier rein. Zack. Die URL wird gleich noch wichtig. Aber was wir jetzt erstmal machen, ist den USB to serial aufzumachen. Und jetzt nehme ich hier das USB-Kabel für Strom und steck das hier rein. Jetzt sehen wir in einer Sekunde, dass er nachdem er den Kernel geladen hat, einfach einen Linux bootet. Und der Bootvorgang ist jetzt auch schon fertig. Also die einzige Meldung, die hier relevant ist, die von Go Crazy kommt, und die kleine Zeile, da sagt er, okay, das ist der Build Timestamp. Ihr seht 17.11, also das ist wirklich auch die Version, die ich gerade eben zusammengebaut habe. Und jetzt kommen wir hier also nochmal zurück zu der URL. Und ich mach das hier einfach mal auf. Und jetzt sehen wir hier einen Web-Interface. Ich scroll einfach mal kurz drüber. Also man sieht hier so eine Liste an Diensten, die gerade laufen. Man sieht, der DHCP-Dienst läuft, und man sieht hier, wie man das Gerät hat, und wie der verwendet wird. Und wir sehen, wie viel permanenten Festspeicher er hat. Da können wir nachher noch drüber reden, und welche Netzwerkadressen er hat. Wenn ich das jetzt nochmal refreshe, dann sehen wir, dass sich der NTP-Klein mittlerweile gefangen hat. Gut, der kriegt jetzt keinen NTP hin, weil ich keinen Forwarding aktiviert habe auf meinem Computer. Aber wir sehen auch, dass das Hello-Programm läuft und die ganze Zeit Hello ausgibt und grundsätzlich lang laufend. Bei DHCP sehen wir, dass er am Anfang beim Boot das Netzwerk-Interface noch nicht fertig hatte, aber danach hat er sich erfolgreiche DHCP-Leaks geholt. So, soweit so gut. Jetzt haben wir also die Grundlagen schon mal etabliert. Gut. So, an unterstützter Hardware unterstützen wir exakt den Raspberry Pi 3. Wir unterstützen keinen anderen Raspberry Pi. Viele Leute, wenn Sie von dem Projekt online erstmals lesen, haben den Raspberry Pi 0W, was ja der ganz aktuelle ist irgendwie für den Zener, den unterstützen wir leider nicht. Und das liegt daran, dass die Anforderungen sind, dass wir einfach einen upstream Linux-Körnel nehmen möchten und den, so wie er ist, einfach für den Raspberry Pi kompellieren und benutzen möchten. Das ist derzeit nur mit dem Raspberry Pi 3 möglich. Wir benutzen den Linux-Körnel in der ARM 64-Variante und bauen den reproduzierbar. Das zeige ich auch nachher noch, wie das funktioniert. Das heißt, der Raspberry Pi 0W schadet aus, weil er nur wählen kann und wir können derzeit noch keinen wählen. Ob wir es jemals können, steht in den Sternen, aber es gibt eine GitHub-Issue, wo man das diskutieren kann, falls man da Interesse daran hat. Und zu guter Letzt ist auch ein weiterer Grund, dass wir die Testmatrix möglichst kleinhalten wollen. Also wenn wir jetzt anfangen und sagen, wir unterstützen alle möglichen Raspberry Pies, dann muss man ja auch immer schauen, dass die alle gut funktionieren. Ich will ja nicht, dass ihr euch mit automatischen Updates eine leicht andere Hardware-Konfiguration habt. Allein schon bei dem Wechsel vom Raspberry Pi 2 auf 3. Wenn man sich da mal anschaut, was mit dem serialen Port passiert ist, dann sieht man, das ist alles ziemlich kompliziert. Selbst das ist nur ein sehr kleines Detail. Wenn dann der nächste Raspberry Pi release wird, müssen wir mal schauen, ob wir den 4er und den 3er unterstützen. Aber das ist auch noch eine ganze Weile hin. Als Randnotiz, ich weiß nicht, wer es schon mal gemacht hat, aber Cross-Compilation in Go ist super einfach. Das ist das erste, wo ich angefangen habe, zu schauen, ob das Projekt umsetzbar wäre. Ich habe hier als ersten Bulletpoint oft die Folie gepackt, wie man ein Go-Paket installiert, also kompiliert und installiert. Das ist einfach mit Go-Install und dann den Fahrt zu dem Paket. Das ist das gleiche Paket, was ich gerade eben schon verwendet habe. Und wenn man das jetzt nicht auf dem Host-System kompilieren und installieren möchte, sondern es für ein Zielsystem Cross-Compilen möchte, dann packt man einfach zwei Umgebungsvariablen dazu. Das ist für den Go-OS, auch nur nötig, wenn man auf einem anderen System arbeitet. Und zu guter Letzt kommt bei uns noch hinzu, wir haben keine Lib C, denn wir haben ja in den User-Land, was komplett in Go implementiert ist. Deswegen müssen wir C-Go auf deaktiviert setzen und dann sind wir fertig. Wohlgemerkt, wenn man jetzt also diese Befehle ausführt und dann die resultierende Hello-Datei auf eine SD-Karte praktikiert, kann man bereits jetzt einfach init equals slash hello als könne Parameter und dann läuft das Programm auf dem Raspberry Pi. Also das ist nicht so, als hätte ich jetzt irgendwie Tage damit verbracht, eine Cross-Compilation-Umgebung aufzusetzen oder so, sondern es sind literally irgendwie diese eine Befehle und dann ist man fertig und das ist super angenehm. Andere Randnotiz, das ist der komplette Code für ein minimales init-System in Go. Es ist super einfach, wir haben eine Superweisfunktion, die ist im Wesentlichen der Endloschleife, die führt Befehle aus, wartet eine Sekunde weiter, wir starten für jedes Programm, was wir laufen lassen möchten, die Superweisfunktion in der Go-Routine im Hintergrund und dann blockieren wir endlos, weil das Programm macht alles im Hintergrund, was man machen möchte und dann sind wir auch schon fertig. Wenn ihr euch anschaut, minimale Init-Systeme in C, die sind meistens deutlich länger und machen dann irgendwie Asynchronous Event-Handling und Child-Reaping und so weiter und so weiter, braucht man alles nicht in Go. Alles funktioniert einfach alles. Und nachdem ich dann also diese beiden Sachen an dem Projekt. So, jetzt ist die nächste Frage, wie kommt eigentlich die Software genau auf den Raspberry Pi? Wir haben gerade schon gesehen, ich habe einfach eine SD-Karte bespielt. Der Raspberry Pi erwartet eine SD-Karte mit einer MS-DOS Partition Table und einem FAT-Datei-System als erste Partition. In dieser ersten Partition sucht der Bootloader vom Raspberry Pi die Firmware-Dateien und startet dann die Firmware-Dateien. Ohne diese Dateien kann der Raspberry Pi nicht starten. Damit wir sicher sind, dass wir über das gleiche sprechen, habe ich auch noch die Befehle auf die Folie gepackt, mit der man unter einem regulären Linux-System eine SD-Karte so einrichten würde. Also man würde F-Disk verwenden, um sie zu partitionieren. Dann benutzt man mkfs.vfatt um das FAT-Datei-System zu erstellen. Man mountet sie, damit man sie ansprechen kann, kopiert init und hello und so weiter und den Linux-Colonel und die Konfig-Dateien und die Firmware darüber und anmountet sie. So, soweit so gut. Allerdings haben wir uns entschieden, diesen Weg nicht zu gehen. Also F-Disk, mkfs und so weiter ist alles, ich finde das unangenehm. Ich finde es unbequem zu automatisieren. Die Schnittstellen sind eklig. Wenn man zum Beispiel sich F-Disk anschaut, sieht man, dass die meisten Leute F-Disk automatisieren, indem sie irgendwie die interaktive Nutzung simulieren. Also irgendwie die Kommando-Befäle so N, P, 1, Enter, Enter und sowas an F-Disk schicken, was ganz hässlich ist. Ich höre da gibt es andere Tools dafür, das stimmt. Aber generell auch, wenn man die Projekte veröffentlicht hat, dann ist es schwierig. Manchmal ist es schwierig. Ich erinnere mich an Zeiten, in denen ich irgendwie verklemmte Loop-Mounts hatte und dann meinen Computer rebooten musste. Die ganzen Befehle erfordern Rutsrechte und auf manchen Betriebssystemen sind die Befehle überhaupt gar nicht vorhanden. Tatsächlich, nachdem wir das Projekt veröffentlicht hatten, kamen einige Leute und haben Probleme auf MacOS gemeldet, die ich dann auch beheben konnte. Aber man sieht, dass da eindeutig Bedarf da ist, dass es so geschrieben und Ziel dieser Übung war, natürlich auch zu schauen, wie viel man eigentlich in Go implementieren kann. Die logische Schlussfolgerung davon ist, dann brauchen wir eine eigene Implementation. Tatsächlich, Partitionstabellen zu schreiben, ist auch eigentlich gar nicht so furchtbar kompliziert. Ich habe hier den Code mal auf die Folie gepackt. Das Einzige, was ich ausgelassen habe, ist Partition 2 bis 4, weil die Partition genauso funktionieren wie die erste Partition, die ich aufgelistet habe. Was die Funktion hier eigentlich macht, ist, sie schreibt 446 leere Bytes, also 0 Bytes. Der Boot-Machine-Code wird nämlich vom Raspberry Pi einfach ignoriert. Dann kommen hier noch ein paar Bytes, die die Partitionen beschreiben. Sie sagt, das ist eine aktivierte Partition. Sie sagt, bei Sektor 8K fängt sie an, ist 100 Megabyte groß. Die Cylinder, Head und Sector Addressing benutzen wir nicht mehr, weil das ist alles obsolet und wir benutzen lieber die logischen Sektorwerte. Und dann machen wir das für die anderen Partitionen, schreiben die Partitionssignatur, die aus in Little Indian encoding, und dann sind wir auch schon fertig. Das Takeaway für mich von dieser ganzen Übung war, dass F durchaus das komplizierteste Programm ist, was ich kenne, um 16 Bytes zu schreiben. So, jetzt haben wir also die Partitions-Tabelle. Jetzt brauchen wir ein FAT-Datei-System. Ich habe mich entschlossen, ein FAT 16B-Datei-System zu implementieren. Es gibt andere Varianten von FAT, aber die 16B scheint mir die sinnvollste. Die Implementation an sich habe ich hier auf der Folie verlinkt. Die Folien werden danach auch hochgeladen. Es ist weniger als 500 Zeilen lang, und wir unterstützen wegen Patentbedenken nur 8.3 Dateinamen. Das ist ein bisschen unbequem, aber da können wir nachher noch drüber sprechen. In einem FAT-Datei-System besteht im Wesentlichen aus einem Bootsektor, was ein anderes Wort ist für Metadaten, aus einer File Allocation Table, die FAT, die also auch den Namen gibt, aus dem Route Directory, also den Einträgen, welche Dateien sich wo befinden und welche Subdirectories sich wo befinden und die Abgespeichert offenbar. Das Einzige, was eigentlich schwierig ist an einem FAT-Datei-System, ist zu verstehen, wie die verschiedenen Abstraktionsebenen funktionieren. Man hat bei jedem Sektor, den man schreibt, ein gewisses Padding. Das heißt, für die Sektor-Size von 512 bytes muss man immer padden. Die Sektoren werden zusätzlich zu Clusters zusammengefasst. Eine Cluster-Size kann man frei wählen und dann in dem Bootsektor kommunizieren. Die Wahl dieses Parameters bestimmt den Overhead des Datei-Systems und auch die maximale Datei-Systemgröße. Das heißt, bei den Datei-Systemen, die Go Crazy im Moment schreibt, haben wir 127 MB als Obergrenze, aber das kann man natürlich anpassen, wenn man das anpassen muss. Aber das hat erst mal gut funktioniert bislang. Als Einschub, wie machen wir eigentlich Updates? Wir haben jetzt schon mehrfach darüber geredet, dass wir eine Partitions-Tabelle und FAT-Datei-Systeme haben. Was ist da eigentlich wo? Auf einer Go Crazy SD-Karte. Das ist sehr angenehm, denn die vier Partitionen kann man einfach als Primär-Partition machen, ohne in dieses logische Partitionsschema abschiffen zu müssen. Die erste Partition ist 100 MB einfach für den Boot. Da wird der Linux-Kandel draufgespeichert, da werden die Firmen-Dateien draufgespeichert. Das muss eine FAT16B-Partition sein. So weit so gut. Nachdem wir dann den FAT16B-Code hatten, dachten wir, dann können wir das Rout-Datei-System doch auch damit machen. Das funktioniert auch, das kann man machen. Das zweite Partition, eine 500 MB-Rout-Partition auch mit einem FAT16B-Datei-System. Aber wir haben uns auch überlegt, ob wir da nicht vielleicht lieber ein SquashFS implementieren wollen oder so, damit man über diese nervige Dateilnamen-Begrenzung hinauskommt. Wir haben zwei Rout-Partitionen, die die gleiche Größe haben und zwischen denen man hin- und herschalten kann. Wir benutzen also so einen A-B-Mechanismus für Updates. Das ist deswegen notwendig, weil die Boot-Partition beim Start des Raspberry-Pies eingelesen wird. Der Kernel wird in die Speicher geladen und deswegen die Rout-Partition, da ist das nicht notwendigerweise so, sondern der Kernel kann vielleicht erst Dateien später nachladen oder einzelne Teile von Dateien später nachladen und deswegen muss das Dateisystem in sich konsistent sein. Das heißt, wir können es nicht überschreiben während wir es gerade benutzen und deswegen funktionieren die Updates so, dass wenn wir gerade Rout-2 benutzen, schreiben wir auf Rout3, schalten um und rebooten und umgedreht für den anderen Fall. Die vierte Partition ist dem Nutzer überlassen. Wir haben eine SD-Karte und kann persistente Daten enthalten mit einem beliebigen Dateisystem, welches vom Linux-Kanal unterstützt wird. Ich würde X4 verwenden, aber wenn andere Leute da Referenzen haben, dann können sie das gerne tun. Für den Update-Mechanismus brauchen wir natürlich nicht nur einen FAT16B-Schreibcode, sondern auch einen FAT16B-Einlesekode, welcher uns dann den Offset quasi für die Commandline.txt zurückgibt, damit wir die Datei austauschen können. Aber so gesehen, wir haben immer noch keinen Dateisystem-Treiber, sondern wir schreiben nur Read-Only-Images und wir modifizieren eine Zeile darin. So, jetzt zur Firmenware. Die Firmenware erlebt in dem repositorygithub.com-go-crazy-slash-Firmware, da könnt ihr gerne mal reinschauen. Dann versteht man das auch ganz einfach. Im Wesentlichen, was wir machen ist, wir nehmen das github.com-rospre-pile-slash-Firmware, kopieren dort aus dem Ordner Boot alle Dateien, die auf ELF-bin und Dat enden, das sind nämlich alle diese Binärfirmenware-Dateien und dann packen wir die in unser Firmenware-Repository und packen sie auf die SD-Karte. Die Dateien sind proprietary Binaries, die wir einfach kopieren müssen. Wir können die nicht kompilieren, weil den Source davon gibt die Raspberry Pi Foundation bzw. Broadcom nicht raus. Es gibt eine Freie Firmenware, die derzeit in Arbeit ist. Die URL habe ich dahin gepackt, allerdings ist diese Freie Firmenware derzeit noch ohne USB-Unterstützung, ohne DMA-Unterstützung und ohne Ethernet. Das ist eine Freie Firmenware, die in der Zukunft hoffentlich ändert. Dann können wir da vielleicht auch wechseln. Der Kernel lebt unerwarteterweise oder nicht überraschenderweise in github.com-slash-go-crazy-slash-kernel. Neben dem eigentlichen Kernel Binary ist dort auch ein Bildprogramm. Das Bildprogramm ist kein Shellscript, sondern in Go geschrieben. Alle Programme, die bei Go Crazy dabei sind, sind in Go geschrieben. Wir können auf die Githubseite gehen und schauen, welche Sprachen da drin sind und wie das Bildprogramm baut, den Kernel reproduzierbar für ARM64. Und das Bildprogramm benutzt einen Docker-Container. Der benutzt deswegen einen Docker-Container, damit wir eine fixe Umgebung haben, die wir dann zum Beispiel auch auf Travis nutzen können. Das heißt, auf einem aktuellen Debian Stretch kann man eine Cross-Compilation-Umgebung sehr einfach einrichten mit apt-install-cross-build-essential-arm64. Nichts anderes macht dieser Docker-Container. Das ist super einfach und war auch einer der Faktoren, die es mir sehr einfach gemacht haben, also an dieser Stelle danke an alle, die da mitgeholfen haben, dass das so funktioniert. Das Resultat von dem Bildprogramm ist die VM-Linux-Datei, also das Kernel-Abbild und der Device-Tree für den Raspberry Pi 3. Der Device-Tree ist quasi eine Parameterisierung des Kernels auf eine gewisse Hardware und ist unter Embedded-System nötig, oftmals. Wir benutzen keine In-It-ID, weil das einfach in unserer Umgebung nicht nötig ist. Ich habe es mir überlegt, aber ich sehe keinen Sinn darin, eine zu benutzen. Das ist ein Beispiel, wie das Kernel-Bildscript funktioniert. Ich habe ein bisschen was weggelassen, nämlich den Teil, wo die .config-Datei modifiziert wird. Aber im Wesentlichen befasst sich der erste Teil mit der Konfiguration und der zweite Teil ist einfach ein Make-Aufruf, um den Kernel zu kompellieren. Ihr seht, dass ein paar Umgebungsvariablen speziell gesetzt sind, damit das Resultat reproduzierbar ist. An dieser Stelle auch noch mal danke für alle, die daran gearbeitet haben, dass der Kernel so einfach reproduzierbar baubar ist. Das war nämlich vor ein paar Jahren noch nicht so. Das macht es sehr schön, weil jetzt Leute, die einfach sagen, okay, ich vertraue den Projekt und geht ab, können sich einfach den Kernel als Binär-Datei runterziehen und benutzen, so weit so gut. Und Leute, die sagen, ich vertraue euch nicht, ich möchte das gerne nachprüfen, können den reproduzierbar bauen. Das ist eine schöne Sache. Wie funktionieren eigentlich diese Updates? Ich habe vorhin gesagt, für diesen Zweck habe ich ein paar kleine Programme geschrieben, die Travis automatisieren. Auf Travis kann man CronJobs laufen lassen, also zeitgesteuert, eine Continuous Integration daran sozusagen. Ich kann das auch mal aufmachen hier im Hintergrund, während ich das erkläre. Okay, während das lädt, erzähle ich mal weiter. Diese CronJobs, was die machen, ich würde weiter erzählen, wenn das funktionieren würde. Sorry, ich mache mal hier weiter, bis sich das fängt. Die CronJobs machen Pultrequests auf und in diesen Pultrequests aktualisieren sie quasi die URL jeweils, die in dem Bildskript drinsteckt. Das heißt, das Bildprogramm, besser gesagt, hat im Falle vom Linux Kernel einfach eine URL drin, also sowas wie kernel.org.slash, pub.slash, Linux 4.10.6 oder so. Und im Fall von dem Firmware-Repository hat sie einfach eine Gitter-Vision, und der CronJob geht also her und schaut, gibt es eine neue Version und wenn ja, dann modifiziert er die Datei und macht einen Pultrequest auf. Und dadurch, dass der Pultrequest aufgemacht wird, läuft in ein Travis Continuous Integration dran los, der wiederum das Programm ablaufen lässt und schaut, dass es auch noch alles funktioniert. Also im Fall vom Linux Kernel, baut er den Linux Kernel, im Fall vom Firmware, lädt er die neuen Firmware-Dateien drunter. Und nachdem das dann erfolgreich passiert ist, aktualisiert er auch gleich den Pultrequest, damit diese Dateien dann auch da drin sind. Denn der Pultrequest an sich hat ja erstmal nur die Versionsnummer aktualisiert, aber da müssen ja dann noch die fertigen Binärabbilder rein. Der aktualisiert also den Pultrequest und das Aktualisieren eines Pultrequests triggert natürlich nochmal ein Continuous Integration dran. In diesem dritten Continuous Integration Job schaut also dann das Programm ist nicht nur die Änderung da, sondern auch die Binärabbilder. Und wenn die auch da sind, dann lässt es einen Testlauf starten. Und das funktioniert so, dass er einfach einen Go Crazy-Abbild baut, also ein Image für die SD-Karte, beziehungsweise genau genommen nur die Boot-Partition, weil die Route-Partition ändert sich ja nicht, es geht ja nur um Firmware und Könne. Und der schickt das dann übers Internet auf einen Raspberry Pi, der bei mir zu Hause läuft, der wiederum schreibt das dann auf seine SD-Karte und startet sich neu. Und der hängt einem anderen Raspberry Pi über eine seriale Schnittstelle und der wiederum schaut dann, ah, hat er jetzt gerade neu gestartet also läuft da das Programm drauf, sagt dann dem Travis, ja okay, das passt jetzt alles und das Travis sagt dann okay, offenbar hat alles gut funktioniert, ich merke das jetzt mal. Und so haben wir also den kompletten Workflow quasi so abgebildet, wie man das auf GitHub halt so macht. Also man fängt an mit irgendwie ja, ich habe eine Änderung, ich mache ein Pull Request, Continuous Integration läuft, Testlauf laufen und dann wird das gemirkt. Ich hoffe, im Hintergrund genau hat das jetzt geladen. Man sieht hier das Programm, welches einfach die GitHub-AP Instrument also benutzt, um das zu machen, die Orchestration, das ist ein bisschen länger als die anderen Programme oder die anderen Auszüge, die ich so gezeigt habe. Was ich gerne noch zeigen möchte, ist wie so ein Pull Request eigentlich aussieht, sofern das lädt. Es ist nämlich relativ schön zu sehen. Also es gibt auch jeweils die Ausgaben, wir arbeiten in jedem Zwischenschritt mit GitHub Issue Labels, das heißt, nachdem ein Pull Request reinkommt, wird der erst mal gebaut und dann wird der Test-Label gesetzt, dann wird der Test laufen lassen und dann wird ein Please-Merge-Label gesetzt und dann wird der eigentliche Merge gemacht. So kann man also, wenn irgendwas schief geht, auch einfach schauen und das Bootlog wird auch nochmal in den eigenen Kommentar reingepackt, so dass man also wirklich auch alles nachverfolgen kann, was da passiert ist. So, das funktioniert alles nicht so, wie ich mir das erhofft hatte, aber wir gehen einfach mal weiter und kommen dann nochmal zurück in der nächsten Folie. Als Zusammenfassung die ursprünglichen Motivationsleitfragen, die wir uns gestellt haben, waren ja, können wir die Angriffsfläche reduzieren, können wir die Updates komplett automatisieren und können wir das einfacher machen, sondern Raspberry Pi ursprünglich zu bespielen. Und als Zusammenfassung würde ich sagen, die Angriffsfläche wurde stark reduziert auf nur noch vier verschiedene Faktoren, nämlich den Go Compiler und Standard Library, den Linux Kernel, die Raspberry Pi Firmware und Go Crazy an sich. Und natürlich die einzelnen Anwendungen, die ihr dann selber dafür schreibt und auf die Angriffsfläche aufzulassen. Das heißt, es gibt nur noch vier verschiedene Sachen, die ihr im Überblick haben müsst, sondern nicht mehr irgendwie hunderte Softwarepakete. Die Updates, wie ich gerade lang und breit erklärt habe, laufen komplett automatisiert ab. Man muss nur dann eingreifen, wenn irgendwas schiefgeht, was bislang noch nicht passiert ist. Und letztendlich, ihr habt selber in der Demo gesehen, dass ich mit einem Befehl eine leere SD-Karte komplett beschreiben kann mit einem Go-Programm, was dann direkt auf dem Raspberry Pi läuft. Also, ich würde sagen, die Fragen können wir alle positiv beantworten. Ich habe noch kurz den Pull Request an. Ihr seht hier, dass er die URL geändert hat. Also, das war damals, als wir von Linux 4.10.3 auf die damals aktuelle 4.10.6 aktualisiert haben. Und wenn man sich die in der Conversation die Ansicht anschaut, dann sieht man, dass hier zuerst der Pull Request kam, dann wurde das Please Boot Label gesetzt. Der sagt dann, ah, der Boot Test ist successful, das Log findet ihr hier in diesem Gist. Dann macht er das Please Merge Label und merkt es dann auch. Also, hier sieht man das mal in Action quasi. In dem Gist sieht man jetzt das Bootlog, aber das lasse ich mal. Stattdessen versuche ich hier mal die Folien wieder zu laden. Super. Gut, jetzt gibt es noch ein paar Anwendungsfälle, die ich vorstellen möchte. Und dann haben wir ein bisschen Zeit für Fragen. Ich habe zu Hause einen AV-Receiver, also quasi ein Verstärker mit vielen Eingängen, bei dem man auch hin und her schalten kann. Und für den habe ich ein bisschen Automatisierung geschrieben. Was das Programm macht, was ich auf dem Raspberry Pi laufen lasse, und das Team called go,Crasy, ist es überwacht, die Computer, die ich zu Hause habe. Schaut, ob sie an sind. Und Chromecast, die ich zu Hause habe und wann immer, also um einen Computer an und benutzt wird oder wenn immer auf dem Chromecast Medien abgespielt werden, schaltet der alle Eingänge passend und alle Pegel passend meinen Videoprojektor und der AV-Rassiver an sich ist auch nicht gut, was HDMI, C, C angeht, aber halt auch für Geräte, die prinzipbedingt, wenn sie zum Beispiel über Tosslink angeschlossen sind, gar kein HDMI können. Das funktioniert soweit ganz gut und hat also zur Folge, dass wenn ich nach Hause komme und irgendwie YouTube-Videos schauen will oder so, kann ich einfach auf der App sagen, starte das mal, da macht es plopp, plopp, plack, und dann sind alle Geräte an und dann kann ich schauen. So, zweiter Anwendungsfall ist Hausautomatisierung. Ich habe mir vor einigen Jahren auf Empfehlung hin die Hormatic-Geräte-Dreihe zugelegt, also das sind so Heizungstermostate und Temperatursensoren und Schalter und was auch immer, und die kommen mit einer sogenannten Central Control Unit, CCU, die kann man verwenden, muss man aber nicht und ich habe die zuerst verwendet, weil ich nicht wollte, also weil ich nicht selber freckeln wollte und da nicht selber irgendwie Energie investieren wollte, aber letztendlich habe ich dann irgendwann gemerkt, oh Gott, das ist nicht nur irgendwie super langsame und super schlimm zu benutzen der Software, sondern sie ist auch noch furchtbar instabil. Also nicht nur ist es ein super frustrierendes Erlebnis, seine Heizungstemperatur umzustellen, das sollte echt nicht sein, sondern es lief auch darauf hinaus, dass nachdem ich dann diese Temperaturdaten exportiert und aufgezeichnet habe, ich bemerkte habe, dass nach zwei Wochen ungefähr, zwei Wochen, die Daten einfach immer aufgehört haben, gesammelt zu werden. Ich dachte, was ist da los, habe mich über SSH eingeloggt und mir das Syslog angeschaut und man sieht, dass die Control Software, die der Hersteller da auf diesem Embedded Device laufen lässt, in Java geschrieben ist und der Umkiller vorbeikommt und sie killt. Und dann dachte ich, oh Gott. Und letztendlich habe ich dann gesehen, man kann nicht nur diese Central Control Unit von denen benutzen, sondern sie haben auch ein kleines Kit und das ist quasi so ein, das ist, glaube ich, 886 Megahertz oder was auch immer da diese Frequenz ist, quasi auch wie SIGBI, aber sie haben ein eigenes Protokoll und dieses kleine Kit unterstützt eben das Protokoll und das kann man dann ansprechen und die denken natürlich, dass man sich das Kit kauft und dann deren proprietary Software verwendet, aber die ist natürlich in Java geschrieben und um die ganze Zeit und ich kann hier nur Go Software laufen lassen, deswegen habe ich gedacht, okay, dann implementiere ich das halt in Go neu und das hat gut funktioniert. Ich habe den Link auf die Folie gepackt, wenn sich das jemand anschauen möchte, die quasi die Idee bei diesem Projekt war, dass ich, wenn man sich viele Heimatomatisierungssachen anschaut, so wie das wie Open Hub oder so, dann sind das immer relativ komplizierte Software-Pakete. Also dann hat man da immer so Sachen, die relativ kompliziert sind, zum aufsetzen, aber die auch in Hrenn relativ kompliziert sind, weil die Entwickler immer versuchen es den Anwendern möglich zu machen, ihre Appartements oder Häuser zu automatisieren, also zu programmieren in dem Sinne. Das heißt, die bauen immer irgendwie Schnittstellen und Konzepte und Abstraktionsebenen und sagen, hier, wenn du irgendwie einen Lichtschalter anmachen willst, dann musst du zuerst einen Thing erstellen und dann das mit dem verbinden und dann hier den Aktor und Sensor und ich denke, oh Gott, ich will nur einen Licht anmachen und deswegen habe ich mich dafür entschieden, keine Konfigurierbarkeit in diesem Fall, sondern die Konfiguration ist quasi das Programm. Wenn jemand eine andere Konfiguration haben will, dann soll die Person eben den bestehenden Programmqualtext nehmen und verändern und dann kann man sich überlegen, ob man die Libraries, die das Programm intern verwendet, irgendwie öffentlich zur Verfügung stellt und dann pflegt und wartet, aber im Moment ist das noch nicht so. Ich will auch keinen UI haben, ich brauche da einfach alles minimal. Also mein Anwendungsfall wird einfach hardcoded und fertig, das ist ein Ansatz, der hat für mich gut funktioniert und das ganze Monitoring und Auswertung mache ich komplett extern über Prometheus. Da gab es, glaube ich, auch einen Vortrag auf der Veranstaltung, da kommt noch und ihr seht hier einen Screenshot auf der rechten Seite von der Folie, wie das in etwa aussieht. Also ich habe da einfach für jedes Gerät habe ich irgendwie diese grünen Dinger zeigen an, wann die sich zuletzt über Funk gemeldet haben und ich habe unten irgendwie die Temperaturdaten und die Feuchtigkeitsdaten und ich sehe direkt, wie die Heizungen gestellt sind und wie viel Batterie stand die einzelnen Geräte noch haben und zusätzlich noch, wie viel Speicher das ganze Ding verwendet und man sieht, der benutzt irgendwie 10 Megabyte Speicher im Maximalfall, also das ist auf jeden Fall und das bleibt auch bei 10 Megabyte, das stürzt nicht nach zwei Wochen nach. So, das Killerfeature. Der dritte Anwendungsfall, den ich vorstellen möchte, sind Backups. Ich habe einen Programm namens Don Dröschchen, weil es die ganze Zeit um Einschlafen und Aufwecken geht. Das weckt Rechner und Network Storages zeitgesteuert auf. Das heißt, wenn ich irgendwie morgens ins Büro gehe, dann kommt das Programm irgendwann und sagt, ah, okay, du bist jetzt wahrscheinlich weg. Ich mache mal hier deine Workstation an und ich mache das Network Storage an und dann loggt er sich über SSH ein und SSH ist so konfiguriert, dass bei einem Login einfach einen Ersing Backup losläuft. Das funktioniert seit Jahren schon relativ gut. Das läuft also auch auf so einem Go Crazy Raspberry Pi. Und den letzten Anwendungsfall, den ich vorstellen möchte, ist Scan to Drive. Das ist ein Programm, welches ich geschrieben habe für den Fujitsu Scan Snap Scanner. Dieser Scanner kommt mit Cloud Anbindung, aber ich weiß nicht, ob ich euch mal genauer angeschaut habe, wie diese Cloud Anbindung funktioniert. Man könnte erwarten, so, okay, da stellt man irgendwie sein Google Drive Account oder Dropbox Account ein oder so was und dann scannt der Dokumente und schiebt die da hoch. Aber das funktioniert nicht so, sondern wie das funktioniert ist. Man hat dann irgendwie so eine Mobile App oder eine Windows App, die man benutzen muss, wann immer man einen Dokument scannen will. Das scheidet schon mal aus. Ich will, der Scan hat einen Knopf, den will ich benutzen. Und dann würde das gescannte Dokument zu dem Hersteller gehen, also zu Fujitsu und dann von dort aus irgendwie in die Cloud geladen werden. Und ich habe relativ großes Vertrauen darin, dass Google Drive auch in ein paar Jahren noch existiert, aber ob Fujitsu ihren Service noch am Laufen hält und ob der sicher bleibt, da habe ich keine Ahnung von und da will ich lieber nichts darauf retten. Deswegen habe ich also selber einen Programm geschrieben, welches einfach die Dokumente einscanned, verschönert und verkleinert aus dem JPEG, was irgendwie eine paar Megabyte groß ist, wird dann einfach ein kleines PDF gemacht, das wird auf Google Drive hochgeladen. Google Drive indexiert das Ganze dann auch und dann habe ich Volltextsuche in allen meinen Dokumenten über die letzten paar Jahre und das ist super angenehm. Wohlgemerkt, das Programm läuft deshalb noch nicht auf Go Crazy, sondern auf einem separaten alten Raspberry Pi, aber das ist quasi das Projekt für die nächsten paar Wochen, dass ich das portiere, damit es nur noch Go verwendet und nicht mehr irgendwie den ganzen anderen C-Software, die da beteiligt ist am Scan. So, jetzt möchte ich mich erst mal recht herzlich bedanken für die Aufmerksamkeit. Mehr Infos zu dem Projekt findet ihr auf gocrazy.gitta.io. Ihr könnt das auch googeln. Wenn ihr Feedback zu dem Vortrag habt, würden mich das sehr freuen, ob es irgendwie interessant war, zu schnell, zu langsam, was auch immer. Ihr könnt einfach den QR-Code Scan und dann ein kleines Formular ausfüllen. Ich lasse das mal hier oben stehen oder in den Folien später schauen. In diesem Sinne, erst mal Danke und jetzt haben wir Zeit für Fragen. Hier vorne, Mikrofon. Test. Du hattest erwähnt, dass du automatische Updates machst. Ja. Willst. So wie ich das verstehe, ist aber ja, der Raspberry Pi, der jetzt bei mir zu Hause dann steht und irgendwie einen Go crazy Image drauf hat, der updated sich ja erst mal nicht. Da müsste ich ja erst mal den Packer laufen lassen und das erst mal, dass ich mich die neue Firmware holen und das in den neuen Canon und alles. Ja. Ist da das geplant, dass das irgendwann passiert, gibt es da eine Möglichkeit, das einzurichten? Ja. Mir ist das auch aufgefallen, nachdem ich die Folien vorbereitet habe vor sieben Tagen und da habe ich mir gedacht, ja, dann mache ich das so einfach und habe mir einen Cronjob geschrieben, der jetzt jeden Tag meine Raspberry Pi update. Und das funktioniert seither. Und der läuft auf dem Go crazy? Der läuft einfach auf meiner Workstation. Aber ja, man könnte das eigentlich auch auf Go crazy machen, wenn man das quasi mehr Meter machen möchte, dass er sich dann selber zerschießt oder aktualisiert. Ja, können wir machen. Ich habe das jetzt erst mal im Test-Botrieb laufen lassen. Ich kann dir auch gerne das Ding schicken, aber ja, könnte man dann langzeit gesehen auch in Go implementieren. Hier vorne noch mehr. Du hattest erwähnt, dass ihr in Go die eigenen Partitionstabellen entsprechend erstellt. Ja. Und das entsprechend die verbliebene Platz von der SD-Karte in X4 oder einem beliebigen anderen Data-System vom User entsprechend verwendet werden kann. Ja. Was natürlich sinnvoll ist, damit man eigene Software und eigene Ressourcen da drauf packt. Ja. Jetzt stellt sich natürlich die Frage, wenn ich jetzt die SD-Karte mit einem X beliebigen Partition-Tool editiere, kommen die denn dann mit den Partitionstabellen zurecht, die ihr vorgefertigt habt? Also wenn ich jetzt anfange mit, keine Ahnung, Pardon oder CF-Disk oder was auch immer, irgendwelchen fancy GUI-Tools. Ja. Also die beißen sich nicht gegenseitig. Das ist korrekt. Also nach meinem besten Wissenstand ist die Partitionstabelle relativ standard. Also ich habe das beim entwickeln auch Beid für Beid verglichen. Das, was in den F-Disk erzeugen würde, wenn man das entsprechende Ergebnis haben will, wie ich es vorhin präsentiert habe, entspricht genau dem, was wir auch schreiben. Und auch in meinen Tests. Ich habe ja vorhin auch kurz das F-Disk minus L gezeigt. Funktioniert das alles einwandfrei. Also sowohl der Raspberry Pi offensichtlich als auch die Linux-Standard-Tools kommen mit den Partitionstabellen klar. Wohl gemerkt, wenn du die Partitionstabellen verändern würdest. Also wenn du jetzt sagst, ich mache jetzt keine Ahnung. Meine Route-Partition wird jetzt ein anderer Typ. Oder ich fange jetzt auf einmal an, die Dateien zu ändern und zu schreiben. Das ist nicht unterstützt. Sondern das Modell basiert darauf, dass wir gewisse Annahmen treffen können und dass wir zum Beispiel den Update-Mechanismus so machen können, dass wir eben da wissen, okay, da existiert genau diese eine Datei, die befindet sich dann dort und die können wir dann aktualisieren. Aber ja, also alles, was man quasi reasonably selbst ändern wollen möchte, es sollte eigentlich unterstützt sein. Und wenn nicht, dann machen wir einen Backup-Port auf und dann können wir das fixen. Wie einfach ist es denn zusätzliche Ressourcen für die Anwendungen mit auf die SD-Karte zu packen? Also wenn ich ein Web-Server habe, HTML-Files, Reader-Unleadzeug und zweite Frage direkt hinterher. Können das Binarys sein, die ich mit nem Mesh Execute einfach starten kann, um aus der Go-Weld rauszukommen? Kannst du das nochmal wiederholen bitte? Kann ich, wenn ich da Ressourcen draufpacken, kann da auch einfach Binarys draufschieben und mit nem Execute-Out-Go einfach aus starten, um aus der Go-Weld rauszukommen. Aha, ja, okay, da kann ich mal, während wir darüber reden, noch eine weitere Seite aufmachen, nämlich Breakglass. So, die erste Frage war, wie einfach ist es denn da eigene Daten dazu zu packen? Die Antwort ist, wenn du das erste Mal eine SD-Karte beschreibst, dann macht er eben die Partitions-Tabelle komplett neu, wie gesagt und er erlaubt dir dann in der vierten Partition ne Persistentes Dateisystem anzulegen, das machst du dann und dann kopierst du einfach manuell deine Dateien da rein. Ich hab das hier auch zum Beispiel in den Breakclass Instructions, steht das auch, also man sieht hier zuerst den Go- Crazy Packer Aufruf und dann würde man das Dateisystem eben mounten in sagen wir Media-SDB4 und würde dann einfach einen entsprechenden Host-Key und einen Authorized-Key- File da drauf packen. Bei Updates wird diese Partition nicht angefasst, das heißt die bleibt einfach weiter bestehen. Das heißt, also quasi der empfohlene Weg um das zu machen ist, du installierst Go-Crazy ganz normal und dann machst du einmalig manuell einfach alles, wie du es halt so brauchst. Man könnte sich jetzt natürlich überlegen, ob du dann für, keine Ahnung, wenn du sagst, ich möchte eine Appliance bauen, die auf Go-Crazy basiert, könntest du natürlich sagen, okay, ich mache jetzt ein eigenes Rapper Script oder Programm, welches dann den Packer aufluft und dann das Setup so macht, wie du es halt brauchst. Um die zweite Frage zu beantworten, nämlich wie leicht man quasi ausbrechen kann, dafür gibt es einen vorgefertigtes Programm schon, welches, denke ich, auch die Frage beantwortet, das nennt sich Break Class. Und wenn man das also mit auf den Raspberry Pi-Packt, der mit Go-Crazy läuft, dann kriegt man dort, nachdem man das Programm explizit startet, also das wird standardmäßig beim Boot nicht gestartet, sondern nur wenn man es wirklich braucht, kriegt man dort einen SFDP und einen SSH-Zugang, über den SFDP-Zugang kann man Dateien hochkropieren, also TAR- Archive, und die werden dann im Ramm entpackt und zur Verfügung gestellt und mit dem SSH kann man dort eine interaktive Shell starten und die Programme können jetzt nicht nur über Break Class im Ramm gehalten werden, sondern du könntest dir auch auf die persistente Daten Partition schreiben. Allerdings, die Programme müssen natürlich ohne Lip-See auskommen. Das heißt, du musst die Statisch kompilieren, was bei manchen Programmen sehr einfach ist. Busybox zum Beispiel hat einfach ein paar Konfigurationsoptionen, wo du einen relativ leicht einen geeigneten Binary rankommst. Das würde ich auch empfehlen, mit Break Class zu benutzen für interaktive Debugging Sessions, aber andere Programme sind teilweise deutlich schwieriger Statisch zu kompilieren. Beantwortet das die Frage oder alles klar? Hier vorne noch eine Frage. Ich habe nochmal Fragen zu dem Update-Mechanismus, den du erwähnt hast. Mir ist nicht ganz klar, ob ich den Respe die SD-Karte rausnehmen muss und woanders reintun, um den Update-Mechanismus auszuführen oder ob das auch im laufenden Respe geht und der sich selber rebutet. Ja, die Antwort ist beides ist unterstützt. Also du kannst entweder die komplette SD-Karte neu übermalen oder du kannst nur die einzelnen Partitionen übermalen, wenn du möchtest. Du kannst aber auch übers Netz aktualisieren und das kannst du sowohl in dem Packer direkt machen, kannst einfach minus Update, Equals und dann die URL, die ich vorhin aufgemacht habe, die ausspuckt, die benutzt du einfach und dann schickt er übers Netz die neuen Daten drüber, schreibt es auf die jeweils inaktive Partitionen und rebutet in die neue Partition dran. Aber der schöne Vorteil davon, wenn du das über Images machst und die dann irgendwie separat schreibst, ist, dass du natürlich diese Images auch aufbewahren kannst. Also wenn du zum Beispiel einen einfachen Rollback haben möchtest, wenn du sagst, ich möchte das jetzt aktualisieren, aber wenn es kaputt geht, habe ich keine Zeit um das zu fixen, dann kannst du einfach sagen, okay, schreib mir mal ein Image auf meine Platte, dann sicherst du das irgendwo hinweg und schreibst es danach über den Updater oder über die SD-Karte direkt drauf. Und der Punkt ist natürlich auch, wenn dann irgendwie das Update schief gehen sollte, kannst du natürlich die SD-Karte einfach wieder einsteigen und das Image drauf spielen mit DD oder was auch immer. Hier vorne noch eine Frage. Ja, gute Frage. Das ist natürlich so ein bisschen ein Painpoint, wenn man irgendwie Geräte im lokalen Netz hat. Wir haben uns entschlossen, dass wir so machen, dass wir Plain-HTTP verwenden und Passwort- Authentifizierung und quasi sagen, dass du für die Sicherheit verantwortlich bist und der Server Exposed seine Ports aber halt nur in dem lokalen Netz. Das heißt, alle IP-Adressen, die als Privat gelten, laut den verschiedenen RFCs, die das regeln, auf denen wird ein Listening-Port aufgemacht und auf den anderen nicht. Das heißt, standortmäßig ist er von außen nicht erreichbar, aber wenn du im LAN bist, dann kannst du ihn darüber aktualisieren. Offenbar ist die Idee, also wir vertrauen dem LAN genug. Ob das in dein konkreten Anwendungsfall stimmt oder nicht, musst du dann selber schauen und dir dann vielleicht überlegen, wie du das alternativ machen möchtest. Bei HTTPS, wenn wir das machen wollten, ist halt immer ein bisschen die Schwierigkeit so, wie schaffst du das initiale Vertrauen? Weil du kannst halt nicht einfach einen Zertifikat installieren in die Browser, das unterstützen die Browser nicht im laufenden Betrieb. Und das macht halt alles so schwierig, weil wir wollen nicht die Benutzer quasi dazu ermuntern, die Sicherheitswarnungen wegzuklicken und zu ignorieren. Deswegen sagen wir halt lieber, okay, es ist besser, wenn es offensichtlich unsicher ist, als wenn es sicher ist, aber dann nicht wirklich, naja, da können wir auch gerne nochmal darüber diskutieren. Gibt es noch andere Fragen? Ansonsten bin ich auch die ganze Veranstaltung über da, ihr könnt mich auch gerne, wenn ihr mich seht, ansprechen und dann können wir noch weiter quatschen. Dann vielen Dank nochmal.