ES STELLT SICH VOR...

Johannes Truschnigg jun.

Bild von Johannes Truschnigg, Juli 2013
  • Geburtsdatum: 28. 08. 1985
  • Herkunft: Bezirk Leoben, Österreich
  • Formale Bildung: Bakk. rer. soc. oek.
  • Beschäftigung: Sysadmin/Software Engineer
  • Nichtraucher: ja
  • Grundwehrdienst abgeleistet: ja
  • Führerscheininhaber: ja
  • Besondere Interessen: Freie Software, GNU/Linux, UNIX-artige Systeme, Skriptprogrammiersprachen, IT-Security, Systemoptimierung

Zur Suche ▼Zum Archiv ▼

Eintrag von 2012-01-01

Wie der Grinch das Botnet gestohlen hat


Anmerkung: Aus Sicherheitsgründen sah ich mich dazu veranlasst, einige Namen und Bezeichner in diesem Text zu zensieren, da es mit Kenntnis dieser möglich ist, unerlaubt Kontrolle über einige fremde Computersysteme zu erlangen. Ich bitte um Verständnis, dass ich diese Daten deshalb nicht öffentlich machen kann.

Der Advent ist schon lange keine stille Zeit mehr. Abseits vom normalen Weihnachtsstress bietet sich rund um die Feiertage auch ein für Cracker attraktives Zeitfenster, um in diesen Tagen weniger genau als üblich bewachte Systeme zu entern und unter ihre Kontrolle zu bringen. Mit so einem Zwischenfall hatte ich kürzlich zu kämpfen, als das IDS eines Webservers verdächtige Aktivitäten in der Nacht vom 22. auf den 23. Dezember meldete.

Ein VHost des installierten Apache-Webservers wuchs des Nachts um einige unschuldig aussehende Dateien im Cache-Directory eines populären CMS - einem Ort im Dateisystem, auf das der Webserver zwingend Schreibzugriff benötigte. Ich musste gar nicht tief graben um zu wissen, womit ich zu tun hatte: die scheinbar unschuldige Textdatei mit dem Namen "os2.txt" demaskierte sich rasch als ein in Perl zusammengehackter IRC-Bot, der über einen im Script kodierten C&C (Command and Control) Channel eine Vielzahl Kommandos entgegennehmen konnte, um auf diese Geheiße hin allerhand unangenehme Aktionen zu starten. Die Palette reichte vom Auffinden von Schwachstellen in Webseiten (Google-Dorks) über Bulk-Mailing via MTA des infizierten Systems und einen etwas kruden TCP-Portscanner bis hin zum Up- und Download von Files via XDCC bzw. HTTP. Ein wahres Schweizer Offiziersmesser für übelwollende Scriptkiddies also.

Einfaches Löschen der unerwünschten Datei ist in so einem Fall niemals anzuraten - man muss analysieren, was man sich eingefangen hat, um dann entsprechende Gegenmaßnahmen planen und umsetzen zu können. Ich beschloss also, dem Möchtegern-Einbrecher ein bisschen nachzusteigen, und mir anzusehen, was er denn so alles treibt oder noch zu treiben plant. Da das Schadprogramm nicht durch primitive Behelfe wie base64-Encoding des Quellcodes obfuskiert war, konnte ich ohne lästige Umwege Einblick in seine Funktionsweise nehmen. Schon in den ersten paar Zeilen der Datei fanden sich einige vielversprechend aussehende Skalardefinitionen:

1 #!/usr/bin/perl [...] 18 my $fakeproc = "/usr/sbin/apache2 -k start"; 19 my $ircserver = "irc.plasa.com"; 20 my $ircport = "6660"; 21 my $nickname = "user-redacted[".int(rand(100))."]"; [...] 23 my $channel = "#channel-redacted"; 24 my $admin = "maliciousUser"; [...]

Ohne den folgenden Code zu lesen konnte ich daraus mit einiger Sicherheit die folgenden Schlüsse ziehen:

  1. Es handelt sich um einen IRC-Bot.
  2. Die Intention des Crackers ist es, mehrere solcher Bots parallel zu installieren und zu kontrollieren - deswegen wird der Nickname des Bots (leidlich) zufällig generiert.
  3. Der Bot scheint zur "Authentifizierung" seines Meisters lediglich dessen IRC-Nickname zu prüfen.

Einer so indirekten wie herzlichen Einladung in einen Botnet-CNC-Channel konnte ich natürlich nicht widerstehen, und leitete meinen ohnehin laufenden IRC-Client gleich in Richtung irc.plasa.com, Teil eines indonesischen IRC-Netzwerkes. Das ergab Sinn, denn der HTTP-Request, den ich laut httpd Access-Log für das Einpflanzen der os2.txt-Datei als verantwortlich identifizieren konnte, erging laut WHOIS ebenfalls von einer Quell-IP-Adresse aus dem Netz der "PT TELKOM INDONESIA", direkt aus dem schönen Jakarta.

irc.plasa.com erwies sich nach dem Verbinden als Teil der "AllNetwork"-Föderation. Dass ich dort normalerweise nichts zu schaffen habe, hinderte mich nicht daran, ein bisschen herumzustöbern. Zuerst wollte ich wissen, ob mein alter Bekannter "maliciousUser" - seines Zeichens passionierter Botnet-Züchter und Drohnen-Meister - für ein persönliches Pläuschchen zu haben wäre:

/WHOIS maliciousUser * maliciousUser: No such nick/channel

Schade, niemand zum Plaudern da. Wenn schon der Meister nicht anwesend ist, dann doch vielleicht eine seiner fleißigen Drohnen? Und um vor solchen einen guten und vertrauenswürdigen Eindruck zu machen, hilft es doch bestimmt, wenn man eine ihnen vertraute Identität annimmt...

/NICK maliciousUser * You are now known as maliciousUser -NickServ- This nickname is registered. Please choose a different nickname, or identify via /NickServ identify <password>.

maliciousUser legte also Wert darauf, dass nur er selbst seinen Nickname tragen würde - deshalb hatte er ihn sich via NickServ reservieren lassen. Das alleine hält niemanden im IRC davon ab, die Identität (bzw. den Nickname) eines beliebigen Users anzunehmen, der momentan nicht online ist. Erst wenn der rechtmäßige "Besitzer" eines Nicknames diesen annehmen möchte und dann feststellt, dass ihn jemand anders trägt, kann er ggf. via Nachricht an NickServ unter Angabe seines Passwortes einen Kick des Identitätsdiebes veranlassen, und daraufhin selbst den so freigewordenen Nickname übernehmen. Der gute maliciousUser war zum Zeitpunkt meiner Nachfroschungen nicht verbunden, und konnte somit nicht einmal hilflos zusehen, als ich die Kontrolle über seine Drohnen übernahm...

/JOIN #channel-redacted /NAMES #channel-redacted * Users on #channel-redacted: maliciousUser user-redacted[93]

Nun, das war zugegeben etwas weniger, als ich mir erwartet hätte: Ein einzelner, etwas armselig und einsam wirkender Bot, verlassen sogar von seinem (vermuteten) Meister maliciousUser - wobei es diese Beziehung noch zu prüfen galt. Laut mir vorliegendem Sourcecode des Bots sollte es das Kommando "!reset" geben, welches, sofern der Bot-Admin es in den Channel oder direkt in ein Query für den Bot schreibt, einen totalen Neuaufbau seiner IRC-Verbindung bewirken sollte. Und tatsächlich:

<maliciousUser> !reset * user-redacted[93] has quit (Quit: Restarting...) <user-redacted[93]> Hi maliciousUser im here !!!

Mein neuer Freund user-redacted[93] ließ sich ohne Umschweife dazu überreden, sich neu zu verbinden. Mehr noch: nach dem erfolgreichen Reconnect war er sogar so freundlich, mir in gebrochenem Englisch mitzuteilen, dass er jetzt anwesend (und bereit zur Entgegennahme neuer Kommandos) wäre.

Nach ein bisschen Umgraben im Quellcode meiner Bot-Kopie beschloss ich, dass ich genug gesehen hatte - die "erweiterten" Features wie z. B. eine vollwertige Shell auf dem infizierten Host musste ich gar nicht mehr mit eigenen Augen sehen, um dem Treiben des echten maliciousUser einen Riegel vorschieben zu wollen. Was aber tut man in so einem Fall? Ohne mehr über die Identität des wahren maliciousUser zu wissen, gibt es nicht viel, das man proaktiv unternehmen könnte. Eine kurze Anfrage bei NickServ ergab, dass es den registrierten Nickname "maliciousUser" noch nicht einmal ganz zwei Tage gab, und dass dieser seine Registrierung noch nicht (via E-Mail-Validation - die E-Mail-Adresse dafür wird von NickServ in der Regel, und so auch hier, nicht herausgegeben) bestätigt hätte. Aus dem Banner des IRC-Servers vermochten mir meine nicht gerade famosen Indonesisch-Kenntnisse auszudeutschen, dass man im Channel #help Administratoren des Netzwerks kontaktieren könnte:

/NICK c0l0 /JOIN #help * Now talking on #help <c0l0> hi everyone <SkiN> yes <SkiN> may i help u ? <c0l0> I need to find out the email address of a person who registered with the nickserv service on your network. I do know the nickname of that person. is that possible? <SkiN> who ? <SkiN> can you speak in bahasa ? <c0l0> sorry, only English or German <c0l0> (and a little bit of Italian) <SkiN> hehe * SkiN just can speak bahasa and litle bit of english <c0l0> it's about the user with the registered nickname "maliciousUser" <SkiN> who the person you're looking for <SkiN> wait pls <c0l0> I will. thanks for your support :) <SkiN> but before i give you the information <SkiN> may i know who are you ? <c0l0> I'm a network administrator. I have reasons to believe that "maliciousUser" is responsible for an intrusion attempt into one of our web servers. <SkiN> maliciousUser has NOT COMPLETED registration verification <c0l0> yes, I noticed that from querying nickserv <SkiN> [16:53] -NickServ- Email : cristercorp@gmail.com (hidden) [...]

So weit, so gut. Wenige Sekunden bevor ich die E-Mail-Adresse durch den freundlichen Admin SkiN mitgeteilt bekommen hatte, passierte in #channel-redacted allerdings etwas Bemerkenswertes: user-redacted[93] schaltete sich selbst spontant ab! Das kann natürlich wirklich Zufall sein - oder aber der Hinweis darauf, dass zumindest SkiN (oder ein mit ihm bekannter User des Netzwerks) irgendwie im Zusammenhang mit dem Aufbau oder Betrieb des Botnetzes stehen könnte. Da sich dieses aber nunmehr auf die ungefährliche Größe von 0 Hosts reduziert hatte, beschloss ich, den Netzwerk-Admin aus user-redacted[93]s IP-Block eine kurze Mitteilung zukommen zu lassen: Dass dieser Host Teil eines Botnetzes wäre, und dass man den Administrator der Maschine zu einem etwas vorgezogenen Neujahrsputz anhalten sollte. Zwei Tage später kam die Antwort (sogar die eines echten Menschen - ich war beinahe gerührt!), dass man sich den Host angesehen hätte, und keine TCP-Verbindungen mehr zum fraglichen IRC-Server bestünden. Ich hoffe für die Betreiber, dass dies immer noch zutrifft.

Die verwundbare Wordpress-Installation auf dem Webserver wurde inzwischen gesundgepatcht, und weitere Einbrüche sind - nach gegenwärtigem Kenntnisstand - vorerst nicht zu erwarten. Das Botnetz, das maliciousUser hätte aufbauen wollen, existiert aber weiterhin, zumindest in Bruchteilen. Alle paar Tage schaue ich kurz vorbei, schlüpfe in den Wolfspelz von maliciousUser und kümmere mich um meine Schäfchen - ich schalte sie also ab und benachrichtige jene, die nachhaltig etwas gegen ihren Befall tun können. Vielleicht laufe ich so ja auch maliciousUser einmal über den Weg. Ich wäre gespannt, was er in unserem Pläuschchen zu erzählen hätte!

direkter Link ▲

Eintrag von 2011-09-26

GNU screen als Systemmonitor für ungenutzte ttys


Fast jeder GNU/Linux-Anwender hat schon einmal mit einem Linux VT (Virtual Terminal) zu tun gehabt: das sind jene durch den Kernel emulierten Terminals, die man durch Drücken von [CTRL]+[ALT]+[F1]...[F12] erreichen kann. Auf manchen dieser auch ttys genannten Bildschirme kann man sich in eine Shell einloggen, auf anderen ist Debug- und Log-Output zu sehen, und auf wieder anderen läuft (zumindest auf Desktop-Maschinen) zumeist das lokale Display eines X-Servers. Die Details sind, wie so oft, distributionsspezifisch.

Unter Debian GNU/Linux werden diese ttys (und was in ihnen direkt nach dem Hochfahren läuft) durch /sbin/init (aus dem Paket sysvinit) verwaltet. In der Standardkonfiguration ist das Setup wenig abwechslungsreich: die ttys 1 bis 6 starten das Programm getty(8), das - sofern man es nicht per Startparameter anders anweist - /bin/login startet. Um den Rest (den konkreten Anmeldevorgang am System unter der Nutzeridentität XY) kuemmert sich dann das PAM-Subsystem.

Meiner Erfahrung nach ist diese Vorbelegung der Linux-VTs reichlich sinnlos: auf Desktops braucht man sie vorwiegend dann, wenn der X-Server des lokalen Displays abstuerzt, und auf Servern arbeitet man im Regelfall ohnehin via ssh(1). In virtualisierten Umgebungen kommt man manchmal in die Verlegenheit, direkt mit einem VT eines Gastsystems zu interagieren, wenn der Gast (vielleicht durch eine irrtümliche Fehlkonfiguration) selbst vom Netzwerk getrennt ist, der Hypervisor-Host (der auch Input- und Output-Geräte für die Gastsysteme emuliert) aber sowohl auf das Netzwerk, als auch auf die virtuelle Tastatur und den virtuellen VGA-Ausgang des Gastsystem Zugriff nehmen kann.

Gründe also, die vielleicht einen oder zwei derart belegte und auf Login-Versuche wartende VTs in Multiuser-Runlevels rechtfertigen, aber wohl nicht gleich sechs an der Zahl. Vor allem der nach dem Bootvorgang sichtbare VT kann meines Erachtens sinnvoller genutzt werden: als Systemmonitor. Zur übersichtlichen Aufteilung des durch Linux emulierten Terminals kann man auf das mächtige GNU screen(1) zurückgreifen: dieser Terminal-Multiplexer ermöglicht es unter anderem, den Anzeigebereich vertikal und hortizontal zu splitten, und in die resultierenden Partitionen einzelne CLI- oder TUI-Programme zu packen - eine Art Tiling Window Manager für Terminals, auch wenn sich eben diese Familie von Fensterverwaltungsprogrammen fuer X11 das Konzept von screen abgeschaut hat, und nicht etwa umgekehrt.

GNU screen kann diese Aufteilungstricks sowohl interaktiv (zur Laufzeit) als auch durch eine Konfigurationsdatei, die screenrc, vorbestimmen lassen. Um den verfügbaren Platz im Terminal in vier Panele (eine 2x2-Konfiguration) aufzuteilen und darin einige nützliche Informationen über den Systemstatus anzuzeigen, kann man sich folgender screenrc behelfen:

shell /bin/true
autodetach on
defutf8 on
startup_message off
caption string "%{= kg}=/\\= %t =/\\="
defwrap off

screen /usr/bin/top
title "CPU, Memory"

split
split -v
focus down

screen /usr/bin/iotop
title "I/O Throughput"

focus down

screen /usr/bin/watch -t -d -n5 "/bin/df"
title "Filesystem Status"

split -v
focus down

screen /usr/bin/watch -t "dmesg | nl | tail -n15"
title "Kernel Messages"

Ausprobieren kann man diese Konfiguration, indem man sie unter einem (beliebigen) Dateinamen speichert, und den Pfad zu dieser als Argument zur Option "-c" von screen anführt, z. B. also so: `screen -c /usr/local/etc/screenrc_sysmon`. Zu beachten ist dabei, dass die durch die Konfiguration referenzierten, zu startenden Programme im System unter den jeweiligen Pfaden installiert sein müssen, da es sonst zu (harmlosen) Fehlern kommt.

Die oben notierte Konfiguration hat noch einen Schönheitsfehler: Sie kann zur Laufzeit verändert bzw. beschädigt werden. Um dies zu verhindern, kann man sich zweier Kniffe behelfen:

  1. Abschalten der Escape-Sequenz
  2. Setzen restriktiver screen-ACLs

GNU screen verwendet eine sogenannte "Escape-Sequenz" - eine spezielle Tastenfolge mit besonderer Bedeutung - um das Verhalten des Programms zur Laufzeit steuern zu können. Indem man diese auf den leeren String "" setzt und damit abschaltet, verhindert man, dass Benutzer auf die durch die Konfigurationsdatei definierten screen-Session-Parameter Einfluss nehmen können. Dies erreicht man durch das folgende (zusätzliche) Statement in der Konfigurationsdatei:

escape ""

Nun gilt es noch, dem Benutzer die Einflussnahme auf in der screen-Session laufende Programme zu verwehren. Der Prozess- und CPU-Last-Monitor `top` z. B. könnte durch Drücken der Taste [Q] beendet werden, was es zu verhindern gilt. GNU screen beherrscht (aus vielerlei Gründen, aber einer der wichtigsten und treibendsten für die Umsetzung dieses Features war wohl die verlockende Vision von Mehrspieler-Nethack-Sessions!) einen Mehrnutzer-Modus, in dem sich zeitgleich mehr als ein Nutzer auf eine screen-Session verbinden können. Ein derartiger Mechanismus schreit natürlich förmlich nach einem Berechtigungssystem (sodass z. B. User A auf Screen 1 vollzugriff hat, User B aber nur lesen darf), welches GNU screen selbstverständlich in Form von Access Control Lists (ACLs) bietet. DIe folgenden drei zusätzlichen Konfigurationszeilen aktivieren den Multi-User-Modus, und entfernen die "write" und "execute"-Berechtigungen für alle Screens in dieser Session von allen Usern:

multiuser on
aclchg * -w "#"
aclchg * -x "#"

Seitens screen ist das schon alles - möchte man aber tatsächlich einen VT als Anzeige für einen derart konfigurierten screen gebrauchen, fehlt noch ein Puzzlestein: Linux VTs haben die (für diesen konkreten Anwendungsfall) unangenehme Angewohnheit, DPMS zu aktivieren, und angebundene Anzeigegeräte nach einigen Minuten in den Standby-Modus zu schicken. Vor allem in virtualisierten Umgebungen ist das (in Abwesenheit eines physischen Monitors) eher schädlich als hilfreich, da man so ohne den Einsatz einer seriellen Konsole nach Ablauf des Standby-Zeitlimits nicht mehr an potenziell hilfreiche Fehlermeldungen im Falle eines Kernel Panics kommt. Auch für unseren GNU screen-Systemmonitor ist dieses Verhalten mehr lästig als nützlich, weswegen wir - gemeinsam mit dem Start der vorkonfigurierten screen-Session - in ein kleines Hilfsprogramm packen:

#!/bin/sh
export TERM=linux
/bin/echo -ne "\033[9;0]"
/usr/bin/setterm -powerdown 0
/usr/bin/screen -c /usr/local/etc/screenrc_sysmon

Das obige Beispiel impliziert natürlich, dass die vorhin erstellte screenrc unter dem Pfadnamen "/usr/local/etc/screenrc_sysmon" abgespeichert wurde. Das Shellscript oben speichert man z. B. unter "/usr/local/bin/sysmon-screen" und setzt die Executable-Permissions darauf. Nun kann man sich daran machen, die konfigurierte Instanz von getty auf dem ersten Linux-VT durch dieses kleine Shellscript zu ersetzen. Dazu muss man unter Debian die Datei "/etc/inittab" ändern, konkret mindestens einen jener Einträge, die den regulären Ausdruck /^[0-6]:/ matchen. Die Änderungen im Detail zu beschreiben ist etwas länglich, weswegen ich einfach einen kleinen patch(1) hier anhänge, aus dem man die notwendigen Eingriffe ableiten kann:

--- a/inittab
+++ b/inittab
@@ -53,5 +53,6 @@
 #
 -1:2345:respawn:/sbin/getty 38400 tty1
 -2:23:respawn:/sbin/getty 38400 tty2
 -3:23:respawn:/sbin/getty 38400 tty3
 +
 +#1:2345:respawn:/sbin/getty 38400 tty1
 +2:23:respawn:/usr/local/bin/sysmon-screen
 +3:2345:respawn:/sbin/getty 38400 tty3
  4:23:respawn:/sbin/getty 38400 tty4

Wer die Konfigurationsdateien aus den obigen Ausführungen lieber herunterlädt anstatt sie selbst händisch zusammenzukopieren, der findet Kopien davon hier:

direkter Link ▲

Eintrag von 2010-10-04

Linux-md, LVM2 und ext4 - Online-Reshaping


Linux steckt heute als treibende Kraft in Home-Routern, Smartphones, Desktops, Servern und Supercomputern. Neben der lizenkostenfreien und quelloffenen Natur der Software sind auch ihre unvergleichliche Flexibilität und bestechende Modularität Gründe dafür. Dies schlägt auch in den Storage-Subsystemen durch und ist meine Motivation, meinen Homeserver mit Gentoo GNU/Linux als Betriebssystem zu verwenden. Vor ein paar Tagen habe ich diesem eine Speichererweiterung gegönnt: Statt vier 1500GB-Festplatten sind nun fünf verbaut, der verfügbare Bruttospeicherplatz beträgt nun stattliche 7500GB - hoffentlich genug für die nächsten zwei oder drei Jahre.

Auch wenn es in meiner Situation nicht unbedingt notwendig gewesen wäre, habe ich es mir zum Ziel gesetzt, die Erweiterung des Server ohne Downtime oder Reduktion der Verfügbarkeit über die Bühne zu bringen. Das bedeutet: wer auch immer Dienste, die der Server anbietet, nutzt, bemerkt nichts davon, dass auf diesem gerade Wartungsarbeiten durchgeführt werden. Alle Fileserveraktivitäten und dergleichen werden vor, während und nach der Erweiterung unterbrechungsfrei zur Verfügung gestellt.

Das ist auf Systemebene alles Andere als eine triviale Sache: Die neue Festplatte muss im laufenden Betrieb zuerst ins System selbst und dann in ein RAID-Array eingebunden werden. Dann muss das Volume Management-Subsystem darüber informiert werden, dass es nun eber mehr Platz auf dem RAID-Array verfügt, und am Ende will auch noch das darauf residierende Dateisystem entsprechend aufgeblasen werden. All das passiert, während Nutzer möglicherweise Daten vom Server lesen oder gar auf ihn schreiben. Zum Glück haben sich Heerscharen von Kernelhackern darüber Gedanken gemacht, wie man solche Anforderungen ohne Datenverlust erfüllen kann - was Administratoren viel Kopfzerbrechen spart. Einen Ansatz, eine solche Erweiterung unterbrechungsfrei durchzuführen, will ich in diesem Posting demonstrieren.

Das Anstecken einer neuen (SATA-)Festplatte zur Laufzeit ist mit einem aktuellen Kernel und einem modernen Controller kein Problem mehr: Kaum registriert der Controllertreiber Bewegung am Port, taucht die neue Disk auch schon unter einem neuen Device Node Name im /dev-Verzeichnis auf. Da mein md-RAID-Setup nicht rohe Festplatten direkt einbindet, sondern MBR-Partitionen als Grundbaustein für mein RAID5-Array benutzt, habe ich zuallererst das Partitionslayout einer existierenden Platte aus dem Verbund auf die neue, fünfte Platte (in meinem Fall /dev/sdf) repliziert:

# sfdisk -d /dev/sdb | sfdisk /dev/sdf

Zu beachten ist dabei, dass sfdisk nur mit MBR-Partitionen umgehen kann. Will man GPT-Partitionen, BSD Disklabels oder irgenwelche anderen Schemata verwenden, ist man auf das wesentlich mächtigere GNU parted oder andere, potenziell plattformspezifische Tools angewiesen. Das dadurch entstehende Blockdevice /dev/sdf1 macht man md (mein Array wird unter dem Node Name /dev/md1 angesprochen) durch zwei Aufrufe von mdadm schmackhaft:

# mdadm --add /dev/md1 /dev/sdf1
# mdadm --grow /dev/md1

Das erste Kommando bindet /dev/sdf1 als Spare Device in den Verbund ein, das zweite sorgt dafür, dass alle Spare Devices zu vollwertigen Member Devices und damit als Nettospeicherplatz (in Form von Blocks - noch nicht in einem Dateisystem!) verfügbar gemacht werden. Dies hat einen RAID Resync/Reshape zur Folge, der auch ganz ohne Last auf dem Array und je nach seiner Kapazität mehrere Stunden dauern kann. Bis auf eine Reduktion der Schreib- und Lesegeschwindigkeiten ist von der Operation sonst aber nichts zu spüren, den Fortschritt der Operation kann man jederzeit in der Datei /proc/mdstat überprüfen.

Danach soll das Logical Volume Management-Subsystem (LVM2) erfahren, dass es nun mehr Speicher zur Verwaltung zur Verfügung hat. Das RAID5-Array /dev/md1 - ein aus Sicht von LVM2 ganz normales Blockdevice wie jedes andere auch - ist ja gerade um 1.5TB gewachsen; das durch es gebildete Physical Volume (PV) aber wähnt sich immer noch die ursprüngliche Kapazität fassend. Diesen Umstand ändert man mit

# pvresize /dev/md1

Ohne zusätzliche Parameter lässt pvresize das PV immer auf die Größe des ganzen zugrundeliegenden Block Devices wachsen, in diesem Fall also um 1.5GB. Hierbei sind keine langwierigen Reshape-Operationen nötig, da nur Metadaten in den PV-Beschreibungsstrukturen geändert werden. Diese Änderung erfolgt augenblicklich. Freilich ist das Vergrößern des PV nicht das Ende vom Lied: Wahrend die Volume Group (VG), die auf dem PV residiert, noch automatisch mitwächst, muss auch das Logical Volume (LV), das das zu vergrößernde Dateisystem beinhaltet, einen Wachstumsschub hinlegen. Im Unterschied zu pvresize muss man seinem Analog fuer LVs, lvresize, allerdings auch sagen, wie groß genau das LV letztendlich werden soll. Hier kann man entweder mit einer groben Kapazitätsangabe (bspw. 14000M, 14G, 0.14T, ...) arbeiten, oder aber Physical Extents (PE) als Einheit verwenden. PEs sind für LVM ungefähr das, was für Festplatten Sektoren sind: Die kleinsten individuell ansprechbaren Speicherblöcke, die vom System bearbeitet werden können. Um herauszufinden, wie viele PEs die gewachsene VG beinhaltet (und wie viele daher maximal für die LV konsumierbar sind), wirft man einen Blick in die Ausgabe von vgdisplay; entscheidend ist die Zeilen mit "Total PE" (zumindest sofern man, wie ich, nur eine LV in der VG definiert hat). Hat man sich dafür entschieden, wie viele PEs die LV nun aufbrauchen darf, erledigt lvresize das innerhalb eines Lidschlags:

# lvresize -l 1430000 /dev/myVG/myLV

Ich persönlich habe es mir zur Gewohnheit gemacht, die Anzahl der PEs immer auf ganze Tausenderstellen abzurunden. Auf diese verliert man maximal knapp unter 4000MiB Nettokapazität (bei der Default-PE-Größe von 4MiB), hat im Zweifelsfall aber ein bisschen mehr Luft für Snapshots oder auch temporäre Volumes, die man - das lehrt die Erfahrung - öfter braucht als man meinen möchte.

Zu guter letzt bleibt noch das Vergrößern des Dateisystems - in meinem Fall ext4. Dies erledigt das Programm resize2fs, und das recht gemächlich. Der Name rührt noch vom Urahn von ext4, dem Second Extended FS (ext2) her, und kann alle Versionen der ext-Dateisysteme vergrößern und auch verkleinern. Der Aufruf ist reichlich unspektakulär:

# resize2fs /dev/myVG/myLV

Abermals gilt: Fordert man nicht explizit weniger an, wird das Dateisystem auf den maximal zur Verfügung stellbaren Platz aufgepumpt. Man kann dem Dateisystem während des Wachsens zusehen, um den Fortschritt der Operation im Überblick zu behalten - wiederholtes Aufrufen von df verlangsamt den Prozess nicht merklich, und liefert unkompliziert Feedback und die Gewissheit, dass alles in Ordnung ist. Wer Zeit sparen, auf Nummer sicher gehen und eine Downtime verkraften will und kann, kann das Dateisystem vor dem Vergrößern unmounten - nötig ist das aber nicht.

Ein angemessenes Wort der Warnung noch zum Schluss: Alle Daten, von denen kein Backup existiert, sind als gelöscht zu betrachten!

direkter Link ▲

Eintrag von 2010-02-01

DSM/TRIM auch für Kingston-SSDs mit Intel-Controller


Über Solid State Disks habe ich erst kürzlich in meinem Blog geschrieben - ich selbst hatte mir vor einigen Wochen ein solches Gerät von Kingston, genauer ein Kingston SSDNow V-Series 40GB, angeschafft. Im Inneren des Geräts werkt ein SSD-Controller von Intel, der zu den besten seiner Art zählt: Gegenwärtig können ihm allein Konkurrenzprodukte der Firma Indilinx das Wasser reichen.

Kingstons 40GB-SSD-Variante der Intel Postville-SSDs hat sich offenbar so gut verkauft, dass Intel dieses Geschäft von nun an lieber selbst - das zumindest ist meine Erklärung dafür, dass Kingston das Gerät nicht mehr "produziert" (eigentlich nur verkauft), und es von Intel seit kurzem ein Produkt namens Intel X25-V G2 40GB gibt, das zur Kingston V-Series baugleich sein soll.

Damit nicht genug, hat man bei Intel und/oder Kingston auch noch beschlossen, dass diese "neue" 40GB-SSD ein durchaus relevantes Feature mehr haben sollte, um es attraktiver als den Vorgänger zu machen: ATA Data Set Management, auch bekannt unter dem Kürzel TRIM. Mittels DSM/TRIM kann ein Dienstprogramm bzw. Dateisystem dem SSD-Controller mitteilen, welche Blöcke auf dem Gerät es de facto nicht mehr allokiert, worauf diese dann wieder in die Kandidatenliste für das Wear Levelling aufgenommen werden können. Dies erhöht im besten Fall die Labenesdauer eines SSD, sorgt aber auf jeden Fall für höhere Schreibgeschwindigkeiten mit zunehmendem Alter des Mediums. Während man bei Kingston anfänglich auf Nachfrage noch meinte, DSM/TRIM für die SSD per Firmware-Update nachzuliefern, gab es vor einiger Zeit einen kleinen Aufschrei in der Netzgemeinde: Seitens Kingston wurde beiläufig bekanntgegeben, dass dieses Feature für diese Produktreihe nicht (mehr) auf der Roadmap stünde - es wären keine Firmware-Updates für die Kingston V-Series mehr zu erwarten.

Dazu sollte man wissen: Die Kingston V-Series SSD verfügt im Auslieferungszustand über die Firmware in Version 02HA - dies ist die erste Version der Firmware für Intel Postville SSDs, die DSM/TRIM aktiviert. Es ist zugleich auch jene Version, die von Intel nach wenigen Stunden wieder aus dem Downloadbereich zurückgezogen wurde, weil sie bei einigen Nutzern unter Windows 7 zu nicht näher beschriebenen Problemen geführt haben soll. Einige Zeit später erschien die fehlerkorrigierte Firmware-Version 02HD, die auch heute noch aktuell ist, und DSM/TRIM problemlos zur Verfügung stellt. Ohne Einblick in den Firmware-Quellcode konnte man also als Kingston-Kunde nicht sicher sein, ob dieser potenziell Datenverlust verursachende Fehler nicht auch in der Firmware der eigenen SSD schlummert - und eine Behebung dieses beunruhigenden Umstandes war nicht abzusehen.

Zum Updaten der Firmware von Intel-SSDs liefert Intel das Image einer FreeDOS-Boot-CD mit dem Programm iSSDFUT.exe. Lässt man dieses mit einer Kingston-SSD im System ablaufen meldet es nach wenigen Sekunden, dass keine Intel-SSD gefunden wurde, die für ein Firmware-Update in Frage käme. Gleich nachdem ich dies mit eigenen Augen beobachten durfte, habe ich mich an das Aushebeln des vermuteten Sperrmechanismus gesetzt. Nach einigen kleinen Modifikationen an der DOS-Binary hatte ich das Update-Programm zumindest so weit gebracht, dass mein SSD - trotz des Kingston-Brandzeichens in der Gerätekennung - in der Liste der erkannten SSDs aufschien. Das Update wurde mir dennoch verweigert: meine Firmware wäre eine "pre-production Version", und ich solle mich doch bitte an den Intel-Support wenden. In Folge ist es mir nicht gleich gelungen, auch diesen Mechanismus zu umgehen - was nicht mehr weiter tragisch ist, da ein overclock.net-User Namens telnet inzwischen ein von meinem Hack inspiriertes, voll funktionstüchtiges Update-Programm veröffentlicht hat. Mit diesem ist es möglich, die Firmware-Version 02HD auch auf ein Kingston-SSD aufzuspielen. Dies ist ein nicht ungefährlicher Prozess, der das Gerät möglicherweise irreparabel beschädigen kann - ich wurde zum Glück vor solchen Problemen verschont.

Ernüchternd allerdings nach dem Flashen die Erkenntnis, dass trotz der aktualisierten Firmware immer noch kein DSM/TRIM im Feature-Set der SSD aufscheinen wollte. Weitere Nachforschungen des Urhebers des modifizierten Update-Programms ergaben, dass ein bestimmtes ATA-Kommando in Richtung des Kingston-Geräts abgesetzt werden muss, um es nun tatsächlich zu aktivieren: dco restore (drive configuration restore). Das Programm `hdparm` erledigt das unter GNU/Linux (hier Beispielhaft am Device sda):

# hdparm --yes-i-know-what-i-am-doing --dco-restore /dev/sda

hdparm warnt, dass diese Operation "EXTREMELY DANGEROUS" ist, und mit hoher Wahrscheinlichkeit zu Datenverlust führen wird. Mit einem Backup gerüstet habe ich es dennoch gewagt, und keine der befürchteten Probleme bekommen. Gemeinsam mit dem Script `wiper.sh` (leider ist eine gepatchte Version für Intel-SSD-Controller notwendig) aus dem hdparm-Distributionstarball und hdparm 9.27 ist es mir nun möglich, DSM/TRIM zur Leistungssteigerung meines SSD zu nutzen. Ab Linux 2.6.33 und unter Nutzung von btrfs oder ext4 gibt es zudem bald automatisches TRIM im Hintergrund, sodass die manuelle Anwendung von `wiper.sh` nicht mehr notwendig ist.

direkter Link ▲

Eintrag von 2009-11-22

Solid State Disks - Hype oder Muss?


Solid State Disks (auch Solid State Drives, kurz SSDs) sind schon seit geraumer Zeit in aller Munde. Während nämlich Prozessoren, Caches, Hauptspeicher und sogar Netzwerkanbindungen in den letzten Jahrezehnten um Größenordnungen schneller geworden sind, hat sich bei rotierenden, magnetischen und/oder optischen Medien vergleichsweise wenig getan. SSDs brechen nun endlich mit dieser lange währenden Tradition.

Aktuelle Festplatten lesen und schreiben sequentiell über 100MiB/s, und die mittlere Zugriffszeit bewegt sich - wenn man von in der Realität erreichten Werten ausgeht, die so nicht unbedingt in den Hersteller-Datenblättern auftauchen - im Bereich um 10ms. Das klingt nach viel bzw. wenig, aber vor allem der zweite Wert, die vergleichsweise lange mittlere Zugriffszeit, führt in der Praxis oft zu lästigen Wartepausen.

Bei einem rotierenden, magnetischen Medium wie einer Festplatte führt jeder Zugriff auf das Dateisystem zu einer Bewegung von Plattern und Leseköpfen: ein komplexes System aus Dateisystem, Platten-, Controllertreiber und Firmware übersetzt die Anforderung von Dateien in das Auslesen physikalischer Positionen auf den Magnetscheiben des Datenträgers. Über viele Jahre hat man tausende Mannstunden in Algorithmen und Kniffe zur effizienten Allokation von physikalisch günstig zueinander gelegenen Blocks schon beim Schreiben investiert, um die so notwendigen Bewegungen auf ein Minimum zu reduzieren, und damit hohe Arbeitsgeschwindigkeit zu gewährleisten. Nicht alle dieser Strategien sind für bestimmte Workloads geeignet: in einem Fileserver etwa will man hohen maximalen Durchsatz, und ein paar Millisekunden mehr Latenz nimmt man dafür gerne in Kauf. Ein großer Mailserver mit zigtausenden Mails in einem Spool-Verzeichnis kann sich solche Verzögerungen nicht leisten, und der Kompromiss kippt zugunsten von mehr, aber kleineren Lesevorgängen pro Zeiteinheit. Durch geschickte Wahl von Dateisystem, Mount-Optionen und IO-Scheduler kann man hier erstaunliche Leistungssteigerungen erzielen.

Besonders fällt oftmals die mittlere Zugriffsgeschwindigkeit ins Gewicht: wenn viele Dateien in einem Verzeichnis existieren, so wird i. A. für jede dieser Dateien mindestens ein eigener Lesezugriff getätigt, wenn diese z. B. gelistet (`ls -l` oder opendir(3)/readdir(3)) werden. Wenn man von 1.000 Dateien in einem Verzeichnis und einer mittleren Zugriffszeit von 10ms ausgeht, so dauert diese Operation rund 10.000ms, also geschlagene zehn Sekunden. Mein Home Directory beinhaltet momentan knapp unter 690 Inodes, hier fällt diese Rechnung also schon recht deutlich ins Gewicht. Dass es in der Realität trotzdem nicht jedes Mal so lange dauert, bis Konqueror mir den Inhalt dieses Verzeichnisses präsentiert, liegt am aggressiven Filesystem-Caching des Linux-Kernels. Viele Charakteristika der Dateien in einem Dateisystem hält der Kernel im Hauptspeicher das Systems vor.

Vor allem hier (und ganz besonders ohne entsprechende Cache-Inhalte) kommt eine spezifische Eigenschaft von SSDs ins Spiel: Aufgrund ihres inneren Aufbaus (NAND-Bausteine anstatt magentischer Platter) kommen sie ohne bewegliche Teile aus, und die mittlere Zugriffszeit dieser Bauelemente liegt nicht wie bei Festplatten im Milli-, sondern im Mikro- bis Nanosekundenbereich. Populäre Programme zum Benchmarken von Blockgeräten sind meist noch nicht auf diese neue, für sie "unerwartete" Größenordnung vorbereitet, und weisen deshalb einfach 0.1ms als mittlere Zugriffszeit für SSDs aus. Selbst wenn man von diesen ziemlich grob approximierten 100 Mikrosekunden ausgeht, würde das die Laufzeit aus dem obigen Beispiel von 10 Sekunden auf 0.1 Sekunden reduzieren, das Listen braucht also um den Faktor 100 weniger Zeit. Die verkürzte Wartezeit ist subjektiv kaum wahrnehmbar - ein deutlicher Gewinn gegenüber der ursprünglichen, zehnsekündigen Zwangspause im Arbeitsfluss.

Aktuelle SSD-Generationen haben mittlerweile auch prinzipbedingte Probleme wie langsame sequentielle oder wahlfreie Schreibzugriffe sehr gut im Griff, und mit dem ATA-T13-Standard TRIM ist demnächst auch für gleichbleibend hohe Performance über die gesamte Lebensdauer einer SSD gesorgt.

Ich persönlich habe trotz dieser rosigen Aussichten erst einmal klein angefangen, und für mein treues Lenovo Thinkpad x200 ein relativ günstiges 40GB Kingston-SSD mit empfehlenswertem Intel-Controller angeschafft: Ein Kingston SSDNow! SNV125-S2. Auch wenn diese nicht ganz die Leistung anderer (mindestens doppelt so teurer) Geräte (ebenfalls mit Intel-Controller) erreicht, ist der Unterschied zu meiner alten 250GB SATA-300 Platte mit 5.400RPM enorm: Xorg startet nun knappe zehn Sekunden nach dem Einschalten des Notebooks, und auch meine X-Session ist in einem Bruchteil der Zeit geladen, die ich zuvor gewöhnt war. Selten zuvor habe ich knapp 80 Euro so gut in Hardware investiert.

Um das Optimum aus einer Solid State Disk unter GNU/Linux herauszuholen sollte man sich idealerweise schon vor dem ersten Beschreiben des Datenträgers unbedingt diesen Artikel von Ted Tso zu Gemüte führen, und für die SSDs im System den noop- oder deadline-IO-Scheduler verwenden.

direkter Link ▲

© 2007-2014 Johannes Truschnigg | Design by Andreas Viklund (modified) | valid xhmtl & css

Created with free software