Skip to content

Verdammte Trötzel-PCs

^ v M ><
Mein Server ist zwar noch keine zwei Jahre alt, aber dass PCs in ein ausgesprochenes Trötzelalter geraten können, war mir noch nie so bewusst wie heute: Erneut ist mir eine Festplatte ausgestiegen (diese verdammten Seagates!!! Sobald die 2TB-Generation da ist, steig ich wieder auf Samsung um!). Na gut, kein Problem, ist ja alles RAID-1. Also Platte raus. Ein Plattenwechsel bedeutet aber: Runterfahren, rausnehmen, hochfahren.

Hmmm... OK! Bei der Gelegenheit kann ich ja grad noch ein Kernel-Update machen und die Netzwerk-Konfiguration anpassen. Ich möchte ein gebridgtes OpenVPN einsetzen, wofür ich also mein lokales Netzwerkinterface in eine Bridge integrieren muss. Unter Gentoo an sich kein Problem, die genaue Vorgehensweise steht in der /etc/conf.d/net.example drin. Diese wurde rasch angepasst, während der neue Kernel (2.6.29.2, bislang lief 2.6.29.1, ergo ein an sich gefahrloses Minor-Update) durchkompiliert wurde.

Danach wurde die Kiste runtergefahren, Platte rausgenommen, wieder hochgefahren, angepingt, nie Antwort erhalten. Jaaa, man kennt das ja, bestimmt hab ich mich irgendwo in der Netzwerk-Konfiguration vertippt. Also Monitor und Tastatur angeschlossen und ans lokale Debuggen gemacht. Und da zeigen sowohl brctl wie auch ifconfig, ebenso die Link-Status-LEDs an Netzwerkkarte und Switch, dass alles in bester Ordnung sei. Dennoch geht gar nix über br0 raus. Na schön, die Bridge wieder abgerissen und die Netzwerkschnittstelle normal betrieben. Immer noch tot. Na gut, da wird wohl zufällig die Onboard-Netzwerkkarte der Platte über den Jordan gefolgt sein. Aber das ist kein Problem, 100MBit-Karten hab ich wie Sand am Meer rumliegen. Eingebaut, hochgefahren, konfiguriert. Und wen wundert's? Natürlich ging kein Mucks raus über die Karte. Aber der Switch sagt: "doch, doch, ich hab ne 100MBit-Verbindung". Langsam wurde ich ärgerlich. Könnt's an Switch oder Kabel liegen? Folglich hab ich meinen Laptop geholt und anstelle des Servers angeschlossen. Die Infrastruktur zeigte nach kurzem Test ihre absolute Funktionstüchtigkeit. Also hab ich ein faules Ei von Ersatzkarte erwischt? Man weiss ja nie, folglich nächste Karte rein. Test natürlich negativ. Hmmm, OK, nächste Karte? Negativ. Karte in anderen PCI-Slot? Negativ. Nochmals die interne Karte? Heee, hoppla, geht wieder? WTF??? Bridge-Konfiguration? Na einwandfrei. Nach einem Reboot? Einwandfrei.

So ganz nebenbei bemerkt: Das WAN-Interface zum ADSL-Router funktionierte die ganze Zeit ohne zu mucken.

Na wie auch immer: Ich hab jetzt eine Stunde lang sinnlos rumgebastelt um ein durch den Computer selbständig generiertes Problem zu beheben, das sich ebenso selbständig gelöst hat, wie es entstanden ist. Arschloch-PC. Scheiss Trötzelkind (das Drecksding hat bei mir einen akuten Anfall von Koprolalie hervorgerufen). Nächstes Mal fliegt er echt zum Fenster raus!

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.

PHP und LDAP

^ v M ><
Ich weiss ja echt nicht, was die PHP-Entwickler geritten hat, als sie ihre Anbindung an LDAP zusammengefrickelt (oh ja!) haben:

Wenn Daten aus dem LDAP-Verzeichnis ausgelesen werden, erfolgt die Rückgabe als Array. Sämtliche Keys des Arrays sind in Kleinbuchstaben geschrieben. Möchte man aber Daten ins LDAP-Verzeichnis schreiben, müssen die Array-Keys Gross-/Kleinschreibung berücksichtigen. Und nur die wenigsten Keys sollten dann reine Kleinbuchstabenketten sein.

Die Fehlermeldungen sind absolut nichtssagend und teilweise falsch. Wenn PHP rumschreit "Value array must have consecutive indices 0, 1,", dann muss das mitnichten bedeuten, dass die Indices nicht konsekutiv sind. Es kann auch einfach heissen, dass die Array-Keys nicht die Gross-/Kleinschreibeordnung einhalten. Es kann aber auch sein, dass ein Array-Feld leer ist.

Oder ganz kurz gesagt: AAAAAAAAAAAAAAAARGH!!!

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

Defektes USV, Teil 2

^ v M ><
Nach einem Telefonat mit dem Support haben wir das USV geöffnet. Ein Feld der Zerstörung hat sich uns präsentiert:


SollIst


Die Ursache liegt vermutlich an dauerhaft zu hoher Temperatur. Offensichtlich reicht die Klimaanlage in unserem Serverraum doch nicht aus.

Defektes USV

^ v M ><
Meine Pechsträhne mit Servern reisst nicht ab. Gestern ist eines der beiden USVs (unterbrechungsfreie Stromversorgung... quasi eine Batterie für Server) im Serverraum meines Arbeitgebers abgeraucht.

Was ich daraus lerne? Wenn der apcupsd meldet,
UPS needs battery replacement NOW

, dann ist damit nicht etwa in "sobald die Ersatzbatterie bestellt und geliefert wurde und danach keiner mehr den Server braucht[1]" gemeint, sondern GENAU JETZT SOFORT!

Rund eine Woche nach der ersten Meldung durfte ich nämlich feststellen, dass die Server nicht mehr ansprechbar waren. Da ich sowieso an diesem Tag (es war der gestrige Samstag) die Batterie ersetzen wollte, konnte ich mich grad drum kümmern. Die Feststellung im Serverraum: Das USV war aus, die Server waren aus, das USV liess sich nicht mehr einschalten und die Batterie kann nicht mehr entfernt werden, da sie aufgebläht ist! So viel zum Thema "unterbrechungsfrei". Na ist ja super... Das Gerät ist übrigens erst gut 2 Jahre alt und ein Profi-Teil eines renommierten, professionellen Herstellers. Wenigstens war das Timing des Ausfalls gut: Samstag, wenige Stunden bevor ich mich eh rangesetzt hätte. Nun ja, dann wird halt ein Fachmann bestellt, der sich darum kümmern soll. Garantie ist immerhin noch drauf.

ad [1]: Vor dem Ersetzen der Batterie fahr ich die Server runter, schalte das USV aus und trenne es vom Strom. Zwar müsste sich die Batterie auch im laufenden Betrieb ersetzen lasse. Aber bei Dingen, die so viel Strom führen, dass sie nicht nur töten können, sondern auch noch Schmerzen bereiten bis man tot ist, bin ich lieber doppelt und dreifach vorsichtig.

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...

Hint File für Cesidian Root

^ v M ><
Das hier ist nur interessant für Betreiber von DNS-Servern mit einem Hang zum Alternativen :-)

Nachdem bekannt wurde, dass ORSN auf Ende Jahr abgeschaltet würde, habe ich mich auf die Suche nach einem alternativen Rootserver-Netz gemacht. Bislang erscheint mir nur Cesidian Root ein halbwegs tauglicher Ersatz, obwohl die Betreiber sogar mir etwas freakig vorkommen. ORSN war richtig professionell, da kommen die anderen schlicht nicht mit.

Cesidian Root bietet jedoch kein Hint-File für die einfache Integration in seinen Nameserver an. Daher musste ich selbst Hand anlegen und selbst eins verfassen:

. 3600000 NS a-root.cesidio.net.
a-root.cesidio.net. 3600000 A 78.47.115.194
. 3600000 NS b-root.cesidio.net.
b-root.cesidio.net. 3600000 A 78.47.115.197
. 3600000 NS c-root.cesidio.net.
c-root.cesidio.net. 3600000 A 24.129.114.64
. 3600000 NS d-root.cesidio.net.
d-root.cesidio.net. 3600000 A 66.92.233.14
. 3600000 NS e-root.cesidio.net.
e-root.cesidio.net. 3600000 A 66.92.233.130
. 3600000 NS f-root.cesidio.net.
f-root.cesidio.net. 3600000 A 89.238.64.147
. 3600000 NS g-root.cesidio.net.
g-root.cesidio.net. 3600000 A 80.239.207.176


Ich empfehle jedoch, Cesidian Root nicht als alleiniges DNS-Root einzutragen. Es ist wohl besser, wenn man das Hint-File des ICANN-DNS-Netzwerks um mein Hint-File für Cesidian Root ergänzt.

Gedanken zur Serversicherheit

^ v M ><
Nachdem der Server wieder (fast) vollständig läuft und ich nun zwei Tage lang Doku (woraus ich das eine oder andere gelungene Howto veröffentlichen werde) geschrieben habe, fasse ich hier ein paar Gedanken zu Serversicherheit zusammen. Wir haben nun extrem viel Arbeit in die Sicherung des Systems gesteckt. Vermutlich haben wir einige Dinge richtig paranoid abgesichert. Aber irgendwie ging es zumindest mir mit der Zeit so, dass ich nur schon das theoretische Maximum an Möglichkeiten ausschöpfen wollte. Quasi eine akademische Suche nach Serversicherheit.


  • Sicherheit ist ein Prozess, kein Zustand. Nur während Δt=0 ist es ein Zustand!

  • Ein sicheres System verwenden. Dazu gehört, dass das System sicher designt wurde, dass Updates leicht einzuspielen sind und dass es vom Hersteller auf lange Frist unterstützt wird.

  • Virtualisierung nutzen, dadurch können Dienste getrennt werden. Wird eine virtuelle Maschine befallen, kann sie einfach ersetzt werden. Virtuelle Maschinen lassen sich leicht backuppen. VMWare bietet ausserdem mit nonpersistenten virtuellen Festplatten eine Möglichkeit, sämtliche Änderungen an einem Dateisystem mit einem Neustart zurückzusetzen.

  • chroot nutzen! Insbesondere besonders exponierte Dienste gehören in ein chroot. Natürlich nutzt ein chroot nur dann, wenn es sauber eingerichtet wird und der Dienst nicht mit root-Rechten läuft.

  • Dienste nutzen, die sicher designt wurden. Dazu gehört insbesondere, dass das Programm standardmässig root-Privilegien abgibt, auch wenn es z.B. privilegierte Ports nutzen will (da kann es einfach mit root-Rechten den Port öffnen und danach die Rechte abtreten).

  • Sicherheit aktiv prüfen. Dazu gehören automatisierte Tests wie rkhunter, logcheck oder auch Statusüberprüfung durch Nagios.

  • Restriktive Firewall. Es darf weder schädliches hinein noch unnötiges heraus. Neue Verbindungen soll das System idealerweise nur zu seinen Update-Servern öffnen dürfen.

  • Nur ein Minimum an Diensten betreiben. Und auch sonst möglichst wenig Software installieren.

  • Ausführliche und vollständige Dokumentation schreiben! Dazu gehört auch, dass jede Änderung am System sofort in der Doku nachzutragen ist, damit auch die anderen Admins wissen, was Sache ist.

  • Backups! Wenn denn doch etwas passiert, sind wenigstens die Anwenderdaten in Sicherheit.

  • Kommunikation mit Co-Admins und Kunden. Wer Daten auf dem Server hat, ist automatisch in den Sicherheitsprozess involviert.

  • Dass Passwörter lang und komplex sein müssen und nie im Klartext übertragen werden dürfen, brauch ich wohl kaum noch einmal zu wiederholen...