Festplattenverschlüsselung mit Debian GNU/Linux

Inhaltsübersicht

Verwendungszweck

Die unter Linux gängigen Dateisysteme unterstützen alle Dateirechte, mit denen man Benutzern den Zugriff auf Dateien erlauben und verbieten kann. Diese Rechte greifen aber nur solange das System läuft und diese Rechte erzwingen kann. Falls eine Person physischen Zugriff auf den Rechner hat können diese Schutzmechanismen leicht umgangen werden - zum Beispiel kann man im BIOS des Rechners die Bootreihenfolge umstellen und anschließend ein Rettungssystem von CD booten, oder die Bootloaderkonfiguration so anpassen daß der Rechner direkt eine Root-Shell lädt. Falls man auch in so einem Fall seine Daten schützen möchte braucht man also weitere Maßnahmen, was sich insbesondere bei mobilen Geräten wie Laptops lohnt, welche leicht entwendet werden können.

Eine Lösung für dieses Problem heißt Kryptographie. Daten werden nicht mehr direkt, sondern nur noch verschlüsselt auf der Festplatte gespeichert. Hat jemand Zugriff auf den ausgeschalteten Rechner, so braucht er so trotzdem noch den Schlüssel oder das Passwort, um die Daten auf der Festplatte zu entschlüsseln. Der Aufwand, den Schlüssel oder das Passwort durch Ausprobieren herauszufinden ist dabei so groß daß selbst die Chance, durch jahrelanges systematisches Probieren den passenden Schlüssel zu finden astronomisch klein bleibt.

Bei der hier vorgestellten Methode geschieht die Verschlüsselung vollautomatisch, es muss lediglich vor dem Mounten der verschlüsselten Partitionen (von Hand oder beim Systemstart) ein Passwort eingegeben oder ein Schlüssel zur Verfügung gestellt werden um die Partitionen zu entsperren. Der große Vorteil dieser Methode ist, daß der Debian-Installer sie (bei der Verwendung von Passwörtern) von Haus aus beherrscht und man gleich bei der Installation eine oder alle Partitionen (bis auf /boot) mit dm-crypt verschlüsseln kann.

Nach oben

Voraussetzungen

Debian Etch beinhaltet schon alles an Software, was für den Einsatz von dm-crypt benötigt wird:

cryptsetup und dmsetup
Damit werden verschlüsselte Partitionen eingerichtet und später entsperrt/gesperrt. Ein Initspkript, um dieses beim Booten automatisch zu erledigen, ist ebenfalls enthalten.
ein Debian-Kernel
Die von Debian mitgelieferten Kernel enthalten alle benötigten Module. Falls man einen eigenen Kernel verwenden möchte muss dieser über Unterstützung für den Devicemapper, dm-crypt und die verwendeten Verschlüsselungs- und Hashalgorithmen (z.B. AES, SHA-1) verfügen.
initramfs-tools
Falls die Root-Partition selbst verschlüsselt wird muss man eine separate, unverschlüsselte /boot-Partition mit Bootloader, Kernel und initrd anlegen. Die initramfs-tools Unterstützen dm-crypt und können den größten Teil der erforderlichen initrd-Konfiguration automatisch erledigen.

Nach oben

DM-Crypt

Der Linux-Devicemapper ist eine Softwareschicht, die man zwischen der Dateisystemebene und den darunterliegenden Geräten und Partitionen einschieben kann. Er kann nicht nur für Verschlüsselung verwendet werden, sondern bildet auch die Grundlage für DM-RAID und den Logical Volume Manager (LVM)  (http://de.wikipedia.org/wiki/Lvm) .

Der Devicemapper verknüpft vorhandene Partitionen mit virtuellen Blockgeräten. Im Betrieb, zum Beispiel beim Mounten, greift man nun auf die virtuellen Geräte zu, alle Zugriffe auf diese werden dann durch den Devicemapper geschleust. Bei dm-crypt findet an dieser Stelle die Verschlüsselung und Entschlüsselung statt. Beim Erstellen der Verknüpfung zu einer verschlüsselten Partition wird das Passwort oder der Schlüssel angegeben. Diesen behält der Devicemapper im Speicher und kann so ohne weiteren Eingriff alle Zugriffe abwickeln bis die Partition wieder gesperrt oder das System neu gestartet wird. Hier ein Beispiel mit /dev/hda3 als verschlüsselter Partition:

/dev/hda3 <-> dm-crypt <-> /dev/mapper/hda3_crypt <-> mount <-> /mnt

Man kann auch mehrere Funktionen des Devicemappers kombinieren. So ist es möglich, RAID-Geräte oder einzelne Logical Volumes zu verschlüsseln, ein komplettes LVM auf einem RAID oder einer oder mehreren verschlüsselten Partitionen anzulegen und so weiter.

Nach oben

LUKS-Erweiterung

LUKS (das Linux Unified Key Setup) ist eine Erweiterung für verschlüsselte Partitionen, die einen Nachteil älteren Methoden zur Plattenverschlüsselung wie cryptoloop beseitigt: Bei LUKS kann man das Passwort oder den Schlüssel der Partition ändern, ohne die Partition neu zu verschlüsseln. Zudem kann man mehrere gleichberechtigte Passwörter und Schlüssel für eine Partition verwenden.

Um das zu ermöglichen besitzt eine LUKS-Partition einen speziellen Anfangsbereich. Während bei cryptoloop der Datenschlüssel für die Partition direkt aus dem Passwort abgeleitet wurde, ist er bei LUKS unabhängig davon. Eine LUKS-Partition verfügt über 8 Speicherplätze, in denen der Schlüssel gesichert wird - jeweils chiffriert durch ein Passwort oder einen Benutzerschlüssel. Auf diese Weise kann man zum Beispiel das Passwort ändern ohne den Datenschlüssel verändern zu müssen - es muss nur der Datenschlüssel, chiffriert durch das neue Passwort, im Anfangsbereich der Partition gespeichert werden.

cryptsetup bietet Funktionen, um LUKS-Partitionen zu verwenden. Der Debian-Installer verwendet es ebenfalls standardmäßig für verschlüsselte Partitionen.

Nach oben

Alternativen

cryptoloop
Dieser Mechanismus existiert schon seit mehreren Jahren. Er verdendet den loopback-Treiber des Kernels, mit dem man auch Abbilddateien von Partitionen oder CDs (zum Beispiel ISO-Images) mounten kann. cryptsetup kann auch heute noch mit diesem Format umgehen, es ist aber inkompatibel zu LUKS.
loop-aes
Die loop-aes-Software existiert ebenfalls schon lange und gilt als ausgereift. Sie wird zwar nicht vom Standardkernel unterstützt, Debian liefert aber vorgefertigte Pakete mit den Kernelmodulen sowie das loop-aes-source-Paket zum selberbauen. Zusätzlich muss man noch das Paket loop-aes-utils installieren. Auch wenn der Name anderes vermuten lässt unterstützt loop-aes nicht nur den AES-Algorithmus sondern als weitere Verfahren Blowfish, Twofish und Serpent. loop-aes wird als Alternative für dm-crypt/LUKS vom Debian-Installer angeboten.
truecrypt  (http://www.truecrypt.org) 
Die Besonderheit dieses Projektes ist daß es nicht nur für Linux, sondern auch für Windows Programme anbietet. Damit kann man verschlüsselte Partitionen oder Container unter beiden Systemen verwenden. truecrypt erfordert allerdings den Neubau des Kernels.

Nach oben

Bei Neuinstallationen: Debian-Installer benutzen

Der Debian-Installer erlaubt es, bei Neuinstallationen das komplette System bis auf /boot oder wahlweise einzelne Partitionen zu verschlüsseln. In der Standardeinstellung wird dabei dm-crypt mit LUKS verwendet, als Algorithmus kommt AES zum Einsatz. Falls die Root-Partition verschlüsselt werden soll muss gleich eine unverschlüsselte Boot-Partition mit angelegt werden. Der Debian-Installer kann nur Passwörter einrichten, Dateischlüssel unterstützt er nicht. Für Swap-Partitionen kann man alternativ einen zufälligen Schlüssel verwenden, der bei jedem Neustart neu generiert wird. Das funktioniert allerdings nicht mit LUKS. Es gibt unter anderem folgende Methoden für die Partitionierung:

normale Partitionen:

Partition 1 <-> verschl. Volume 1 <-> /mnt1
Partition 2 <-> verschl. Volume 2 <-> /mnt2
Partition 3 <-> verschl. Volume 3 <-> /mnt3

LVM auf verschlüsseltem Volume:

                                  log. Volume 1 <-> /mnt1
Partition <-> verschl. Volume <-> log. Volume 2 <-> /mnt2
                                  log. Volume 3 <-> /mnt3

verschlüsselte Volumes auf LVM:

              log. Volume 1 <-> verschl. Volume 1 <-> /mnt1
Partition <-> log. Volume 2 <-> verschl. Volume 2 <-> /mnt2
              log. Volume 3 <-> verschl. Volume 3 <-> /mnt3

Um verschlüsselte oder logische Volumes anzulegen, muss einem vorhandenen Volume beziehungsweise einer Partition der Verwendungszweck physikalisches Volume für Verschlüsselung oder physikalisches Volume für LVM zugewiesen werden. Ist das abgeschlossen, muss im Menü der Punkt Verschlüsselte Datenträger konfigurieren beziehungsweise Logical Volume Manager konfigurieren aktiviert werden.

Nach oben

LUKS-Partition vorbereiten

Im Folgenden werde ich an einem Beispiel erklären, welche Befehle benötigt werden um eine verschlüsselte Partition mit dm-crypt/LUKS einzurichten und zu verwenden.

Vorbereitung: Es wird eine verfügbare Partition oder ein leeres Logical Volume benötigt. Es ist *nicht* möglich, eine bestehende Partition ohne Verlust aller auf ihr gespeicherten Daten zu verschlüsseln. Vor der Initialisierung kann die Partition mit Zufallswerten überschrieben werden. Von außen kann man später die verschlüsselten Daten nicht von den leeren Bereichen mit Zufallswerten unterscheiden. Außerdem werden dabei alte noch vorhandene Datenreste überschrieben.

Achtung: Nach einmaligem Überschreiben kann man nicht mehr über ein herkömmliches Datenrettungsprogramm an die Datenreste gelangen, aufwändigere Methoden (bei denen die Festplatte im allgemeinen zerlegt werden muss) können das unter Umständen immer noch! Um noch vorhandene Daten wirklich unwiderruflich zu löschen muss die Partition mehrmals überschrieben werden. Es gibt unterschiedliche Meinungen darüber wie oft das nötig ist, ich gehe hier nicht weiter auf dieses Thema ein.

In meinem Beispiel wird nun die Partition /dev/hda3 mit Zufallswerten überschrieben. Dazu dient /dev/urandom als Quelle:

dd if=/dev/urandom of=/dev/hda3 bs=10M

liest jeweils Blöcke von 10 Megabytes Größe aus /dev/urandom und schreibt diese dann auf die Platte, solange bis die Partition voll ist.

Nachdem die Partition vorbereitet wurde muss sie nun über cryptsetup initialisiert werden. Praktischerweise gibt es ein kleines Skript namens luksformat, welches dieses mit vernünftigen Voreinstellungen für die Verschlüsselung erledigt. Außerdem legt es zusätzlich noch ein Dateisystem auf der Partition an. Da die Partition nur unter Linux benutzt werden soll werde ich das ext3-Dateisystem verwenden:

sirius:~# luksformat -t ext3 /dev/hda3
creating encrypted device on /dev/hda3

WARNING!
========
Daten auf /dev/hda3 werden unwiderruflich überschrieben.

Are you sure? (Type uppercase yes): YES

luksformat fragt nach einem Passwort für die Partition, welches insgesamt dreimal eingegeben werden muss. Abschließend entsperrt es die Partition, legt ein ext3-Dateisystem an und sperrt sie dann wieder. Statt luksformat könnte man auch direkt cryptsetup benutzen, die entsprechenden Befehle wären:

cryptsetup luksFormat --cipher aes-cbc-essiv:sha256 /dev/hda3
cryptsetup luksOpen /dev/hda3 luksformatxxx
mkfs.ext3 /dev/mapper/luksformatxxx
cryptsetup luksClose /dev/mapper/luksformatxxx

Damit sind die Vorbereitungen angeschlossen und die Partition kann verwendet werden.

Nach oben

Partition benutzen - cryptsetup und mount

Um die Partition nun zu mounten muss sie entsperrt werden. Dabei wird das Passwort oder der Schlüssel angegeben. cryptsetup konfiguriert den Device Mapper entsprechend, so daß dieser die verschlüsselte Partition mit einer Gerätedatei in /dev/mapper verknüpft, welche dann ganz normal mit mount eingehängt werden kann. Der Name dieser Datei ist frei wählbar, zur Übersichtlichkeit benutze ich hda3_crypt:

sirius:~# cryptsetup luksOpen /dev/hda3 hda3_crypt
Enter LUKS passphrase:
key slot 0 unlocked.
Command successful
sirius:~# ls /dev/mapper
control hda3_crypt

Die Partition ist damit entsperrt. Alle Zugriffe auf /dev/mapper/hda3_crypt laufen nun durch den Device Mapper. Erfolgt ein Schreibzugriff auf hda3_crypt so werden die Daten verschlüsselt und dann auf hda3 gespeichert. Erfolgt ein Lesezugriff auf hda3_crypt wird der passende Datenblock von hda3 gelesen, entschlüsselt und dann ausgegeben. Die Partition kann mit mount eingehängt werden:

sirius:~# mount /dev/mapper/hda3_crypt /mnt
sirius:~# mount | grep hda3
/dev/mapper/hda3_crypt on /mnt type ext3 (rw)

Wie man sehen kann benötigt mount keine Informationen über die Verschlüsselung, es verwendet einfach das vom Device Mapper erstellte Gerät wie eine normale Partition.

Nach dem Entsperren kann man über dieses Gerät auf alle Daten auf der Partition zugreifen. Möchte man die Partition vorübergehend nicht mehr verwenden kann man sie sperren - dazu wird sie ausgehängt und anschließend die Device-Mapper-Verknüpfung gelöscht:

sirius:~# umount /mnt
sirius:~# cryptsetup luksClose /dev/mapper/hda3_crypt
sirius:~# ls /dev/mapper
control

Nach oben

Einbinden automatisieren - crypttab

Auf die oben beschriebene Art und Weise kann man die verschlüsselten Partitionen von Hand aktivieren und deaktivieren. Auf die Dauer ist das aber sehr lästig. cryptsetup sieht allerdings eine Möglichkeit vor, Partitionen automatisch beim Hochfahren des Systems zu entsperren. Dazu trägt man diese in der Datei /etc/crypttab ein. Folgende Informationen können dort eingetragen werden:

Die komplette Zeile für das oben genannte Beispiel würde also so aussehen:

# <target name> <source device>         <key file>      <options>
     hda3_crypt       /dev/hda3               none           luks

Beim nächsten Neustart des Systems wird cryptsetup automatisch die Partition entsperren und dabei nach dem Passwort fragen. Um die Partition beim Systemstart automatisch einzuhängen muss nur noch ein Eintrag in der /etc/fstab angelegt werden, zum Beispiel:

/dev/mapper/hda3_crypt    /mnt    ext3    auto,defaults    0    0

Nach oben

Datei statt Passwort als Schlüssel

Im vorangegangenen Beispiel wurde ein Passwort zum Entsperren der verschlüsselten Partition benutzt. Der Debian-Installer kann ebenfalls nur verschlüsselte Partitionen mit Passwörtern einrichten (oder, im Falle von Swap, mit Zufallsschlüsseln).

Alternativ kann man aber auch eine Datei, zum Beispiel auf einem USB-Stick, als Schlüssel verwenden. Während man bei der Benutzung von Passwörtern diese (für jede verschlüsselte Partition) beim Hochfahren eintippen muss, bleibt einem bei Schlüsseldateien diese Arbeit erspart - man muss nur dafür sorgen, daß auf den Schlüssel zugegriffen werden kann (zum Beispiel indem der USB-Stick eingesteckt wird).

Wie oben geschrieben kann man für eine LUKS-Partition bis zu acht Passwörter oder Schlüssel verwenden. Vom Debian-Installer oder von luksformat angelegte Partitionen können also mit einer Schlüsseldatei nachgerüstet werden. Die dazu nötigen Schritte lassen sich mit cryptsetup erledigen. Zunächst einmal muss aber eine Schlüsseldatei erstellt werden. Sie sollte nicht zu klein sein (unsicher), aber auch nicht zu groß (lange Dauer beim Entsperren). Ich verwende eine vier kilobyte große Datei:

sirius:~# dd if=/dev/urandom of=/media/usb/key bs=4k count=1
1+0 Datensätze ein
1+0 Datensätze aus
4096 Bytes (4,1 kB) kopiert, 0,0018383 Sekunden, 2,2 MB/s

Als nächstes muss der Schlüssel der LUKS-Partition hinzugefügt werden. Dabei wird das bestehende Passwort eingegeben und damit dann der Datenschlüssel dechiffriert. Dann wird er durch die Schlüsseldatei neu chiffriert und in einer freien Speicherstelle gesichert:

cryptsetup luksAddKey /dev/hda3 /media/usb/key
Enter any LUKS passphrase:
key slot 0 unlocked.
Command successful

Nun kann testweise die Partition mit dem neuen Schlüssel statt dem Passwort entsperrt werden:

sirius:~# cryptsetup luksOpen /dev/hda3 hda3_crypt --key-file /media/usb/key
key slot 1 unlocked.
Command successful

Damit kann die Partition ähnlich wie mit einem Passwort manuell entsperrt werden. Dieser Vorgang lässt sich aber auch über die crypttab automatisieren. An dieser Stelle kommt nun die keyfile-Option ins Spiel. Aus dem vorherigen Beispiel wird:

# <target name> <source device>         <key file>      <options>
     hda3_crypt       /dev/hda3     /media/usb/key           luks

Das ist allerdings noch nicht alles. cryptsetup muss angewiesen werden, das Medium mit dem Schlüssel vor dem Abarbeiten der crypttab zu mounten. Dazu muss es einen Eintrag für das Medium in der /etc/fstab geben, außerdem muss die der Mountpunkt in /etc/default/cryptdisks eingetragen werden:

CRYPTDISKS_MOUNT="/media/usb"

Nach dem Entsperren aller verschlüsselten Partitionen wird das Medium automatisch wieder ausgehängt. Zur Sicherheit kann nun noch die initial ram disk neu gebaut werden:

update-initramfs -u

Das Passwort kann auch weiterhin als Ersatz beibehalten (oder mit cryptsetup luksDelKey entfernt) werden. Ist der USB-Stick mit dem Schlüssel eingesteckt, fährt das System ohne Benutzereingaben hoch und entsperrt alle in der crypttab eingetragenen Partitionen selbstständig. Diese Konfiguration funktioniert für alle Partitionen außer der Root-Partition. Da auf dieser Partition gerade die zum Entsperren notwendigen Programme liegen sind hier einige weitere Maßnahmen notwendig.

Nach oben

root-Partition mit Passwort verschlüsseln

Wie oben schon erwähnt kann der Bootloader das System nicht direkt von einer verschlüsselten Root-Partition hochfahren. Man benötigt also eine separate, unverschlüsselte Boot-Partition. Auf dieser befinden sich nachladbare Module des Bootloaders, der Kernel und eine initial ram disk (initrd). Diese enthält ein Minimalsystem mit Treibern für den Festplattencontroller, für das Dateisystem auf der Root-Partition und in unserem Fall auch cryptsetup. Wer ein neues System mit dem Debian-Installer einrichtet kann gleich eine Boot-Partition mit anlegen, bei einem vorhandenen System kann sie jederzeit von Hand angelegt und eingebunden werden. Bei einem vorhandenen System empfiehlt es sich außerdem, für den Umzug der Root-Partition auf eine verschlüsselte LUKS-Partition den Rechner mit einer Live-CD wie GRML (http://grml.org)  zu starten und alle Änderungen von dort aus zu erledigen.

Während beim Wechsel anderer Partitionen auf dm-crypt nur die crypttab und die fstab angepasst werden müssen, reicht das bei der Root-Partition nicht aus. Es muss ebenso die Bootloaderkonfiguration geändert werden. Für dieses Beispiel gehe ich davon aus, daß grub verwendet wird und die Einträge für die Kernel automatisch durch update-grub erzeugt wurden. Als Beispiel dient wieder hda3. Ich setze ebenso voraus, daß der fstab schon hda3 durch hda3_crypt ersetzt wurde und die crypttab einen Eintrag für diese Partition enthält. In der /boot/grub/menu.lst muss nun der Root-Eintrag geändert werden. Dazu wird die #kopt-Zeile angepasst. Zum Beispiel wird

# kopt=root=/dev/hda3 ro

geändert zu

# kopt=root=/dev/mapper/hda3_crypt

Das Kommentarzeichen am Anfang der Zeile muss erhalten bleiben. Das Programm update-grub übernimmt die kopt-Einstellung für alle automatisch erstellten Kerneleinträge und legt eine neue menu.lst an, mit dem Befehl update-initramfs -u wird außerdem noch eine neue initrd erstellt.

Damit ist die Konfiguration abgeschlossen. Beim nächsten Neustart verlangt cryptsetup nach dem Passwort für die Root-Partition. Diese wird dann entsperrt und von der initrd aus eingehängt.

Nach oben

root-Partition mit Schlüssel auf USB-Stick

Wie normale Partitionen mit einem Schlüssel auf einem USB-Stick automatisch entsperrt werden können wurde oben schon erklärt. Um das bei der Root-Partition zu ermöglichen sind leider einige weitere Eingriffe nötig. So muss man sicherstellen daß die initrd die nötigen Treiber für den USB-Stick enthält. Außerdem funktioniert das automatische Mounten des Sticks über CRYPTDISKS_MOUNT und die fstab nicht, da die dazu nötigen Informationen in der initrd nicht vorhanden sind.

Es gibt aber eine Alternative. In der crypttab kann man der Partition ein Keyscript zuweisen, welches den Schlüssel besorgt und ihn ausgibt. Dieses Skript wird, sofern es in der crypttab eingetragen ist, automatisch in die initrd übernommen. Es muss alle zum Erlangen des Schlüssels notwendigen Schritte übernehmen, das beinhaltet das Laden der Treiber für den USB-Stick, das Anlegen eines Mountpunktes, das Mounten, die Ausgabe des Schlüssels und das Aushängen des USB-Sticks. Das Skript wird im laufenden Betrieb außer in der initrd nicht benötigt und kann zum Beispiel in /root angelegt werden. Meines sieht folgendermaßen aus:

#!/bin/sh
modprobe usb-storage 1>&2 #Kernelmodul für den USB-Stick laden
sleep 5                   #5 Sekunden warten damit der Stick bereit ist
mkdir /usb 1>&2           #Mountpunkt anlegen
mount -t vfat -o ro,umask=077 /dev/sda1 /usb 1>&2 #Stick mounten
cat /usb/key              #Schlüssel ausgeben
umount /usb 1>&2          #USB-Stick aushängen

Da cryptsetup den Schlüssel in der Standardausgabe des Skriptes erwartet, wird die Ausgabe aller anderen Programmaufrufe im Skript in die Fehlerausgabe umgelenkt (1>&2). Außerdem muss das Skript ausführbar sein.

Außerdem muss noch sichergestellt werden, daß die initrd alle nötigen Treiber enthält. update-initramfs fügt automatisch die Module für USB-Speicher hinzu. Die Module für das auf vielen USB-Sticks verwendete FAT-Dateisystem muss man aber ausdrücklich anfordern. Dazu werden in der Datei /etc/initramfs-tools/modules folgende Zeilen hinzugefügt:

nls_cp437
nls_iso8859_1
vfat

Als vorletztes muss nun die crypttab angepasst werden:

# <target name> <source device>   <key file>      <options>
     hda3_crypt       /dev/hda3         none  luks,keyscript=/root/keyscript

Nun wird eine Kopie der alten initrd in /boot erstellt. Diese wird als Ersatz benötigt falls das Entsperren der Root-Partition nicht klappt. Dann kann nämlich das System nicht hochgefahren werden. Startet man neu und verlangt von grub, statt der neuen die alte initrd zu verwenden, kann man die Root-Partition wieder mit dem Passwort entsperren und nach dem Hochfahren den Fehler beheben. Das geht wesentlich schneller als die Benutzung einer Live-CD für diesen Zweck. Als letztes wird dann eine neue initrd erstellt:

sirius:~# update-initramfs -u
update-initramfs: Generating /boot/initrd.img-2.6.18-4-k7

Nach einem Neustart wird cryptsetup nun versuchen, den Schlüssel vom USB-Stick einzulesen und damit die Root-Partition zu entsperren. Nachdem das erfolgt ist wird von der initrd zur Root-Partition gewechselt und das System wie gewohnt hochgefahren.

Nach oben

Weiterführende Links

Nach oben

letzte Aktualisierung: 2009-11-17, 14:14:37
http://www.andreasjanssen.de - andreas.janssen@gmail.com
Valid XHTML
 1.1! Valid CSS!