Aus Linux-Magazin 07/2014

Kpatch und Kgraft

© Anatoliy Samara, 123RF

Den Kernel mit Security-Updates im laufenden Betrieb patchen, das ist das Ziel von zwei Projekten, mit denen derzeit Red Hat und Suse vorpreschen. Kpatch und Kgraft teilen manche Ansätze, unterscheiden sich aber auch in vielen Details und sind derzeit noch nicht für den produktiven Einsatz geeignet.

Bei Verbesserungen des Linux-Kernels oder bei Security-Updates vertrauen Admins meist der uralten Binärprozedur: Sie installieren aktualisierte Pakete des Kernels von ihrem Distributor oder bauen sich selbst einen neuen Kern, um dann das System neu zu starten.

Wer die Kernelupdates diverser Distributionen in den vergangenen Monaten und Jahren aufmerksam verfolgt hat, mag dabei schnell zu dem Schluss kommen, dass die jahrelangen, legendären Linux-Uptimes heute nur mehr mit unterlassenen Kernelpatches und damit einhergehenden Sicherheitslücken oder anderen Risiken machbar seien.

Geht gar nicht mehr: Cluster rebooten

Erst nach dem Reboot stehen schließlich die neuen Kernelfunktionen beziehungsweise die gewünschten Security-Fixes zur Verfügung. Dieser Vorgang, obgleich täglich tausendfach überall auf der Welt durchgeführt, wirkt zunächst völlig unspektakulär, sorgt aber im Hintergrund gelegentlich für Geräusche, die jeder Admin sich lieber ersparen würde.

Gehört der neu zu startende Server zum Beispiel zu einem Cluster, muss der Administrator Sorge dafür tragen, dass Pacemaker oder ein anderer Clustermanager nicht versehentlich einen Ausfall entdeckt und Notfallmaßnahmen einleitet. Laufende Services verschiebt der Cluster-Admin in der Regel manuell vor dem Reboot auf andere Systeme.

Doch der Reboot bedeutet ja nicht nur Arbeit, sondern in vielen Fällen auch Ausfallzeit, Downtimes für Services, deren Effekte der Admin abzufedern hat. Nicht zuletzt deshalb trachten IT-Verantwortliche in aller Welt danach, Neustarts zu verhindern, auch wenn “bloß ein neuer Kernel eingespielt worden ist”.

Aber auch noch andere Benutzergruppen würden sich über derlei Möglichkeit freuen. Kernel- und Treiberentwickler könnten deutlich effizienter arbeiten, wenn sie nicht nach jedem Code-Update einen Neustart durchführen müssten – so genannte Hotpatches stehen auch bei ihnen hoch im Kurs.

Ksplice

Bis jetzt war das auf Linux leider Illusion. Doch vor einigen Wochen brachten sowohl Suse als auch Red Hat Lösungen auf den Markt, die das Patchen des Kernels im laufenden Betrieb möglich machen sollen. Doch weder Suse noch Red Hat haben das Prinzip erfunden: Oracle stellt mit Ksplice [1] bereits seit einiger Zeit eine Lösung dieser Art zur Verfügung, die aber unter diversen patentrechlichen Problemen leidet und deren Lizenzbedingungen nur bedingt zuversichtlich stimmen. Zudem behält Oracle das Werkzeug mittlerweile ausschließlich den eigenen Business-Kunden vor, die Open-Source-Variante von Ksplice wird seit geraumer Zeit nicht mehr entwickelt.

Not invented here?

Sowohl Red Hat als auch Suse bieten in Form von Kpatch [2] und Kgraft [3] Alternativen an, die Ksplice in Sachen Funktionalität ebenbürtig sein sollen. Technisch gibt es zwischen den Ansätzen große Unterschiede, auch die gebotene Funktionalität divergiert merklich. Vielleicht ist das auch der Grund dafür, dass Red Hat und Suse mit eigenen Ansätzen vorpreschen, statt sich auf die gleiche Entwicklung zu einigen.

Böse Zungen schieben die Entscheidung allerdings eher auf Red Hats angeblich chronisches Not-invented-here-Syndrom, doch dürften in diesem konkreten Fall tatsächlich technische Details den Ausschlag gegeben haben.

Kgraft von Suse

Kgraft kommt aus Suses eigener Entwicklungsabteilung. Mittlerweile hat das Konzept Serienreife erlangt und sich der Hersteller damit an die Öffentlichkeit gewagt. Kgraft macht sich eine ganze Reihe von Funktionen zunutze, die moderne Versionen des Linux-Kernels unterstützen, dazu gehören INT3-Trap-Calls genauso wie Ready-Copy Updates (RCU) und Memory Profiling per Mcount. Das Potpourri aus Ansätzen verleiht Kgraft am Ende die Fähigkeiten, die es braucht, um Code im Kernel on the Fly durch anderen Code zu ersetzen.

Was dann folgt, ist technisch hochgradig komplex. Kgraft macht sich zum Beispiel massiv die Tatsache zunutze, dass der Profiling-Code von GCC am Anfang jeder Funktion beim Kompilieren etwas Platz lässt. In diesem Bereich liegen anfänglich Aufrufe der »ftrace()« -Funktion über einen »@__fentry__@-Call« . Allerdings werden diese beim Systemboot durch NOP-Einträge ersetzt. Jede Funktion hat am Anfang also eine gewollte Leerstelle, eben jene »NOP« -Einträge.

Kgraft nutzt genau die und ersetzt sie durch INT3-Handler, die beim Aufruf einer spezifischen Funktion ohne weitere Zwischenschritte sofort an eine andere Stelle des Kernelcodes springen können. Anders formuliert: Der Aufruf einer Funktion in einem Kernel mit Support für Kgraft führt stets dazu, dass Kgraft selbst aufgerufen wird. Kgraft sitzt also überall mit im Boot.

Patches als Kernelmodule

Da stellt sich sofort die Frage, wie der Code in den Kernel kommt, zu dem der Handler im Kgraft-Fall springen soll. Die Suse-Entwickler beschlossen, gepatchten Kernelcode in Form ganz normaler Kernelmodule zur Verfügung zu stellen. Damit ein Anwender also Code on the Fly ersetzen kann, braucht er ein entsprechendes Kernelmodul mit einer neueren Version der gewünschten Funktion. Nur Funktionen im Kernel lassen sich mittels Kgraft austauschen; an den internen Datenstrukturen des Kernels lässt sich über Kgraft nicht drehen.

Die Kgraft-Kernelmodule lädt der Admin eines Systems genau so wie jedes andere Modul auch. Das ist praktisch, da sich Kgraft-Updates in die vorhandene Paketarchitektur vieler Distributionen integrieren lassen. Für Suse, Red Hat, Debian und Ubuntu ist es schließlich nichts Neues, Kernelfunktionen über zusätzliche Modulpakete zu liefern. Bis jetzt hat das Verfahren zwar nur Treiber betroffen, die vorher nicht im Kernel waren. Aber mit Blick auf die Interfaces, die die Kgraft-Module besitzen, sind sie identisch zu normalen Kernelmodulen.

Dieses Prinzip erlaubt es, Kgraft-Patches in Form von Paketen über alle Systeme einer Installation zu verteilen und sie dort mittels »insmod« in den laufenden Kernel zu spielen. Wer Puppet oder Chef nutzt, kann den gesamten Vorgang sogar automatisieren. Viel bequemer lassen sich In-Place-Updates von Kernelfunktionen kaum noch gestalten. So sammelt sich Modul um Modul, bis der Admin in Ruhe einen Reboot durchführt. Ob dieser stetig wachsende Modulstapel irgendwelche Probleme verursacht, muss sich aber erst noch zeigen, weil Erfahrungswerte bisher fehlen.

Variante drei: Red Hats Kpatch

Auch Red Hat präsentiert gerade eine Lösung, die das Austauschen von Kernelcode im laufenden Betrieb ermöglicht. Bei den roten Hüten nennt sich das Ganze Kpatch http://2, und so wie Suse Kgraft alleine entwickelt hat, stampfte auch Red Hat Kpatch selber aus dem Boden. Direkte Anleihen an Oracles Ksplice bestehen also in beiden Fällen nicht. Technisch folgt Kpatch in gewisser Hinsicht den grundlegenden Entscheidungen, die auch Kgraft verwendet. Und doch gibt es massive Unterschiede.

Zunächst zu den Gemeinsamkeiten: Wie Suses Kgraft klinkt sich auch Kpatch in den Kernel über das Ftrace-Subsystem ein, das GCC beim Kompilieren automatisch einbezieht. Letztlich fängt Kpatch Funktionsaufrufe also auf sehr ähnliche Weise ab. Anders als Kgraft kommt Kpatch aber selbst als Kernelmodul daher, Admins brauchen den Hostkernel also nicht für den Hotpatch-Mechanismus zu patchen wie bei Suse.

Das bietet beispielsweise für die Szenarien Vorteile, in denen Admins den Patchmechanismus selbst durch eine neuere Version austauschen möchten. Bei Suse impliziert das zwangsläufig einen Reboot, bei Red Hat nicht.

Kpatch schiebt übrigens gleich zwei Module in den Kernel: Das »hot patch module« enthält die eigentliche Kpatch-Funktionalität und das »core module« stellt das Interface zur Verfügung, über das sich später Patches in den Kernel einspielen lassen.

Auch bei Kpatch: Schon wieder Patch-Module

Auch Kpatch erwartet die Updates für Funktionen in Form von Kernelmodulen, die in den Hostkernel zu laden sind. Beim Aufruf einer Funktion, die in neuerer Version über ein Kpatch-Patch bereitsteht, wird der Aufruf der Funktion dann zur “neuen” Version der Funktion weitergeleitet. Das »core module« dient als zentrale Patch-Registry und weiß, ob für eine bestimmte Funktion ein Patch per Kpatch installiert ist; abhängig davon führt es alten oder neuen Code aus.

Red Hat liefert übrigens mit Kpatch ein Werkzeug namens »kpatch-build« aus, das aus einem Patch für Linux ein Update-Modul macht. Und ebenso gehört auch ein Kpatch-Utility zum Lieferumfang, das die vorhandenen Hotpatches komfortabel verwaltet. Über dieses Werkzeug lassen sich sogar Patches definieren, die nach einem Systemneustart erneut geladen werden sollen.

Das klingt zwar zunächst, als konterkariere es den Kpatch-Ansatz insgesamt, ist dabei in Wirklichkeit aber sehr pfiffig: Wenn ein Admin sich eine funktionierende Kombination aus stabilem Kernel und zusätzlichen Patches gebaut hat und es fällt danach der Strom aus, sodass ein Reboot unumgänglich wird, so möchte er möglicherweise nicht gleich durch ein Kernelupdate eine zweite Baustelle aufmachen, sondern die bekante Umgebung wieder laden. Dabei hilft, wie sich das Laden von Modulen mit dem Kpatch-Utility realisieren lässt.

In der Praxis

Im Alltag fallen beim Vergleich beider Lösungen mehrere Details auf: So arbeitet Kpatch gründlicher, als es bei Kgraft der Fall ist. Im Kgraft-Beispiel gilt das Patch für eine Funktion nämlich nur für Aufrufe der Funktion, die nach dem Anwenden des Patch stattfinden. Funktionen, die schon vorher liefen, bleiben vom Patch unbeeinflusst.

So können mehrere Versionen der gleichen Funktion im Kernelspace vorliegen. Das wird möglicherweise dann zum Problem, wenn ein Kernelpatch ein kritisches Problem behebt und davon auch zentrale Treiber wie die für Netzwerkhardware betroffen sind. Denn jene lassen sich nicht ohne Weiteres ent- und wieder neu laden, um in den Genuss der korrigierten Funktionen zu kommen.

Red Hat folgt einer anderen Philosophie; ist ein Kpatch-Patch erst mal geladen, ersetzt es alle schon aktiven Funktionsaufrufe im Kernel ebenfalls durch die neue Version der Funktion, sodass das beschriebene Problem bei Red Hat gar nicht erst auftreten kann.

Die folgenden Anleitungen zeigen, wie sich Kgraft auf Open Suse 13.1 und Kpatch auf Fedora in der Version 20 mit recht neuen Kerneln (Abbildung 1) in Betrieb nehmen lassen. Das gelingt zwar auch auf anderen Distributionen, doch gestaltet sich dort der Installationsaufwand deutlich umfangreicher.

Abbildung 1: Testsysteme im Einsatz: Suse 13.1 mit Kernel 3.13 und Fedora 20 mit einem nagelneuen 3.14er.

Abbildung 1: Testsysteme im Einsatz: Suse 13.1 mit Kernel 3.13 und Fedora 20 mit einem nagelneuen 3.14er.

Angetestet: Kpatch auf Fedora

Auf Fedora 20 steht zunächst die Installation einiger Zusatzpakete an. Die folgende Anleitung setzt voraus, dass alle Pakete systemweit auf dem neuesten Stand sind. Zum Einsatz kommt die zu Redaktionsschluss aktuelle Kernelversion 3.14.3-200.fc20. Für ein funktionierendes Kpatch sind folgende Pakete notwendig:

  • »gcc«
  • »kernel-devel«
  • »elfutils« und »elfutils-devel«
  • »rpmdevtools«
  • »pesign«
  • »yum-utils«

Der Befehl »yum-builddep« kümmert sich nach der Installation der genannten Pakete per »yum install« darum, dass auch die passenden Kernelheader ihren Weg auf das System finden. Wer Ccache nutzen möchte, sollte dieses Paket ebenso installieren. Danach folgt der Download von Kpatch selbst: Mittels Git lässt sich das Repo auf die lokale Platte spiegeln. »git clone https://github.com/dynup/kpatch« tut genau dies. Mit »cd kpatch && make && make install« sorgt der Admin dafür, dass die Module zur Verfügung stehen.

Um zu testen, ob Kpatch wie gewünscht funktioniert, hilft das Anwenden eines kleinen Patch. Das Red-Hat-Beispiel schlägt vor, »/proc/meminfo« so zu ändern, dass der Kernel die »VmallocChunk« -Zeile fortan durchgehend in Großbuchstaben anzeigt. Für Fedora 20 erledigt dies das Patch in Listing 1.

Listing 1

meminfo-string.patch für Fedora 20

01 $ diff -ruN orig/fs/proc/meminfo.c new/fs/proc/meminfo.c
02 --- orig/fs/proc/meminfo.c 2014-03-31 05:40:15.000000000 +0200
03 +++ new/fs/proc/meminfo.c  2014-05-11 16:33:19.148771809 +0200
04 @@ -131,7 +131,7 @@
05   "Committed_AS:   %8lu kB\n"
06   "VmallocTotal:   %8lu kB\n"
07   "VmallocUsed:    %8lu kB\n"
08 -    "VmallocChunk:   %8lu kB\n"
09 +    "VMALLOCCHUNK:   %8lu kB\n"
10  #ifdef CONFIG_MEMORY_FAILURE
11   "HardwareCorrupted: %5lu kB\n"
12  #endif

Nach dem Editieren folgt der Prozess, der das eigentliche Kpatch-Patch baut: »Kpatch-build meminfo-string.patch« stößt den Prozess an. Im Anschluss muss der Admin dann seine Geduld unter Beweis stellen, denn für ein Kpatch-Modul baut das Helper-Tool im ersten Schritt den originalen Kernel, im zweiten Schritt den gepatchten, und erst im dritten Schritt wird dann aus dem Delta der beiden Trees das Kpatch-Modul gebildet. Das erklärt auch, warum der Einsatz von »ccache« sinnvoll ist.

Wer erstmals mit Kpatch arbeitet, wird sich von der Dauer dieses Prozedere möglicherweise genervt fühlen, doch bei Dutzenden von Rechnern relativiert sich der Zeitverlust durch das Kompilieren eines Kernels statt der zahlreichen Reboots schnell wieder.

Am Ende des Bauvorgangs steht ein »Kpatch-meminfo-string.ko« , das sich mit »sudo Kpatch load Kpatch-meminfo-string.ko« in den Kernel bugsieren lässt. Ein Blick in »/proc/meminfo« verrät anschließend, dass die Änderung tatsächlich funktioniert hat (Abbildung 2). Nach dem gleichen Schema würden die Änderungen anderer Funktionen im Kernel ebenfalls funktionieren.

Abbildung 2: Vor dem Einspielen des Patch mit Kpatch (links) zeigt »/proc/meminfo« das gewohnte Bild. Nach dem Laden des Patch findet sich an gleicher Stelle »VMALLOCCHUNK«, jetzt in Großbuchstaben.

Abbildung 2: Vor dem Einspielen des Patch mit Kpatch (links) zeigt »/proc/meminfo« das gewohnte Bild. Nach dem Laden des Patch findet sich an gleicher Stelle »VMALLOCCHUNK«, jetzt in Großbuchstaben.

Höhere Einstiegshürde: Kgraft auf Open Suse

Erwartungsgemäß stellt sich im Test heraus, dass die Einstiegshürde für Kgraft auf Open Suse ein Stück höher liegt (Abbildung 3). Das liegt daran, dass Kgraft sich nicht als Modul für Linux bauen lässt, sondern einen speziell gepatchten Kernel zwingend voraussetzt. Bevor sich Kgraft nutzen lässt, ist immer das Bauen eines Kernels angesagt.

Abbildung 3: Auch Kgraft von Suse erlaubt das Laden einzelner Patches in den Kern zur Laufzeit. Doch die Einstiegshürden sind wesentlich höher.

Abbildung 3: Auch Kgraft von Suse erlaubt das Laden einzelner Patches in den Kern zur Laufzeit. Doch die Einstiegshürden sind wesentlich höher.

Während der verantwortliche Red-Hat-Entwickler in »README.md« des Kpatch-Github-Repository ausführliche Kpatch-Installationsanleitungen bereitstellt, fällt die Dokumentation für Kgraft vergleichsweise spärlich aus. Suse gibt zwar den Link [4] an, dort finden Interessenten die Kgraft-gepatchte Version des gerade aktuellen Suse-Kernels – aber nur im Quelltext, ausführliche Anleitungen sind nicht zu entdecken (Abbildung 4). Bei dem durchaus nicht trivialen Vorgang, einem Open-Suse-System per Selbstbau das Hirn auszutauschen, bleibt der Admin also zunächst auf sich gestellt.

Abbildung 4: Suse stellt den Kgraft-Tree bereit, liefert aber praktisch keine Dokumentation mit, die dem Admin verrät, was er damit tun soll. Am Ende ist viel Handarbeit angesagt.

Abbildung 4: Suse stellt den Kgraft-Tree bereit, liefert aber praktisch keine Dokumentation mit, die dem Admin verrät, was er damit tun soll. Am Ende ist viel Handarbeit angesagt.

Wer die Dokumentation gefunden hat, startet eine wahre Bastel-Orgie: Nach einem Git-Checkout des Repository vom Entwickler Jiri Slaby steht das Kompilieren des Quelltextes an. Suse beschreibt in einem eigenen Blogeintrag unter [5], wie sich ein Kernel nach Suse-Manier herstellen lässt, trivial ist der Tausch des Kerns dennoch nicht.

Und selbst im Anschluss an den erfolgreichen Start eines Selbstbau-Kernels sind die Strapazen noch nicht zu Ende. Denn ähnlich wie bei Kpatch obliegt es anschließend dem User selbst, mit Hilfe verschiedener Skripte von Slaby die passenden Moduldateien zu bauen. Am Ende des Vorgangs darf er diese in den Kernel laden.

Es würde diesen Artikel sprengen, eine detaillierte Erklärung der benötigten Schritte bis zum einsatzbereiten Kgraft-System abzuliefern; wer sich für Details interessiert, inspiziert das genannte Repository von Jiri Slaby.

Gleichgemacht

Die Idee, Kernelpflaster on the Fly anzuwenden und nicht das Booten eines neuen Kernels zu verlangen, ist prinzipiell großartig. Denn während sich der Aufwand bei einzelnen Systemen noch in Grenzen hält, ist das koordinierte Rebooten von Hunderten oder Tausenden Nodes in großen Installationen ein Kraftakt. Da kommt es gerede recht, wenn sich eine Korrektur im laufenden Betrieb und ohne großes Aufsehen installieren lässt. Bis die Technik tatsächlich beim Endanwender ankommt, wird es aber dauern. Und derzeit ist ja noch komplett unklar, wohin die Reise überhaupt geht.

Vorteil Red Hat

Für die Red-Hat-Lösung lassen sich gegenüber der Suse-Idee Vorteile ausmachen. Dass man den Kernel nicht patchen muss, um Live-Patches möglich zu machen, ist sicher hilfreich. Auch das Abfangen eventueller Fehler scheint bei Kpatch derzeit besser zu funktionieren, als es bei Kgraft der Fall ist.

Rein äußerlich tun beide Lösungen allerdings das Gleiche, wer sich nicht mit der Thematik beschäftigt, dem fallen die Unterschiede nur bei der Bedienung auf oder bei der Installation, die bei Kpatch um vieles leichter als bei Kgraft und viel besser dokumentiert ist.

Wie immer stellt sich bei Kernel-bezogenen Features freilich die Frage, wie es mit den Lösungen weitergeht. Suse wie auch Red Hat haben angekündigt, ihre Live-Patch-Lösung in absehbarer Zeit zum Bestandteil des offiziellen Kernels machen zu wollen. Damit das klappt, müssen sie allerdings das Plazet von Linus Torvalds haben, der sich in der Vergangenheit immer wieder als Kernel-Zerberus einen Namen gemacht hat.

Auch ist bekannt, dass Torvalds wenig begeistert davon ist, in Linux mehrere Implementierungen für gleiche oder sehr ähnliche Features zu haben. Dass er Kgraft und Kpatch gleichermaßen durchwinkt, scheint eher unwahrscheinlich. Was wird passieren? Denkbar scheint, dass eine der zwei Lösungen sich durchsetzt und die andere verdrängt. Oder dass Torvalds auf ein Joint-Venture drängt und so eine dritte Lösung entsteht, die Vorteile beider Systeme kombiniert.

Wer Kpatch oder Kgraft bereits jetzt ausprobieren will, findet weder in der Community-Version Open Suse noch in Fedora passende Pakete, es ist also im Augenblick noch massive Handarbeit angesagt – bei Suse deutlich mehr als bei Fedora.

Der Autor

Martin Gerhard Loschwitz arbeitet als Principal Consultant bei Hastexo. Er beschäftigt sich dort intensiv mit den Themen HA, Distributed Storage und Open Stack. In seiner Freizeit pflegt er den Clustermanager Pacemaker für Debian.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben