Entwicklung

Linux-Kernelmodule - Teil 1

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Auch wenn es sich bei Linux um ein monolithisches Betriebssystem handelt, sind viele Teile davon in Modulen aufgebaut. Diese Kernelmodule können zur Laufzeit geladen und auch wieder entladen werden. Wie man so ein Modul entwickelt und zum Laufen bringt möchte ich hier kurz zeigen.

C-Code

Linux wird in C entwickelt und darum werden auch Kernel-Module in C geschrieben. Sie bestehen im Grunde aus zwei Funktionen: Eine, die beim Laden ausgeführt wird und eine, die beim Entladen ausgeführt wird.

Beginnen wir mit einem einfachen Hello-World-Beispiel:

Zuerst brauchen wir eine Bibliothek, die wir brauchen um ein Modul laden zu können:

#include <linux/module.h>
#include <linux/init.h>

Die Header-Datei module.h wird von jedem Modul benötigt und die Datei init.h stellt Makros zur Verfügung, die wir brauchen um die Funktionen zu registrieren, was wir jetzt auch machen:

#include <linux/module.h>
#include <linux/init.h>

// Methode, die beim Laden ausgeführt wird
static int __init hello_init(void)
{
	return 0;
}

// Methode, die beim Entladen ausgeführt wird
static void __exit hello_exit(void)
{
}

// Registrieren der Methoden
module_init(hello_init);
module_exit(hello_exit);

An dieser Stellen wurden zwei Funktionen eingebaut, die jeweils entweder beim Laden oder Entladen ausgeführt werden. Mit module_init und module_exit wird dem Betriebssystem mitgeteilt, welche es sind.

Das alles sieht zwar nett aus, tut aber noch nichts. Darum soll das Modul das berühmte “Hello world” ins syslog schreiben:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>

// Methode, die beim Laden ausgeführt wird
static int __init hello_init(void)
{
	printk(KERN_DEBUG  "Hello World!");
	return 0;
}

// Methode, die beim Entladen ausgeführt wird
static void __exit hello_exit(void)
{
	printk(KERN_DEBUG  "Bye World!");
}

// Registrieren der Methoden
module_init(hello_init);
module_exit(hello_exit);

Mit printk(<loglevel>,<text>) lässt sich das bewerkstelligen. Um das Loglevel angeben zu können, benötigen wir aber noch zusätzlich die Datei kernel.h.

Wenn man das Module so ausführt wird Linux übrigens sofort über die fehlende Lizenzangabe jammern. An dieser Stelle sollte man aber auch gleich noch Informationen über den Autor angeben:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>

#define DRIVER_AUTHOR "Johannes Mittendorfer <...@... .com>"
#define DRIVER_DESC "Hello world"

// Methode, die beim Laden ausgeführt wird
static int __init hello_init(void)
{
	printk(KERN_DEBUG  "Hello World!");
	return 0;
}

// Methode, die beim Entladen ausgeführt wird
static void __exit hello_exit(void)
{
	printk(KERN_DEBUG  "Bye World!");
}

// Registrieren der Methoden
module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);

In diesem Beispiel habe ich den Autor und den Titel oben definiert und unterhalb samt Lizenz, in diesem Fall GPL, angegeben.

Jetzt kann man das Modul ausführen. Aber wie eigentlich? Dazu braucht man ein…

Makefile

Das Makefile gibt an, wie der Code kompiliert werden soll. Alles was man dazu braucht ist eine Datei namens Makefile mit folgendem Inhalt:

obj-m += helloworld.o

Wenn man jetzt im Verzeichnis make ausführt, dann sollte in etwa so etwas erscheinen:

make -C /lib/modules/3.11.0-19-generic/build M=/home/johannes/Schreibtisch/kernel modules
make[1]: Betrete Verzeichnis '/usr/src/linux-headers-3.11.0-19-generic'
  CC [M]  /home/johannes/Schreibtisch/kernel/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/johannes/Schreibtisch/kernel/helloworld.mod.o
  LD [M]  /home/johannes/Schreibtisch/kernel/helloworld.ko
make[1]: Verlasse Verzeichnis '/usr/src/linux-headers-3.11.0-19-generic'

Außerdem sollte im Verzeichnis eine Datei namens helloworld.ko entstanden sein. Das ist das fertige Modul. Das muss aber jetzt noch an einen vorgesehenen Platz.

Installation

Die ko-Datei muss unterhalb des Ordners /lib/modules/<kernel-version>/kernel/ kopiert werden. Die Kernelversion lässt sich durch den Befehl uname -r herausfinden. Um die Module neu einzulesen braucht es dann den Befehl sudo depmod -a und schließlich zum Laden des Modules modprobe helloworld.

Wenn alles geklappt hat, sollte man jetzt im Syslog ein “Hello world” sehen!

(Das sieht man zum Beispiel durch tail -f /var/log/syslog)

Teil 2 kommt dann irgendwann, wenn ich Zeit habe. ;)

Security

Heartbleed - Oder wie das Internet unsicher wurde

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Die Aufregung war groß, als die Sicherheitslücke CVE-2014-0160, genannt Heartbleed, am 7. April bekannt wurde. Nach Schätzungen von Experten sind oder waren bis zu 75% der Server im Internet betroffen.

Wieso?

Durch diesen Fehler in der Open Source Software OpenSSL war, und ist es zum Teil immer noch möglich, einen Teil des Arbeitsspeichers eines Servers, der diese Software verwendet, auszulesen und so die Anfragen anderer Benutzer zu sehen.

Heartbleed-Logo

Diese Anfragen können auch den Benutzernamen und das Passwort beinhalten, die durch SSL eigentlich sicher übertragen werden sollen. Ein weiteres Problem ist zudem, dass man so auch an den privaten Schlüssel, also das Herzstück nahezu aller modernen Verschlüsselungen, kommen kann.

Der Bug, der diese Sicherheitslücke ausgelöst hat, steckt in einem Stück Code, das für einen sogenannten Heartbeat zuständig ist. Es handelt sich dabei um eine Methode um festzustellen, ob der Client, der sich mit einem durch SSL geschützten Webserver verbunden hat, immer noch aktiv ist oder man die Verbindung trennen kann. Wenn hier der Client jedoch eine besondere Antwort schickt, antwortet der Server mit bis zu 64 kbyte seines Hauptspeichers.

Betroffen waren unter anderem die Server großer Konzerne und stark frequentierte Webseiten wie yahoo.com, mail.de und sparkasse.at. Es ist also davon auszugehen, dass alle Logins seit Bekanntwerden der Lücke mitgelesen wurden. Bei Seiten, die keinen ECC-Algorithmus verwenden, ist es zudem möglich alle bisherigen Verbindungen, wenn diese aufgezeichnet wurden, zu entschlüsseln.

Auch meine Website war eine Zeit lang verwundbar, da mein Hoster Uberspace auch OpenSSL verwendet. Dieser hat jedoch vorbildlich mit umfangreicher Information reagiert.

Was jetzt?

Zunächst ist es jetzt wichtig zu wissen, ob ein Dienst den man verwendet für die Lücke anfällig ist oder war. Im Zweifel sollte man dazu den Betreiber kontaktieren. Wenn man nun festgestellt hat, dass dies so ist, sollte man umgehend das Passwort ändern. Wenn man das gleiche Passwort auch auf anderen Seiten verwendet, sollte es auch dort geändert werden.

Ich denke, dass OpenSSL nicht schlecht ist. Bis jetzt hat es gut funktioniert, es ist gratis und open source. Natürlich ist es immer möglich, dass sich Fehler einschleichen, aber das ist bei einem kommerziellen Produkt auch möglich.

Gerade weil es open source ist, war es überhaupt möglich die Lücke zu finden. Ich möchte lieber nicht wissen, wie viele derartiger Bugs sich in kommerzieller Software befinden, aber noch nicht gefunden wurden.

Weitere Informationen über die Lücke gibt es übrigens auf der eigens dafür eingerichteten Website.

Entwicklung

Wenn grunt nichts mehr tut

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Was tun, wenn grunt nichts mehr tut, also keinerlei mehr Ausgabe liefert?

Es liegt meist am Paket node. Es hat überhaupt nichts mit nodejs zu tun und kann weg. Das heißt: sudo apt-get remove node löst das Problem.

Schon sollte dem fröhlichen Automatisieren nichts mehr im Wege stehen!

Software

DSLR-Steuerung für Linux

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Die Steuerprogramme für digitale Spiegelreflexkameras sind oftmals nur für Windows und Mac verfügbar. Für den Linux-Benutzer gibt es aber, wie von mir vor kurzem entdeckt, gphoto2.