Xen auf Debian. Teil 1

Eigentlich wollte ich hier auch auf die Xen-Installation eingehen, aber dafür gibt es ja schon genug Anleitungen im Netz, auch auf Deutsch. Die meisten Anleitungen sind hoffnungslos veraltet, weil XEN sich einfach extrem schnell bewegt. Während man noch vor 2 Jahren viel zu konfigurieren hatte, wenn man ein Bridged oder Routed Setup haben wollte, muss man dafür heute nur noch eine Zeile in der Konfigurationsdatei ändern. Die meiner Meinung nach beste Anleitung für XEN im Internet ist die von Denny Schierz.

Für XEN würde ich auf jeden Fall lvm empfehlen, einerseits hat das den Vorteil der höheren Geschwindigkeit, andererseits ist man damit aber auch viel flexibler als mit dem traditionellen Partitionen. Allerdings werde ich auch das überspringen, weil Henrik Skupin schon eine tolle Anleitung dazu online gestellt hat. Ich gehe also davon aus, dass eine LVM-Partition zur Verfügung steht und XEN zusammen mit den XEN-Tools installiert ist.

Im folgenden, ersten Teil soll es darum gehen, eine Basis zu schaffen für weitere Arbeiten. Wir erstellen also eine XEN-Instanz mit Debian und sichern diese Basiskonfiguration mit einigen grundlegenden Schritten ab. Dann machen wir daraus ein tar-Archiv und legen das Image beiseite, um davon dann jeweils beliebige Server zu erstellen, ohne immer wieder die selben Handgriffe durchführen zu müssen.

Beginnen wir ohne weitere Umschweife

Wir erstellen mit folgendem Befehl eine neue Xen-Instanz:
# xen-create-image --ip=[IP-Adresse] --hostname=[Hostname]

Das kann einige Minuten dauern, die Daten dafür werden aus etc/xen-tools/ geholt, allerdings kann man viele Parameter auch noch im Nachhinein noch ändern, die Konfigurationsdateien für die Instanzen liegen unter etc/xen/[name der instanz].cfg

Wir starten die Instanz mit
# xm create -c [hostname].cfg

wobei wir mit -c gleich eine Konsole für die Instanz bekommen. Natürlich kann man auch nachträglich noch auf die Instanz wechseln mit:
# xm console [hostname]

Erste Amtshandlung auf der neuen Konsole ist natürlich:
# apt-get update && apt-get upgrade

Dann noch:
# apt-get install locales
# dpkg-reconfigure locales

Um eine deutsche Tatstatur und deutsche Texte zu bekommen und ein abschließendes:
# tzconfig

Um auch die Zeitzone richtig zu setzen.

auf ntp für die Zeit können wir verzichten, weil schon einer auf dem Wirt läuft und es keine gute Idee ist, beide gegeneinander laufen zu lassen.

Damit ist die Instanz ganz grundlegend schon einmal eingerichtet. Ab jetzt folgen die Applikationen, um den Server abzusichern: Firewall, SIV, IDS

Beginnen wir mit der Firewall:
Zunächst müssen unsere Firewall-Regeln bei jedem Systemstart geladen werden. Dazu richten wir die Kpnfigurationsdatei ein, vergeben die entsprechenden Rechte und legen die Datei in die Runlevel-Verzeichnisse:

# touch /etc/init.d/firewall
# chmod 775 /etc/init.d/firewall
# update-rc.d firewall defaults

Die Datei muss jetzt aufgefüllt werden. Im Grunde sollte man natürlich immer nur die Ports offen lassen, die man tatsächlich auch verwendet. Nicht benötigte Ports also im folgenden einfach auskommentieren. Dazu ein Hinweis: Auch wenn man selbst keinen DNS-Server betreibt, muss der Port 53 UDP offen bleiben, damit solche Sachen wie “apt-get update” funktionieren.


#!/bin/sh
echo "initialisiere Firewall ..."
# Module laden
modprobe ip_conntrack_ftp
# Alles bisherige loeschen und nichts akzeptieren
iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -Z
iptables -N MYDROP
iptables -N MYACCEPT
#
# Loopback freigeben, fuer lokale Apps
#
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
#
# Eigene Chains definieren (MYDROP/MYACCEPT)
#
iptables -A MYDROP -j LOG --log-level 3 --log-prefix "FW-DROP: "
iptables -A MYDROP -j DROP
iptables -A MYACCEPT -j LOG --log-prefix "FW-ACCEPT: "
iptables -A MYACCEPT -j ACCEPT
#
# Mitloggen, wenn invalid
#
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j MYDROP
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
#
#
# ssh
iptables -A INPUT -p tcp --dport 22 -j MYACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j MYACCEPT
# ping erlauben, selber pingen
iptables -A INPUT -p icmp -j MYACCEPT
iptables -A OUTPUT -p icmp -j MYACCEPT
# DNS als Client
iptables -A INPUT -p udp --dport 53 -j MYACCEPT
iptables -A OUTPUT -p udp --dport 53 -j MYACCEPT
# Webserver
iptables -A INPUT -p tcp --dport 80 -j MYACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j MYACCEPT
# Mails, SMTP, POP, IMAP
iptables -A INPUT -p tcp --dport 25 -j MYACCEPT
iptables -A OUTPUT -p tcp --dport 25 -j MYACCEPT
iptables -A INPUT -p tcp --dport 110 -j MYACCEPT
iptables -A OUTPUT -p tcp --dport 110 -j MYACCEPT
iptables -A INPUT -p tcp --dport 143 -j MYACCEPT
iptables -A OUTPUT -p tcp --dport 143 -j MYACCEPT
# FTP nach draussen
iptables -A INPUT -p tcp --dport 21 -j MYACCEPT
iptables -A OUTPUT -p tcp --dport 21 -j MYACCEPT
#
echo "Firewall ist konfiguriert und aktiv"

Datei speichern und die Firewall starten. Vorsicht: ssh muss in jedem Fall erlaubt sein, sonst sperrt man sich im nächsten Schritt selbst aus 😉
# /etc/init.d/firewall start

Etwas unangenehm ist, dass die Firewall jetzt auf die Shell loggt. Wenn das System etwas unter Last steht, kann einen das leicht verrückt machen. Es reicht ja, wenn es in Syslog geloggt wird. Also ändern wir /etc/default/klogd und dort die Zeile
KLOGD=”-x”
in
KLOGD=”-x -c 4″
Abspeichern. Fertig.

Jetzt ist Tripwire an der Reihe. Tripwire ist ein System Integrity Verifier. Vereinfacht gesagt: Es stellt sicher, dass das System noch in dem Zustand ist, in dem wir es verlassen haben und zeichnet alles mit, was sich doch verändert hat und sich nicht hätte ändern dürfen/sollen.

Installation wie immer bei Debian:
# apt-get install tripwire

Dann in den Dialogen alles abnicken und die Passphrasen für die Keys und die Signaturen eingeben. Damit werden später die Konfigurationsdateien verschlüsselt, damit ein Angreifer nicht sehen kann, wie Tripwire konfiguriert ist und die Konfiguration auch nicht ändern kann. Sonst wäre das System ja nicht besonders sinnvoll. Da der local-key nach dem Hostnamen genannt wird – [hostname]-local.key –, muss er neu erstellt werden, wenn man die Instanz mit einem anderen Hostnamen startet. Das kann man bequem erreichen über:
# dpkg-reconfigure tripwire

Die Konfigurationsdateien liegen unter /etc/tripwire

twcfg.txt ist die Konfigurationsdatei und sollte gleich gelöscht werden, denn darin werden wir nichts ändern und Tripwire bezieht ja seine Informationen aus der verschlüsselten Konfigurationsdatei tw.cfg
Wenn man twcfg.txt doch noch irgendwann brauchen sollte, reicht einfach:
# twadmin --print-cfgfile > /etc/tripwire/twcfg.txt

Wichtig ist für uns die Policy-Datei twpol.txt. Hier wird festgelegt, was alles überwacht werden soll und was an Aktionen ausgeführt werden soll. Ich werde nicht auf den Inhalt der Datei eingehen. Hier ändern wir nur drei Einstellungen. Wir kommentieren folgende Zeilen aus:

/etc/rc.boot -> $(SEC_BIN) ;
Alles, was /root/ im Pfad trägt ( Z.B.: /root/.elm -> $(SEC_CONFIG) ; )
/proc -> $(Device) ;

Ersteres existiert unter Debian nicht, was zu Fehlermeldungen führt und letztere ändern sich zu häufig, als dass ein Logging sinnvoll wäre.

Das jetzt abspeichern und die Datei verschlüsseln. Das ist wichtig, sonst erkennt Tripwire die Datei gar nicht an:
# twadmin --create-polfile -S /etc/tripwire/site.key /etc/tripwire/twpol.txt

Anschließend wir die Policy-Datei gelöscht. Auch die kann bei Bedarf wiederhergestellt werden mit:
# twadmin --print-polfile > /etc/tripwire/twpol.txt

Jetzt initialisieren wir Tripwire.
# tripwire --init

Daraufhin können wir auch gleich eine manuelle Integritätsprüfung vornehmen:
# tripwire --check

Diese Prüfung wird zwar ohnehin täglich automatisch durchgeführt, aber man sollte sie auf jeden Fall nach jeder Änderung ausführen, um so nicht nach Tagen den Überblick zu verlieren, was man selbst geändert hat und was nicht. Da Tripwire den aktuellen Zustand des Systems mit einer Datenbank vergleicht, muss nach jeder Änderung am System natürlich auch die Datenbank aktualisiert werden (env LANG=C ist notwendig wegen eines Debian-Bugs, falls im Report UTF-8-Zeichen auftauchen):
# env LANG=C tripwire --update --twrfile /var/lib/tripwire/report/.twr

Es folgt eine Liste der Änderungen, die mit dem letzten –check übereinstimmen sollte. Vor jeder Änderung steht ein x in eckigen Klammern [x]. Wenn man dies belässt, wird die Änderung akzeptiert und die Datenbank aktualisiert, entfernt man das x wird die Änderung auch zukünftig angemeckert. Wenn man die Datei abspeichert, wird die Datenbank aktualisiert. Vorsicht: Der Report wird in Vi geladen. Der Editor wird mit ESC in den Befehlsmodus gesetzt, dann wird mit einem Doppelpunkt der Befehl eingeleitet. “wq!” speichert und schließt die Datei. Jetzt noch twpol.txt entfernen und Tripwire steht für uns Wache.

Es folgt als letzter Schritt Snort, ein Intrusion Detection System. Es hält zwar keine Angriffe von Außen ab, aber zumindest berichtet es uns darüber, was böse Hacker so alles versucht haben, um bei uns einzudringen. Installation wie üblich:
# apt-get install snort

Bei der Installation geben wir unsere eigene Aderesse als Heimnetz an, weil wir Snort nur auf dem eigenen Rechner laufen lassen wollen.
Vorsicht: Dies muss später geändert werden, wenn dieses Image auf einem anderen Rechner laufen soll. Die Konfiguration läuft über dpkg-reconfigure snort. Hier kann man auch angeben, wer die täglichen Report zu den Einbruchsversuchen erhalten soll,

Wir werden nichts weiter an der Konfiguration ändern, da Snort auch so schon recht sinnvoll eingerichtet ist. Allerdings ist das beste IDS nur so gut wie die Signaturen, die ihm zur Verfügung stehen. Unter Debian übernimmt das Oinkmaster. Installation:
# apt-get install oinkmaster

Jetzt müssen wir noch die Update-URL ändern, damit Oinkmaster Updates bekommt. Die Konfigurationsdatei liegt unter /etc/oinkmaster.conf
Die aktuelle URL lautet: http://www.snort.org/pub-bin/downloads.cgi/Download/comm_rules/Community-Rules-2.3.tar.gz

Und wir tragen Oink in die Crontab ein, damit wir das Aktualisieren der Signaturen nicht ständig von Hand vornehmen müssen. Das wird doch leicht lästig. Mir reicht ein Update pro Tag. Dazu fügen wir folgendes der Crontab unter /etc/crontab hinzu:
10 6 * * * root oinkmaster -o /etc/snort/rules/

Abschließend legen wir noch einen Benutzer an, mit dem wir uns von Remote anmelden können, damit wir ssh für Root sperren können.

# useradd -m [username]
# passwd [username]
# [passwort eingeben]

Jetzt noch die Konfigurationsdatei für ssh ändern. Unter /etc/ssh/sshd_config ändern wir die Zeile “PermitRootLogin yes” zu “PermitRootLogin no”.

Wir können uns dann mit einem unprivilegierten Benutzer anmelden und mit “su” zu Root wechseln.

Damit haben wir ein zumindest rudimentär eingerichtetes und abgesichertes System, das wir als Grundlage für praktisch jeden beliebigen Server verwenden können.

Als nächstes erstellen wir ein tar-Archiv vom Image. Dazu muss die Instanz herunter gefahren werden.

Wir erstellen ein Verzeichnis für das Archiv
# mkdir /var/xen-images

Wir erstellen einen Mount-Point für das Image
# mkdir /mnt/xen

Wir mounten das Image, wobei vg0 hier für die lvm-Partition steht und image-disk für den Namen der Instanz
# mount /dev/vg0/image-disk /mnt/xen/

Jetzt erstellen wir das Archiv. Das kann eine ganz Weile in Anspruch nehmen.
# cd /mnt/xen/
# tar pcfzv /var/xen-images/Image.tar.gz *

Das schöne daran: Egal wie groß man die Partition für die Instanz gewählt hat, alles wird in ein handliches Paket von etwas über 100 MB gepackt

Wir verlassen den Mountpoint und und löschen ihn dann wieder
# cd / ; umount /mnt/xen

Da wir nun eine immer gültige Ausgangsbasis für neue Server haben, entfernen wir die bisherigen Installationsmethoden aus der xen-tools-Konfigurationsdatei.
In /etc/xen-tools/xen-tools.conf kommentieren wir folgende Zeile aus:
debootstrap = 1

Ab sofort können wir neue Server ganz einfach anlegen mit
# xen-create-image --tar=/var/xen-images/Image.tar.gz --ip=[ip -Adresse] --hostname=[hostname]

Wenn wir eine neue Instanz mit diesem Image starten, müssen wir noch einen neuen localkey für Tripwire erstellen:
# dpkg-reconfigure tripwire

und dann die alten Datenabanken löschen aus /etc/tripwire und /var/lib/tripwire

Wir müssen auch die IP-Adresse, auf die Snort achten soll, vorgeben
# dpkg-reconfigure snort

Das ist der Basis-Server. Jetzt kann man natürlich nach belieben einen MTA, Datenbank- und Webserver installieren und all die Dienste, die einen Root-Server erst so richtig interessant machen. Darauf gehe ich dann im nächsten Teil ein.

7 thoughts on “Xen auf Debian. Teil 1”

Leave a Reply

Your email address will not be published. Required fields are marked *