Skip to content

AMD, multiple Monitore und Gnome

^ v M ><
Sobald man mehr als zwei Monitore angeschlossen hat, beginnt Gnome bei der Multimonitorfähigkeit zu versagen. Ich habe zwei Monitore zu einem grossen Desktop zusammengefasst (AMD nennt dies in seinen proprietären Treibern BigDesktop) und einen weiteren Monitor separat laufen. Leider maximieren sich Fenster nun über den ganzen Dualscreen statt sich perfekt auf einen Monitor einzupassen. Besonders mühsam ist dies, wenn man ein Video im Vollbildmodus betrachten will. Mit nur zwei angeschlossenen Monitoren passiert dies nicht - selbst wenn diese zu einem grossen Desktop zusammengefasst werden. Interessanterweise sind aber das Hintergrundbild sowie die Panel perfekt an den Monitor angepasst. Da kommt als Verdächtiger folglich rasch der Window Manager, also Metacity in Frage.

Folglich habe ich diesen durch diverse andere Varianten ersetzt. openbox scheitert genau so am Multimonitor und mutter stürzt direkt mit Speicherzugriffsfehler ab. Aber xfwm4 aus Xfce4 funktioniert gemäss Wunsch. Allerdings braucht es dann noch einiges an Tweaking, bevor das ansonsten gewohnte Metacity-Verhalten wiederhergestellt ist (und ein paar sehr nette Komfortfunktionen dazugewonnen wurden).

Zunächst muss xfwm mit ein paar Accessoires installiert, gestartet und konfiguriert werden. Alle Angaben sind wie üblich für Debian und verwandte Systeme:

su
aptitude install xfwm4 xfce4-utils xfce4-settings
exit
xfmw4 --replace &
xfwm4-settings
xfce4-settings-helper

Der xfce4-settings-helper verschwindet sofort im Hintergrund und aktiviert die Tastenkürzel wie z.B. Alt-F2 wieder.

Jetzt stört mich nur noch, dass Fenster auch beim Scrollen mit dem Mausrad Fokus bekommen. Dies lässt sich über den xfce4-settings-editor abstellen, indem man den Wert des Eintrags /xfwm4/raise_with_any_button auf FALSE setzt.

Soweit so einfach. Kommen wir nun zum zeitlich aufwändigsten Teil. Um nun xfwm4 permanent als Standard einzurichten, gibt es unzählige Möglichkeiten. Ich habe nur eine gefunden, die "gefühlt fehlerfrei" funktioniert und diese ist technisch gesehen totaler Blödsinn. Und zwar habe ich in gnome-session-properties zwei neue Starter angelegt. Einer startet /usr/bin/xfwm4 --replace und ein zweiter /usr/bin/xfce4-settings-helper. Das ist natürlich insofern doof, da erst metacity und danach xfwm4 als Ersatz gestartet wird. Dies führt bei mir jedoch zu absolut keiner Startverzögerung, ganz im Gegensatz zu der Variante, eine ~./gnomerc anzulegen und darin die Zeile export WINDOW_MANAGER="/usr/bin/xfwm4" einzufügen. Das Resultat ist ein um 10 Sekunden verzögertet Start von Gnome. Das ist natürlich nicht akzeptabel. Ebenso gibt es die Variante im gconf-editor unter /desktop/gnome/session/required_components den Schlüssel windowmanager von gnome-wm zu xfwm4 zu ändern. Das Resultat hierbei war, dass gar kein Window Manager mehr gestartet wurde. Also noch schlimmer! Tja, und unter Debian gibt's noch die /etc/alternatives/x-window-manager. Diesen Symlink von /usr/bin/metacity auf /usr/bin/xfwm4 zu ändern bringt grad gar nichts, da dieser Symlink auf meinem System von gnome-wm (ist nur ein Shellskript) gar nicht ausgewertet wird.

Somit wär also ein Freitagabend verschwendet, weil Debian Stable ja sooo bugfrei ist.

Linux auf richtig grossen Partitionen installieren... trotz BIOS

^ v M ><
Schade, dass nagelneue Boards immer noch dieses eklige BIOS statt dem wesentlich moderneren EFI mitbringen. BIOS und Grub können nämlich nichts mit GPT anfangen, was für grosse Partitionen über 2TB aber notwendig ist. Und BIOS bzw MBR begrenzt die Partitionsgrösse auf anachronistische 2TB. Denn wenn man schon 4*2TB kauft, um ein anständiges NAS zu basteln, will man sich nicht lange mit Daten hin-und-her-Schaufelei von Partition A nach Partition B und zurück befassen. Doch auch dafür gibt es eine Lösung:

Es darf einfach keine Partition über 2TB Grösse existieren, auch nicht als Software-RAID-Verbund. Aber LVM darf sich darüber hinwegsetzen.

Daher mein Setup:
- Am Anfang der Platten eine kleine Partition von 128MB als RAID-1 für /boot
- Danach drei Partitionen à 666GB, welche jeweils als RAID-10 zusammengefasst werden
- Die drei RAID-10 Partitionen werden mittels LVM zu einem gigantischen logischen Volume zusammengefasst. Alternativ kann man natürlich auch ein RAID-5 nehmen, dann tauscht man 2TB mehr Festplattenplatz gegen massiven CPU-Overhead bei allen Zugriffen ein.

Zuerst mal mit einer Live-CD nach Wahl starten und die Disks vorbereiten. Zu beachten ist, dass so grosse Festplatten gerne mit 4k-Sektoren ausgeliefert werden:

cfdisk -h224 -s56 /dev/sda #erstellen von 4 Partitionen vom Typ FD (RAID autodetect) unter Beachtung der 4k-Sektorengrenze
sfdisk -d /dev/sda | sfdisk --force /dev/sdb #sfdisk mag die 4k-Sektorengrenzen nicht, daher erzwingen wir sie
sfdisk -d /dev/sda | sfdisk --force /dev/sdc
sfdisk -d /dev/sda | sfdisk --force /dev/sdd
mdadm --create --verbose /dev/md0 --level=1 --raid-devices=4 /dev/sd?1
mdadm --create --verbose /dev/md1 --level=10 --raid-devices=4 /dev/sd?5
mdadm --create --verbose /dev/md2 --level=10 --raid-devices=4 /dev/sd?6
mdadm --create --verbose /dev/md3 --level=10 --raid-devices=4 /dev/sd?7
pvcreate /dev/md[123]
vgcreate bigdisk /dev/md[123]
vgchange -a y bigdisk

Danach erstellt man ein paar logische Volumen nach Bedarf, startet die Setup-CD (in meinem Fall natürlich Debian Squeeze) und schon läuft die Sache rund. Partman wird sich zwar trotzdem beschweren, lässt aber die Installation zu. Und Grub installiert sich ganz normal im MBR.

LibreOffice the Debian way

^ v M ><
Da heute LibreOffice 3.3 in stabiler Version freigegeben wurde, wird es höchste Zeit, das proprietär gewordene OpenOffice.org loszuwerden. Da LibreOffice schon im experimental-Zweig von Debian Einzug gehalten hat, lässt es sich sehr elegant auch unter Squeeze (derzeit noch testing) installieren.

Zuerst muss der experimental-Zweig zu apt hinzugefügt werden:
cat >> /etc/apt/source.list <<EOF
deb http://ftp.ch.debian.org/debian/ experimental main
deb-src http://ftp.ch.debian.org/debian/ experimental main
EOF
cat >> /etc/apt/preferences <<EOF
Package: *
Pin: release a=testing
Pin-Priority: 700

Package: *
Pin: release a=experimental
Pin-Priority: 600
EOF

aptitude update


Anschliessend kann bequem irgendwelche Software aus experimental hinzugefügt werden, indem mittels dem Parameter -t an aptitude/apt-get signalisiert wird, welcher Debian-Zweig verwendet werden soll. Die LibreOffice-Paket haben jedoch noch ein paar unsaubere Abhängigkeiten, so dass derzeit einige davon aus testing verwendet werden müssen.
aptitude install libhsqldb-java
aptitude -t experimental install libreoffice libreoffice-l10n-de libreoffice-gnome ttf-opensymbol

Kernel Update und proprietärer Ati-Treiber unter Debian

^ v M ><
Irgendwie läuft der Ati-Kram noch nicht ganz zufriedenstellend. Immerhin hat es AMD unterdessen fertiggebracht, ihr Treiberpaket mit korrekten md5-Signaturen zu versehen. Ich hab daher auf meinem Debian Squeeze ein Kernel-Update auf 2.6.36.3 vorgenommen (mit dem 2.6.37 kann man den Ati-Murks unmöglich kompilieren) und dann den aktuellen Ati-Treiber versucht zu installieren. Nicht ganz trivial, aber es geht. Ich setze mal voraus, dass ein vollständiges build-environment samt gcc und xorg-dev installiert ist.

Erst ein Kernel-Update:
cd /usr/src
tar -jxf /path/to/linux-2.6.36.3.tar.bz2
cd linux-2.6.26.3
cp /boot/config-2.6.32-5-amd64 .config
make oldconfig
fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers --jobs=8
dpkg -i ../linux-image-2.6.36.3-custom_amd64.deb

Mit --jobs=8 wird der nagelneue Quadcore auch endlich mal etwas ausgereizt :-)

Gut, danach reboot und Installation der Ati-Treiber samt der dubiosen Patches von hier:
sh ati-driver-installer-10-12-x86.x86_64.run
cd /
patch -p1 < /path/to/arch-2.6.36.patch
patch -p2 < /path/to/ati-drivers-2.6.36.patch
patch -p1 < /path/to/ati-drivers-fix_compilation-bug-297322.patch
patch -p1 < /path/to/sema_init.patch
cd /lib/modules/fglrx/build_mod
./make.sh
cd ..
./make_install
modprobe fglrx


Dann klappt's auch mit AMD. Die grosse Stolperfalle ist der zweite Patch, welcher anders codierte Pfadangaben drin hat und darum mit -p2 statt -p1 aufgerufen werden will. Der Rest ist ziemlich geradeaus.

Backups

^ v M ><
Neulich bin ich mal gefragt worden, wie ich Backups mache. Die Antwort: Mit einem relativ simplen Cron-Skript und rdiff-backup per SSH auf den Fileserver. Das gibt ein schönes inkrementelles Backup, bei dem man beliebig weit zurückgehen kann, allerdings behalte ich nur die Daten der letzten zwei Monate. Rdiff-Backup braucht relativ wenig Rechenleistung, Bandbreite und Speicherplatz und funktioniert auch hervorragend über's Internet. Wird das Cron-Skript häufig genug aufgerufen, emuliert dieses Backup recht gut das Verhalten von Apples Time-Machine. Nachteilig ist lediglich, dass es in meinem Fall ein vom Clienten initiiertes Backup ist. Solange der zu sichernde Rechner die Daten auf den Backup-Server schreibt, ist ein Backup nicht sicher vor Manipulationen. Besser wäre es, wenn der Server vom Clienten lesen würde. Nur bräuchte der Server dann root-Login auf dem Clienten, was auch nicht unbedingt der Sicherheit förderlich ist...

Folgendes muss man auf dem Server einrichten:
  • SSH-User für's Backup
  • Im $HOME/.ssh/authorized_keys die public-SSH-Keys des root-Users der zu sichernden Systeme eintragen (ja, das Backup-Skript wird in der Regel als root laufen, da man z.B. auch /etc sichern will).
  • Im Verzeichnis, welches die Backups enthalten soll, muss für jeden zu sichernden Rechner ein Verzeichnis erstellt werden, das so heisst, wie der Host (zu erfahren durch Eingabe von "hostname" auf dem Client)
  • In diesen Verzeichnissen muss jeweils eine Verzeichnisstruktur erstellt werden, welche der $DIRECTORIES-Variable aus untenstehendem Skript entspricht.
  • Zuletzt chownt man diese gesamte Struktur an den zuerst erstellen SSH-User.

Und so schaut mein Skript aus:
#!/bin/bash

### Settings ###
DIRECTORIES="/etc /home /usr/local/bin"
EXCLUDES="/home/*/.local/share/Trash"
SSHUSER="rdiff-backup"
SSHHOST="192.168.0.1"
REMOTEDIR="/mnt/backup/$(hostname)/"
RDIFF="/usr/bin/rdiff-backup"
RDIFFOPTIONS="ssh -p 2222 %s rdiff-backup --server"
FILEAGE="2M"

NOW=$(date +"%Y-%m-%d")
GZIP="$(which gzip)"
STATUSFILE="/var/tmp/rdiff-backup-status"
LOCKFILE="/var/lock/rdiff-backup-lock"
DUMPDIR="/home/backup"

if [ -e "$LOCKFILE" ]; then
echo "Lockfile exists, quitting..."
exit 255
fi

touch "$LOCKFILE"

### Packages List ###
dpkg --get-selections | $GZIP > $DUMPDIR/dpkg.$NOW.txt.gz
RETVAL=$(($RETVAL + $?))

### File based Backup ###
for DIR in $DIRECTORIES; do
EXCLUDESLIST=""
for EXCLUDE in $EXCLUDES; do
SIZE=$(expr match "$EXCLUDE" "$DIR")
if [ $SIZE -gt 0 ]; then
EXCLUDESLIST="$EXCLUDESLIST --exclude $EXCLUDE"
fi
done
$RDIFF $EXCLUDESLIST --remote-schema "$RDIFFOPTIONS" $DIR $SSHUSER@$SSHHOST::$REMOTEDIR/$DIR
RDIFFRETVAL=$?
RETVAL=$(($RETVAL + $RDIFFRETVAL))
if [ $RDIFFRETVAL = 0 ]; then
$RDIFF --force --remote-schema "$RDIFFOPTIONS" --remove-older-than $FILEAGE $SSHUSER@$SSHHOST::$REMOTEDIR/$DIR
RETVAL=$(($RETVAL + $?))
fi
done

find $DUMPDIR -ctime +7 -exec rm -f '{}' ';'
RETVAL=$(($RETVAL + $?))

echo $RETVAL > "$STATUSFILE"
rm -f "$LOCKFILE"
exit $RETVAL

Was bedeuten nun all die Variablen unter "Settings"?
  • DIRECTORIES: Die zu sichernden Verzeichnisse.
  • EXCLUDES: Nicht zu sichernde Verzeichnisse
  • SSHUSER: Mit welchem User wird per SSH am Server angemeldet
  • SSHHOST: Die Adresse des Backup-Servers. Entweder eine IP oder ein Hostname.
  • REMOTEDIR: Das Basisverzeichnis, worin auf dem Server die Backups gespeichert werden.
  • RDIFF: Pfad zum lokal rdiff-backup Binary
  • RDIFFOPTIONS: Wenn man zusätzliche Optionen angeben will, z.B. einen alternativen SSH-Port. Kann man auch leer lassen
  • FILEAGE: Nach wie vielen Tagen/Monaten/Jahren die Inkremente gelöscht werden sollen

Linux, Nokia E72 und Synchronisation

^ v M ><
Nachdem ich mir mal wieder einen neuen Hirngrill besorgt hab, wollte ich dessen Daten natürlich bei Gelegenheit wieder auf den PC sichern. Programm der Wahl ist hierfür natürlich opensync. Als Übertragung würde sich zwar Bluetooth anbieten, was in einer theoretisch einfacheren Konfiguration von Opensync enden würde. Jedoch ist mir Bluetooth im Allgemeinen etwas zu fummelig. Daher bin ich ganz froh darüber, dass mein neues Gerät auch über USB synchronisiert werden kann. Das erfordert zwar eine etwas aufwändigere Konfiguration, dafür erhoffe ich mir davon längerfristig einfachere Ausführung des Synchronisationsvorgangs.

Eine ältere aber sehr gute Anleitung für ein anderes, vergleichbares Gerät habe ich ziemlich schnell gefunden. Daher an dieser Stelle nur ein kurzes Update für mein Modell:

Zur Programminstallation gilt eigentlich nur zu sagen, dass Ubuntu in der Geschmacksrichtung "Krüppliger Koala" schon alle Programme in den Standard-Repositories hat, ein einfaches
aptitude install multisync0.90 multisync-tools opensync-plugin-syncml opensyncutils opensync-plugin-file

reicht also schon (ggf noch weitere Plugins nach Bedarf hinzufügen).

Danach musste ich auch wieder eine handgefertige udev-Regel für den Zugriff als eingeschränkten Benutzer anlegen. Dies funktioniert analog zur verlinkten Anleitung, lediglich die Device-ID muss angepasst werden. lsusb meldet folgende Daten:
Bus 001 Device 006: ID 0421:0223 Nokia Mobile Phones

woraus sich folgende Regel ableiten lässt:
BUS=="usb", SYSFS{idVendor}=="0421",SYSFS{idProduct}=="0223",GROUP="plugdev",USER="lukas"


Das neue Upstart-System vom Koala erfordert einen etwas anderen Befehl zum Neustart von udev:
sudo service udev restart

anschliessend sollte das Gerät auch neu angestöpselt werden. Das Handy fragt dann auch nach dem Betriebsmodus, für die Synchronisation hab ich immer "PC Suite" angewählt. Damit funktioniert die Synchronisation problemlos, folglich habe ich auch keinen anderen Modus getestet. Der Befehl syncml-obex-client -u sollte nun genauere Geräteinformationen ausgeben. Nun lassen sich im multysync-GUI oder mit den opensync-Kommandozeilentools die Plugins konfigurieren. Diese sind relativ gut dokumentiert, wodurch sich auch die XML-Konfigurationsdateien sehr einfach den eigenen Bedürfnissen anpassen lassen.

Würgaround für Koala-Sound

^ v M ><
Da mein krüppliger Koala immer noch nach dem Booten etwas gar schweigsam ist und die Entwickler bislang kein Update zur Verfügung gestellt haben, hab ich halt einen Würgaround gebastelt:

Erstelle ein Skript /usr/local/bin/unmute.sh mit Berechtigung +x mit folgenden Inhalt und füge es zum Gnome-Session-Management als Autostart-Programm hinzu
#!/bin/sh
pactl set-sink-mute 1 0
pactl set-sink-volume 1 35000
pactl set-sink-mute 0 0
pactl set-sink-volume 0 35000

Das setzt die Ausgabelautstärke auf beiden Soundkarten auf 53%. Keine Ahnung, wieso 35000 53% entspricht.

iSCSI-Spielereien mit Debian und Ubuntu

^ v M ><
In einer der letzten Ausgaben des Linux-Magazins war ein Artikel über Fileserver und iSCSI drin. iSCSI ist ein Protokoll, welches SCSI-Befehle über TCP transportiert. Man kann damit also Massenspeicher übers Netzwerk verwenden. Eine sehr interessante Sache. Leider ist der Linux-Magazin-Artikel ausgesprochen unvollständig und geht nur auf die Clientseite ein. Wie also bau ich meinen eigenen iSCSI-Server?

Das Gentoo-Wiki hilft hier mal wieder mit einer simplen Anleitung aus der Patsche. Nun gilt es nur noch, diese auf Debian/Ubuntu anzupassen. Mein iSCSI-Target (Server) läuft auf Debian Lenny, da braucht's folgende Pakete:
aptitude install iscsitarget iscsitarget-modules-$(uname -r)

Danach wird die zu exportierende Festplatte in der Datei /etc/ietd.conf definiert:
Target iqn.2009-05.com.example.debianhost:storage.disk1
Lun 0 Path=/dev/hda,Type=fileio
MaxConnections 1

Und anschliessend der Dienst gestartet:
sed 's/false/true/' -i /etc/default/iscsitarget
/etc/init.d/iscsitarget start

Auf der Clientseite braucht's nur die Installation des Pakets open-iscsi sowie dessen Anpassung. Die Datei /etc/iscsi/initiatorname.iscsi bekommt folgenden Inhalt:
InitiatorName=iqn.2009-05.com.example.debianhost:storage.disk1

Ausserdem wird das zu benutzende Netzwerk-Interface definiert:
ifconfig eth0
iscsiadm -m iface -I iface0 --op=new
iscsiadm -m iface -I iface0 --op=update -n iface.hwaddress -v xx:xx:xx:xx:xx:xx

Danach wird open-iscsi gestartet mittels
/etc/init.d/open-iscsi start

Nun kann man nach Targets suchen, sie einbinden, mounten, nutzen, wieder aushängen... wofür man es halt auch immer nutzen will:
iscsiadm -m discovery -t st -p 192.168.0.6 -P 1
iscsiadm -m node -T iqn.2009-05.com.example.debianhost:storage.disk1 -l
mount /dev/sdc1 /mnt
umount /mnt
iscsiadm -m node -T iqn.2009-05.com.example.debianhost:storage.disk1 -u


Coole Sache, da muss ich auf jeden Fall noch weiter mit rumspielen :-) Insbesondere, da man damit nicht nur SCSI-Geräte übers Netz transportieren kann, wieder Name vielleicht suggeriert. In der Tat habe ich meinen ersten Gehversuch mit einer ganz normalen IDE-Platte gemacht (erkennbar an der Freigabe des Geräts /dev/hda). Das funktioniert also wirklich mit allen Blockgeräten. Sehr cool :-)

Wofür ich das nun abseits eines Servers brauchen könnte? Nun, z.B. kann ich eine DVD ins Laufwerk meines Desktop-Rechners legen und sie dann über WLAN auf meinem Netbook abspielen (sofern die Bandbreite ausreicht... was noch zu testen wäre).

Regelbasiertes Routing

^ v M ><
Seit kurzem hab ich den Bedarf, gewissen Netzwerkverkehr über ein VPN zu tunneln. Da die direkte Anbindung aber wesentlich schneller ist als die Anbindung des VPN-Servers, wäre es eine eher mässig produktive Massnahme, einfach allen Verkehr übers VPN laufen zu lassen. Aber unter Linux sind auch anspruchsvolle Routinglösungen genial einfach. Alles, was man so benötigt, hat man in der Regel standardmässig dabei, nämlich die Tools iptables und ip. Mittels iptables werden die umzuroutenden Pakete identifiziert und markiert, mittels ip wird eine Routing-Regel und ein Routing-Tabelleneintrag erstellt. Wirklich total simpel:
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
TCP_PORTS="993 5222"
for PORT in $TCP_PORTS; do
iptables -t mangle -A OUTPUT -p tcp --dport $PORT -j MARK --set-mark 1
done

In diesem Fall werden einfach alle Pakete markiert, welche an einen bestimmten TCP-Port gesendet werden. Bei Bedarf können natürlich problemlos weitere Regeln (auch für UDP, ICMP oder bestimmte Zieladressen) gesetzt werden. Iptables setzt der Kreativität eigentlich keine Grenzen. Damit auch die Antworten eintreffen, müssen die Pakete geNATet werden. Nun benötigt man noch eine passende Routenkonfiguration:
ip rule add fwmark 1 table 1
ip route add default dev tun0 table 1
ip route flush cache

Sollte der VPN-Tunnel mal zusammenbrechen, muss einfachh nach dem Wiederaufbau der VPN-Verbindung die Route nochmals neu gesetzt und der Puffer nochmals geleert werden. Das war's.

Apache mit voll funktionalem mod_chroot in Debian

^ v M ><
Apache ist ein äusserst exponierter Dienst. Grad auf Servern mit vielen Seiten und zahlreichen PHP-Skripten ist das durchaus die grösste Bedrohung für die Serversicherheit. Daher empfiehlt es sich, der Absicherung von Apache besonders viel Aufmerksamkeit zukommen zu lassen. Eine wichtige Methode der Absicherung ist das chroot, in dem der Apache in ein Unterverzeichnis des Systems gesperrt wird. Gelingt ein Angriff auf ein Webskript, so sind für den Angreifer noch immer weitere Hürden in den Weg gelegt, bevor er sich im System einnisten kann.

Relativ einfach lässt sich ein chroot mittels mod_chroot einrichten. Es gibt auch unzählige Howtos im Internet. Aber leider kein einziges brauchbares. Apache ins chroot sperren ist an sich keine Sache. Die nötigen Pakete installieren, dann noch zwei Konfigurationseinträge vornehmen und gut. Gut? Nein! Denn damit geht eigentlich gar nichts mehr, ausser der Auslieferung statischer Webseiten und ein Bisschen Basis-PHP. Email? Tot! ImageMagick? Tot! Das muss nicht sein. Daher mein Howto für Apache mit mod_chroot, mod_php5, suhosin und PHP im safe_mode:

Zuerst müssen die nötigen Pakete installiert werden:
aptitude install apache2 libapache2-mod-chroot libapache2-mod-php5 php5-suhosin php5-imagick imagemagick dash msttcorefonts

Weitere PHP-Module können nach Bedarf installiert werden, wie z.B. php5-gd php5-imap php5-ldap php5-mcrypt php5-mysql. Vorsicht ist bei suhosin geboten, einige grössere PHP-Applikationen bekommen dadurch Probleme. Entsprechende Workarounds müssen dann per individueller Konfiguration eingebaut werden. Die meisten wichtigeren Applikationen haben in ihrer Hilfe oder im Supportbereich entsprechende Informationen.

Ein erster Härtungsschritt ist, dass Apache der Zugang zu einer Shell entzogen wird. Eine Shell ist nicht notwendig und nur ein weiterer potentieller Unsicherheitsfaktor. Also:
usermod -s /bin/false www-data


Nun müssen die Module aktiviert werden:
a2enmod mod_chroot && a2enmod php5


In der Datei /etc/apache2/apache2.conf muss folgende Zeile eingefügt werden:
ChrootDir /var/www


Als nächster Schritt wird das chroot gebaut. Das ist ein sehr langer und aufwändiger Prozess. Denn ins chroot müssen sämtliche ImageMagick-Binaries sowie ein SMTP-Server samt ihrer Abhängigkeiten kopiert werden. Ich hab das chroot wie schon bei Teamspeak mit den Thread Local Storage Bibliotheken gebaut. XEN-User sollten davon Abstand nehmen und die "normalen" Bibliotheken verwenden. Als Mini-Mailserver habe ich mich für esmtp entschieden, wer andere vorlieben hat, darf sich natürlich auch gerne ssmtp anschauen oder versuchen mini_sendmail zum Laufen zu überreden.

Mailer vorbereiten

Leider akzeptiert Debian nur die Installation eines MTA gleichzeitig. Da man als Systemmailer wohl lieber Postfix oder Exim einsetzt, muss hier etwas getrickst werden. Verwendet hier bitte für den Download der Pakete (auch wenn sie recht klein sind) den Debian Mirror EURER Wahl, damit sich die Last entsprechend verteilt. Ausserdem muss auf die Versionsnummer acht gegeben werden, die kann sich natürlich mit der Zeit ändern. .deb-Pakete sind mit dem Packer ar gepackt, dieser sollte standardmässig auf jedem Debian-System installiert sein.
mkdir ~/esmtp
cd ~/esmtp
wget http://mirror.switch.ch/ftp/mirror/debian/pool/main/e/esmtp/esmtp_0.5.1-4.1_i386.deb
wget http://mirror.switch.ch/ftp/mirror/debian/pool/main/libe/libesmtp/libesmtp5_1.0.4-2_i386.deb
ar xv esmtp_0.5.1-4.1_i386.deb
tar -zxf data.tar.gz
ar xv libesmtp5_1.0.4-2_i386.deb
tar -zxf data.tar.gz


Basis-Chroot bauen

Bei sämtlichen Befehlen, die nun folgen, wird davon ausgegangen, dass man sich im Verzeichnis /var/www befindet. Ist dem nicht so, so stimmen natürlich die relativen Pfade nicht mehr und das Howto schlägt fehl. Wie schon eingangs erwähnt, sollten XEN-User aus Performancegründen nicht die TLS-Bibliotheken verwenden.
cd /var/www
mkdir bin etc lib tmp usr
mkdir -p lib/tls/i686/cmov usr/lib/i686/cmov var/lib/php5 var/log/apache2 var/run
chown www-data:www-data tmp
chown www-data:www-data var/lib/php5
chown www-data:www-data var/log/apache2
chown www-data:www-data var/run
touch var/run/apache2.pid
ln -sf var/run/apache2.pid /var/run/apache2.pid
cp /bin/dash bin
cd bin
ln -sf dash sh
cd ..
cp /etc/mime.types etc
grep www-data /etc/passwd > etc/passwd
cp /lib/ld-linux.so.2 lib
cp /lib/libgcc_s.so.1 lib
cp /lib/libnss_dns.so.2 lib
cp /lib/tls/i686/cmov/libc.so.6 lib/tls/i686/cmov
cp /lib/tls/i686/cmov/libdl.so.2 lib/tls/i686/cmov
cp /lib/tls/i686/cmov/libpthread.so.0 lib/tls/i686/cmov
cp /lib/tls/i686/cmov/libresolv.so.2 lib/tls/i686/cmov
cp /usr/lib/libz.so.1 usr/lib
cp /usr/lib/i686/cmov/libcrypto.so.0.9.8 usr/lib/i686/cmov
cp /usr/lib/i686/cmov/libssl.so.0.9.8 usr/lib/i686/cmov

Dash wird als Shell mit minimalem Speicherbedarf installiert. Leider benötigt esmtp zwingend eine Shell, ansonsten verweigert er den Dienst. Dies ist natürlich ein klarer Sicherheitsmangel, der durch Workarounds wie safe_mode behoben werden muss.

Nun wird der Mailer ins chroot kopiert:
cp ~/esmtp/usr/bin/esmtp bin
cp -r ~/esmtp/usr/lib usr/lib


Und als nächstes wird der Mailer konfiguriert. Unter Annahme, dass auf dem Server z.B. ein Postfix oder Exim als Mailserver läuft, muss dazu die Datei /var/www/etc/esmtprc mit folgendem Inhalt erstellt werden:
hostname = 127.0.0.1:25
starttls = disabled


Ausserdem ist jetzt der Zeitpunkt gekommen, um PHP mitzuteilen, wie es mailen soll. Ausserdem kann man bei der Gelegenheit auch weitere Absicherungen vornehmen und z.B. den safe_mode einschalten. Dazu müssen ein paar Direktiven in der Datei /etc/php5/apache2/php.ini angepasst oder eingefügt werden. Beachte, dass die Shell in /bin liegt, während als safe_mode_exec_dir /usr/bin konfiguriert wird. PHP-Skripte können also nicht auf die Shell zugreifen.
safe_mode = On
safe_mode_exec_dir = /usr/bin
expose_php = Off
display_errors = Off
log_errors = On
sendmail_path = /bin/esmtp -t

ImageMagick und Schriften

Es müssen ein paar weitere Bibliotheken sowie die benötigten ImageMagick-Binaries ins chroot kopiert werden:
mkdir -p usr/lib/mime/packages/
mkdir usr/bin
cp /lib/tls/i686/cmov/libm.so.6 lib/tls/i686/cmov/
cp /usr/lib/libMagick.so.9 usr/lib/
cp /usr/lib/liblcms.so.1 usr/lib/
cp /usr/lib/libtiff.so.4 usr/lib/
cp /usr/lib/libjasper-1.701.so.1 usr/lib/
cp /usr/lib/libjpeg.so.62 usr/lib/
cp /usr/lib/libpng12.so.0 usr/lib/
cp /usr/lib/libXext.so.6 usr/lib/
cp /usr/lib/libXt.so.6 usr/lib/
cp /usr/lib/libSM.so.6 usr/lib/
cp /usr/lib/libICE.so.6 usr/lib/
cp /usr/lib/libX11.so.6 usr/lib/
cp /lib/libbz2.so.1.0 usr/lib/
cp /usr/lib/libxml2.so.2 usr/lib/
cp /usr/lib/libfreetype.so.6 usr/lib/
cp /lib/tls/i686/cmov/libdl.so.2 usr/lib/
cp /usr/lib/libXau.so.6 usr/lib/
cp /usr/lib/libXdmcp.so.6 usr/lib/
cp /usr/lib/mime/packages/imagemagick usr/lib/mime/packages
cp /usr/bin/animate usr/bin
cp /usr/bin/compare usr/bin
cp /usr/bin/composite usr/bin
cp /usr/bin/conjure usr/bin
cp /usr/bin/convert usr/bin
cp /usr/bin/display usr/bin
cp /usr/bin/identify usr/bin
cp /usr/bin/import usr/bin
cp /usr/bin/mogrify usr/bin
cp /usr/bin/montage usr/bin

Wer noch Schriften braucht, kann diese nach Bedarf installieren. Die Dateinamen der Schriftdateien müssen komplett in Kleinbuchstaben gehalten sein.
mkdir -p usr/share/fonts/truetype/msttcorefonts/
cp /usr/share/fonts/truetype/msttcorefonts/verdana.ttf usr/share/fonts/truetype/msttcorefonts/

DocumentRoot

Der Startvorgang des Apache verläuft in etwa folgendermassen:
  1. Apache startet ausserhalb der chroot-Umgebung und wertet die Konfiguration in /etc/apache2 aus.
  2. Apache schreibt sein PID in die vorgegebene pid-Datei
  3. Apache prüft die Existenz der DocumentRoot-Verzeichnisse gemäss Konfiguration in den vhosts.
  4. Apache öffnet die Logfiles gemäss Konfiguration in den vhosts.
  5. Apache wechselt ins chroot.
  6. Apache öffnet die Sockets.
  7. Apache wechselt zu einem unpriviliegierten User.
  8. Apache ist bereit. Sämtliche Anfragen werden nun im chroot bearbeitet. Die Ausführung von PHP-Skripten findet nun im chroot statt.

Folglich muss von den DocumentRoot-Verzeichnissen eine Schatteninstallation und eine Life-Installation vorgenommen werden. Wird in der Apache-Konfiguration z.B. die Direktive
DocumentRoot /var/www/htdocs/myhost

eingetragen, müssen folgende Verzeichnisse erstellt werden:
mkdir -p /var/www/htdocs/myhost
mkdir -p /var/www/var/www/htdocs/myhost

Effektiv arbeiten wird Apache dann mit dem Verzeichnis /var/www/var/www/htdocs/myhost, dorthin gehören folglich alle HTML-Dateien.

Apache starten, stoppen, neu laden

Jetzt kann man mal die ganze Sache testen und Apache starten. Ich habe festgestellt, dass mod_chroot leider die reload- und restart-Befehle zerschiesst. Folglich bleiben nur noch start und stop übrig. Um eine geänderte Konfiguration einzulesen, bleibt folglich leider keine andere Möglichkeit, als Apache erst zu stoppen und dann wieder zu starten. Bei stärker frequentierten Seiten freuen sich da vermutlich nicht alle User darüber. Sorry, aber dafür gibt's wohl keine Lösung.
/etc/init.d/apache2 start
/etc/init.d/apache2 stop

Enterprise WLAN mit Radius und LDAP

^ v M ><
Ich habe mein WLAN jetzt umgestellt auf Authentifizierung per Radius und LDAP. Das ist eigentlich schon eine Konfiguration für grössere Firmen. Ich mach das für mich allein :-) Damit habe ich mein privates Single-Sign-On nun auch auf WLAN ausgeweitet.

Das Setup:
  • OpenLDAP als zentrale Authentifizierungs-Instanz. Die Passwörter sind mittels SSHA1 verschlüsselt.

  • FreeRadius als Authentikator für WLAN.

  • WRT54GL mit Tomato-Firmware (wobei DDWRT mit Chillispot jetzt erst recht interessant wäre)

  • Client mit Ubuntu 8.10, die Konfiguration erfolgt Klickibunti über den Network Manager


An sich ist das gar nicht mal schwer, eine gute Vorkonfiguration und gutes Howto vorausgesetzt. Für die Vorkonfiguration habe ich mich auf Gentoo verlassen, nach der Installation von FreeRadius lag da schon ein recht brauchbares und sauber strukturiertes Setup vor. Die Anpassungen habe ich anhand dieses Howtos vorgenommen, welches fast alles erklärt. Lediglich eine Sache bleibt dieses Howto schuldig: Was mache ich, wenn ich keine Passwörter im Klartext in meinem LDAP möchte?

Die Antwort auf diese Frage hat eine kurze Recherche und etwas ausprobieren ergeben: Die PAP-Konfiguration muss so eingestellt werden, dass PAP die Header des Passwort-Strings auswertet. LDAP liefert nämlich ein Passwort in der Form {SSHA}XYZ/ABC zurück, der Teil in den Klammern ist der Header und gibt den verwendeten Hashing-Algorithmus an. Das geschieht durch folgende Konfiguration in /etc/raddb/modules/pap:
pap {
auto_header = yes
}


Uffa, so einfach. Jetzt sollte ich nur noch die Radius-Konfiguration etwas ausmisten und nicht benötigte Authentifizierungs-Module deaktivieren sowie Accounting (z.B. per MySQL) einbauen.

Update: In letzter Zeit habe ich mehrere Anfragen zu diesem Beitrag erhalten. Ich nutze und betreue seit Jahren keine Radius-Installationen mehr, so dass ich bei Problemen mit Radius keine Fragen beantworten kann.

TeamSpeak im Chroot

^ v M ><
Teamspeak ist böse. Es ist proprietär, die letzte Version des Servers ist ein uralter RC und es ist komisch in der Konfiguration. Nun, was macht man mit sowas kriminellem? Na klar, einsperren! z.B. in einem chroot. Wie das bei mir funktioniert hat, erkläre ich hier:

Ein kurzes Suchen mit der Suchmaschine meines geringsten Misstrauens hat mich zu einer bereits sehr guten Anleitung geführt, welche ich mit leichten Modifikationen übernehmen konnte. Ich musste zum einen das Startskript etwas anpassen, zum anderen verwendet mein System standardmässig die TLS (Thread Local Storage) Bibliotheken der glibc. Für XEN-User ist dieser Hinweis insofern wichtig, als dass man diese Bibliotheken unter XEN aus Performancegründen nicht nutzen sollte. Auf einem XEN-System sind diese daher standardmässig nicht installiert. Da ist folglich ein Vorgehen gemäss der Originalanleitung zu empfehlen.

Ich bin so vorgegangen:
Erst werden die Verzeichnisse erstellt, ein Benutzer angelegt und Teamspeak entpackt. Danach werden die Berechtigungen angepasst. Leider konnte ich es Teamspeak nicht austreiben, in seinem Installationsverzeichnis Schreibrechte zu fordern (ein weiterer guter Grund für ein chroot).
mkdir /opt/teamspeak
cd /opt/teamspeak
tar -jxf ts2_server*.tar.bz2
useradd teamspeak -d /opt/teamspeak -s /bin/false
chown -R teamspeak:teamspeak tss2_rc2
chown root:root tss2_rc2/server_linux
chown root:root tss2_rc2/*.so


Nun werden die benötigten Bibliotheken ins chroot kopiert. Mittels ldd /opt/teamspeak/tss2_rc2/server_linux und ldd /opt/teamspeak/tss2_rc2/*.so lassen sich diese leicht bestimmen. Teamspeak fordert ebenfalls Zugriff auf /dev/null, was insofern blöd ist, dass man nun Teamspeak nicht auf einer Partition installieren kann, welche mit der Option "nodev" gemountet wurde:
mkdir etc dev lib tmp
mkdir -p usr/lib/gconv usr/lib/locale /lib/tls/i686/cmov var/run
grep teamspeak /etc/passwd > etc/passwd
grep teamspeak /etc/group > etc/group
cp /etc/localtime etc
cp /lib/ld-linux.so.2 lib
cp /lib/tls/i686/cmov/libc.so.6 lib/tls/i686/cmov
cp /lib/tls/i686/cmov/libdl.so.2 lib/tls/i686/cmov
cp /lib/tls/i686/cmov/libpthread.so.0 lib/tls/i686/cmov
cp /lib/libncurses.so.5 lib
cp /lib/libgcc_s.so.1 lib
cp /usr/lib/gconv/ISO8859-15.so usr/lib/gconv
cp /usr/lib/gconv/gconv-modules usr/lib/gconv
cp /usr/lib/locale/locale-archive usr/lib/locale/
mknod -m666 dev/null c 1 3

nano /etc/init.d/teamspeak


Der letzte Befehl startet einen Editor, mit welchem das Startskript erstellt wird. Im von mir verwendeten Editor nano lassen sich Dateien durch Eingabe von ctrl+o speichern und der Editor sich durch ctrl+w beenden. Meine grundlegende Änderung im Startskript gegenüber der Vorlage ist ein Wechsel ins Teamspeak-Verzeichnis. Dieser erwies sich als notwendig, damit Teamspeak überhaupt startet. Ausserdem habe ich nur die start und stop Parameter implementiert, den Rest brauche ich eigentlich nicht.
#! /bin/sh
CHROOT_DIR=/opt/teamspeak
EXECDIR=/tss2_rc2
USER=teamspeak
GROUP=teamspeak

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:${CHROOT_DIR}
EXEC=${EXECDIR}/server_linux
DAEMON=${EXEC}
NAME=tss2
DESC="TeamSpeak 2 Server"
PIDFILE=${EXECDIR}/server.pid
test -x ${CHROOT_DIR}${DAEMON} || exit 0

set -e

case "$1" in
start)
echo "Starting $DESC: $NAME"
start-stop-daemon --start --quiet --pidfile $PIDFILE \
--chuid $USER:$GROUP \
--chroot ${CHROOT_DIR} \
--startas $EXEC \
--chdir ${EXECDIR}
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME "
start-stop-daemon --stop --quiet --pidfile ${CHROOT_DIR}$PIDFILE \
--exec ${CHROOT_DIR}$DAEMON
echo "."
;;
esac



Das war's auch schon. Jetzt muss Teamspeak nur noch gestartet werden. Ausserdem kann man bei dieser Gelegenheit auch noch elegant die generierten Admin-Passwörter auslesen:
chmod a+x /etc/init.d/teamspeak
/etc/init.d/teamspeak start
update-rc.d teamspeak defaults 95
grep "admin account" tss2_rc2/server.log

VMWare Server und Clock Drift

^ v M ><
So toll VMWare Server ist, manchmal ist er echt störrisch. In diesem Fall wollten die Uhren der Gastsysteme schlicht nicht synchron bleiben. Mal waren sie massiv zu langsam, dann wieder viel zu schnell. Und alle Gäste waren unterschiedlich schnell. Das Problem ist allerdings nicht selten, entsprechen ist das Internet voll mit Lösungsansätzen.

In meinem Fall war die Clock Drift aber so mühsam, dass ein ganzer Massnahmenkatalog nötig war, der als "Best Of The Web" durchgehen kann:

1. Installation der VMWare Tools
2. Deaktivieren des CPU Frequency Scaling beim Hostsystem
3. Übergabe von Bootparametern an die Kernel der Gastsysteme: clocksource=pit nosmp noapic. Ersterer bremst zu schnelle, die anderen beschleunigen zu langsame Uhren. Es gäbe noch nolapic, aber damit wollten meine Gäste nicht mehr starten.
4. Manipulation der .vmx-Dateien aller Gäste. Es mussten folgende Parameter angefügt werden:
tools.syncTime = "TRUE"
host.cpukHz = "2200000"
host.noTSC = "TRUE"
ptsc.noTSC = "TRUE"
hostinfo.noTSC = "TRUE"
timeTracker.periodicStats = "TRUE"
timeTracker.statsIntercal = "10"

Aber jetzt scheint die Sache endlich solide zu laufen. Hat ja nur 6h und 100 Reboots gedauert, das Problem zu lösen...

Firefox 3 und selbstsignierte SSL-Zertifikate

^ v M ><
Vieles ist an Firefox 3 besser als an Firefox 2. Einiges ist anders und gewöhnungsbedürftig, aber deshalb nicht zwingend schlechter. Einiges ist aber eindeutig zur Katastrophe geworden. Mein Liebling hierbei ist der Umgang mit selbstsignierten SSL-Zertifikaten. Was da nun an Verrenkungen nötig ist, damit entsprechende Seiten (wie z.B. diese hier) wieder Erreichbar sind, ist unglaublich. Den dadurch entstehenden Sicherheitsgewinn erachte ich als minimal, die nötigen Arbeitsschritte für gelegentliche Internetuser hingegen für unüberwindbar. Daher eine kleine Anleitung in vier Bildern. Einfach immer dort klicken, wo der Pfeil hinzeigt:


Achtung! Fehler! Alarm! Problem! Na gut, machen wir mal eine Ausnahme.


Ja, Ausnahme hinzufügen.


Gut, nun das Zertifikat herunterladen.


Und nun speichern. Es ist natürlich auch sinnvoll, hier erst auf "Ansehen..." zu klicken und das Zertifikate nochmals zu überprüfen. Anschliessend wird die Seite geladen.

Wirklich kritische Dinge gibt es auf Planetknauer.net nicht. Da ich keine Bank bin, Eure Kreditkartendaten nicht abfrage etc pp. ist das Hinzufügen der Ausnahme wenig bedenklich. Bei e-Banking, Online-Shopping sowie sonstigen Dingen, bei denen es um Geld, personenbezogene, private oder Firmendaten geht, sollte man natürlich drauf achten, dass die Gegenseite ein gültiges Zertifikat einer offiziellen CA (Certificate Authority) verwendet. Dann erscheint auch diese Warnung nicht. Alles andere ist unseriös.