Raspberry Pi: So verkleinert man SD-Card-Images

Wer Backups macht, ist nur zu faul zum Neu-Aufsetzen eines Systems. Und so erstelle auch ich immer wieder mal in loser Folge Images von meinen SD-Cards, die ich auf meinen Raspberries zu verschiedenen Produktiv-Zwecken im Einsatz habe. Nun ist es mir jedoch schon mehrfach vorgekommen, dass z. B. ein Image einer 8-GB-Karte nicht auf eine andere (neue) 8-GB-Karte passt, weil auf dieser einige wenige Byte an Speicherplatz fehlen (insbesondere SDHC-Karten von Intenso und CnMemory sind häufig von wenigen kB bis mehreren MB kleiner als ihre Kollegen von z. B. SanDisk oder Transcend). Nachdem ich kürzlich eine neue Karte nicht mit dem Image eines dringend benötigten Backups beschreiben konnte, stand ich erst mal blöd da. Speicherkarten sind bei mir nicht gerade Kartonware 😉

Nun habe ich aber einen Weg gefunden, wie man unter Linux mit dem eigentlich genialen Partitionierungstool GParted ein SD-Card-Image, das ich z. B. mit dd (Linux) oder Win32DiskImager erzeugt habe, verkleinern kann. Eine Datenpartition ist ja in den seltensten Fällen bis zum letzten Bit mit Nutzerdaten aufgefüllt, so dass sich diese problemlos verkleinern lässt, damit sie auf eine neue SD-Karte passt. Nun ist es jedoch so, dass GParted nur auf physische Geräte (Festplatten, Memory-Cards usw.) schreiben kann, nicht jedoch auf Image-Dateien. Wie reduziert man also Image-Dateien bzw. die darin enthaltenen Partitionen?

Um Image-Dateien und die darin enthaltenen Partitionen zu verkleinern, braucht man nur drei Tools, die in den meisten Linux-Distrtibutionen bereits enthalten sind: 1. GParted, 2. fdisk und 3. truncate. Wie gesagt – GParted kann nur auf physischen Geräten (Devices) arbeiten, nicht jedoch auf Images. Deshalb müssen wir als Erstes ein Device für das Image erstellen. Dafür nutzen wir die Loopback-Funktion unter Linux. Falls diese noch nicht aktiviert sein sollte, tun wir dies mit

sudo modprobe loop

Nun kann man mit

sudo losetup -f

das Device /dev/loop0 bereitstellen. Nun erstellen wir aus der Imagedatei.img das Device /dev/loop0:

sudo losetup /dev/loop0 Imagedatei.img

Soooo – das Device /dev/loop0 ist somit schon mal vorhanden, es enthält den Gesamtinhalt von Imagedatei.img. Wir wollen jedoch die einzelnen Partitionen bearbeiten, die darin enthalten sind. Also geben wir diese dem Kernel wie folgt bekannt:

sudo partprobe /dev/loop0

Dieser Befehl gibt uns/dev/loop0p2 zurück – die zweite verfügbare Partition in der Imagedatei.img. Dies ist das Device (= Partition), mit dem GParted arbeiten kann (die /dev/loop0p1 ist die kleine FAT16-Partition, die der Raspberry Pi zum Booten benötigt – die belassen wir so, wie sie ist).

Nun geht es endlich daran, die Partition zu verkleinern. Dazu starten wir GParted wie folgt:

sudo gparted /dev/loop0

Hier klicken wir oben auf die Partition /dev/loop0p2 (Aktivieren) und anschließend auf den Button „Verändern/Verschieben“ (die Schaltfläche, die so ähnlich aussieht wie ein Play-Button). In dem Fenster, das nun erscheint, sehen wir einen Balken, der die Größe der Partition sowie den tatsächlich genutzen Speicherplatz anzeigt. Den rechten Rand des Balkens kann man jetzt mit der Maus nach links ziehen – bis zur gewünschten reduzierten Partitionsgröße. Anschließend klickt man auf „Ändern/Verschieben“. Nun sind wir wieder im Hauptfenster (s. o.) und siehe da: Die Partition ist jetzt kleiner und es wird der neu gewonnene freie Speicherplatz angezeigt – so sieht es zumindest aus. Jetzt noch oben in der Button-Leiste auf den Haken klicken – und los geht’s. Wenn alles gut geht (d. h. wenn die Imagedatei keine Fehler enthält), wird jetzt ca. 2 – 3 Minuten lang aufgeräumt und umsortiert. Sobald diese Prozedur abgeschlossen ist, können wir GParted schließen. Das Loopback-Device /dev/loop0 brauchen wir nicht mehr, also geben wir das Device wieder frei mit

sudo losetup -d /dev/loop0

Nun ist bereits viel erreicht, aber wenn wir uns die Imagedatei.img mit ls -l ansehen, so sehen wir, das sie immer noch genauso groß ist wie zuvor. Wir müssen noch den durch die Partitionsverkleinerung freigewordenen Speicherplatz freigeben, damit das Image auf eine neue, kleinere SD-Karte passt. Dazu müssen wir wissen, auf welchen Speicherblöcken die Partition beginnt und endet. Hierfür benutzen wir fdisk:

fdisk -l Imagedatei.img

Hier sehen wir in etwa Folgendes:

Hier achten wir auf das Gerät mit der Bezeichnung Imagedatei.img2 in der untersten Zeile. Im Bild endet es im Sektor 9404415 (abhängig jeweils davon, um wieviel die Partition in GParted verkleinert wurde). Oben sehen wir, dass jeder Sektor 512 Byte groß ist. Das Beispiel im Bild zeigt, dass unsere (verkleinerte) Partition an Byte 9404415 x 512 endet. Alles, was dahinter kommt, ist unser freier und ungenutzter Speicherplatz, um den wir die Imagedatei.img verkleinern wollen.

Dazu nutzen wir abschließend das Tool truncate. Als Parameter benötigen wir wiederum den End-Block der Partition 2, in diesem Beispiel also 9404415 und die Blockgröße 512 Byte. In der Praxis sieht der Befehl so aus:

truncate –size=$[(9404415+1)*512] Imagedatei.img

Nun ist das Ziel erreicht: Die Imagedatei hat jetzt die reduzierte Größe und wir können das Image auf eine neue SD-Card schreiben. Das mache ich mit

sudo dd if=./Imagedatei.img of=/dev/mmcblk0 bs=1M

Überzeugen Sie sich zuvor mit „df“, ob /dev/mmcblk0 wirklich Ihr SD-Card-Device ist!

Raspberry 2 (Wheezy): GCC und G++ auf 4.8 updaten – so geht’s

Ich habe auf einem älteren Raspberry Pi 2B noch ein Raspbian/Wheezy laufen, auf dem einige spezielle Anwendungen ihren Dienst tun, deren Entwickler von Zeit zur Zeit ihre Updates als C++-Sourcen via Github veröffentlichen. Nun ist passiert, was irgendwann ja mal passieren musste: Der Compiler gab nach einem Update einige Fehler aus, weil einige benötigte Funktionen nicht verfügbar waren. Mit anderen Worten: GCC musste von der etwas betagten Version 4.6.3 auf (mindestens) 4.7 upgedated werden. Diese ist jedoch so ohne Weiteres nicht auf dem alten Raspian Wheezy per apt verfügbar. Und einfach mit „sudo apt-get install gcc-4.7“ eine neue Version drüberbügeln – damit allein ist es nicht getan. Was also tun?

Nach einigen Recherchen bin ich auf diese Anleitung gestoßen. Die habe ich Schritt für Schritt abgearbeitet. Und seitdem kann ich wieder neue Releases problemlos compilieren.

Zunächst öffnet man mit dem Editor seines Vertrauens (z. B. nano) die Datei /etc/apt/sources.list .

sudo nano /etc/apt/sources.list

Normalerweise steht dort seit Wheezy-Zeiten nur eine Zeile drin, nämlich „deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi“. Um Software aus neueren Jessie-Repositories installieren zu können, muss man die sources.list um folgenden Inhalt erweitern:

deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi
deb http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi
# Quelltext-Repository aus Raspian Jessie hinzufügen
deb-src http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
deb http://archive.raspbian.org/raspbian jessie main contrib non-free rpi
deb-src http://archive.raspbian.org/raspbian jessie main contrib non-free rpi

Nun die sources.list speichern und schließen. Jetzt fügt man im Verzeichnis /etc/apt/ eine Datei namens „preferences“ hinzu (sudo nano preferences) und schreibt dort Folgendes hinein:

Package: *
Pin: release n=wheezy
Pin-Priority: 900
Package: *
Pin: release n=jessie
Pin-Priority: 300
Package: *
Pin: release o=Raspbian
Pin-Priority: -10

Auch diese Datei speichern und schließen. Nun fährt man auf den eigenen Software-Stand ein Update mit „sudo apt-get update“. Nachdem das durchgelaufen ist, ist man in der Lage, GCC und G++ 4.8 aus den Jessie-Repositories zu installieren. Das geht mit

sudo apt-get install -t jessie gcc-4.8 g++-4.8

Das dauert nun etwas. Zwischendurch wird man gefragt, ob sämtliche noch laufende Dienste neu gestartet werden dürfen (u. a. Apache). Diese Abfrage bestätigt man mit „Yes“. Falls noch andere GCC-/G++Versionen auf dem Raspi vorhanden sein sollten, entfernt man diese mit

sudo update-alternatives --remove-all gcc 
sudo update-alternatives --remove-all g++

Wenn man will (oder muss, weil aus irgendwelchen Gründen noch ältere Versionen benötigt werden), kann man diese auch wieder hinzufügen:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50

Soooooo – ab sofort ist GCC 4.8 der Standard-Compiler auf der Himbeere (Testen mit „gcc -v“). Falls man evtl. andere GCC-Versionen aktivieren möchte, so geht das mit

sudo update-alternatives --config gcc
sudo update-alternatives --config g++

Raspberry Pi verliert WLAN-Verbindung: die ultimative Abhilfe

Wer einen Raspberry Pi mit USB-WLAN-Stick (z. B. Edimax) im 24/7-Betrieb laufen hat, der kennt das Problem: Sobald der WLAN-Hotspot auch nur kurzzeitig weg ist – sei es durch übermäßigen Traffic durch andere Teilnehmer oder durch Nachtabschaltung -, schaltet das WLAN-Plugin des RasPi ab. Man hat dann keine Chance mehr, administrativ per SSH auf den Raspberry zuzugreifen und es hilft nur ein harter Reset oder „Stecker raus – Stecker rein“, um das Ding neu zu starten und online zu bringen. Mehr als einmal ist es mir schon passiert, dass ich auf die Art die SD-Card zerschossen habe.

Nun habe ich mir endlich mal die Zeit dafür genommen, nach Abhilfe für dieses Problem zu suchen. Auf einem alten Raspberry Pi 2B hab ich seit Ewigkeiten einen kleinen Webserver laufen, dessen Inhalte auch brav bei Bing & Co. indexiert werden. Es ist schon passiert, dass die Webseiten in den Suchmaschinen nicht mehr gelistet wurden, weil der RasPi von mir unbemerkt mehrmals einige Tage nicht mehr am Netz hing – ich schaue ja nicht ständig nach dem zart-bläulichen Blinken der WLAN-LED. Die Suchmaschinen-Bots schauen gelegentlich mal nach, was es bei mir so Neues gibt, erreichen den Server nicht und folgerichtig fliegen die Seiten aus dem Index. Und per Cronjob das Ding in loser Folge neustarten zu lassen, („falls mal was sein sollte“) erschien mir auch recht unprofessionell.

Ich hab mir wie folgt beholfen: Im Verzeichnis /etc/ifplugd/action.d gibt es eine Shellskript-Datei namens ifupdown. Die hab ich umbenannt nach ifupdown.bak (da steht zwar nicht viel drin, aber könnte man ja nochmal brauchen). Danach habe ich im Verzeichnis /etc/wpa_supplicant/ nach der Datei ifupdown.sh Ausschau gehalten. Diese hab ich nach /etc/ifplugd/action.d kopiert und nach ifupdown umbenannt. Die bisherige ifupdown wird dadurch durch eine neue Version ersetzt. Diese versetzt den Raspberry  in die Lage, sich in das vorhandene WLAN-Netzwerk wieder „einzubuchen“, wenn es denn mal weg war. Nun wird der RasPi abschließend mit sudo reboot neu gestartet. Wenn man alles richtig gemacht hat, ist zunächst alles unverändert: WLAN startet, die entsprechende LED blinkt. Nun kann man testen, ob der gewünschte Reconnect funktioniert: Einfach das WLAN abschalten oder den Stecker am Router ziehen, wie auch immer. Jetzt sieht man, dass die LED des WLAN-Moduls in loser Folge kurz aufblinkt und nach „seinem“ Funknetz sucht (bisher ging die LED aus und der RasPi war offline). Sobald der WLAN-Hotspot wieder da ist, verbindet sich der Raspberry Pi wieder binnen wenigen Sekunden. Bei meinen Tests hatte ich vor dem Ausschalten des WLANs eine SSH-Session offen. Nachdem das Netz wenige Minuten weg und dann wieder da war, war die SSH-Verbindung immer noch bzw. wieder unverändert vorhanden – ls -l flog über den Bildschirm, als wenn nichts gewesen wäre.

Einen Haken hat die ganze Sache jedoch: Sobald man den Raspberry auf diese Art umkonfiguriert hat, funktioniert die LAN-Buchse nicht mehr. Also WLAN off und dann Netzwerk-Stecker in die Ethernetbuchse geht nicht. Aber hierfür haben wir ja die ifupdown.bak gesichert. Wenn man also wieder mal ein Netz per Leitung braucht: Einfach die Datei nach ifupdown umkopieren, und schon ist wieder alles beim Alten.

Sprechende URLs mit GetSimple CMS und nginx

Ich liebe so kleine CMSe wie GetSimple, mit denen man ohne Datenbank-Gedönse schnell eine kleine performante Website hochziehen kann. Auf einem Raspberry Pi 2B habe ich einen Webserver mit nginx aufgesetzt, die Dateien von GetSimple CMS eingespielt – und läuft. Nun kann nginx leider nicht mit den .htaccess-Dateien von Apache umgehen, mit denen man z. B. Zugriffsbeschränkungen und Redirects steuern kann. Das führt bei GetSimple dazu, dass man im Backend unter den Einstellungen den Haken bei „Nutze freundliche URLs – Erfordert mod_rewrite auf Ihrem Server“ zwar setzen kann, wenn man dann aber auf der Website in der Navigation auf entsprechende Unterseiten klickt, rennt man gnadenlos auf einen Server-Error 500.

Hier muss man also statt .htaccess direkt in der Serverkonfiguration editieren. Unter /var/www/etc/nginx/sites-available öffnet man mit su-Rechten die Datei „default“. In dem Bereich „server { … }“ sucht man sich den Eintrag „location / { … }“ und fügt dort folgende Zeile ein:

try_files $uri $uri/ /index.php?id=$uri&$args;

Dieser Eintrag sorgt dafür, dass GetSimple URLs umschreiben kann. Jetzt diese Datei speichern und mit „sudo service nginx restart“ den Webserver neu starten. Und nun klappt es auch mit den Fancy URLs. Das wird übrigens auch die SEO-Freaks freuen.

Wer sich in die GetSimple-optimierte nginx-Konfiguration einarbeiten möchte: Hier findet man eine gute Dateivorlage mit den Zugriffsrechten innerhalb der GetSimple-CMS-Verzeichnisstruktur.

 

Wieder einmal PuTTY: Darstellung von Linien, Umlauten und Sonderzeichen

Ich greife öfter mittels des Terminalprogramms PuTTY unter Windows auf Linux-Rechner zu – insbesondere auf meine Raspberry Pis. Nun kommt es immer wieder mal vor, dass bestimmte zeichenorientierte Anwendungen auf einer Linux-Konsole in PuTTY falsch dargestellt werden. Ich muss z. B. häufig mit dem alsamixer Audio-Einstellungen der USB-Soundcard eines Raspberrys ändern. Aus den gewohnten Rahmenlinien wird in PuTTY ein Buchstaben-Mix umgesetzt, die als lppk-Zeichenfolge bekannt ist. Hinzu kommt, dass die F-Tasten in PuTTY nicht richtig funktionieren und dafür sorgen, dass alsamixer beendet wird, wenn ich mit F3 bzw. F4 zwischen den Wiedergabe- und Aufnahmeeinstellungen umschalten will. Hier helfen einige PuTTY-Einstellungen.

raspberry_putty-lqqk

Diese verwurstete Darstellung nervt mich schon seit Jahren.

 

Unter Connection/Data ist es wichtig, dass man im Feld „Terminal-type String“ das vorgegebene „xterm“ durch das Wort „linux“ ersetzt. Achtung – kontextsensitiv! „linux“ muss komplett kleingeschrieben werden. Somit haben wir die richtige Rahmendarstellung schon mal im Griff. Nun ist es noch wichtig, unter Terminal/Keyboard unter „Function keys and keypad“ den Radiobutton „Linux“ zu setzen – dann funktioniert es auch mit den F-Tasten.

putty-alsamixer

So soll es sein!

 

Eigene Webseiten vor fremden Frames schützen

Es kommt ja immer wieder mal vor, dass die eigene Homepage irgendwo im Web von fremden Leuten per HTML-Frame eingebunden wird – diese Leute machen sich also fremde Webseiten zu eigen. Okay – das mag allenfalls ein urheberrechtliches Problem sein, aber man kann diese uralte HTML-Technik (Frames sind in HTML5 nicht mehr vorgesehen!) auch für richtig bösartige Sachen nutzen. Da baut sich jemand Böses einen Frameset, bindet darin meine Webseite ein und verlinkt seinen Frameset z. B. bei Twitter. Nun wird meine Webseite von zigtausenden Surfern angeklickt – schlimmstenfalls reißt das meinen Webserver in die Knie. Oder jemand lässt mittels Frames meine schöne, hochkulturell wertvolle Seite zusammen mit was-weiß-ich-was-für Seiten im Browser erscheinen.

Wie kann man das nun verhindern? Nun, ich betreibe eine kleine Homepage auf einem Apache2-Server auf einem Raspberry Pi (für wenige Besucher pro Stunde reicht das voll und ganz). In der httpd.conf habe ich eine Zeile eingefügt, welche bewirkt, dass in dem HTTP-Response-Header eine Anweisung ausgegeben wird, dass meine Webseiten nur von meinem eigenen Webserver in Frames eingebunden werden darf. Diese Zeile lautet wie folgt:

Header always append X-Frame-Options SAMEORIGIN

Anstatt „SAMEORIGIN“ kann man auch die Option „DENY“ setzen. Dann darf nicht mal mehr mein eigener Webserver den Content in Frames darstellen – wer weiß, was meine Designer-Kollegen da für einen Unfug treiben 🙂

Nachdem man die Änderung in der httpd.conf gespeichert hat, startet man den Webserver mit sudo service apache2 restart neu. Sollte es beim Neustart zu Fehlermeldungen kommen, ist in der Apache2-Konfiguration das Modul „mod_headers“ nicht aktiviert. Dies kann man nachholen, in dem man in der Konsole „sudo a2enmod headers“eingibt. Jetzt sollte der Apache2-Neustart fehlerfrei laufen.

Und wie testet man jetzt, ob die Änderung wirklich aktiv ist? Hier gibt es eine Testseite, in der man sich den HTTP-Header des eigenen Webservers (und natürlich jedes anderen Webservers der Welt) ansehen kann. Dort sollte jetzt die Zeile

X-Frame-Options: SAMEORIGIN

erscheinen.

Übrigens: Wenn Sie keinen Zugriff auf die Servereinstellungen Ihres Webspaces haben – man kann auch mit .htaccess das Kapern Ihrer Webseiten mit Frames verhindern. Die hinzuzufügende Zeile lautet: Header append X-FRAME-OPTIONS „SAMEORIGIN“

Ach ja, und wo wir schon mal dabei sind: Wenn Sie in der Auflistung des HTTP-Headers die Zeile sehen: „X-Powered by“ – und dahinter Ihre detaillierte PHP-Version (ein Freudenfest für Hacker!), sollte man das schleunigst in der php.ini abschalten, indem man in der Zeile expose_php = On das „On“ durch ein „Off“ ersetzt.

Apache und .htaccess auf dem Raspberry Pi

Ich habe auf meinem Raspberry Pi einen Apache2 laufen, der auch meistens per WLAN über den Router ans Netz angebunden ist. Nun ist der Apache in der Standardinstallation eine höchst unsichere Kiste. Verzeichnisse unter /var/www sind offen einsehbar, was natürlich nicht so lustig ist. Also ist hier das Anlegen einer .htaccess-Datei die erste Wahl. Dazu muss die Nutzung der .htaccess erst einmal aktiviert werden.

Man öffnet dazu mit nano, vi oder dem Editor Ihrer Wahl die Datei ‚/etc/apache2/sites-available/default‘. Dort findet man eine Zeile „AllowOverride None“. Die ändert man zu „AllowOverride All“. Zu beachten ist hier, dass man diese Zeile mehrfach findet. Wir bearbeiten hier den Bereich „<Directory /var/www“.

Jetzt können wir im Web-Hauptverzeichnis eine leere Datei .htaccess anlegen. Um Verzeichnisse unsichtbar zu machen (403 – Forbidden), schreiben wir die Zeile „Options -Indexes“ hinein.

Jetzt die Änderungen speichern und den Apache neu starten (sudo service apache2 restart). Ab jetzt sind die Dateien in den Unterverzeichnissen mit dem Browser nicht mehr einsehbar.

Eine nette Übersicht aller .htaccess-Funktionen auf Deutsch findet man unter http://www.trash.net/faq/htaccess.shtml .

PuTTY und der Ziffernblock

Wenn ich mal mit Windows 7 arbeite (kommt selten genug vor 😉 ) und per SSH auf meinen Raspberry Pi zugreifen möchte, nutze ich PuTTY. Seit langem ärgert es mich ein wenig, dass ich auf dem Ziffernblock der Tastatur keine Ziffern im Terminalfenster erhalte, sondern die alternativen Steuerzeichen (so als ob NumLock off wäre).

Abhilfe ist ganz einfach: in den PuTTY-Einstellungen unter „Terminal > Features“ die Option „Disable Application Keypad mode“ aktivieren. Am besten gleich diese Änderung unter „Session“ bei den Saved Sessions dauerhaft speichern.

Dann klappts auch mit den Zahlen.