This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
für <pass>). Das Root-File-System muss und darf als einziges FS Pass 1 erhalten; andere FS können dagegen 2, 3, 4 ... oder 0 erhalten. Mit 0 lässt sich die automatische Prü- 0 1 0 0 0 0 0 0 0 2 0 2 0 3 0 3 0 0 0 0
74
Erste Schritte
1 2 fung durch fsck deaktivieren. Bei schwerer wiegenden Problemen wird fsck jedoch unabhängig von einem Pass-0-Eintrag dennoch gestartet. Möglicherweise wird das System dann auf einem Root-Login zur manuellen Fehlerbeseitigung bestehen und den Startvorgang unterbrechen. Weitere Hinweise zum Umgang mit dieser Problematik finden Sie in Abschnitt 4.13, Festplatte prüfen.
debian:~# cat /etc/fstab # /etc/fstab: static file # #
3 4 5
system information.
6
7 8 9 10 11
Nähere Informationen zu den einzelnen Optionen finden Sie in Tabelle 2.13. Beachten Sie, dass in unserem Beispiel die Ausführung von suExec (siehe Abschnitt 3.3, Apache) innerhalb von /home über die Optionen nosuid und noexec unterbunden wird. Falls Sie suExec nutzen möchten, ist die Partition, in der Skripte mit suExec eine andere User-ID erhalten sollen, unbedingt mit rw, exec, suid zu mounten.
12 13 14
Generell gilt: Lediglich die Root-Partition sollte ohne nodev gemountet werden. Die Option user hat auf einem Server nichts zu suchen, da kein User CDROM oder Floppy mounten muss. Schließlich wird bis auf den Admin beziehungsweise den Support des Dienstleisters niemand eine Floppy oder CDROM einlegen können. Darüber hinaus empfiehlt es sich, errors=remount-ro auf /usr sowie unter Debian und SUSE ebenfalls auf /etc und /var anzuwenden. Für /tmp empfiehlt sich dagegen errors=continue. Besonders vorsichtige Administratoren mounten die /usr-Partition lediglich read-only (ro). Um neue Software zu installieren oder Sicherheits-Updates einzuspielen, müssen Sie /usr jedoch im rw-Modus remounten. Das funktioniert glücklicherweise mit mount -o remount rw /mountpoint auch im laufenden Betrieb. Falls Sie die Root-Partition von read-only auf read-write remounten möchten, müssen Sie zusätzlich die Option -n übergeben, da mount sonst
Wichtige Systemprogramme in der Übersicht
75
vor dem Remounten auf /etc/mstab schreibenden Zugriff nehmen möchte, was aufgrund des read-only-Status des Mediums zwangsweise fehlschlagen wird. In /etc/fstab definierte Geräte können über den Mountpoint bequem mit mount/mountpoint eingebunden werden. Root kann auch ohne entsprechende /etc/fstab-Einträge beliebig Devices einhängen. Dies geschieht ganz einfach über mount /dev/devicename /foo/mountpoint. Falls das FS von /dev/devicename nicht korrekt erkannt werden sollte, können Sie es über die Option -t zusätzlich angeben. Möchten Sie von den Voreinstellungen abweichen, können Sie die gewünschten Mount-Optionen von Tabelle 2.12 nach Angabe von -o auflisten. Um ein FS auszuhängen können Sie umount /mountpoint verwenden. Mount-Option
Bedeutung
rw | ro
Read-write (les- und schreibbar) | read-only (nur lesbar).
errors=[opt] (Linux)
opt steuert Verhalten im Fehlerfall. Mit continue wird das FS lediglich als fehlerhaft markiert, aber der Mount-Vorgang fortgesetzt. Remount-ro mountet ein als fehlerhaft erkanntes FS im read-onlyModus, und über panic lässt sich ein sofortiger Halt des Systems erzwingen. Beachten Sie, dass fsck-Prüfungen in den Startskripten Ihres Systems continue übergehen und das Filesystem »selbstständig« ro- für eine fsck-Prüfung mounten können.
[no]suid
Ignoriert (nosuid) oder erlaubt Nutzung des suid-Bits.
[no]exec
Gestattet oder verbietet (noexec) die Ausführung von Programmen in der jeweiligen Partition.
[no]dev
Gestattet oder verbietet die Nutzung von Gerätedateien.
[no]auto
Legt fest, ob das FS beim Systemstart automatisch eingebunden werden soll (auto) oder nicht (noauto). Selbstverständlich ist auto auf jedes FS, das direkt mit dem System zusammenhängt, anzuwenden. Deshalb wird diese Option auch in der Voreinstellung verwendet.
[no]user
Erlaubt oder verbietet es unprivilegierten Accounts, das angegebene FS zu (u)mounten.
usrquota,grpquota
Mountet das FS mit Quota-Support. Usrquota, grpquota kann kombiniert angegeben werden.
defaults (Linux)
rw, suid, dev, exec, auto, nouser und async.
Voreinstellungen in OpenBSD
Ob rw, ro oder sw, ist immer anzugeben. Wenn keine weiteren Optionen übergeben werden, mountet OpenBSD das ffs mit: dev,suid,exec,auto und nouser.
sw | pri=42 (Linux)
Das Swap FS ist mit der Option sw (unter Linux ebenfalls als pri=42) zu mounten.
Tabelle 2.12 Die wichtigsten Mount-Optionen für /etc/fstab
76
Erste Schritte
1 2 2.3.9
Das UNIX-Rechtesystem (chmod, chown, chgrp)
3
Unter UNIX stehen für jede Datei drei Zugriffsmodelle zur Verfügung: User (Eigentümer), Group und Others. Für jede Gruppe können Lese-, Schreib- und Ausführrechte einzeln gesetzt werden. Hierzu können Sie den alphabetischen oder oktalen Modus verwenden:
4 5
chmod u=rwx,g=x,o= foo chmod 710 foo
6
Beide Methoden würden die Zugriffsrechte von foo auf Lese-, Schreib- und Ausführbarkeit für den Eigentümer sowie Ausführrechte für die Gruppe setzen. Alle anderen User, die der Gruppe nicht angehören, die der Datei zugewiesen ist, können foo weder lesen noch schreiben oder ausführen. Da der oktale Modus wesentlich schneller zu schreiben ist, lohnt es sich, die notwendigen Zahlenkürzel zu lernen.
7 8 9
Weil sich hinter dem oktalen Modus ein schlüssiges System verbirgt, ist dies einfacher, als es auf den ersten Blick scheinen mag. Um das Ausführrecht mit dem Leserecht zu kombinieren, müssen einfach die Werte 1 (Ausführrecht) und 4 (Leserecht) addiert werden. Dieses Prinzip setzt sich konsequent fort, so dass Sie lediglich die Oktalwerte für Ausführrecht (1), Schreibrecht (2), Leserecht (4), Sticky-Bit (1), Set-GID (2) und Set-UID(4) kennen müssen, um sämtliche Zugriffsmodi definieren zu können.
10 11 12 13
Die Syntax des Oktal-Modus lautet: chmod [x]ugo foo. [x] Steht für die Zusatzoption, u für User, g für Group und o für Others.
14 Bedeutung
Oktal
Alphabetisch
Ausführbar
1
x
Schreibbar
2
w
Lesbar
4
r
Ausführ- und schreibbar
3
xw
Ausführ- und lesbar
5
rx
Schreib- und lesbar
6
rw
Ausführ-, les- und schreibbar
7
rwx
Zusatzoptionen
Oktal
Alphanumerisch
Sticky-Bit
1
o+t
Tabelle 2.13 Alle chmod-Optionen im oktalen und alphanumerischen Modus in der Übersicht
Wichtige Systemprogramme in der Übersicht
77
Bedeutung
Oktal
Alphabetisch
SGID
2
g+s
SUID
4
u+s
Sticky und SGID
3
o+t,g+s
Sticky und SUID
5
o+t,u+s
Sticky, SUID und SGID
7
o+t,u+s,g+s
Tabelle 2.13 Alle chmod-Optionen im oktalen und alphanumerischen Modus in der Übersicht (Forts.)
Die Rechte einer Datei können über ls -l /foo ausgegeben werden. Ein t am Ende steht für ein gesetztes Sticky-Bit:
linbook:~ # ls -lds /tmp drwxrwxrwt 38 root root
4096 May 31 16:15 /tmp
Beachten Sie, dass es sich um ein kleines t und kein großes T handelt. Ein großes T würde darauf hinweisen, dass zwar das Sticky-Bit gesetzt ist, aber die Gruppe Others kein Ausführrecht besitzt. Beachten Sie, dass das Sticky-Bit nur sinnvoll ist, wenn Others Schreibrecht besitzt (siehe den folgenden Abschnitt Das Sticky-Bit). Das Gleiche gilt auch für SUID oder SGID. Ist das Bit richtig gesetzt, wird ein kleines »s« ausgegeben. Falls jedoch »S« großgeschrieben dargestellt wird, fehlt das Ausführrecht beim Eigentümer (SUID) beziehungsweise bei der Gruppe (SGID):
linbook:~ # chmod 2740 unsinn ; ls -l unsinn -rwxr-S--1 root root 4 Dec 13 19:16 unsinn linbook:~ # chmod g+x unsinn ; ls -l unsinn -rwxr-s--1 root root 4 Dec 13 19:16 unsinn Beachten Sie, dass der alphabetische Modus sehr gut geeignet ist, um einzelne Rechte hinzuzufügen (g+x) oder zu entziehen (g-x). Das Sticky-Bit Mit dem Sticky-Bit kann das Modell der Zugriffsrechte innerhalb eines Ordners und seiner Unterverzeichnisse zu einem Sondermodus geändert werden, in dem es – völlig unabhängig von den tatsächlich gesetzten Zugriffsrechten – lediglich dem Eigentümer gestattet ist, Dateien zu löschen. Allerdings ist das Auslesen und Ändern von bestehenden Dateien bei lasch gesetzten Zugriffsrechten dennoch möglich:
78
Erste Schritte
1 2 user@linbook:/tmp> ls -l beispiel.sticky -rw-rw-rw- 1 root root 5 Mai 31 16:52 beispiel.sticky user@linbook:/tmp> rm beispiel.sticky rm: Entfernen (unlink) von "beispiel.sticky" nicht möglich:\ Die Operation ist nicht erlaubt user@linbook:/tmp> echo "Test" > beispiel.sticky user@linbook:/tmp> cat beispiel.sticky Test
3 4 5 6
Vielleicht fragen Sie sich, wofür das Sticky-Bit überhaupt gut sein soll, wenn Dateien einfach von jedermann geändert werden können. Nun, dies trifft nur bei fehlerhaften Zugriffsrechten zu:
7 8
user@linbook:/tmp> su root -c "chmod 644 beispiel.sticky" Password: user@linbook:/tmp> cat beispiel.sticky Test user@linbook:/tmp> echo "bla" > beispiel.sticky bash: beispiel.sticky: Permission denied
9 10 11
Das /tmp-Verzeichnis ist das beste Beispiel für ein sinnvolles Sticky-Bit: Temporäre Dateien sollten von jedem Account angelegt werden dürfen. Durch das Sticky-Bit ist es möglich, Others-Schreibrechte auf einen Ordner zu erteilen, ohne dass jedermann die Möglichkeit erhält, Dateien nach Belieben zu löschen. Dies ist äußerst kritisch, da es allen ermöglicht, eine bestehende Konfigurationsdatei durch eine andere zu ersetzen. Hat der User Leserechte, kann er die Datei über einen Zwischenschritt sogar nach Belieben ändern:
12 13 14
linbook:~ # mkdir /nonsticky ; chmod 777 /nonsticky linbook:~ # echo "test" > /nonsticky/rootfile && su - user user@linbook:~> cd /nonsticky/ user@linbook:/nonsticky> ls -l rootfile -rw-r--r-1 root root 5 Mai 31 17:04 rootfile user@linbook:/nonsticky> echo "changed" > rootfile bash: rootfile: Permission denied user@linbook:/nonsticky> chmod 666 rootfile chmod: Beim Setzen der Zugriffsrechte für "rootfile": \ Die Operation ist nicht erlaubt user@linbook:/nonsticky> cat rootfile > roottmp user@linbook:/nonsticky> rm rootfile rm: schreibgeschützte Datei "rootfile" entfernen? yes user@linbook:/nonsticky> mv roottmp rootfile ; ls –l
Wichtige Systemprogramme in der Übersicht
79
insgesamt 4 -rw-r--r--
1 user users
5 Mai 31 17:05 rootfile
Lokale Nutzer könnten somit einen erfolgreichen Angriff starten, wenn rootfile eine bedeutende Konfigurationsdatei wäre. Sobald user das Ziel seiner Bemühungen erreicht hat, könnte er rootfile löschen und so seine Spuren obendrein verwischen. SGID- und SUID-Bit Über das SGID- beziehungsweise SUID-Bit werden Programmaufrufe nicht mit der GID oder UID des aufrufenden Nutzers, sondern mit der des Eigentümers beziehungsweise der Gruppe der Datei ausgeführt. Damit dies klappt, ist es natürlich notwendig, dass die Datei auch vom Eigentümer beziehungsweise der Gruppe ausführbar ist. Weiterhin gilt es zu beachten, dass SGID- oder SUID-Bit-Programme ein gewisses Sicherheitsrisiko bergen: Einem lokalen Angreifer könnte es beispielsweise über einen Buffer-Overflow gelingen, dem Programm beliebige Kommandos zur Ausführung zu übergeben. Deshalb sollten Sie es möglichst vermeiden, SUID- oder GID-Bits auf Root zu setzen. Weitere Informationen hierzu finden Sie in Abschnitt 5.6.3, Zugriffsrechte. Ändern von Eigentümer und Gruppe einer Datei Das Ändern des Eigentümers kann nur mit Root-Rechten erfolgen. Gehört ein Nutzer mehreren Gruppen an, kann er jedoch die Gruppe, die einer Datei zugewiesen ist, ändern:
chgrp groupname foo weist die Gruppe groupname der Datei foo zu. Wer ein Verzeichnis mit sämtlichen Unterverzeichnissen und allen enthaltenen Dateien einer anderen Gruppe zuweisen möchte, muss chgrp mit der zusätzlichen Option -R (rekursiv) aufrufen: chgrp -R groupname /foodir. Die Änderung des Eigentümers kann durch Root im gleichen Stil durchgeführt werden. chown username foo setzt den Eigentümer der Datei foo auf username. Um sämtliche Dateien eines Verzeichnisses dem Nutzer username zu überschreiben, ist ebenfalls die Option -R (rekursiv) zu übergeben: chown -R
username /foodir.
80
Erste Schritte
1 2 2.3.10 User-Verwaltung (useradd, userdel, usermod, groupadd, groupdel)
3
Die User-Verwaltung findet über die Dateien /etc/passwd und /etc/shadow statt. Die Datei /etc/passwd enthält unter anderem Angaben zu UID und GID (der Hauptgruppe), in /etc/groups sind alle Gruppen aufgeführt. Wurden einem Nutzer Untergruppen zugewiesen, so ist der User-Name in /etc/groups hinter den ihm zugewiesenen Untergruppen aufgeführt. Da /etc/passwd für jedermann lesbar sein muss, wurden die Passwörter in die Datei /etc/shadow ausgelagert.
4 5 6
Die Dreiteilung der Nutzerverwaltung erschwert die manuelle Bearbeitung der Konfigurationsdateien. Glücklicherweise stehen zur User- und Gruppenverwaltung gelungene Administrations-Tools bereit. Deshalb müssen Sie sich nicht näher mit der Formatierung und dem Aufbau von /etc/passwd, /etc/shadow und /etc/groups auseinander setzen.
7 8 9
Anlegen eines neuen Accounts (useradd, passwd, chpasswd)
10
Useradd -m -p * foo genügt, um den Nutzer foo mitsamt seinem Home-Verzeichnis anzulegen, -p * setzt ein ungültiges Passwort in /etc/shadow. Solange der Account kein gültiges Passwort erhalten hat, ist ein Login mit diesem Nutzernamen nicht möglich. Falls Sie diese Option vergessen, wäre – je nach /etc/ssh/sshd.conf (PermitEmptyPasswords)- und /etc/login.defs (PASS_MIN_ LEN)-Konfiguration – ein Login über schlichtes Drücken der Entertaste möglich!
11 12 13
Falls Sie versehentlich useradd ohne -p * aufrufen und ein Passwort gar nicht erwünscht ist, da es sich beispielsweise um einen System-Account handelt, müssen Sie den Account aus Sicherheitsgründen nicht löschen. Sie können /etc/shadow ebenfalls manuell editieren und foo:!: durch foo:*: ersetzen. Da die Wildcard als verschlüsseltes Passwort betrachtet wird, es aber nicht möglich ist, diesen Wert durch Eingabe irgendeiner Kombination zu erreichen, ist ein Login somit nicht möglich. Noch schneller als die manuelle Bearbeitung von /etc/shadow geht es übrigens mit echo "foo:*" | chpasswd -e. Option
Bedeutung
-m
Legt automatisch ein Home-Verzeichnis für den Nutzer im Verzeichnis /home ab und überschreibt es.
-p *
Setzt ein ungültiges Passwort, um Login über schlichtes Drücken der Return-Taste auszuschließen. Unbedingt verwenden!
14
Tabelle 2.14 Wissenswerte Optionen zum Befehl useradd
Wichtige Systemprogramme in der Übersicht
81
Option
Bedeutung
-g foo
Teilt dem anzulegenden Account die Hauptgruppe foo anstelle der Standardgruppe zu (meist users).
-G foo1,foo2
Weist dem anzulegenden Account die Untergruppen foo1 und foo2 zusätzlich zur Hauptgruppe zu.
-s /bin/shell
Definiert /bin/shell als Standard-Shell für den neuen Account. Falls es sich lediglich um einen systeminternen Account handelt oder ein Login ohnehin nicht erlaubt wird, sollten Sie als Shell /bin/false verwenden.
-u x
Verwendet als UID den numerischen Wert x.
-d /homedir
Legt als Heimatverzeichnis /homedir fest.
Tabelle 2.14 Wissenswerte Optionen zum Befehl useradd (Forts.)
Das Nutzerpasswort ist über passwd [username] zu definieren. Wird username nicht angegeben, kann das Passwort des eigenen Accounts geändert werden. Somit dürfen und sollten Nutzer ihr Passwort nach dem ersten Login selbst ändern. Lediglich Root ist es gestattet, das Passwort aller Accounts zu ändern. Falls Sie das Anlegen von Nutzer-Accounts automatisieren möchten, können Sie auf echo "username:passwortname" | chpasswd zurückgreifen. Ändern eines bestehenden Accounts (usermod) Über usermod ist es Root gestattet, die Daten eines Accounts nachträglich anzupassen. Die Syntax lautet usermod [optionen] username. Die Optionen sind mit denen von useradd identisch. Über die zusätzliche Option -l ist es darüber hinaus möglich, den Nutzernamen zu ändern:
usermod –l neuerUsername –s /bin/false alterusername Löschen eines bestehenden Accounts (userdel) Mit userdel username wird der Account username gelöscht. Allerdings bleiben seine Dateien weiterhin erhalten. Mit der zusätzlichen Option -r werden neben dem Home-Verzeichnis auch die Mail-Daten gelöscht. Achten Sie darauf, dass username somit sämtliche E-Mails vor der Anwendung von -r abholt. Weiterhin sollten Sie find /* -u UID ausführen, um sämtliche Dateien des Nutzers, die außerhalb seines Home- oder Mail-Verzeichnisses gespeichert wurden, zu lokalisieren und gegebenenfalls zu löschen.
2.3.11 sudo Sollen einem Account Root-Rechte lediglich zur Nutzung einzelner Befehle eingeräumt werden, ist es keine gute Idee, gleich das Root-Password offen zu legen
82
Erste Schritte
1 2 oder einen weiteren UID-0-Account anzulegen. Besser ist es, auf das sudo-Paket zuzugreifen, über das unprivilegierte Benutzer zur Ausführung bestimmter Befehle in die Root-Rolle schlüpfen dürfen.
3 4
Allerdings gab es in der Vergangenheit immer wieder Sicherheitslücken in sudo, die einen Missbrauch (vollständige Root-Rechte) ermöglichten. Weiterhin ist es in der Regel auf einem Webserver nicht notwendig, anderen Root-Rechte für einzelne Befehle einzuräumen. Deshalb sollten Sie nach Möglichkeit auf sudo verzichten.
5 6
Die Installation von sudo ist dank der für Ihr System bereits vorbereiteten Pakete völlig unproblematisch. Um einem Account Root-Rechte für bestimmte Befehle zu gewähren, ist /etc/sudoers wie folgt zu editieren:
7 8
username ALL=/pfad/programm1,/pfad/programm2
9
Beachten Sie, dass der vollständige Pfad zum Programm anzugeben ist (siehe whereis programmname). Das ALL vor =programmliste erlaubt den Aufruf von sudo generell. Alternativ könnten Sie explizit $HOSTNAME des Servers verwenden. Um Befehle einzuschränken, können Sie eine Liste der erlaubten Optionen übergeben:
10 11
foo ALL=/usr/sbin/rcapache status,/usr/sbin/rcapache restart
12
foo könnte jetzt den Status des Apache-Webservers überprüfen und dürfte sogar einen Restart nach Änderungen an der Konfigurationsdatei vornehmen. Dennoch ist ihm ein Stoppen des Webservers untersagt:
13 14
foo@linbook:~> sudo /usr/sbin/rcapache stop Sorry, user foo is not allowed to execute \ '/usr/sbin/rcapache stop' as root on linbook. foo@linbook:~> sudo /usr/sbin/rcapache restart Shutting down httpd done Starting httpd [ PERL PHP4 ]
2.4
Shell-Crashkurs
Ob Sie Ihren Server nun remote über SSH oder direkt über eine lokale Konsole administrieren; die Befehlseingabe und Ausführung erfolgt stets über die Shell. Interessant ist, dass Sie weder in Linux noch unter BSD an eine feste Shell gebunden sind. Die Shell ist selbst ein Programm, das durch einfachen Aufruf gestartet und genutzt werden kann:
linux:/# /bin/tcsh linux:/# echo $shell
Shell-Crashkurs
83
/bin/tcsh linux:/# exit exit linux:/# echo $SHELL /bin/bash Mit einem Wechsel der Shell verändert sich häufig auch die Ausgabe vor dem Cursor-Prompt. In unserem Beispiel wird von /bin/tcsh der Hostname (Linux) unterstrichen ausgegeben. Die Standard-Shell, die nach einem Benutzer-Login aufgerufen wird, kann darüber hinaus von Root flexibel festgelegt werden (siehe usermod in Abschnitt 2.3.10, User-Verwaltung (useradd, userdel, usermod, groupadd, groupdel)). Zwischen den einzelnen Shells gibt es massive Unterschiede, die in der Regel erst in umfangreichen Shell-Skripten und Features (wie zum Beispiel der Suche nach Befehlszeilenmuster vorangegangener Anweisungen) deutlich werden.
2.4.1
Automatische Dateinamenerweiterung
Eines der meistgenutzten Shell-Features ist die automatische Dateinamenerweiterung. Geben Sie einmal shu gefolgt von der Taste (ÿ__) ein, und schon ergänzt die Shell das Wort shu zum Befehl shutdown. Dies funktioniert sowohl mit Verzeichnissen oder herkömmlichen Dateien als auch mit Systembefehlen. Falls zu einem Muster mehrere Ergänzungsmöglichkeiten vorhanden sind, wird das Muster, soweit möglich, ergänzt. Nach einem Doppelklick auf die Taste (ÿ__) werden die Auswahlmöglichkeiten angezeigt:
linux:/# linux:/# linux:/# killme1
touch killme1 killme2 rm /k-(TAB)-(TAB) rm /killme killme2
Allerdings arbeitet die Textergänzung unter Verwendung eines deutschen Tastatur-Layouts in der OpenBSD-3.6-Standard-Shell csh nicht korrekt. Sie sollten deshalb überlegen, die ksh zu verwenden oder die Bash zu installieren und mit usermod (wie in Abschnitt 2.3.10, User-Verwaltung (useradd, userdel, usermod, groupadd, groupdel), beschrieben) als Standard-Shell festzulegen. Die folgenden Beispiele beziehen sich ebenfalls auf die Linux-Standard-Shell Bash.
2.4.2
Befehlshistorie
In der Praxis ist die Befehlshistorie ebenso unverzichtbar wie die Erweiterung der Dateinamen. Drücken Sie auf die Cursor-Pfeiltaste nach oben beziehungsweise nach unten, um durch die interne Liste der zuvor eingegebenen Befehle
84
Erste Schritte
1 2 zu browsen. Mit dieser Methode können Tippfehler ohne langwierige Neueingabe bequem korrigiert und umfangreichere Befehlsfolgen schnell erneut aufgerufen werden.
3 4
Es wird häufig vorkommen, dass Sie längere Zeit mit der Shell arbeiten und demzufolge sehr viele Befehle in der History-Datei landen. Häufig wäre es schneller, die Befehlszeile nochmals einzugeben, als sie über die History-Funktion herauszusuchen. Ich spreche von wäre, weil die Shell es gestattet, Befehlszeilen über einen Suchbegriff herauszufiltern.
5 6
Drücken Sie hierzu (Strg) + (R) und geben Sie den Suchbegriff ein. Um beispielsweise durch sämtliche Befehlszeilen zur Erstellung von Tar-Archiven zu browsen, müssen Sie (Strg) + (R) drücken und tar eingeben. Danach können Sie durch wiederholte Eingabe von (Strg) + (R) durch sämtliche Befehlszeilen blättern, die tar enthalten.
7 8 9
(reverse-i-search)'tar': tar -cjf outbox_archiv.tar.bz2 \ outbox && echo "outbox archiviert" & 2.4.3
10
Cursor-Befehle
11
Wer längere Befehlsfolgen in eine einzelne Zeile übernimmt, wird neben der History-Funktion zudem von den Cursor-Befehlen profitieren. Tabelle 2.15 verrät sämtliche Tastenkürzel, um die Position des Cursors zu steuern, einzelne Wörter zu vertauschen oder gar zu löschen. Die bash-Manpage verrät weitere nützliche Kniffe, die in der Praxis jedoch eher selten benötigt werden.
12 13 14
Kürzel
Beschreibung
(Strg) + (E)
Cursor ans Zeilenende.
(Strg) + (A)
Cursor an den Zeilenanfang.
(Alt) + (B)
Cursor ein Wort zurück.
(Alt) + (F)
Cursor ein Wort vor.
(Alt) + (T)
Vertauscht die ersten beiden Wörter vor der aktuellen Cursor-Position.
(Alt) + (D)
Löscht alle Ziffern ab Cursor-Position bis zum Wortende. Steht der Cursor vor dem Wortanfang, wird das nächste Wort vollständig entfernt. Alternativ könnte der Cursor auf dem ersten Buchstaben stehen.
(Esc) + (æ___)
Entfernt sämtliche Zeichen ab Cursorposition bis zum nächsten Wortanfang. Steht der Cursor vor einem Wortende, aber auf einem Leerzeichen, werden sämtliche Leerzeichen sowie das erste vor dem Cursor stehende Wort gelöscht.
Tabelle 2.15 Tastenkürzel für Cursor-Befehle in der Übersicht
Shell-Crashkurs
85
Kürzel
Beschreibung
(Strg) + (K)
Löscht alle eingegebenen Zeichen ab Cursorposition bis zum Zeilenende.
(Strg) + (U)
Löscht sämtliche Zeichen vom Zeilenanfang bis zur Cursorposition.
(Strg) + (C)
Verwirft die gesamte Eingabe.
(Strg) + (D)
Löscht Zeichen vor der Cursor-Position.
Tabelle 2.15 Tastenkürzel für Cursor-Befehle in der Übersicht (Forts.)
2.4.4 Umleitung von Ein- und Ausgabe Ein Großteil der berüchtigten Flexibilität von UNIX-Shells liegt in der variablen Ein- und Ausgabebehandlung begründet. So können Sie die Standardeingabe (stdin = 0) beispielsweise anstatt sie über die Tastatur einzugeben aus einer Datei auslesen und einem Programm direkt übergeben. Oder, anders herum, die Ausgabe eines Programms (stdout = 1 und stderr = 2) in eine Datei umleiten, anstatt dieses auf dem Bildschirm auszugeben. Spielen Sie folgende Beispiele nach:
user@linbook:~/test> test user@linbook:~/test> user@linbook:~/test> user@linbook:~/test> test Anhängen user@linbook:~/test> user@linbook:~/test> Überschreiben
echo "test" echo "test" > testdatei echo "Anhängen" >> testdatei cat testdatei
echo "Überschreiben" > testdatei cat testdatei
Beachten Sie, dass durch > foo die Bildschirmausgabe in die Datei foo umgeleitet wird. Falls foo noch nicht existiert, wird die Datei angelegt. Falls foo bereits existieren sollte, wird der alte Inhalt der Datei durch den neuen ersetzt. Um den alten Inhalt beizubehalten und foo lediglich um weitere Zeilen zu ergänzen, ist >> foo zu verwenden. Die Standard-Fehlerausgabe stderr können Sie mit 2> beziehungsweise 2>> abfangen:
user@linbook:~/test> unsinn 2> errormeldung user@linbook:~/test> blödsinn 2>> errormeldung user@linbook:~/test> cat errormeldung
86
Erste Schritte
1 2 bash: unsinn: command not found bash: blödsinn: command not found
3
Möchten Sie neben stdout auch stderr umleiten, könnten Sie zu 2>> errormeldung 1>> errormeldung greifen. Allerdings geht es mit einem kleinen Trick auch einfacher:
4 5
user@linbook:~/test> echo "blödsinn" >> errormeldung 2>&1 user@linbook:~/test> cat errormeldung bash: unsinn: command not found bash: blödsinn: command not found blödsinn
6 7
Über 2>&1 wird stderr an stdout geleitet. Unsere Fehlermeldung wird demnach anstelle von stderr auf stdout ausgegeben. Da stdout jedoch in die Datei Errormeldung geleitet wird, erscheinen weder Fehler noch Standardausgaben auf dem Bildschirm, sondern alle Ausgaben werden in Errormeldung gesichert. Natürlich ist es mit 1>&2 oder >&2 möglich, stdout an stderr zu leiten: echo
8 9 10
"blödsinn" 2>> errormeldung >&2. Selbstverständlich ist neben dem schreibenden Zugriff auch eine lesende Umleitung mit < möglich. Allerdings wird diese Umleitung nicht von allen Programmen unterstützt:
11 12
user@linbook:~/test> more < errormeldung bash: unsinn: command not found bash: blödsinn: command not found blödsinn user@linbook:~/test> echo < errormeldung
13 14
user@linbook:~/test> Da die Shell auch in der Lage ist, durch Substitution Befehle vor Ausführung des eigentlichen Kommandos zu interpretieren, ist dieses Verhalten nicht weiter problematisch, sondern kann ganz einfach umgangen werden:
> echo 'more < rechenaufgabe'" = "'bc < rechenaufgabe' 5+8 = 13 Zunächst werden die beiden in Backquotes verschachtelten Befehle ausgeführt. Drücken Sie dazu die Shift-Taste zusammen mit der Taste rechts neben dem ß, um den Gravis zu erhalten. Danach wird das Ergebnis über einen simplen Echo-Befehl auf stdout ausgegeben. Lassen Sie sich von dieser kleinen Spielerei nicht täuschen. Die Kommandosubstitution ist äußerst leistungsfähig. Viele administrative Aufgaben lassen sich erst durch sie vernünftig lösen.
Shell-Crashkurs
87
Über die so genannte Pipe ist es zudem möglich, Ausgaben nicht in Dateien, sondern direkt an beliebige Programme zu übergeben:
user@linbook:~/test> echo 5+8 | bc 13 2.4.5
Ausführung als Hintergrundprozess
Die Ausführung aufwändiger Befehle, wie das Erstellen eines Tar-Archivs, kann die aktuelle Shell durchaus für mehrere Minuten blockieren. Um in der Zwischenzeit ohne erneuten Login weiterarbeiten zu können, ist es möglich, Befehle über ein abschließendes & als Hintergrundprozess zu starten:
user@linbook:~/test> tar -czf testdatei.tgz testdatei & macvampi@linbook:~/test> tar -czf archiv.tgz errormeldung & [1] 5719 macvampi@linbook:~/test> ps -x | grep tgz 5719 pts/10 R 0:00 tar -czf archiv.tgz errormeldung macvampi@linbook:~/test> [1]+ Done tar -czf archiv.tgz errormeldung Beachten Sie, dass beim Start eines Hintergrundprozesses die Nummer des von Ihnen gestarteten Hintergrundprozesses [1] zusammen mit der PID 5719 des Prozesses ausgegeben wird. Sobald der Prozess abgeschlossen wurde, wird die interne Hintergrundprozessnummer, zusammen mit der Meldung done und dem aufgerufenen Befehl, ausgegeben.
2.4.6 Befehlsverknüpfungen Sie können mehrere Befehle, durch ein Semikolon getrennt, in einer einzelnen Zeile notieren:
user@linbook:~/test> fetchmail; mutt In unserem Beispiel wird nach Ausführung des Befehls fetchmail das Programm mutt gestartet. Beachten Sie, dass der zweite Befehlsaufruf auch dann ausgeführt wird, wenn der erste fehlschlägt:
> tar -xf bla; echo "echo wird auf jeden Fall ausgeführt" tar: bla: Cannot open: Datei oder Verzeichnis nicht gefunden tar: Error is not recoverable: exiting now echo wird auf jeden Fall ausgeführt Sie können die Ausführung der folgenden Befehle aber vom Status der vorangegangenen Befehle abhängig machen. Mit dem doppelten & werden nachfol-
88
Erste Schritte
1 2 gende Befehle nur ausgeführt, wenn der vorangegangene Befehl erfolgreich abgeschlossen wurde. Eine doppelte Pipe bewirkt das Gegenteil: Befehle werden nur ausgeführt, wenn der vorangegangene Befehl fehlgeschlagen ist:
3 4
user@linbook:~/test> tar -xf bla 2> /dev/null || echo \ "Fehler: Datei nicht gefunden" Fehler: Datei nicht gefunden user@linbook:~/test> tar -cf bla.tar errormeldung && echo \ "Archiv konnte erzeugt werden" Archiv konnte erzeugt werden user@linbook:~/test> tar -cf bla.tar errormeldu && echo \ "Archiv konnte erzeugt werden" tar: errormeldu: Cannot stat: Datei oder Verzeichnis \ nicht gefunden tar: Fehler beim Beenden, verursacht durch \ vorhergehende Fehler. user@linbook:~/test> tar -xf bla.tar 2> /dev/null || echo \ "Fehler: Datei nicht gefunden" user@linbook:~/test>
5 6 7 8 9 10 11
Wer eine Programmiersprache erlernt hat, wird sich unweigerlich an If-ThenElse-Bedingungen erinnert fühlen. Tatsächlich ist die Shell weit mehr als eine flexible Schnittstelle zwischen Benutzereingabe und Systemausgabe. Es stehen neben Schleifen auch Bedingungen und mathematische Funktionen bereit. Shell-Befehle können in eine Datei geschrieben und – wie in einer anderen Skriptsprache – bei Dateiaufruf direkt von der Shell interpretiert werden. Wie dies im Detail funktioniert, erfahren Sie in Abschnitt 4.7.1, Einführung in die Shell-Programmierung.
2.4.7
12 13 14
Setzen von Umgebungsvariablen
Umgebungsvariablen stehen in der Shell unmittelbar zur Verfügung, um beispielsweise bei Eingabe eines Befehls automatisch das richtige Programm aufzurufen (der Pfad wird also automatisch um den richtigen Wert von $PATH erweitert). Unter OpenBSD sind in der Voreinstellung jedoch wichtige Standardbefehlsverzeichnisse nicht in $PATH enthalten, und wenn Sie unter Linux eigene Programme kompilieren, kann es sich als sinnvoll erweisen, $PATH um die Verzeichnisse der selbst kompilierten Binärdateien zu erweitern.
Shell-Crashkurs
89
Für eine temporäre Erweiterung von $PATH genügt:
user@linbook:~> PATH='echo $PATH:/bin/bla:/bin/blub' user@linbook:~> echo $PATH /usr/bin:/bin:/usr/sbin:/bin/bla:/bin/blub Beachten Sie, dass die einzelnen Pfadangaben über einen Doppelpunkt zu trennen sind. Möchten Sie den Wert von $PATH dauerhaft ändern, ist die Datei ~/.profile entsprechend anzupassen. Tipp In ~/.profile können Sie beliebige Umgebungsvariablen definieren und so beispielsweise die von Tomcat benötigte Variable $JAVA_HOME setzen.
2.4.8 Definition von Aliasen für Befehle Wie Umgebungsvariablen können auch Aliase für Befehle in ~/.profile definiert werden. Das Schöne ist, dass Sie mit Aliasen auch komplexere Vorgänge zusammenfassen oder einfach anstelle des gefährlichen shutdown -r now (hoffentlich verwenden Sie hier nie versehentlich die Option -h!) eine beliebige andere Bezeichnung wie beispielsweise Neustart verwenden können:
alias Neustart='shutdown -r now' Sie können den Alias temporär (direkt in der Konsole) oder in ~/.profile dauerhaft festlegen.
2.5
Der Bootloader
Jedes Betriebssystem benötigt einen Bootloader, der beispielsweise den Kernel lädt und das Root-Filesystem initialisiert. Die Linux-Bootloader lilo und grub sind darüber hinaus in der Lage, sich über das Bootable-Flag der Festplattenpartition hinwegzusetzen (bei Installation im Master-Boot-Record) und können neben Linux zudem Windows oder OpenBSD booten. Der OpenBSD-Bootloader boot ist dagegen lediglich in der Lage, das RootDevice und den Kernel des zu bootenden OpenBSD-Systems zu ändern. Wenn Sie neben OpenBSD auch Windows betreiben möchten, müssen Sie das Bootable-Flag der Festplatte mit fdisk auf die Windows-Partition setzen. In Win 95, 98 und ME steht fdisk.exe über die Eingabeaufforderung bereit, um das Bootable-Flag unter Windows wieder auf die OpenBSD-Partition zurückzusetzen. Wer eine andere Windows-Version nutzt, sollte einen Blick auf den Ranish-Partition-Manager werfen (http://www.ranish.com/part/), der über eine Boot-
90
Erste Schritte
1 2 Diskette sehr schnell die Änderung des Bootable-Flags ermöglicht und auf der CD zum Buch (windows/partbeta.zip) enthalten ist.
3
2.5.1
4
LILO – Generic Bootloader for Linux
Die Konfigurationsdatei lilo.conf des Linux-Loaders finden Sie im Verzeichnis /etc Ihrer Distribution. Um neben Linux, Windows oder OpenBSD booten zu können, müssen Sie lediglich die entsprechende Partition als other angeben und ein Label definieren:
5 6
other=/dev/hda1 label="Windows(hda1)" other=/dev/hda2 label="OpenBSD(hda2)"
7
Lilo übernimmt das Booten einer other-Partition nicht selbst, sondern initialisiert den auf der Partition installierten Bootloader, der dann das eigentliche Booten des jeweiligen Systems übernimmt. Die Konfiguration zum Start eines Linux-Systems ist etwas komplexer, da hier neben Root-Device auch Kernel und gegebenenfalls initrd zusätzlich anzugeben sind:
9
8
10 11
root = /dev/hda5 ... image=/vmlinuz label="Woody(2.2.20)" image=/usr/src/linux-2.6.10/arch/i386/boot/bzImage label="Woody(MyKern)"
12 13 14
Beachten Sie, dass als Image der kompilierte Kernel als Pfadangabe des aktuellen Systems anzugeben ist. Weiterhin wurde /dev/hda5 als globale Variable für das zu bootende Linux-System festgelegt. Dieser Wert ist für das Booten einer »anderen« Linux-Installation natürlich zu überschreiben:
image = /suse/boot/vmlinuz label = SUSE initrd = /suse/boot/initrd ... Als Root-Device ist zwingend /dev/devicename zu verwenden. Damit KernelImage und initrd korrekt von Lilo eingebunden werden können, muss das FS der »anderen« Linux-Installation entsprechend eingehängt sein. Dies ist jedoch schnell vergessen. Glücklicherweise macht Sie Lilo beim Schreiben des neuen MBR auf Probleme sofort aufmerksam:
Der Bootloader
91
debian:/# lilo Added Woody(2.2.20) * Added Woody(MyKern) Added Windows(hda1) Added OpenBSD(hda2) Fatal: open /suse/boot/vmlinuz
No such file or directory
Das Sternchen hinter Woody(2.2.20) symbolisiert, dass dieses System als Default gestartet wird, sobald der Countdown (timeout) abgelaufen ist und am Bootprompt kein anderes System ausgewählt wurde. Da Sie beim Start Ihres Servers kaum Gelegenheit haben werden, am Bootprompt irgendetwas auszuwählen, sollten Sie nicht nur das Default-System auf die gewünschte LinuxInstallation (und Kernel-Version) setzen, sondern auch den Timeout erheblich verkürzen:
prompt timeout=20 default="Woody(MyKern)" Der Timeout wird in Dezisekunden angegeben. Das heißt, bei 20 Dezisekunden werden lediglich zwei Sekunden (20*0.1) bis zum Start des Default-Systems gewartet. Denken Sie daran, dass Änderungen innerhalb von /etc/lilo.conf erst beim nächsten Aufruf von Lilo in den MBR geschrieben und erst dann aktiv werden. Tipp Haben Sie ein Rettungssystem oder eine andere Linux-Installation gestartet, dann können Sie den Default am besten umstellen, indem Sie die »ursprüngliche« Linux-Partition mounten und chroot /mountpoint aufrufen. Nun ist /etc/lilo.conf zu editieren und Lilo aufzurufen. Vergessen Sie nicht, vor dem shutdown -r now den Chroot-Käfig mit exit zu verlassen!
2.5.2
Boot (OpenBSD) und Bootable-Flag (fdisk)
Falls Sie den Linux-Bootloader Lilo nicht nutzen, um OpenBSD zu starten, müssen Sie die OpenBSD-Partition mit dem Bootable-Flag in fdisk kennzeichnen:
# fdisk -e wd0 Enter 'help' for information fdisk: 1> p #: id ... [ start: size ] ----------------------------------------------------0: ... [ 63: 1606437 ] Win95 FAT32L
92
Erste Schritte
1 2 1: ... [ 9639000: 6426000 ] OpenBSD *2: ... [ 1606500: 8032500 ] unused 3: ... [ 16065000: 43969905 ] Extended LBA fdisk: 1> f 1 Partition 1 marked active. fdisk:*1> p #: id ... [ start: size ] ----------------------------------------------------0: ... [ 63: 1606437 ] Win95 FAT32L *1: ... [ 9639000: 6426000 ] OpenBSD 2: ... [ 1606500: 8032500 ] unused 3: ... [ 16065000: 43969905 ] Extended LBA fdisk:*1> q Writing current MBR to disk.
3 4 5 6 7 8 9
Beim nächsten Neustart wird von der mit Sternchen markierten OpenBSD-Partition gebootet. Hierzu wird Boot gestartet, das wiederum zunächst wd0a mountet und die Konfigurationsdatei /etc/boot.conf ausliest. In dieser wiederum können Sie die zu nutzende Root-Partition von wd0a auf eine beliebige andere Partition umstellen:
10 11
# cat /etc/boot.conf set device wd0d set image = /bsd set timeout = 2
12
Über Device wird die Root-Partition des zu startenden Systems angegeben. Falls Sie neben wd0a beispielsweise eine weitere OpenBSD-Installation unter wd0d aufgesetzt haben, wird diese über device wd0d gestartet. Beachten Sie, dass der Pfad zum Kernel-Image vom definierten Root-Device (/wd0d in unserem Beispiel) aus betrachtet anzugeben ist. Der Wert Timeout bestimmt die Wartezeit, die bis zum automatischen Booten verstreichen darf. Sie können die Werte mit set option wert ebenfalls direkt am Bootprompt eingeben. Die gleichzeitige Definition von device, image und timeout ist nicht möglich. Sie müssen für jeden Wert einen neuen Set-Befehl eingeben.
14
13
Hinweis: Falls Sie auf das in wd0a ursprünglich installierte OpenBSD erneut zurückgreifen möchten, müssen Sie die boot.conf von wd0a ändern. Wie eingangs erwähnt, wird vom OpenBSD-Bootloader immer wd0a gemountet, um /etc/boot.conf auszulesen. Das heißt, die /etc/boot.conf von /wd0d kann nicht berücksichtigt werden. Mounten Sie wd0a gegebenenfalls, um die Datei anpassen zu können:
Der Bootloader
93
# mkdir /wd0a # mount /dev/wd0a /wd0a # vi /wd0a/etc/boot.conf
2.6
Netzwerkeinstellungen und Konfiguration
Zunächst sollten Sie prüfen, ob Ihre Netzwerkkarte vom installierten Betriebssystem unterstützt wird (siehe Abschnitt 1.4.4, Hardware-Unterstützung). In einem OpenBSD-System wird die Netzwerkkarte bereits bei der Installation eingebunden. Falls dies hier nicht möglich ist, werden Sie die Karte auch nachträglich nicht initialisieren können und sich zunächst nach kompatibler Hardware umsehen müssen. Um den Server ans Internet anzubinden, sind im Wesentlichen drei Schritte notwendig: 1. Initialisierung der Netzwerkkarte, 2. Konfiguration des Routers und 3. Konfiguration eines Nameservers. Sämtliche Einstellungen lassen sich ohne Neustart vornehmen oder im laufenden Betrieb ändern. Sobald notwendige Konfigurationen erfolgreich abgeschlossen wurden, können Sie die einzelnen Schritte über ein eigenes Startskript in den Startprozess des Servers integrieren. Sie können zudem die systemspezifische Konfiguration Ihres Systems entsprechend anpassen. In Tabelle 2.16 finden Sie eine Übersicht über die für ein lokales Netz reservierten IP-Adressen mit zugehörigen Subnet-Masks. Lokale IP-Adressen werden übrigens im Internet nicht geroutet, weshalb Paketfilterregeln, die Ports für lokale Adressen öffnen, recht effektiv sind. Beachten Sie, dass lediglich Rechner, die im selben IP-Adressbereich liegen, ohne zusätzliches Routing direkt kommunizieren können. Das bedeutet, dass der Rechner 192.168.0.1 zwar direkt mit 192.168.0.255 kommunizieren kann, nicht aber mit 192.168.1.35 oder 10.0.0.3. IP-Adresse
Subnetmask
192.168.[0–255].[0–255]
255.255.255.0
172.[16–31].[0–255].[0–255]
255.255.0.0
10.[0–255] .[0–255] .[0–255]
255.0.0.0
Tabelle 2.16 Für lokale Netzwerke reservierte IP-Adressen werden im Internet nicht geroutet.
94
Erste Schritte
1 2 2.6.1
sipcalc macht die Bestimmung von IP-Adressen einfach
3
Die Ermittlung der Subnetmask oder von IPV6-Adressen ist zugegebenermaßen nicht trivial. Doch sipcalc nimmt Ihnen die Arbeit ab. Das Tool finden Sie auf der CD zum Buch sowie unter http://www.routemeister.net/projects/sipcalc/download.html. Die Installation ist mit ./configure && make && make install schnell erledigt und die Bedienung ebenso einfach:
4 5
debian:~/sipcalc-1.1.2# sipcalc 213.221.110.143 -[ipv4 : 213.221.110.143] - 0 [CIDR] Host address Host address (decimal) Host address (hex) Network address Network mask Network mask (bits) Network mask (hex) Broadcast address Cisco wildcard Addresses in network Network range
6 7
-
213.221.110.143 3588058767 D5DD6E8F 213.221.110.143 255.255.255.255 32 FFFFFFFF 213.221.110.143 0.0.0.0 1 213.221.110.143 - 213.221.110.143
8 9 10 11 12 13
Sipcalc bietet weitere Ausgabeformen, eine Liste aller Funktionen kann wie üblich mit der Option --help ausgegeben werden.
14 2.6.2
Konfiguration eines Netzwerk-Interfaces unter Linux
Wer unter Linux einen Standard-Kernel verwendet, wird zunächst mit modprobe treibername den Treiber der Netzwerkkarte laden müssen. Wurde ein Kernel selbst kompiliert und der Treiber statisch eingebunden, ist dieser Schritt weder notwendig noch möglich, da der Treiber bereits in den Kernel integriert ist. Tatsächlich generiert make modules modules_install lediglich als Module (M) gekennzeichnete Kernel-Erweiterungen. Statische Treiber werden also nicht als Modul erzeugt, um gesondert geladen werden zu können. Damit modprobe treibername nicht bei jedem Neustart zu übergeben ist, können Sie den Treibernamen unter SUSE direkt als eigene Zeile in /etc/modules.conf eintragen:
alias eth0 natsemi
Netzwerkeinstellungen und Konfiguration
95
Unter Debian ist /etc/modutils/aliases entsprechend zu editieren und der Befehl update-modules aufzurufen. Ifconfig Mit dem Laden des Treibers der Netzwerkkarte oder seiner direkten Integration als statische Kernel-Erweiterung ist es natürlich noch nicht getan: Nun müssen Sie das Netzwerk-Interface mit ifconfig initialisieren:
ifconfig eth0 192.168.0.81 up Wer mehr als eine Netzwerkkarte hat und die entsprechenden Treiber geladen hat, kann danach ifconfig eth1 192.168.0.34 up für die zweite Netzwerkkarte nutzen. Natürlich können Sie genauso problemlos eine dritte oder vierte Netzwerkkarte initialisieren. Hierbei kann ebenfalls der gleiche Kartentyp zum Einsatz kommen (es genügt, wenn der Treiber einmal geladen wurde). Möchten Sie einer Netzwerkkarte mehr als eine IP-Adresse zuweisen, ist nach dem Device-Namen :nr zu verwenden. Das heißt eth0:1 für die zweite IP-Adresse von eth0 oder eth0:2 für die dritte und so weiter. Ob die Initialisierung des/der Netzwerk-Interfaces funktioniert hat, können Sie ebenfalls mit ifconfig überprüfen:
linux:~ # ifconfig | grep in eth0 Link encap:Ethernet HWaddr 00:02:E3:22:A7:B0 inet addr:192.168.0.81 Bcast:192.168.0.255 \ Mask:255.255.255.0 inet6 addr: fe80::202:e3ff:fe22:a7b0/10 Scope:Link eth0:1 Link encap:Ethernet HWaddr 00:02:E3:22:A7:B0 inet addr:192.168.0.109 Bcast:192.168.0.255 \ Mask:255.255.255.0 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host lo ist das Loopback-Device, das gänzlich ohne Netzwerkkarte arbeitet und lediglich für die interne Prozesskommunikation zuständig ist. Beachten Sie, dass Broadcast- und Netmask-Adresse von ifconfig automatisch anhand der IPAdresse bestimmt wurden. Falls Sie sich bei der IP-Adresse eines Interfaces vertippt haben sollten, ist das Interface mit ifconfig eth0 down zu deaktivieren, bevor es erneut mit der richtigen Adresse initialisiert werden kann.
96
Erste Schritte
1 2 Um ifconfig nicht bei jedem Systemstart ausführen zu müssen oder über ein manuelles Startskript abzusetzen, finden Sie in den nächsten Abschnitten kurze Hinweise zu speziellen Konfigurationsdateien Ihrer Distribution.
3 4
Interface-Einstellungen unter Debian
5
Editieren Sie die Datei /etc/network/interfaces:
auto lo eth0 iface lo inet loopback iface eth0 inet static address 192.168.0.34 netmask 255.255.255.0 gateway 192.168.0.1
6 7 8
Beachten Sie, dass Address, Netmask und Gateway (siehe Gateway über route festlegen) jeweils in einer eigenen Zeile stehen müssen und nicht zusammen mit dem iface-Eintrag eine einzelne Zeile bilden dürfen. Weiterhin ist eth0 in die Auto-Zeile aufzunehmen, um bei einem Start- beziehungsweise Stopp-Prozess von /etc/init.d/networks berücksichtigt zu werden. Um zu testen, ob die Anpassungen korrekt arbeiten, ist selbstverständlich kein Neustart des Servers, sondern lediglich ein /etc/init.d/networks stop && /etc/init.d/networks start && ifconfig notwendig.
9 10 11 12
Interface-Einstellungen unter SUSE
13
Sie finden unter SUSE im Verzeichnis /etc/sysconfig/network die Datei ifcfg.template, die als ifcfg-eth0 zu speichern und anzupassen ist. Im Normalfall sollte bereits für jede Netzwerkkarte eine entsprechende ifcg-eth-Datei angelegt worden sein, die Sie jedoch auch nachträglich anpassen können.
14
Möchten Sie einem Netzwerk-Interface via Sysconfig eine zweite IP-Adresse zuweisen, können Sie die bestehende Datei, zum Beispiel ifcfg-eth0 als ifcfgeth0:1, duplizieren. In der neuen Datei ist Device (zum Beispiel DEVICE=eth0:1) und IPADDR entsprechend anzupassen. Nach einem rcnetwork restart können Sie über ifconfig prüfen, ob die zweite IP-Adresse wunschgemäß eingerichtet wurde. Gateway über route festlegen Ein Webserver ist zwangsläufig an einen Gateway (oder Router) angebunden, da der Server nicht als Einziger direkt am Backbone hängt. In einem LAN ist der Einsatz eines Routers ebenfalls notwendig, um sämtlichen Rechnern einen Zugang zum WWW über eine einzige Internetanbindung bereitzustellen. Mit
Netzwerkeinstellungen und Konfiguration
97
route add default gw 192.168.0.1 wird die IP-Adresse 192.168.0.1 als Router festgelegt. Falls dennoch keine Verbindung zum Internet hergestellt werden kann, ist wahrscheinlich ein anderer Gateway bereits als Default festgelegt (Ausgabe von route gekürzt um Flags, Metric ...):
linux:/ # route Kernel IP routing table Destination Gateway 192.168.0.0 * default 192.168.0.4 default 192.168.0.1
Genmask 255.255.255.0 0.0.0.0 0.0.0.0
In diesem Fall könnte der Gateway 192.168.0.1 nicht angesprochen werden, da lediglich der erste Eintrag (192.168.0.4) verwendet würde. Mit route del default gw 192.168.0.4 könnte der unsinnige Eintrag gelöscht werden. Um nicht bei jedem Neustart des Betriebssystems den route-Befehl erneut absetzen zu müssen, können Sie unter SUSE die Zeile
default 192.168.0.1 - in /etc/sysconfig/network/routes eintragen beziehungsweise einen vorhandenen Eintrag entsprechend anpassen. Sie können die Änderungen mit /etc/init.d/network restart testen. Die Gateway-Konfiguration ist in Debian mit den Interface-Einstellungen zusammengelegt worden. Die erste in /etc/network/interfaces eingetragene Gateway-Adresse wird als default gw verwendet (siehe Interface-Einstellungen unter Debian).
2.6.3
Konfiguration eines Netzwerk-Interfaces unter OpenBSD
Die Netzwerkkarten werden über /etc/hostname.* von /etc/netstart beim Systemstart initialisiert. Um IP-Adresse und Netmask der Netzwerkkarte zu ändern, müssen Sie deshalb /etc/hostname.interfacename editieren und danach sh /etc/netstart aufrufen.
# cat /etc/hostname.sis0 inet 192.168.0.34 255.255.255.0 NONE Ob die Netzwerkkarte korrekt initialisiert wurde, können Sie mit ifconfig interfacename überprüfen:
98
Erste Schritte
1 2 # ifconfig sis0 sis0: flags=8843
3 4 5 6 7
Möchten Sie einer Netzwerkkarte mehr als eine IP-Adresse zuweisen, können Sie dies über Aliase in /etc/hostname.interfacename erledigen:
8
# echo "inet alias 192.168.0.32 255.255.255.0" \ >> /etc/hostname.sis0 # sh /etc/netstart && ifconfig sis0 ... inet 192.168.0.34 netmask 0xffffff00 broadcast 192.168.0.255 inet 192.168.0.32 netmask 0xffffff00 broadcast 192.168.0.255
9 10 11
Gateway über route festlegen Überprüfen Sie mit route show, ob bereits ein Gateway gesetzt ist. Falls sich die IP-Adresse des Gateways geändert hat oder wenn Sie sich bei der Definition des Gateways während der Installation von OpenBSD vertippt haben, können Sie den Eintrag mit route delete löschen und mit add neu anlegen:
12
# route show Routing tables
14
13
Internet: Destination Gateway Flags default 192.168.0.36 UG ^C # route delete default 192.168.0.36 delete net default: gateway 192.168.0.36 # route add default 192.168.0.1 add net default: gateway 192.168.0.1 Damit der richtige Default-Gateway beim nächsten Start von OpenBSD automatisch eingestellt wird, ist er in /etc/mygate entsprechend anzupassen:
# cat /etc/mygate 192.168.0.1
Netzwerkeinstellungen und Konfiguration
99
2.6.4 Konfiguration eines Nameservers (unter Linux und OpenBSD) In UNIX-Systemen werden die in der Datei /etc/resolv.conf festgelegten Nameserver angesprochen, um einen Domain-Namen in eine IP-Adresse aufzulösen. Falls die Datei in Ihrem System nicht existieren sollte, können Sie /etc/resolv.conf einfach selbst anlegen. Der Inhalt sollte wie folgt aussehen:
nameserver 192.168.0.25 nameserver 192.168.0.1 Sie können bis zu drei Nameserver angeben. Falls der erste die gewünschte Adresse nicht auflösen kann, wird die Domain an den nächsten zur Auflösung gereicht. Dies ist vor allem in einem Unternehmen mit Intranet interessant, da so neben dem firmeneigenen Nameserver (der lediglich für interne Adressen wie buchhaltung.firma eingerichtet werden könnte) auch der des Zugangsproviders angesprochen werden kann. Hinweis Bei jeder aufzulösenden Domain sieht das System in /etc/resolv.conf nach, welche Nameserver bereitstehen. Änderungen an /etc/resolv.conf werden somit direkt verfügbar, ohne irgendeinen Dienst oder den gesamten Server neu starten zu müssen.
2.7
Manuelles Installieren (Kompilieren) von Programmen
Bevor Sie zur Installation eines im Quelltext bezogenen Programms schreiten, sollten Sie das Programmpaket zunächst in das Verzeichnis eines unprivilegierten Nutzers (beispielsweise /home/user/install) verschieben und mit su - user in die Haut dieses Users schlüpfen. In der Regel werden Sie das Programm als (komprimiertes) tar-Archiv bezogen haben und es zunächst mit dem richtigen Befehl (siehe Tabelle 2.16) entpacken müssen. Name
Befehl
Paket.tar.gz | paket.tgz
tar -xzf Paket.tar.gz | tar –xzf Paket.tgz
Paket.tar.bz2
tar -xjf Paket.tar.bz2
Paket.tar
tar -xf Paket.tar
Tabelle 2.17 Optionen zum Entpacken eines tar-Achivs. Weitere Informationen zu tar finden Sie im Abschnitt 4.8.6, Vollbackup mit tar.
100
Erste Schritte
1 2 Werfen Sie einen Blick auf ./configure --help | less. Falls die Anfrage mit »No such file or directory« quittiert wird, sollten Sie es mit
3
./config -–help | less
4
erneut versuchen. Manche Programmierer sehen keine Notwendigkeit darin, ein ./config[ure]-Skript für das von make aufgerufene Makefile vorzuschalten. In der Regel genügt dann
5
make ; su root –c "make install"
6
um das Programm zu installieren. Dennoch kann es nicht schaden, zuvor einen Blick auf das Makefile zu riskieren.
7
Manche Programme, wie beispielsweise der Apache-Webserver, erschlagen den Anwender mit einer Fülle von Installationsoptionen. Glücklicherweise müssen Sie ausschließlich die Optionen übernehmen, deren Auswirkung Sie erzielen möchten. Ein Beispiel: In der Voreinstellung von Apache wird mod_cgi eingebunden. Möchten Sie auf CGI verzichten, ist die in der Ausgabe ./configure --help aufgeführte Option --disable-cgi zu verwenden.
8 9 10 11
In der Regel werden Sie sich jedoch zunächst eingehender mit dem Programm beschäftigen müssen, es also in Betrieb nehmen und Erfahrungen sammeln, bevor Sie einzelne Optionen über ./configure übergeben oder manuelle Änderungen direkt im Makefile vornehmen können.
2.7.1
12 13
Sollen Installationspfade angepasst werden?
14
Eine Stilfrage ist die Änderung von Installationspfaden. Üblicherweise werden selbst kompilierte Programme nach Aufruf von make install in das Verzeichnis /usr/local/bin oder /usr/local/sbin installiert. Die Konfigurationsdateien befinden sich anstelle von /etc meist im Verzeichnis /usr/local/etc. Durch die Anpassung der Installationspfade an Ihr System stellen Sie einerseits ein einheitliches »Layout« sicher. Auf der anderen Seite bietet die Trennung zwischen installierten Systempaketen und selbst kompilierten Programmen den Vorteil, beispielsweise neben der »offiziellen« Paketinstallation des Webservers Ihres Systems einen eigenen Apache kompilieren zu können. Diesen können Sie in Ruhe austesten und konfigurieren. Bei größeren Problemen kann unmittelbar auf die ursprüngliche Installation zurückgegriffen werden, da Konfigurations- und Programmdateien an anderen Orten als die der »eigenen« Installation abgelegt sind. In meinen Augen überwiegt dieser Vorteil die teils verwirrende Situation, zwei »identische« Programmversionen im selben System »zu betreiben«. Dies kann zu ärgerlichen
Manuelles Installieren (Kompilieren) von Programmen
101
Situationen führen, wie beispielsweise »weshalb werden die Änderungen in /etc/programm_config nicht berücksichtigt« oder dem versehentlichen Start der »offiziellen« anstelle der »eigenen« Programmversion. Andererseits wissen Sie ja jetzt, dass selbst kompilierte Programme ihre Konfigurationsdateien in der Regel in /usr/local/etc ablegen. Sie können dies im Zweifelsfall mit grep überprüfen:
$ cd /home/user/install/programmsource && grep etc Makefile sysconfdir = ${prefix}/etc $ grep ^prefix Makefile prefix = /usr/local Ob ein Programm tatsächlich mit ./configure && make && su -c "make install" root kompiliert werden kann, hängt noch von einem weiteren Faktor ab: den Abhängigkeiten. Tatsächlich enthalten die wenigsten Programmpakete alle benötigten Systembibliotheken. Häufig werden nur Standardbibliotheken eingebunden, die bereits in einer minimalen Server-Installation vorhanden sind. Deshalb werden Sie in der Regel nicht mit Fehlermeldungen konfrontiert. Früher oder später werden Sie dennoch auf eine fehlende Bibliothek stoßen. Falls eine Suche innerhalb der zu Ihrem System verfügbaren Pakete das gesuchte Puzzleteil nicht zu Tage fördert und Sie zudem entsprechende Entwicklungspakete (-devel-Paket) bereits eingespielt haben, sollten Sie sich im READ- oder INSTALLATION-File des Tarballs nach Informationen zu den benötigten Programmen oder Bibliotheken umsehen. Häufig finden sich auf der jeweiligen Projekt-Website hilfreiche Informationen zu den Installationsvoraussetzungen. In der Regel ist der Bezug fehlender Komponenten jedoch einfacher, als die Fehlermeldungen von ./configure oder make erwarten lassen. Ein Beispiel für fehlende dependencies (PHP mit zlib):
checking for ZLIB support... yes checking if the location of \ ZLIB install directory is defined... no configure: error: Cannot find libz debian:/home/download/# apt-get install zlib* Reading Package Lists... Done Building Dependency Tree... Done ... The following NEW packages will be installed: ldso libc5 libc5-altdev libcompress-zlib-perl libnkf-ruby \ libruby libzlib-ruby zlib-bin zlib1 zlib1-altdev \
102
Erste Schritte
1 2 zlib1g-dev zlibc ... 0 packages upgraded, 12 newly installed, \ 0 to remove and 0 not upgraded. Need to get 2593kB/2613kB of archives. \ After unpacking 9642kB will be used. Do you want to continue? [Y/n] n Abort. debian:/home/download/# apt-get install zlib1g-dev
3 4 5 6 7
Erläuterung: In der Regel werden zur manuellen Kompilierung stets die Developer-Pakete (dev) benötigt. Da apt zum Suchwort zlib jedoch ganze zwölf Pakete findet, wurde die Installation abgebrochen und lediglich zlib1g-dev bezogen. Tatsächlich war dies das einzige Paket, das zur Kompilierung von PHP mit der zlib auf meinem Debian-Basissystem fehlte.
2.7.2
8 9
Sicherheitsaspekte
10
Überprüfen Sie nach der Programminstallation unbedingt die Zugriffsrechte der Dateien. Häufig werden insbesondere für die Konfigurationsdateien zu lasche Zugriffsrechte gesetzt. Ein globales Readable mag dem Open-SourceGedanken gerecht werden, ist aber aus Sicherheitsgründen zu vermeiden. Im Normalfall benötigt lediglich der User, mit dem das Programm letztlich ausgeführt wird, Zugriff auf die Konfigurationsdateien.
11 12 13
Weiterhin sollten Sie sich angewöhnen, für jedes installierte Programm, das nicht zwingend mit Root-Rechten laufen muss, einen unprivilegierten NutzerAccount anzulegen und das Programm über su nutzeraccount -c "/usr/local/bin/programmname" zu starten.
2.7.3
14
Überprüfen der Vertrauenswürdigkeit von Programmpaketen
In der Vergangenheit ist es Angreifern gelungen, in vermeintlich vertrauenswürdige Software-Pakete eine Backdoor einzuschmuggeln – sogar OpenSSH war hiervon bereits betroffen. Dummerweise werden Sie jedoch nicht am Einspielen von Sicherheits-Updates oder an einer gelegentlichen manuellen Tarball-Installation vorbeikommen. Die Wahrscheinlichkeit, dass ein Angreifer Ihren Server über eine noch nicht geschlossene Sicherheitslücke knackt, ist deutlich größer, als dass Sie durch Einspielen eines Updates eine Backdoor öffnen.
Manuelles Installieren (Kompilieren) von Programmen
103
Glücklicherweise werden zu den meisten Programmen und Sicherheits-Patches gleich mehrere Downloadserver betrieben. Über die so genannten Prüfsummendateien (meist mit md5sum erzeugt) können Sie die Integrität eines Downloads verifizieren. Hierzu sollten Sie mindestens zwei Prüfsummendateien von alternativen FTP-Servern zu dem zu installierenden Paket (die Versionsnummer muss natürlich identisch sein) beziehen. Danach sind zunächst die Prüfsummendateien zu vergleichen, und bei Übereinstimmung können Sie die Originaldatei überprüfen. Ein Angreifer hätte somit alle drei von Ihnen genutzten Server knacken müssen, um die Änderungen am Code verbergen zu können. In der Praxis sind die folgenden Schritte durchzuführen:
user@debian:~$ wget http://www.apache.org/dist\ /httpd/httpd-2.0.46.tar.gz.md5 user@debian:~$ wget ftp://ftp.apache.de/mirrors\ /dev.apache.org/dist/httpd/httpd-2.0.46.tar.gz.md5 user@debian:~$ diff httpd-2.0.46.tar.gz.md5 \ httpd-2.0.46.tar.gz.md5.1 Stimmen die Dateien überein, wird von diff keine Ausgabe erzeugt:
user@debian:~$ cat httpd-2.0.46.tar.gz.md5 \ httpd-2.0.46.tar.gz.md5.1 MD5(httpd-2.0.46.tar.gz)= ff682f82f0808eb01df60824d959ebe8 MD5(httpd-2.0.46.tar.gz)= ff682f82f0808eb01df60824d959ebe8 Nun gilt es, die eigentliche Datei zu beziehen, die md5sum zu bilden sowie mit unseren zuvor bezogenen md5sum-Dateien zu vergleichen:
user@debian:~$ wget http://ftp.leo.org/pub/comp/general\ /infosys/www/daemons/apache/dist/httpd/httpd-2.0.46.tar.gz user@debian:~$ md5sum httpd-2.0.46.tar.gz | cut \ -d " " -f1 > md5sum.tmp user@debian:~$ cut -d " " -f2 < httpd-2.0.46.tar.gz.md5 \ > orig.md5sum user@debian:~$ diff md5sum.tmp orig.md5sum In diesem Beispiel konnte die Integrität von httpd-2.0.46.tar.gz erfolgreich bestätigt werden. Sie werden feststellen, dass dies eigentlich immer der Fall ist. Es bedarf großer Disziplin, die Prüfsummen für jede einzelne Datei zu beziehen. Leider steht der Mehraufwand in keinem Verhältnis zum (sichtbaren) Nutzen, weshalb viele Administratoren einfach aus Bequemlichkeit auf einen Prüf-
104
Erste Schritte
1 2 summenvergleich verzichten. Ganz egal, was andere auch behaupten mögen, für Ihren Webserver ist jeder Aufwand, der die Sicherheit erhöht, Arbeit wert. Verzichten Sie deshalb nicht darauf, Prüfsummen zu vergleichen!
3 4
Leider ist es trotz Prüfsummenvergleich möglich, dass durch direkten Angriff auf das CVS-Repository eines Open-Source-Projektes (in der Regel arbeiten mehrere Entwickler über das Internet an ein und demselben Code) unbemerkt eine Backdoor eingeschmuggelt wird. Wenn Sie sehr vorsichtig sein wollen und es sich nicht um ein Sicherheits-Update handelt, sollten Sie deshalb eine Woche abwarten, bevor Sie das bereits bezogene Programm installieren. Falls tatsächlich bösartiger Code in der Datei enthalten sein sollte, so wird dies in der Regel innerhalb von zwei bis vier Tagen nach Veröffentlichung bemerkt und publiziert werden.
2.7.4
5 6 7 8
Deinstallation
9
Die saubere Deinstallation eines selbst kompilierten Programms kann eine aufwändige Angelegenheit sein. Zunächst sollten Sie in das src-Verzeichnis /home/user/install/paketname wechseln und hoffen, dass ein make uninstall sämtliche Programmpakete deinstalliert.
10 11
Falls Sie Pech haben, wird make uninstall nicht funktionieren. In diesem Fall ist die erneute Kompilierung des Programms notwendig. Dies mag sich paradox anhören, aber durch ein erneutes su root -c "make install > /root/install.out" können Sie in der Protokolldatei install.out sämtliche installierten Dateien auflisten. Danach ist install.out in einem Editor zu bearbeiten. Dabei sollten Sie darauf achten, lediglich Programmdateien zu löschen und nicht etwa ein Verzeichnis, das auch andere Dateien enthält (wie beispielsweise /usr/local/bin). Am besten ignorieren Sie sämtliche mkinstalldirs-Zeilen, wenn Sie nicht sicher sind, dass in diesem Verzeichnis keine programmfremden Dateien abgelegt wurden.
12 13 14
Beispielsweise sollten Sie die Zeilen
/bin/sh ./mkinstalldirs /usr/local/bin /usr/bin/install -c pen /usr/local/bin/pen /usr/bin/install -c mergelogs /usr/local/bin/mergelogs ... /bin/sh ./mkinstalldirs /usr/local/man/man1 /usr/bin/install -c -m 644 ./pen.1 \ /usr/local/man/man1/pen.1 /usr/bin/install -c -m 644 ./mergelogs.1 \
Manuelles Installieren (Kompilieren) von Programmen
105
/usr/local/man/man1/mergelogs.1 ... zur sauberen Deinstallation wie folgt anpassen:
/usr/local/bin/pen /usr/local/bin/mergelogs ... /usr/local/man/man1/pen.1 /usr/local/man/man1/mergelogs.1 ... Sobald die Vorbereitungen abgeschlossen sind, können Sie mit rm 'cat /root/install.out' alle Dateien wunschgemäß entfernen.
2.8
Startskripte
Beim Start des Betriebssystems gilt es, nicht nur elementare Systembestandteile zu initialisieren, sondern auch grundlegende Serversoftware wie SSH-, Weboder Mailserver automatisch zu starten. Da sich Linux am Startprozess von System V orientiert, bestehen erhebliche Unterschiede zwischen den Startskripten von Linux und OpenBSD.
2.8.1
Linux
Durch die Bemühungen der Linux-Standard-Base ist der Startprozess der verschiedenen Linux-Distributionen so gut wie auf einen gemeinsamen Nenner gebracht worden. So bestehen zwischen Debian und SUSE lediglich kleinere Unterschiede hinsichtlich der vorbereiteten Templates zur Erstellung eigener Startskripte und Tools wie insmod. Diese sollen dabei helfen, Runlevel-Links schneller und bequemer zu erstellen. Tatsächlich brauchen Sie sich keine Gedanken um ein formschönes Startskript zu machen, das einheitlich formatiert und in grüner Farbe über den erfolgreichen Start eines Dienstes informiert. Immerhin werden Sie kaum vor Ort sein, um über einen Monitor den Startvorgang überwachen zu können. Das Verzeichnis /etc/init.d/ dient einheitlich zur Ablage von Skripten, die über /etc/init.d/scriptname [start||stop] den Programmstart mit den Standardoptionen für Logfile-Verzeichnis, User-Namen und andere übernehmen oder das saubere Beenden eines Daemons beim Shutdown des Servers sicherstellen.
106
Erste Schritte
1 2 Falls im Tarball des selbst kompilierten Programms kein passendes init.d-Startskript mitgeliefert wurde, können Sie ein eigenes Startskript erstellen:
3
#!/bin/sh case "$1" in start) echo -n "Starte Programmname" /pfad/programm –optionen ;; stop) echo -n "Stoppe Programmname" killall programmname ;; *) echo "Fehler: /etc/init.d/scriptname [start||stop]" esac;
4 5 6 7 8
Passen Sie die Programmaufrufe Ihren Wünschen entsprechend an und speichern Sie das Skript im Verzeichnis /etc/init.d/ mit den Rechten 755. Weitere Informationen zur Programmierung von Shell-Skripten finden Sie in Abschnitt 4.7.1, Einführung in die Shell-Programmierung.
9 10
Bevor Sie das fertige Startskript aktivieren, sollten Sie die Funktionstüchtigkeit mit /etc/init.d/scriptname start sowie /etc/init.d/scriptname stop überprüfen. Funktioniert alles reibungslos, können Sie sich der Erstellung von Start- und Stopplinks zuwenden.
11 12
Damit Sie die Startlinks im richtigen Runlevel anlegen, sollten Sie mit runlevel in Erfahrung bringen, in welchem Runlevel Ihr Server-System arbeitet:
13
debian:~# runlevel N 2
14
Werfen Sie einen Blick in das Verzeichnis der Start- und Stopplinks des Runlevels N 2:
debian:~# ls -l /etc/rc2.d/ total 0 lrwxrwxrwx 1 root root 18 May 22 S10sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 15 May 22 S11klogd -> ../init.d/klogd ... lrwxrwxrwx 1 root root 13 May 22 S20ssh -> ../init.d/ssh ...
2003 \ 2003 \
2003 \
Startskripte
107
lrwxrwxrwx
1 root root 14 May 22 S89cron -> ../init.d/cron
2003 \
In den Runlevels wird lediglich mit »ordinären Softlinks« auf das jeweilige Startskript des aufzurufenden Programms verwiesen. Beachten Sie, dass die Reihenfolge des Linkaufrufs über den Dateinamen festgelegt wird; S10sysklogd wird somit vor S89cron aufgerufen. Beachten Sie außerdem, dass S20ssh gestartet wird. Richten Sie die Reihenfolge nach der Wichtigkeit des Dienstes. Die Paketfilter-Konfiguration sollte beispielsweise direkt nach den Netzwerkeinstellungen initialisiert werden. Daemons wie Logsurfer können dagegen durchaus zuletzt gestartet werden. Da die Stopplinks in umgekehrter Reihenfolge aufgerufen werden (zunächst werden die Links mit der höchsten Knr verfolgt), können Sie die Stopplinks mit derselben Nummer wie die Startlinks setzen:
debian:~# cd /etc/rc2.d/ debian:/etc/rc2.d# ln -s ../init.d/scriptname S92programm debian:/etc/rc2.d# ln -s ../init.d/scriptname K92programm debian:/etc/rc2.d# ls -l ./*92* lrwxrwxrwx 1 root root 19 Mai 31 17:05 \ ./K92programm -> ../init.d/scriptname lrwxrwxrwx 1 root root 19 Mai 31 17:05 \ ./S92programm -> ../init.d/scriptname 2.8.2
OpenBSD
Die Steuerung für den automatischen Start der offiziellen OpenBSD-Pakete ist sehr bequem über /etc/rc.conf zu erledigen:
httpd_flags=NO # for normal use: "" (or "-DSSL" \ after reading ssl(8)) Um den Apache-Webserver bei jedem Neustart automatisch zu aktivieren, müssen Sie lediglich NO durch "" ersetzen. Die empfohlenen Startoptionen stehen in der Regel direkt nach dem Kommentarzeichen. Auch die Aktivierung eigener Programme ist im Handumdrehen erledigt. Fügen Sie einfach am Ende des gewünschten Startbefehls /etc/rc.local ein. Mit grundlegenden Kenntnissen in der Shell-Programmierung (siehe Abschnitt 4.7.1) können Sie natürlich ebenfalls /etc/rc.conf nutzen, um Startvariablen für das »neue« Programm festzulegen, und den Startbefehl in /etc/rc.local lediglich dann ausführen, wenn flags nicht auf NO sitzen sowie hier angegebene Parameter beim Programmstart übergeben werden.
108
Erste Schritte
1 2
2.9
Der eigene Kernel
3
Für einen Webserver empfiehlt es sich, nicht nur einen unveränderten Original-Kernel zu verwenden, sondern diesen ausschließlich mit den tatsächlich benötigten Features zu kompilieren. Auf multimediale Gimmicks wie Grafik und Sound können Sie ebenso gut verzichten wie auf die Unterstützung sämtlicher Netzwerkkarten oder Infrarot. Weiterhin sollte der Kernel für Ihren Prozessor optimiert werden.
4 5 6
2.9.1
Linux
7
Die offiziellen Kernel-Quellen finden Sie unter http://www.kernel.org. In Ihrer Linux-Distribution sollten ebenfalls mehrere Kernel-Varianten enthalten sein, die jedoch vom Distributor mit mehr oder weniger sinnvollen Anpassungen (patches) versehen worden sind.
8 9
Der aktuelle 2.6er-Kernel ist aufgrund seines überarbeiteten Schedulers, besserer Speicherverwaltung, UML oder ACL der 2.4er-Entwicklungslinie vorzuziehen. In fast allen Praxistests erledigt der Kernel 2.6 gegenüber dem 2.4er die gleichen Aufgaben deutlich schneller. Lediglich bei der Auslieferung von statischen HTML-Seiten kann der 2.4er mithalten und je nach Dateisystem und Features den Kernel 2.6 sogar überholen. Für den 2.4er spricht, dass einige Erweiterungen noch nicht in den offiziellen Kernel-Quellcode eingeflossen sind – wie beispielsweise linux-vserver (siehe Kapitel 6, Linux-VServer).
10 11 12 13
In beiden Fällen ist es glücklicherweise mit make menuconfig (einzugeben im entsprechenden Quellverzeichnis – also dem entpackten Tar-Archiv) möglich, die gewünschten make-Optionen bequem auszuwählen. Im Folgenden möchte ich lediglich auf empfehlenswerte Abweichungen von den Standardeinstellungen eingehen. Es ist jedoch sinnvoll, selbst in den Optionen zu stöbern. Zu den meisten Punkten können Sie über die Taste (?) interessante und wissenswerte Informationen abrufen.
14
Um eine Option zu aktivieren, als Modul zu kompilieren oder zu deaktivieren, genügt ein Klick auf die Taste (____). Nicht jede Komponente kann als Modul oder fester Kernel-Bestandteil kompiliert werden. Einerseits empfiehlt sich eine Kompilierung als Modul (M), um den eigentlichen Kernel klein zu halten. Andererseits sollten Sie wesentliche Bestandteile wie Paketfilter oder DeviceSupport grundsätzlich statisch (*) einkompilieren.
Der eigene Kernel
109
Abbildung 2.5 make menuconfig vereinfacht die Auswahl der richtigen ./configure-Optionen erheblich.
Kompilierung von 2.4.29 왘 Loadable module support
Die Möglichkeit, Module nachträglich in den Kernel zu laden, ist beispielsweise nützlich, um eine Boot-Diskette zu erstellen – selbst wenn Sie in Ihren Kernel nur das Notwendigste einkompilieren, wird dies durchaus den Rahmen einer Boot-Diskette sprengen. Für Ihren Webserver sollten Sie lieber ausschließlich statische Module verwenden und enable loadable module support deaktiveren! Dies erhöht die Sicherheit ungemein, da es Angreifern nicht möglich ist, durch Hinzuladen von Kernel-Modulen Unheil anzurichten. Prominentes Beispiel für eine solchen Exploit ist der Ptrace-Bug (siehe Abschnitt 5.6.5, Informationen zu /proc, insmod und dem Ptrace-Bug). 왘 Processor-Typ and Features
Über den ersten Punkt Processor Family kann der Kernel auf einen bestimmten Prozessor optimiert werden. Obwohl ein Athlon-Prozessor ebenfalls mit einem für Intel kompilierten Kernel arbeitet, ist es für eine optimale Performance nötig, den Prozessor-Typ des eigenen Systems (nicht des Testsystems, sondern des Server-Systems) auszuwählen. Die Option Symmetric multi-processing support ist in der Voreinstellung aktiviert. Falls Sie kein Multiprozessorsystem Ihr Eigen nennen, können Sie diese Option getrost deaktivieren.
110
Erste Schritte
1 2 왘 General Setup
3
BSD Process Accounting ist in der Voreinstellung nicht aktiviert, obwohl es grundsätzlich eine gute Idee ist, was auch die Hilfe zu dieser Option unterstreicht. Deshalb sollten Sie BSD Process Accounting nachträglich aktivieren.
4
Die Option Systrace support ist nur verfügbar, wenn der Systrace-Patch eingespielt wurde. Weitere Informationen zu Systrace finden Sie im Abschnitt 5.4, Systrace.
5 6
왘 Block-Devices
Loopback device support ist häufig eine sinnvolle Idee (siehe losetup in Abschnitt 4.14, Das Rettungssystem). Falls Sie nicht sicher sind, ob Sie Loopback-Devices benötigen, können Sie den Support als Modul kompilieren.
7 8
Der für das CD-ROM-Notfallsystem interessante RAM disk Support steht hier ebenfalls mit seiner Unteroption Initial RAM disk (initrd) support (bei statischer Einbindung von RAM disk) zur Verfügung. Allerdings ist RAM disk Support für den Kernel des Serversystems selbst nicht notwendig. Der Kernel für das CD-ROM-System kann ein anderer sein (siehe Abschnitt 4.14, Das Rettungssystem).
9 10
왘 Networking-Options
11
Network packet filtering sollte generell aktiviert werden, um Paketfilterregeln mit iptables erstellen zu können. Zudem sollte TCP syncookie support für einen Webserver aktiviert werden.
12
왘 Networking-Options/Netfilter-Configuration
13
Connection tracking und IP tables support sollten statisch in den Kernel eingebunden werden. Um die Firewall-Regeln aus Abschnitt 5.3, Der Paketfilter, vollständig nachvollziehen und selbst umsetzen zu können, müssen weiterhin die Unterpunkte
14
왘 Multiple port match support, 왘 Connection state match support, 왘 Packet filtering, 왘 REJECT target support und 왘 LOG target support
ebenfalls als statische Komponenten ausgewählt werden. 왘 SCSI support
Wer keine hochwertige SCSI-Festplatte oder ein SCSI-Raid-System in seinem Server vorweisen kann, kann auf den SCSI-Support verzichten.
Der eigene Kernel
111
왘 Network device support
Wie der Name vermuten lässt, finden Sie hier unter anderem Treiber für 10-, 100- und 1000-Mbit-Ethernetkarten. Damit etwas mehr Übersicht in die Auswahllisten kommt, wurden die einzelnen Treiber in verschiedene Abschnitte aufgeteilt. Herkömmliche Treiber finden Sie unter Ethernet (10 or 100 Mbit) nach Auswahl von EISA, VLB, PCI and on board controllers. Falls in Ihrem Server eine andere Netzwerkkarte als in Ihrem Testserver verwendet wird, ist es aus Sicherheitsgründen besser, beide Treiber fest einzukompilieren und auf das dynamische Einbinden von Modulen zu verzichten. 왘 Character-Devices
Auf einem Server-System sollte kein grafisches Betriebssystem laufen, selbst dann nicht, wenn ein bekannter Großkonzern aus Redmond das anders sieht. Da wir unseren Server bereits ohne ein X-Window-System installiert haben, das für eine grafische Oberfläche benötigt wird, können Sie zudem auf /dev/agpgart (AGP Support) und Direct Rendering Manager (XFree86 DRI support) verzichten. 왘 File-Systems
Hier finden sich wichtige Punkte wie die Quota (siehe Abschnitt 4.6, Speicherplatz mit Quotas beschränken), Support oder Unterstützung verschiedener Filesysteme. Ich empfehle Ihnen, neben ext3 journalling file system support auch second extended fs support (bekannt als ext2) statisch in den Kernel aufzunehmen. Weitere Informationen hierzu finden Sie in diesem Kapitel unter 2.1.2, Das richtige Filesystem). 왘 Der virtual memory file system support wird häufig nicht benötigt. Werfen
Sie ruhig einen Blick in die ausführliche Hilfe zu diesem Punkt, bevor Sie sich entscheiden, virtual memory file system support beizubehalten oder zu deaktivieren. Selbstverständlich sollten Sie ebenfalls in /etc/fstab und /etc/mtab einen entsprechenden Mount-Eintrag Ihrer Distribution auskommentieren, um nicht etwa mit einer erschreckenden, aber harmlosen Fehlermeldung wie »Falscher Dateisystemtyp ... oder Superblock ist beschädigt ...« konfrontiert zu werden. 왘 Network File Systems 왘 In der Regel werden und sollten Sie auf einem Webserver keinen Fileser-
ver betreiben. Deshalb sollten Sie NFS file system support und NFS server support nicht benötigen und deaktivieren. 왘 Sound
Ein richtiger Server hat keine Soundkarte. Selbst wenn Sie einen herkömmlichen Tower mit Onboard-Sound beim Rechenzentrum abstellen, ist es nicht sinnvoll, sound card support aktiviert zu lassen.
112
Erste Schritte
1 2 Sind die Kernel-Einstellungen für unseren Webserver optimiert, können Sie das Menü über exit verlassen und die Einstellungen speichern. Nun gilt es, den Kernel mit
3 4
make dep clean bzImage modules modules_install zu kompilieren (dep bzImage) sowie die benötigten Module (modules modules_install) zu erstellen. Der Vorgang wird selbst auf einem leistungsstarken, aktuellen Rechnersystem mehrere Minuten beanspruchen. Auf einem älteren System müssen Sie eher mit 30 Minuten oder gar ein bis zwei Stunden rechnen.
5 6 7
Um den neuen Kernel aktivieren zu können, müssen Sie das System mit dem neuen Kernel booten. Welche Schritte hierzu erforderlich sind, wird nach dem Abschnitt zur Konfiguration von Kernel 2.6.10 beschrieben.
8 9
Kompilierung von 2.6.10 왘 General Setup
10
BSD Process Accounting ist in der Voreinstellung nicht aktiviert, obwohl es grundsätzlich eine gute Idee ist, was auch die Hilfe zu dieser Option unterstreicht. Deshalb sollten Sie BSD Process Accounting nachträglich aktivieren.
11
Die Option Systrace support ist nur verfügbar, wenn der Systrace-Patch eingespielt wurde. Weitere Informationen zu Systrace finden Sie im Abschnitt 5.4, Systrace.
12 13
왘 Loadable module support
Die Möglichkeit, Module nachträglich in den Kernel zu laden, ist beispielsweise nützlich, um eine Boot-Diskette zu erstellen – selbst wenn Sie in Ihren Kernel nur das Notwendigste einkompilieren, wird dies durchaus den Rahmen einer Boot-Diskette sprengen.
14
왘 Für Ihren Webserver sollten Sie lieber ausschließlich statische Module
verwenden und enable loadable module support deaktiveren! Dies erhöht die Sicherheit ungemein, da es Angreifern nicht möglich ist, durch Hinzuladen von Kernel-Modulen Unheil anzurichten. Prominentes Beispiel für einen solchen Exploit ist der Ptrace-Bug (siehe Abschnitt 5.6.5, Informationen zu /proc, insmod und dem Ptrace-Bug (Linux)). 왘 Processor-Typ and Features
Über den ersten Punkt Processor Family kann der Kernel auf einen bestimmten Prozessor optimiert werden. Obwohl ein Athlon-Prozessor ebenfalls mit einem für Intel kompilierten Kernel arbeitet, ist es für eine optimale Performance nötig, den Prozessor-Typ des eigenen Systems (nicht des Testsystems, sondern des Server-Systems) auszuwählen.
Der eigene Kernel
113
Die Option Symmetric multi-processing support wird zur Unterstüzung von Multiprozessorsystemen benötigt. Falls Ihr Computer nur mit einem Prozessor ausgestattet ist, kann diese Option deaktiviert bleiben. 왘 PowerManagement options (ACPI, APM)
Wahrscheinlich geht es Ihnen wie mir und Sie möchten keine experimentellen Code-Schnipsel in das Herz Ihres Linux-Kernels aufnehmen. Sie können den Punkt Software Suspend (EXPERIMENTAL) beruhigt deaktiveren – ein Webserver sollte ohnehin nie in den Ruhezustand versetzt werden. Auch der Punkt Sleep States (EXPERIMENTAL), der unter ACPI Support versteckt wurde, darf wie IBM Thinkpad Laptop Extras deaktiviert werden. 왘 Device Drivers/Block devices
Loopback device support ist häufig sinnvoll (siehe losetup in Abschnitt 4.14, Das Rettungssystem). Der für das CD-ROM-Notfallsystem interessante RAM disk Support steht hier ebenfalls mit seiner Unteroption Initial RAM disk (initrd) support (bei statischer Einbindung von RAM disk) zur Verfügung. Allerdings ist RAM disk Support für den Kernel des Serversystems selbst nicht notwendig. Der Kernel für das CD-ROM-System kann ein anderer sein (siehe Abschnitt 4.14, Das Rettungssystem). 왘 Device Drivers/SCSI device support
Wer keine hochwertige SCSI-Festplatte oder ein SCSI-Raid-System in seinem Server vorweisen kann, kann auf den SCSI-Support verzichten. 왘 Device Drivers/IEEE 1394 (FireWire) support
Mit größter Wahrscheinlichkeit werden Sie keine FireWire-Geräte an Ihren Server anschließen und somit alle vorselektierten Features deaktivieren wollen. 왘 Device Drivers/Networking support
Den richtigen Treiber für Ihre Netzwerk-Karte sollten Sie unter Ethernet (10 or 100 Mbit) beziehungsweise Ethernet (1000 Mbit) finden. Beachten Sie, dass die meisten Treiber unter dem Menüpunkt EISA, VLB, PCI and on board controllers versteckt sind. Deaktivieren Sie alle vorselektierten Treiber bis auf die Treiber der Netzwerkkarten Ihres Servers beziehungsweise Ihres lokalen Testsystems. Plip, PPP und SLIP benötigen Sie wahrscheinlich nicht, diese können deaktiviert werden. 왘 Device Drivers/Networking support/Networking options
Ich empfehle die Aktivierung von TCP syncookie support für einen Webserver. Network packet filtering sollte generell aktiviert werden, um Paketfilterregeln mit iptables erstellen zu können.
114
Erste Schritte
1 2 왘 File-Systems
3
Hier finden sich wichtige Punkte wie die Quota (siehe Abschnitt 4.6, Speicherplatz mit Quotas beschränken), Support oder Unterstützung verschiedener Filesysteme. Ich empfehle Ihnen, neben ext3 journalling file system support auch second extended fs support (bekannt als ext2) statisch in den Kernel aufzunehmen. Auch die seit Kernel 2.6 verfügbaren Zusatzoptionen ACL (Access Control Lists) und Security Labels, die in den Unterpunkten extended attributes zu ext2, ext3 und auch reiserFS versteckt wurden, sind eine Überlegung wert. Weitere Informationen hierzu finden Sie in diesem Kapitel unter 2.1.2, Das richtige Filesystem).
4 5 6 7
왘 File-Systems/Network File Systems
In der Regel werden und sollten Sie auf einem Webserver keinen Fileserver betreiben. Deshalb benötigen Sie NFS file system support und NFS server support nicht und können sie deaktivieren.
8 9
Sind die Kernel-Einstellungen für unseren Webserver optimiert, können Sie das Menü über exit verlassen und die Einstellungen speichern. Nun gilt es, die Kompilierung des Kernels mit make anzustoßen. Nachdem der Vorgang durchlaufen ist, was auch auf aktuellen Systemen einige Zeit beanspruchen wird, sollten Sie Zeilen wie:
10 11 12
Root device is (3, 2) Boot sector 512 bytes. Setup is 2352 bytes. System is 1848 kB Kernel: arch/i386/boot/bzImage is ready
13 14
sehen können. Wurden keine Fehlermeldungen ausgegeben, dann können Sie den Kernel wie im folgenden Abschnitt beschrieben aktivieren. System mit neuem Kernel booten Sobald die Prozedur durchlaufen ist, finden Sie den fertigen Kernel als arch/i386/boot/bzImage im Verzeichnis der Kernel-Quellen linux-2.4.29 beziehungsweise linux-2.6.10. In Lilo ist der vollständige Pfad zum bzImage des neuen Kernels unter image= einzutragen und mit label="Mein Kernel" ein griffiger Name für das eigene Kernel-Image zu vergeben. Werfen Sie einen Blick in das Boot-Verzeichnis Ihrer Distribution. Hier sollte eine System.map-Datei zum bereits verwendeten Kernel mit Namen: System.map-Kernel-Version stehen. An diese Stelle sollten Sie auch die System.map des Kernel-Quellverzeichnisses mit entsprechend angepassten Dateinamen kopieren. Da uname -r die Bezeichnung des Kernels ausgibt, mit dem
Der eigene Kernel
115
das System gebootet wurde, können Sie beim Kompilieren einer neuen KernelVersion oder nach Nutzung von Patches den Befehl uname nicht verwenden, um den Namen Ihres neuen Kernels herauszufinden. In diesem Fall gilt es einen Blick in die Datei bsetup.s (liegt im gleichen Verzeichnis, in dem bzImage erzeugt wurde) zu werfen:
debian:/usr/src/linux-2.4.29 # grep \ kernel_version arch/i386/boot/bsetup.s .word kernel_version # pointing to kernel \ version string kernel_version: .ascii "2.4.29" Sie müssen nur noch die Kernel-Versionsbezeichnung (in unserem Beispiel 2.4.29) an die Bezeichnung »System.map-« hängen. In unserem Beispiel ist als Mapname somit System.map-2.4.29 zu verwenden. Der cp-Befehl lautet folglich: cp System.map /boot/System.map-2.4.29 Beachten Sie, dass die Kernel-Versionsbezeichnung nach dem Einspielen von Patches wie linux-vserver oder systrace oder bei Nutzung eines speziellen Kernel-Archivs von einer simplen Versionsbezeichnung abweichen kann und deshalb über grep kontrolliert werden sollte! Ist das System mit dem neuen Kernel nach Aufruf von lilo und einem Neustart korrekt gestartet, dann können Sie ihn als Default-Kernel festlegen (siehe Abschnitt 2.5.1, LILO – Generic Bootloader for Linux) Weitere Informationen zu Lilo finden Sie auch im Abschnitt 2.5.1, LILO – Generic Bootloader for Linux.
2.9.2
OpenBSD
Um einen eigenen Kernel kompilieren zu können, müssen Sie zunächst die Kernel-Quellen über einen Mirror beziehen. Im Verzeichnis /pub/OpenBSD/3.6/ sollten Sie die Dateien src.tar.gz und sys.tar.gz finden, die beide benötigt werden und auch auf der CD zum Buch zu finden sind. Die Pakete sind in das Verzeichnis /usr/src zu entpacken. Danach können Sie in das neue Verzeichnis /usr/src/sys/arch/i386/conf wechseln und cp GENERIC foo aufrufen, um die Anpassungen nicht direkt an der ursprünglichen Konfigurationsdatei vornehmen zu müssen. Anstelle des Löschens nicht gewünschter Konfigurationsoptionen sollten Sie die Zeile durch ein Kommentarzeichen deaktivieren, um so bei einer späteren
116
Erste Schritte
1 2 Neukompilierung versehentlich deaktivierte Optionen wieder problemlos aktivieren zu können.
3
Insbesondere die Konfigurationsoptionen zu PCMCIA und dem CardBus-Support können neben nicht benötigten Treibern zu Netzwerkkarten, Controllern, Joysticks, jeglicher Unterstützung für Audio und andere für einen Webserver unnütze Bestandteile getrost deaktiviert werden.
4 5
Sobald die Anpassungsarbeiten abgeschlossen sind, können Sie config foo aufrufen. Eventuell weist Sie config auf Einstellungen hin, die im Zusammenhang mit der Deaktivierung einzelner Optionen ebenfalls auskommentiert werden müssen oder die für Ihre Konfiguration benötigt werden und wieder zu aktivieren sind.
6 7 8
# config foo foo:278: wdc* at pcmcia? is orphaned (nothing matching \ pcmcia? declared) *** Stop.
9 10
In diesem Fall könnte die Zeile
wdc*
11
at pcmcia? function ?
ebenfalls auskommentiert werden, damit config wunschgemäß durchläuft:
12
# config foo Don't forget to run "make depend" Kernel options have changed -- you must run "make clean"
13 14
Wechseln Sie nun ins Verzeichnis ../compile/foo und rufen Sie make clean depend && make auf. Auch hier könnten unerwartete Komplikationen auftreten, wenn einzelne Bestandteile unerwartet Abhängigkeiten zu auskommentierten Einträgen aufweisen, die von config im Vorfeld nicht erkannt wurden:
if_sis.o: Undefined symbol '_mii_phy_reset' \ referenced from text segment i82365.o: Undefined symbol '_pcmcia_card_attach' \ referenced from text segment Aus den Beispielzeilen können Sie entnehmen, dass das Interface sis (meine Netzwerkkarte) auf mii-phy-Geräteinformationen zugreifen muss. Weiterhin habe ich irgendwo das Auskommentieren einer PCMCIA-Zeile übersehen. Letzteres lässt sich recht einfach korrigieren. Die Frage nach dem von sis benötigtem mii-Modul lässt sich dagegen nicht so einfach beantworten. Wenn Sie sich nicht sicher sind und im Web ebenfalls keine Informationen finden können, hilft lediglich die Aktivierung aller mii-Einträge weiter.
Der eigene Kernel
117
Die Änderungen sind wiederum über config foo vor dem erneuten make clean depend && make zu aktivieren. Falls alles funktioniert hat, finden Sie am Ende des Kompilierungsprozesses anstelle einer Fehlermeldung die Zeilen:
text data 2228224 77824
bss 237896
dec hex 2543944 26d148
Vergleichen Sie die Kernel-Größe Ihres angepassten Kernels mit dem des Standardsystems, um die sicherlich deutlichverringerte Kernel-Größe bewundern zu können:
# ls -l bsd -rwxr-xr-x 1 root # ls -l /bsd -rw-r--r-- 1 root
wsrc wheel
2523456 Jun 4515116 Oct
1 20:11 bsd 5
2002 /bsd
Allerdings können Sie noch immer nicht mit Sicherheit beurteilen, ob der Kernel das System sauber booten wird und darüber hinaus sämtliche Hardware (insbesondere Netzwerkkarte) korrekt eingebunden werden kann. Deshalb sollten Sie den alten Kernel nicht einfach durch den neuen ersetzen, sondern den neuen unter anderem Namen nach / verschieben:
# cp /sys/arch/i386/compile/foo/bsd /meinkernel Zur endgültigen Überprüfung bietet sich ein Rebooten an. Geben Sie am Bootprompt vor dem Laden des eigentlichen Systems set image /meinkernel ein und klicken Sie zweimal auf Return. Nun startet das System mit Ihrem »eigenen« Kernel. Falls alles wunschgemäß funktioniert hat und die Hardware erkannt wurde, können Sie die Zeile set image /meinkernel in /etc/boot.conf eintragen, um zukünftig bei jedem Start den »neuen« Kernel automatisch zu berücksichtigen. Siehe Abschnitt 2.5.2, Boot (OpenBSD) und Bootable-Flag (fdisk).
118
Erste Schritte
1 2
3 Wichtige Serverdienste
3 4 5
3.1
OpenSSH.................................................................. 121
3.2
Domain Name Server System ................................... 129
3.3
Apache ..................................................................... 139
3.4
Tomcat ..................................................................... 189
3.5
MySQL oder PostgreSQL? ........................................ 197
3.6
MySQL ..................................................................... 199
3.7
PostgreSQL .............................................................. 208
3.8
Die Komponenten eines Mailservers........................ 222
3.9
Postfix ...................................................................... 223
3.10 Courier-IMAP ........................................................... 255 3.11 Das Webinterface SquirrelMail ................................ 258 3.12 Der FTP-Server ProFTPD .......................................... 259
6 7 8
1
Einführung
2
Erste Schritte
3
Wichtige Serverdienste
4
Verwaltung und Administration
5
Server absichern
6
Linux-Vserver
7
Der eigene Server
8
Bürokratisches
1 2
3
Wichtige Serverdienste
3
Denn jede Sache, die gegeben nicht verliert, während sie besessen und nicht gegeben wird, wird niemals besessen, auf welche Weise sie besessen werden soll. (Aurelius Augustinus)
4 5 6
3.1
OpenSSH 7
Der Secure-Shell-Server ist der wohl wichtigste Dienst auf einem Webserver. Über ihn wird die Administration erledigt. Fällt der Dienst aus, lässt sich der Webserver nicht mehr von außerhalb steuern. Selbstverständlich ist der SSHDaemon begehrtes Angriffsziel von BlackHats und deshalb unbedingt mit den neuesten Sicherheits-Updates zu pflegen.
8 9
OpenSSH zählt unter OpenBSD, SUSE und Debian wie selbstverständlich zum Grundsystem. Unter SUSE und Debian kann OpenSSH, das übrigens vom OpenBSD-Team entwickelt wird, auch nachträglich über yast beziehungsweise dselect installiert oder entfernt werden.
10 11 12
Da in einer Telnet-Kommunikation neben den eigentlichen Verbindungsdaten auch das Passwort im Klartext übertragen wird, ist Telnet aus Sicherheitsgründen keine Alternative zu SSH. Ein Telnet-Server hat auf Ihrem Webserver nichts verloren und ist gegebenenfalls zu deinstallieren.
13 14
3.1.1
Konfiguration
Der sshd wird über /etc/ssh/sshd_conf konfiguriert. Die Standard-Einstellungen Ihres Systems sind in der Regel anzupassen. Damit der SSH-Server lediglich das sicherere Protokoll 2 verwendet, ist gegebenenfalls die »1« aus der Zeile Protocol zu entfernen. Login nur bestimmten Nutzern oder Gruppen erlauben Root-Logins sollten auf keinen Fall erlaubt sein. Dies würde Angreifern das Erraten Ihres Passwortes über eine Brute-Force-Attacke gestatten. Die Zeile PermitRootLogin no sperrt den root-Account für Logins. Nach dem Login als User können Sie gegebenenfalls su- verwenden, um root-Rechte zu erlangen. Noch besser ist es, lediglich ausgewählten Usern Zugriff über SSH zu gestatten. Sie können eine Nutzerliste über die Zeile AllowUsers festlegen. Die einzelnen
OpenSSH
121
Einträge sind mit einer Leertaste zu trennen. Es ist sogar möglich, den Zugriff eines Nutzers auf eine bestimmte IP-Adresse zu beschränken:
AllowUsers [email protected] ichbins Diese Zeile würde einen root-Login lediglich bei einer Verbindungsanfrage von 12.34.56.78 erlauben. Der Nutzer ichbins darf sich jedoch von jedem beliebigen Rechner aus einloggen. Sollen mehrere Nutzer SSH-Zugriff erhalten, bietet es sich an, mit »AllowGroups« zu arbeiten:
AllowGroups login [email protected] Diese Zeile erlaubt allen Usern der Gruppe Login, sich über SSH einzuloggen. Nutzer der Gruppe root können sich ausschließlich über den Rechner 12.34.56.78 einloggen. Rhosts deaktivieren Üblicherweise ignoriert SSH das unsichere Rhost-Protokoll. Dies ist sehr empfehlenswert und sollte in Ihrer Konfigurationsdatei entsprechend voreingestellt sein. Prüfen Sie daher, ob die Zeilen
RhostsAuthentication no IgnoreRhosts yes RhostsRSAAuthentication no in Ihrer Konfigurationsdatei enthalten sind, und ergänzen Sie die Datei gegebenenfalls. Authentifizierung Der Zugriff auf SSH kann neben einem Passwort auch über Schlüsselaustausch erfolgen (siehe den folgenden Abschnitt, PubkeyAuthentication). Es ist empfehlenswert, die Passwortübergabe generell zu aktivieren, um im Notfall von jedem x-beliebigen Rechner mit SSH-Client auf den Server zugreifen zu können:
PasswordAuthentication yes PermitEmptyPasswords no Aus Gründen der Sicherheit sollte immer ein Passwort vergeben sein. Dennoch wird dies bei der Erstellung eines Accounts schnell vergessen. Damit durch eine derartige Schusseligkeit nicht auch noch ein direkter Login in das System erfolgen kann, sollte auf einem existierenden Passwort bestanden und leere Passwörter mit »PermitEmptyPasswords no« ignoriert werden.
122
Wichtige Serverdienste
1 2 PubkeyAuthentication
3
Neben der Authentifizierung durch Passworteingabe kennt OpenSSH die »PubkeyAuthentication«. Insbesondere für Automatismen (zum Beispiel für ein regelmäßiges Backup) ist dies sehr nützlich. Obwohl die RSA- und DSA-Schlüssel sicherer sind als die Übertragung eines Passwortes, sind RSA- und DSA-Keys dennoch mit Vorsicht zu genießen: Wird der Arbeitsrechner mit den Schlüsseln geknackt, stehen dem Angreifer gleichzeitig die entsprechenden ServerAccounts offen.
4 5 6
Wer keinen besonders abgesicherten Server für die brisante Automationsaufgabe verwenden kann, auf dem beispielsweise lediglich für Backups ein SSHDaemon installiert ist und weder Mail- noch Webserver oder andere laufen, sollte es unbedingt vermeiden, Keys für den root-Account zu nutzen. Weisen Sie den zu übertragenden Daten einen unprivilegierten Account zu (oder erteilen Sie seiner Gruppe Leserecht), und verwenden Sie für das automatisierte Backup den unprivilegierten Account.
7 8 9 10
Um PubkeyAuthentication zu aktivieren, sind die folgenden Zeilen in die /etc/sshd/sshd_config aufzunehmen:
11
PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys
12
Mit ssh-keygen erzeugte Schlüssel ermöglichen den passwortlosen Login. Wie bereits erläutert, sollten Sie aus Sicherheitsgründen lediglich für unprivilegierte Accounts einen Key erzeugen. Unter UNIX-Derivaten rufen Sie dazu nach dem Wechsel zum gewünschten Nutzer-Account (der später die Verbindung zum Server aufbauen können soll) den Befehl ssh-keygen -t dsa auf. Die zu erzeugenden Schlüssel (id_dsa und id_dsa_pub) sind im Verzeichnis ~/.ssh abzulegen (Voreinstellung bestätigen). Bei der Frage nach der Passphrase ist lediglich (2 x) Return zu drücken.
13 14
Übertragen Sie id_dsa_pub auf den Server in das Home-Verzeichnis des Accounts, zu dem ein automatischer Login ermöglicht werden soll: scp .ssh/id_dsa.pub [email protected]: und loggen Sie sich auf dem Server mit dem Namen des Accounts und dem entsprechendem Passwort ein. Danach können Sie cat id_dsa.pub >> .ssh/authorized_keys ausführen. Falls das Verzeichnis .ssh noch nicht existieren sollte, können Sie es einfach selbst anlegen. Aus Sicherheitsgründen sollten Sie unbedingt darauf achten, dass die Zugriffsrechte des .ssh-Verzeichnisses auf 700 und die der authorized_keys-Datei auf 600 eingestellt sind und dem entsprechendem User gehören.
OpenSSH
123
Hinweis Leider sind Schlüssel, die mit ssh-keygen des OpenSSH-Pakets beziehungsweise dem kommerziellen SSH erzeugt wurden, nicht miteinander kompatibel. Das heißt, Sie müssen auf dem Client dieselbe SSH-Variante wie auf dem Server einsetzen (lediglich die Versionsnummer darf – in begrenztem Rahmen – abweichen). Falls Sie sich trotz korrekter Rechte von .ssh und authorized_keys nicht ohne Passwort einloggen können, sollten Sie daher auf dem Client dieselbe OpenSSH-Version wie auf dem Server installieren.
3.1.2
Betrieb
Um unseren Webserver mit SSH zu administrieren, benötigen Sie auf Ihrem Arbeitsrechner einen SSH-Client, der über das Protokoll 2 kommunizieren kann. Unter Linux, BSD und Mac OS X zählt ein SSH-Client bereits zum Lieferumfang und ein simples ssh [email protected] stellt eine SSH-Verbindung mit dem User nutzername zum Server servername.de her. Nach Eingabe des richtigen Passworts steht Ihnen eine Shell auf servername.de zur Verfügung. Vor Eingabe des Nutzernamens und Passworts prüft der SSH-Client den ServerKey. Sprechen Sie einen neuen Server an, ist der Key über die Eingabe von Yes einmalig zu bestätigen. SSH-Keys ändern sich lediglich dann, wenn Sie auf dem Server einen neuen HostKey erzeugen. Falls sich ein Angreifer zwischen SSH-Server und Client klinkt (»Man in the middle attack« genannt), ändert sich der Server Key und der Client macht Sie darauf aufmerksam. Fahren Sie dann auf keinen Fall mit der Eingabe des Nutzernamens und des Passworts fort, sonst hat der Angreifer gewonnen und Ihre Zugangsdaten abgefangen. In der Konfigurationsdatei des SSH-Clients /etc/ssh/ssh_config können Sie mit der Zeile
StrictHostKeyChecking yes ein versehentliches Bestätigen der Sicherheitsmeldung verhindern. Der SSHClient bricht den Vorgang automatisch ab, wenn der Server Key nicht mit dem gespeicherten Key übereinstimmt. Falls sich der Key tatsächlich geändert hat, sind die entsprechenden Zeilen (siehe IP-Adresse/Serverdomain) aus der Datei ~/.ssh/known_hosts zu entfernen.
124
Wichtige Serverdienste
1 2 scp (Secure Copy)
3
Secure Copy ermöglicht das Kopieren einzelner Dateien oder ganzer Verzeichnisse über eine sichere SSH-Verbindung. Mit:
4
scp ~/files.tgz [email protected]:~/Backup/ wird die Datei files.tgz vom Home-Verzeichnis des lokalen Rechners in den Ordner Backup des Users username auf dem Server hostname.de kopiert. Weitere Hinweise zu scp finden Sie in der gleichnamigen Manpage.
5
sftp (Secure-FTP)
7
6
Obwohl es SSH-Clients für Windows und Linux gibt, mit denen scp so komfortabel wie in einem Datei-Browser genutzt werden kann, wurde Secure Copy dennoch für das Kopieren einzelner Dateien oder Verzeichnisse ausgelegt. Wer scp als sichere Alternative zu FTP nutzen möchte, sollte deshalb lieber zu sftp greifen. In aktuellen OpenSSH-Versionen zählt sftp nicht nur zum Lieferumfang, es wird sogar in der Voreinstellung aktiviert:
Subsystem
sftp
8 9 10
/usr/local/libexec/sftp-server
11
Falls Sie diese Zeile am Ende Ihrer sshd_config finden, ist sftp unmittelbar einsatzbereit. Fehlt die Zeile, können Sie über whereis sftp-server den korrekten Verzeichnispfad herausfinden, um das Ende der Konfigurationsdatei mit der Subsystemzeile manuell zu ergänzen.
12 13
Für Linux sind neben gftp und der Konqueror-Erweiterung kio_fish auch grafische Clients vorhanden, die das SFTP-Protokoll unterstützen. Für einen Testlauf auf der Konsole genügt jedoch der Aufruf sftp [email protected].
14
Für Windows empfiehlt sich der SFTP-fähige FTP-Client FileZilla (SFTP über SiteManager aus dem File-Menü wählbar), der über http://sourceforge.net/projects/filezilla/ erhältlich und auf der CD zum Buch vertreten ist. Mac-User, die noch nicht auf OS X umgestiegen sind, müssen wohl oder übel mit einem kommerziellen Client wie Interarchy (http://www.interarchy.com) vorlieb nehmen. Putty und WinSCP2 für Windows Für Windows empfiehlt sich Putty als SSH-Client. Sie finden putty.exe im Windows-Verzeichnis der CD zum Buch sowie im Internet unter http://www.chiark.greenend.org.uk/~sgtatham/putty/. In der Voreinstellung ist die Schrift in Putty schlecht lesbar. Sie können Schriftart und -größe im Startfenster über Auswahl von Windows sowie den Unter-
OpenSSH
125
punkt Appearance an Ihre Wünsche anpassen. Auch die Schriftfarben lassen sich über Colours angenehmer gestalten. Speichern Sie Ihre Änderungen als Default-Settings (auf den ersten Abschnitt Session klicken) ab, um nicht bei jedem Start von Putty diese Schritte erneut vornehmen zu müssen. Wer scp über Windows nutzen möchte, wird an WinSCP2 großen Gefallen finden. Die Freeware ist auf der CD zum Buch sowie über http://winscp.vse.cz erhältlich.
Abbildung 3.1 Putty ist ein flexibel konfigurierbarer SSH-Client für Windows-Systeme.
3.1.3
User-Home-Verzeichnis chrooten
Leider stehen die Entwickler von OpenSSH einer offiziellen Integration von Chroot-Funktionen in den OpenSSH-Code kritisch gegenüber. Da jedoch einem mit SSH eingeloggten User sämtliche Informationen offen stehen, die worldreadable sein müssen, haben Sie die Wahl, lediglich vertrauenswürdigen Mitarbeitern einen SSH-Zugang anzubieten oder OpenSSH mit einem Chroot-Patch neu zu installieren. Falls Ihre Partner oder Mitarbeiter willens sind, scp oder sftp zu nutzen, ist der Sicherheitsgewinn den zusätzlichen Aufwand durchaus wert. Obwohl Sie die OpenSSH-Version Ihres Systems patchen könnten, empfehle ich Ihnen die zusätzliche Installation einer gepatchten neben der bereits genutzten Version.
126
Wichtige Serverdienste
1 2 So können Sie bei etwaigen Problemen jederzeit zur Standard-Version Ihrer Distribution zurückkehren.
3
Installation
4
Unter http://chrootssh.sourceforge.net finden Sie eine aktuelle OpenSSHVersion, die bereits den Chroot-Patch erhalten hat. Weiterhin sollten Sie die Quellen von OpenSSL (http://www.openssl.org) und Zlib (http://www.gzip.org/zlib/) vor der Installation der gepatchten OpenSSHVariante kompilieren. Beachten Sie, dass zur Installation von OpenSSL im ersten Schritt lediglich ./config anstelle des sonst üblichen ./configure aufzurufen ist.
5 6 7 8
Sobald die Installation von OpenSSH abgeschlossen ist, sollten Sie die Konfigurationsdatei /usr/local/etc/sshd_config (für die gepatchte OpenSSH-Version: /usr/local/sbin/sshd) entsprechend Ihren Wünschen anpassen. Im nächsten Schritt gilt es, den »alten« SSHD-Server zu beenden, ohne die aktuelle Verbindung auszuhebeln. Dies ist unkomplizierter, als es zunächst klingen mag. Die Hauptinstanz besitzt den ältesten Startzeitpunkt:
debGal:~# ps -aux | grep sshd root 192 0.0 0.7 6508 2000 ? root 484 0.0 0.7 6412 1972 ?
9 10 11
S 13:43 S 17:24
0:00 /usr/sbin/sshd 0:00 /usr/sbin/sshd
12
In unserem Beispiel würde der Befehl kill 192 den SSH-Server beenden, ohne die aktuelle Verbindung zu trennen.
13
Danach ist über /usr/local/sbin/sshd die gepatchte Version zu starten und zu testen, ob Sie eine zweite Verbindung aufbauen können. Loggen Sie sich auf keinen Fall vorher aus, da Ihr Server mangels korrekt arbeitendem SSH-Server nicht mehr von außen administrierbar sein könnte.
14
Beachten Sie, dass bei der Installation des OpenSSH-Servers ein neuer Key erzeugt wurde. Anhand der Warnmeldung erkennen Sie, dass der gepatchte und nicht der ursprüngliche SSH-Server Ihrer Distribution auf die Verbindungsanfrage antwortet. Hat der Login geklappt, können Sie in den Startskripten Ihres Systems den Aufruf des »alten« SSHDs durch /usr/local/sbin/sshd ersetzen. Einrichtung eines chrooted SSH-Accounts Damit die Chroot-Umgebung überhaupt nutzbar ist, gilt es, neben /bin/sh (der Chroot-Patch setzt diese Shell voraus) auch die wichtigsten Systembefehle wie
OpenSSH
127
ls, rm oder mkdir mitsamt den benötigten Bibliotheken zu kopieren. Welche Dateien benötigt werden, verrät ldd:
debGal:/lib# ldd /bin/sh libncurses.so.5 => /lib/libncurses.so.5 (0x40017000) libdl.so.2 => /lib/libdl.so.2 (0x40055000) libc.so.6 => /lib/libc.so.6 (0x40059000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) Die Ausgabe kann von Ihrem System abweichen. Für einen ersten Testversuch mit dem neuen Account chr sind folgende Befehle notwendig:
mkdir -p /home/chr/bin mkdir /home/chr/lib cp /bin/sh /bin/ls /home/chr/bin/ cp 'ldd /bin/ls | cut -d" " -f3' /home/chr/lib/ cp 'ldd /bin/sh | cut -d" " -f3' /home/chr/lib/ Nun können Sie über chroot /home/chr /bin/sh prüfen, ob Sie in das Verzeichnis chrooten können. Nach Eingabe von cd / && ls dürften lediglich die beiden Verzeichnisse /bin und /lib zu sehen sein. Sie können den Käfig über ein simples exit verlassen. Wenn Sie den Nutzer-Account chr erzeugen, sollten Sie als Home-Verzeichnis /home/chr/./home verwenden und das Verzeichnis /home/chr/home anlegen sowie dem Nutzer chr überschreiben. Erst das sinnlos wirkende /./ veranlasst die gepatchte Version Ihres OpenSSH-Servers, den bis zu dieser Stelle angegebenen Pfad als Chroot-Verzeichnis zu verwenden. Aus /home/chr/./home wird somit chroot /home/chr/. Nach dem Einloggen findet sich chr daher in seinem /home-Verzeichnis wieder, ohne auf die Ordner unterhalb von /home/chr zugreifen zu können. Damit OpenSSH die User-ID dem Account zuordnen kann (ist für einen Login zwingend notwendig), gilt es, abschließend die entsprechende Zeile aus der /etc/passwd-Datei zu übernehmen:
mkdir /home/chr/etc grep "chr" /etc/passwd > /home/chr/etc/passwd Die grundlegenden Vorbereitungen sind damit abgeschlossen. Loggen Sie sich über ssh testweise ein, um den Account und die korrekte Arbeitsweise des gepatchten OpenSSH zu überprüfen. Abschließend sollten Sie erwünschte Befehle wie mkdir, rmdir, mv, cp oder rm zusammen mit den benötigten Bibliotheken ins Nutzerverzeichnis von chr kopieren. Damit Sie diesen Vorgang nicht für jeden SSH-Account wiederholen müssen, bietet sich ein Shell-Skript an.
128
Wichtige Serverdienste
1 2 Alternativ wäre es auch möglich, ein Dummy-Verzeichnis anzulegen, das bereits die richtige Struktur und sämtliche Befehle enthält. Ist ein neuer SSHchroot-Zugang einzurichten, könnten Sie das Verzeichnis einfach kopieren und dem Nutzer übertragen.
3 4
Hinweis: Um sftp nutzen zu können, müssen Sie das sftp-server-Binary mit seinen Bibliotheken (siehe ldd /usr/lib/sftp-server) an die gleichnamigen Orte im Chroot-Käfig kopieren.
5 6
3.2
Domain Name Server System 7
Die Kommunikation zwischen einzelnen Rechnern erfolgt im Internet über IPAdressen. Lediglich durch Zahlenkombinationen wie 192.168.0.33 (eine lokale Adresse) wissen die Rechner, wohin einzelne Pakete geschickt werden sollen oder an welche Adresse eine Anfrage zu richten ist.
8 9
Da Menschen sich Namen in der Regel leichter merken können als Zahlen, wurde das DNS-System eingeführt. Nameserver speichern IP-Adressen dezentral ab und sind in der Lage, unzählige Anfragen nach der IP-Adresse einer Domain zeitnah zu beantworten.
10 11
Der Aufruf von http://www.wunschname.de führt daher zunächst zu einer Nachfrage beim voreingestellten DNS. In der Regel stellt jeder ISP einen DNS zur Verfügung und erklärt den Nutzern, wo dieser in den Windows-Einstellungen zu konfigurieren ist. Unter UNIX dient übrigens /etc/resolv.conf zur Konfiguration der vom System zu nutzenden Nameserver.
12 13 14
Erst wenn der Nameserver die Domain in eine IP-Adresse aufgelöst und diese dem Client mitgeteilt hat, startet der Client den eigentlichen Verbindungsaufbau über die IP-Adresse von http://www.wunschname.de. Da im Header jedoch auch der Domain-Name übergeben wird, ist es möglich, mehrere verschiedene Homepages mit ein und derselben IP-Adresse über unterschiedliche Domain-Adressen anzusprechen. Ein Ausfall des DNS-Systems wäre fatal, wenn die Struktur nicht dezentral angelegt wäre. Der Trick ist: DNS bei Internet-Zugangs-Providern speichern IPAdressen zwischen, um Anfragen schneller beantworten zu können. In regelmäßigen Abständen (meist alle zwei Tage oder einmal täglich) werden die Datenbestände bei einer erneuten Anfrage aktualisiert. Ist der für die Domain zuständige DNS nicht erreichbar, wird die Adresse nochmals aus dem »veralteten« Zwischenspeicher hervorgezaubert. Da ein Ausfall des Nameservers nicht ungewöhnlich ist, und es gleichzeitig sehr unwahrscheinlich ist, dass die IP-Adressen und Domains Ihres Servers
Domain Name Server System
129
allen wichtigen DNS bereits bekannt sind, bestehen Domain-Vergabestellen wie die DENIC (zuständig für .de-Domains) bei Domain-Registrierungen und -Änderungen auf zwei voneinander unabhängigen DNS-Servern. Die DNS dürfen noch nicht einmal im selben Subnetz liegen. Doch keine Sorge, bis Ihnen ein zweiter DNS-Server in einem »fremden« Subnetz zur Verfügung steht, können Sie zu günstigen Konditionen (manchmal sogar kostenlos) einen zweiten Nameserver bei Ihrem Domain-Dienstleister nutzen. Aufmerksame Leser werden sich an dieser Stelle fragen, woher DNS einzelner ISPs erfahren, welcher DNS für eine Domain zuständig ist. Sobald eine Domain registriert wird, leitet die Vergabestelle die entsprechenden Daten (DomainName und Nameserver1 sowie Nameserver2) an den Root-Nameserver für die jeweilige Domain weiter. Ist einem DNS eine Domain unbekannt, startet er eine Anfrage an einen der zuständigen Root-Nameserver. Als Antwort erhält er die für diese Domain zuständigen Nameserver zurück. Nun wird er aus den mitgeteilten DNS »zufällig« einen für seine erste Anfrage auswählen (ist dieser offline, wird der zweite ausprobiert). Eine aktuelle Liste der Root-Nameserver liegt jeder Bind-Installation bei und kann über less /var/named/root.hint eingesehen werden.
1.
Root-NS
2. Haupt-NS firma.de
Anfragender NS
3.
Nameserver entwicklung.firma.de
Abbildung 3.2 Durch die dezentrale Struktur des DNS können durchaus mehr als zwei Anfragen notwendig sein, um eine IP-Adresse zu ermitteln.
Hierbei gilt zu beachten, dass für eine Domain zuständige DNS nicht zwangsläufig alle Informationen bereithalten. Insbesondere Subdomains (forschung.universitaet-oberschlau.de), die auf Filialen oder ausgelagerte Abtei-
130
Wichtige Serverdienste
1 2 lungen einer großen Firma verweisen, werden manchmal über einen (oder mehrere) zusätzliche DNS verwaltet, wie Abbildung 3.2 verdeutlicht.
3
Häufig werden Subdomains lediglich genutzt, um auf andere Webseiten desselben Angebots als Einstiegsseite zu verweisen. So könnte »nachrichten.firma.de« auf die Seite mit aktuellen Nachrichten der Firma »firma.de« verweisen, »kontakt.firma.de« jedoch auf das Impressum. IP-Adresse und zuständige Nameserver können in beiden Fällen identisch sein. Wie der Apache anhand der Domain-Adresse dennoch »auf eine andere Startseite« verweist, wird in Abschnitt 3.3.3, Default Server und virtuelle Hosts, erläutert.
4 5 6 7
3.2.1
Grundkonfiguration
8
Um der grauen Theorie etwas Farbe zu verleihen, widmen wir uns einem kleinen, lokalen Nameserver, der in der Lage sein soll, die Rechner Ihres lokalen Netzwerks anhand von (Sub-)Domains aufzulösen.
9
Installieren Sie zunächst das Bind9-Paket Ihres UNIX-Derivats (falls noch nicht geschehen), und fügen Sie am Ende der Konfigurationsdatei /var/named/ named.conf (unter Debian /etc/bind/named.conf) folgende Zeilen ein:
10 11
zone "home.test" in { type master; file "db.home.test"; };
12 13
Nach dem nächsten Reload der Nameserver-Konfigurationsdatei weiß Bind, dass er für die Domain home.test als »master« zuständig ist. Die Informationen über die Domain home.test werden über die Datei db.home.test geladen. Letztere gilt es, im Verzeichnis /var/named/ mit folgenden Zeilen zu erstellen:
$TTL 2D @
IN SOA
@ @ *
IN NS IN A IN A
14
@
admin.localhost.test. ( 1999092901 ; serial 1D ; refresh 2H ; retry 1W ; expiry 1D ) ; Negative C-TTL home.test. 192.168.0.25 192.168.0.25
Domain Name Server System
131
$TTL 2D (Time to live) $TTL 2D legt die Time to live fest. Nach Ablauf dieser Zeit (im Beispiel zwei Tage) sind Nameserver angehalten, den Cache bei der nächsten Anfrage zu aktualisieren (die Nameserver-Informationen zur angefragten Domain neu zu beziehen). SOA (Start Of Authority) SOA-Record legt fest, in welchem Zuständigkeitsbereich die Toplevel-Domain liegt, und gibt die E-Mail-Adresse des zuständigen Administrators an (hier [email protected]). Beachten Sie, dass anstelle des @-Zeichens ein Punkt zu verwenden ist. Der erste Eintrag in der Klammer bezeichnet die Seriennummer. Verwenden Sie hier das Datum mit angehängter Versionsnummer im Format: YYYYMM DDNR. So steht 2003011203 für die dritte Änderung am 12. Januar 2003. Achtung: Bei einer Domain-Registrierung wird geprüft, ob die angegebenen Nameserver dieselbe Versionsnummer für die Domain verwenden. Slave-Nameserver (siehe Abschnitt 3.2.3, Bind im harten Server-Einsatz) verwenden das Refresh-Intervall zur Aktualisierung ihrer Zonendaten. Falls ein Refresh gerade nicht möglich ist, wartet der Slave das unter retry definierte Zeit-Intervall ab, bevor der nächste Versuch gestartet wird. Diese Prozedur wiederholt sich so lange, bis der Refresh erfolgreich durchgeführt werden konnte. Gelingt es dem Slave nicht, die Zonendaten neu zu beziehen, wird der Slave nach dem in expire definierten Zeitraum den Cache löschen und weitere Domain-Anfragen an diese Zone mit »nicht existent« beantworten. Negative caching time to live gibt den Zeitraum an, in dem von anfragenden Nameservern bei einem negativen Ergebnis ohne erneute Abfrage an den eigentlichen Nameserver die Domain-Anfrage mit unbekannt beantwortet wird. Wird eine Domain nicht gefunden, befragt der gleiche Nameserver den für diese Domain zuständigen Nameserver erst nach Ablauf der negativen CTTL erneut nach der gewünschten Domain. Innerhalb des Zeitraums beantwortet der Nameserver Domain-Anfragen »eigenmächtig« als unbekannt. Die zeitliche Problematik von Domain-Änderungen und -Umzügen wird durch die $TTL- und SOA-Intervalle deutlich. Da die Zeitwerte immer von der letzten Anfrage des fremden Nameservers abhängig sind, können durchaus mehrere Tage vergehen, bis sämtliche fremde cachende Nameserver die Domain-Informationen aktualisiert haben.
132
Wichtige Serverdienste
1 2 IN NS
3
IN NS legt den zuständigen Nameserver fest. Üblicherweise ist der Eintrag doppelt vorhanden, da meist zwei Nameserver die Daten einer Domain bereithalten.
4 5
IN A, Domainnamen, @ und * Das At-Zeichen steht als Kürzel für unsere Domain-Zone. Anstelle von @ könnten Sie also auch home.test. eingeben. Beachten Sie den abschließenden Punkt hinter der Toplevel-Domain test. Fehlt dieser, erweitert Bind den Eintrag zusätzlich um Domainname.Topleveldomain. Aus home.test würde die Subdomain home.test.home.test entstehen.
6 7 8
Dies erklärt auch die letzte Zeile * IN A 192.168.0.25. Sämtliche angefragten Subdomains werden mit der IP-Adresse 192.168.0.25 aufgelöst. Selbstverständlich könnten Sie Subdomains auch definieren:
@ buchhaltung *.buchhaltung.home.test. *
IN IN IN IN
A A A A
9
192.168.0.35 192.168.0.33 192.168.0.34 192.168.0.35
10 11
Der zweite Eintrag mappt buchhaltung.home.test auf die IP 192.168.0.33. Falls buchhaltung.home.test um eine weitere Subdomain erweitert wird, liefert der Nameserver die IP 192.168.0.34 als zuständigen Server aus. Für alle anderen Subdomains (und home.test) ist dank @ und * der Rechner mit der IP 192.168.0.35 zuständig.
12 13 14
Die Reihenfolge ist hierbei unbedingt zu beachten. Falls Sie das Sternchen an den Anfang von IN-A-Records stellen, wird der Server 192.168.0.35 für sämtliche Domains der Zone home.test zuständig.
3.2.2
Testlauf
Laden Sie zunächst über /etc/init.d/named reload die Zonendateien neu. Installieren Sie das Paket dnsutils (enthaltene Programme zählen zum OpenBSD-Grundsystem), und rufen Sie dig domainname auf, um den in /etc/resolv.conf eingetragenen Nameserver nach der Domain domainname zu befragen. Falls Sie einen anderen Nameserver unabhängig von der ResolverKonfiguration ansprechen möchten, können Sie das At-Zeichen verwenden:
user@linbook:~> dig @192.168.0.25 buchhaltung.home.test ; <<>> DiG 9.1.3 <<>> @192.168.0.25 buchhaltung.home.test ;; global options: printcmd
Domain Name Server System
133
;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5083 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1,\ ADDITIONAL: 1 ;; QUESTION SECTION: ;buchhaltung.home.test. IN A ;; ANSWER SECTION: buchhaltung.home.test. 172800 IN A 192.168.0.33 ;; AUTHORITY SECTION: home.test. 172800 IN NS home.test. ;; ADDITIONAL SECTION: home.test. 172800 IN A 192.168.0.25 ;; Query time: 7 msec ;; SERVER: 192.168.0.25#53(192.168.0.25) ;; WHEN: Sat Feb 8 19:20:52 2003 ;; MSG SIZE rcvd: 85 Die IP-Adresse des für buchhaltung.home.test zuständigen Servers finden Sie unter der Zeile ANSWER SECTION (192.168.0.33). Sämtliche zuständigen Nameserver werden im Abschnitt AUTHORITY SECTION gelistet. Über ADDITIONAL SECTION ist zu erkennen, dass die Haupt-Domain home.test über die IPAdresse 192.168.0.25 erreichbar ist und die Subdomain buchhaltung.home.test (IP 192.168.0.33) vermutlich auf einem anderen Rechner liegt.
3.2.3
Bind im harten Server-Einsatz
Im Wesentlichen unterscheidet sich der Umgang mit echten Domain-Adressen nicht von dem mit unseren lokalen Test-Domains. Indes gilt es, MX-Records für die zuständigen Mailserver zu erteilen und einige Sicherheitsvorkehrungen zu treffen, um den für seine Sicherheitsprobleme bekannten Bind abzusichern. Weiterhin gilt es, einen zweiten Nameserver aufzusetzen. Bind sollte auf Anfragen lediglich dann antworten, wenn die Domain in seinem Zuständigkeitsbereich liegt (so genannte Zonentransfers sind zu verbieten). Die MX-Records (Mail-Exchanger) Wie der Name schon sagt, werden über die MX-Records die zuständigen Mailserver einer Domain definiert. Anfragende Mailserver stellen die Nachricht dem mit höchster Priorität erreichbaren Server zu. Verwenden Sie mehr als einen Mailserver, ist es empfehlenswert, einen Rechner als Backup-Mailserver
134
Wichtige Serverdienste
1 2 zu konfigurieren, der Nachrichten selbst dann annimmt, wenn der eigentliche Mailserver nicht erreichbar ist.
3
Als besonderen Clou können Sie die bestehende Mailserver-Konfiguration einfach übernehmen. Postfix erkennt automatisch, wenn er nicht als Root-Mailserver für eine Domain zuständig ist, und leitet die Nachrichten an den Root-Mailserver weiter, sobald dieser erneut erreichbar ist.
4 5
Der Vorteil liegt auf der Hand: Sie sind nicht der Geduld oder den Fehlermeldungen des fremden Mailservers ausgeliefert, da bei einem Ausfall des HauptMailservers der Backup-Server zur Verfügung steht. Erweitern Sie die Zonendateien Ihrer Domain um folgende Zeilen:
6
@ @
8
IN IN
MX 10 MX 20
7
root.mailserver.de. secondmail.meinezweitdomain.de.
9
Die Reihenfolge spielt keine Rolle. Abfragende Mailserver verwenden immer den ersten erreichbaren Mailserver mit dem niedrigsten MX-Eintrag (in unserem Beispiel root.mailserver.de).
10
Sicherheitsvorkehrungen innerhalb named.conf
11
Üblicherweise sind im Abschnitt Options der named.conf-Datei bereits einige Grundeinstellungen enthalten. Vergleichen und ergänzen Sie Ihre Konfigurationen gegebenenfalls durch folgende Zeilen:
12 13
options { directory "/var/cache/bind"; version "Nameserver meiner Firma"; allow-transfer { none; }; allow-recursion { localhost; }; };
14
Falls der Abschnitt Options nicht in Ihrer named.conf-Datei vorhanden ist, können Sie die Zeilen am Anfang der Konfigurationsdatei einfügen. Die eingangs erwähnte Problematik der Rekursion wird mit allow-recursion { localhost; }; auf die lokalen Dienste des Servers beschränkt. Arbeiten Sie mit einem zweiten Slave-Nameserver, ist anstelle von none unter allow-transfer die IP-Adresse des Slave-Nameservers einzutragen. Erlauben Sie Zonentransfers lediglich zu Ihren Slave-Nameservern (mehrere IP-Adressen durch Semikolon trennbar), da sonst jedermann Zugriff auf die gesamten Zonendaten Ihres Nameservers erhält und nicht nur einzelne Domains abfragen kann.
Domain Name Server System
135
Bind chrooten Der Bind-Daemon benötigt lediglich Zugriff auf seine Konfigurations- und Zonendateien. Deshalb kann er recht einfach in einem Chroot-Käfig als unprivilegierter Nutzer betrieben werden. Prüfen Sie zunächst, mit welchem User Bind derzeit läuft (ps –aux | grep named). Falls noch kein unprivilegierter Account für Bind existiert, sollten Sie zunächst einen neuen anlegen. Danach sind die folgenden Befehle aufzurufen:
mkdir –p /home/bind/var/cache/bind mkdir /home/bind/var/run chown –r bind /home/bind/var/* mv /var/named /home/bind/var/named ln –s /home/bind/var/named /var/named Hinweis Unter Debian finden Sie die Konfigurationsdateien anstelle von /var/named unter /etc/bind. Selbstverständlich sind die Verzeichnisangaben entsprechend abzuändern. Bind9 wechselt erst nach dem Programmaufruf ins Chroot-Verzeichnis. Deshalb werden das Binary und die benötigten Bibliotheken nicht im späteren ChrootKäfig gebraucht, und Sie können Bind über /usr/sbin/named -t /home/bind -u bind starten. Ein Slave-Nameserver Wer zwei eigene Nameserver betreibt, hat die Möglichkeit, die Zonendateien über Shell-Skripte abzugleichen. Allerdings können sich Administratoren diese Arbeit sparen, indem der zweite Nameserver als Slave konfiguriert wird und die Zonendaten über Zonentransfers selbstständig vom Master-Nameserver bezieht. Damit dies möglich ist, müssen Sie im Master-Nameserver Zonentransfers für die IP-Adresse des Slave-Nameservers erlauben. Es sei an dieser Stelle nicht verschwiegen, dass hierdurch eine potentielle Missbrauchsmöglichkeit (zum Beispiel über Spoofing) entsteht. Andererseits ersparen Sie sich den doppelten Pflegeaufwand. Eine Automatisierung über ein Shell-Skript birgt ebenfalls Gefahren. Die Zeile allow-transfer { 192.168.0.2; }; im OptionsAbschnitt von named.conf des Master-Nameservers würde dem Slave-Nameserver (192.168.0.2) einen Zonentransfer gestatten.
136
Wichtige Serverdienste
1 2 Die Konfiguration des Slave-Nameservers geht ebenso schnell von der Hand. Auch hier gilt es, lediglich die named.conf anzupassen:
3
zone "home.test" in { type slave; file "/etc/bind/db.home.test"; masters { 192.168.0.25; }; };
4 5 6
Hinweis Damit die Zonendatei geschrieben werden kann, benötig der User, unter dem Bind läuft, selbstverständlich ebenfalls Zugriff auf das Konfigurationsverzeichnis (in unserem Beispiel einer Debian-Chroot-Installation ist /home/bind/etc/bind dem Nutzer named zu überschreiben).
7 8 9
Änderungen an den Zonendateien des Masters übernimmt der Slave nach Ablauf des als Refresh definierten Zeitintervalls im SOA-Record. Sollen die Änderungen unmittelbar übernommen werden, ist der Slave-Nameserver neu zu starten. Ein Reload genügt nicht, da lediglich bei einem Neustart die bestehenden Zonendaten anhand der Seriennummer auf Änderungen überprüft werden. Allerdings genügt ein Reload, damit der Slave die Daten einer neuen Zone beziehen kann.
3.2.4
10 11 12 13
Domains registrieren und KK-Anträge
Domain-Verwaltungsbetriebe wie DENIC, AFILIAS oder CORENIC erhalten Domain-Anträge in einem automatisierten Verfahren von Registraren. Auch wer kein offizieller DENIC-Partner ist, hat die Möglichkeit, bei der DENIC Domains registrieren zu lassen.
14
Allerdings sind die Gebühren für eine direkte Registrierung einer Hand voll Domains sehr hoch, weshalb kleinere Hoster Domains nicht selbst registrieren, sondern die Anträge über einen »offiziellen« Registrar an die DENIC leiten. Dies kann sich für Sie nachteilig auswirken, wenn der Dienstleister den zwischengeschalteten Registrar nicht vereinbarungsgemäß bezahlt oder gar Pleite geht. Obendrein kommt es nicht selten vor, dass Domains nicht über ein und denselben Registrar angemeldet sind, sondern verschiedene Firmen beauftragt werden. Da für die Verwaltung der Domain-Namen nicht die Vergabestelle zuständig ist, müssen Sie in so einem Fall für Ihre eigenen Domains KK-Anträge bei sämtlichen involvierten Registraren einreichen. Um sich diesen Papierkrieg zu
Domain Name Server System
137
ersparen, rate ich dringend, Domains nur bei »offiziellen« Registraren zu bestellen. Unter http://www.denic.de/doc/DENIC/mitglieder.shtml finden Sie eine Liste sämtlicher »offizieller« Registrare für .de Domains. Darunter sind viele Firmen, die gleichzeitig Hosting-Pakete und dedizierte Server anbieten. Unter anderen ist bei http://www.server-service.de, http://www.hostserver.de oder http://www.http.net auch eine Domain-Registrierung ohne HostingPaket möglich. Betreiben Sie lediglich einen Nameserver, gilt es, bei einer Zusammenarbeit mit einem »offiziellen« Registrar darauf zu achten, ob der Dienstleister Ihnen einen oder gar zwei Nameserver für die Domain zur Verfügung stellt. Meist ist dies alles andere als selbstverständlich und (wenn überhaupt) ausschließlich als kostenpflichtige zusätzliche Dienstleistung erhältlich. Verfahren Obwohl die technische Realisierung der Administrationsoberfläche zur Domain-Verwaltung bei den einzelnen Registraren abweichen wird, gibt es grundsätzliche Verfahrenspunkte, die Sie überall wiederfinden und die Sie kennen sollten. Beachten Sie außerdem Abschnitt 8.3, Rechtliche Hinweise und Verfahrensfragen zu Domain-Adressen. .de-, .com-, .net- und .org-Domains Um .de-Domains zu beantragen oder über einen KK-Antrag ändern zu können, benötigen Sie ein so genanntes Handle für sich selbst (tech-c1 und zone-c2) sowie den admin-c3. Das Handle ist (kostenlos) gesondert und mit den jeweiligen Kontaktinformationen zu beantragen. Sobald das Handle erstellt ist, können Sie es über seine Kennung bei der Beantragung neuer Domains oder KK-Anträgen einsetzen. .info und .biz Die Handhabung von Info-Domains kann insbesondere bei KK-Anträgen Geduld erfordern, da das Zusammenspiel zwischen Registraren und der AFILIAS bisher nicht reibungslos abläuft. Für Sie bedeutet dies, dass Anträge durchaus mehrfach abzusenden sind, bevor die Abwicklung ordnungsgemäß abgeschlossen ist. 1 Tech-c = Technischer Verwalter 2 Zone-c = Zonenverwalter der Nameserver 3 Admin-c = Domain-Eigner (Endkunde). Der Domain-Eigner kann alternativ eine andere Person oder Firma als Ansprechpartner festlegen.
138
Wichtige Serverdienste
1 2 Leider werden bei .info- und .biz-Domains Handles erst mit der Domain-Vergabe beziehungsweise der Übernahme bereitgestellt. Dies führt dazu, dass Sie bei jedem (erneuten) Absenden eines Domain-Antrags die Kontaktdaten vollständig ausfüllen müssen.
3 4
Ärgerlicherweise sind Domain-Übernahmen auch unnötig kompliziert: Nach der erfolgreichen »Domain-Übernahme« (Bestätigung: TRANSFER OF DOMAIN »xy« REQUESTED SUCCESSFULLY) ist zusätzlich ein Update auszuführen, um die Domain in den eigenen Zugriffsbereich zu überschreiben und die Nameserver-Einträge zu aktualisieren.
5 6 7
3.2.5
Wann lohnt sich der eigene Nameserver?
8
Der Betrieb eines eigenen Nameservers lohnt sich nicht. Verwenden Sie lieber die Nameserver Ihres Dienstleisters für Domain-Registrierungen. Erst wenn Ihnen zwei eigene Server in unterschiedlichen Subnetzen zur Verfügung stehen, wird der Einsatz eigener Nameserver interessant, da Sie nun einen automatisierten Datenabgleich über ein Shell-Skript oder einen Slave-Nameserver vornehmen können.
9 10 11
Häufig bieten Registrare auch E-Mail-Robots an, über die per E-Mail neue Domain-Zonen angelegt und bestehende geändert werden können. Sogar das Bestellen oder Löschen einer Domain ist möglich. Allerdings sollten Sie davon aus Sicherheitsgründen Abstand nehmen. Neben möglichem Missbrauch von Seiten Dritter wären Sie denkbaren Programmfehlern Ihrer AutomationsSkripte ausgeliefert. Auch wenn üblicherweise nicht mehr als zehn DomainBestellungen pro Tag erlaubt sind, ist ein amoklaufender Robot ärgerlich und kann neben zusätzlicher Arbeit zudem Kosten und einige peinliche Telefonate verursachen.
3.3
12 13 14
Apache
Der Apache Daemon ist durch seine Eigenschaft als Webserver wohl der bekannteste Server-Dienst. Obwohl die Version 2 schon seit gut zwei Jahren als stabil bezeichnet werden kann, bieten sowohl Debian als auch OpenBSD noch immer lediglich die Version 1.3.x mit den entsprechenden Zusatzerweiterungen an. Da PHP 4.3.1 und neuere Versionen neben mod CGI (für Perl/Python) bereits stabil mit dem Apache 2 zusammenarbeiten, ist es nur eine Frage der Zeit, bis alle wichtigen Module und kommerziellen Erweiterungen einwandfrei mit Apache 2 zusammenspielen und die Distributoren sich dazu entschließen, Apache 1.3.x nicht länger zu verwenden. Vermutlich wird dies bereits mit dem
Apache
139
Erscheinen einer der nächsten OpenBSD- und Debian-Versionen der Fall sein. Ich will deshalb zugunsten der Performance-, Flexibilitäts- und Stabilitätsverbesserungen auf Installation und Konfiguration von Apache 2 eingehen. Die Konfigurationshinweise zu PHP oder mod_cgi lassen sich zu großen Teilen direkt auf die Version 1.3.x übertragen. Ich werde auf Besonderheiten gegebenenfalls hinweisen, so dass dieser Abschnitt auch für Nutzer der Version 1.3.x Hilfestellungen und Konfigurationstipps enthält. Vorweg weise ich darauf hin, dass eine zuverlässige Traffic-Auswertung (mod_logio) und die leistungsstarken Ausgabefilter, die es ermöglichen, in PHP- oder CGI-Skripten gleichzeitig auch SSI einzusetzen, erst seit Version 2 verfügbar sind. Neben der eigentlichen Auslieferung von HTML-Seiten an den Browser eines Clients ist der Apache nahezu grenzenlos erweiterbar. So verwundert es kaum, dass dank Modulen für einen Proxyserver serverseitige ImageMaps, WebDAV, Integration eines FTP-Servers oder Cookies zur eindeutigen Nutzeridentifizierung (um Besucherverhalten und Wege durch die Homepage beobachten zu können) nicht nur ganze Bücher gefüllt werden können, sondern kritische Stimmen den aufgeblasenen Umfang des Quellcodes einer Apache-Installation bemängeln. Dies ist allerdings nur bedingt richtig, da der Apache modular angelegt ist und lediglich mit den tatsächlich gewünschten Erweiterungen kompiliert werden kann. Tatsächlich empfiehlt es sich, den Apache aus Performance- und Sicherheitsgründen möglichst klein zu halten. Wer einen Proxyserver benötigt, dem sei Squid wärmstens ans Herz gelegt. Übrigens ist ein Proxyserver nur bedingt geeignet, die Server-Last zu senken. Falls Sie Lastverteilung realisieren möchten, eignet sich ein echter Loadbalancer wie pen (siehe Abschnitt 4.11, Loadbalancing) besser als mod_proxy und auch besser als Squid. Auch für anonymous FTP bietet sich ein richtiger FTP-Server eher an als die Erweiterung des Apache-Webservers. Auf die eindeutige Nutzeridentifizierung und Verfolgung mit mod_usertrack möchte ich schon aus Datenschutzgründen nicht näher eingehen. Die Möglichkeiten von mod_usertrack sind nur dann legitim, wenn Nutzer dem zugestimmt haben und entsprechend informiert wurden sowie keine »ahnungslosen« Surfer vorbeischauen können, wie beispielsweise in einem durch Passwort geschützten Bereich. Der experimentelle Stand der höchst interessanten Cache-Module (mod_cache, file-cache, mem-cache, disk-cache) spricht leider noch immer gegen den Einsatz auf einem Internet-Server. Ähnliches gilt für den effektiven Kompressionsfilter mod_deflate (in Apache1.3.x: mod_gzip), mit dem sich einerseits Bandbreite spa-
140
Wichtige Serverdienste
1 2 ren lässt, andererseits jedoch bei Browsern, die mit den komprimierten Daten nichts anfangen können, »nur Müll auf dem Monitor« erscheint.
3
Leider gewährt auch der selektive Einsatz von mod_deflate nach Prüfung der Browser-Kennung keine Sicherheit (Browser-Kennung lässt sich in der Regel ändern), so dass Sie derzeit auf den Einsatz dieses Moduls verzichten müssen, um sicherzugehen, keine Besucher mit älteren oder noch nicht entsprechend ausgereiften Browsern auszusperren.
4 5 6
Wer trotz der aufgeführten Gründe eines der von mir nicht näher besprochenen Module einsetzen möchte, dem sei die offizielle Apache-Dokumentation ans Herz gelegt. Der direkte Link zu den Modulhinweisen lautet: http://httpd.apache.org/docs-2.0/mod/.
3.3.1
7 8
Installation
9
Apache 2.0.52 finden Sie auf der CD zum Buch (src/httpd-2.0.52). Ich empfehle aus Sicherheitsgründen jedoch unbedingt die Installation der unter http://www.apache.org/dyn/closer.cgi bereitgestellten stabilen und aktuellsten Version, die Sie im Verzeichnis httpd der Mirrors finden.
10 11
Dank des bereits angesprochenen Sammelsuriums an Erweiterungen fällt ./configure --help=short sehr umfangreich aus. In Tabelle 3.1 habe ich die wichtigsten Zusatzerweiterungen oder mögliche Ausgliederungskandidaten zusammengestellt. Diese Übersicht sollte Ihnen helfen, ./configure die richtigen Optionen zu übergeben.
12 13 14
Eine Besonderheit des modularen Konzepts von Apache ist es, dass Erweiterungen entweder statisch oder als dynamische Module kompiliert werden können. Letzteres empfiehlt sich immer dann, wenn einzelne Module starken Weiterentwicklungen sowie häufigen Sicherheits-Patches unterliegen. Solange Updates mit der von Ihnen genutzten Apache-Version zurechtkommen, ist es ausreichend, das betreffende Modul neu zu kompilieren. Das erneute Übersetzen des gesamten Webservers, um lediglich eine neue Version von mod_php einzuspielen, entfällt. Da statisch kompilierte Erweiterungen performanter sind als dynamisch geladene Module, ist es nicht empfehlenswert, sämtliche Zusatzerweiterungen als dynamische Module zu kompilieren. Falls Sie die Module auth, access, digest, ssl oder alias zum Zeitpunkt des Kompilierens nicht benötigen, empfiehlt es sich, diese Erweiterungen als dynamische Module zu kompilieren, um sie bei Bedarf ohne langwierige Neukompilierung sofort aktivieren zu können.
Apache
141
Beachten Sie, dass der Apache Module erst durch die ./configure-Option --enable-so dynamisch laden kann. In der Voreinstellung ist die Unterstützung zum Laden von externen Modulen deaktiviert. Minimalbeispiel für statische Webseiten Für eine minimale Apache-Installation, mit der lediglich statische Seiten angezeigt werden sollen, können Sie bedenkenlos die verbesserten Möglichkeiten des Multi-Threading-MPMs »worker« verwenden und sämtlichen »Ballast über Bord werfen«:
./configure --disable-access --disable-auth \ --disable-include --enable-logio --disable-env \ --disable-status --disable-asis -–disable-cgid \ --disable-imap --disable-negotiation \ --disable-actions --disable-userdir \ -–with-mpm=worker Vielleicht sind Sie etwas verblüfft über die Verwendung von -–disable-cgid anstelle von -–disable-cgi. Die Begründung ist recht einfach: Wird der MPM-Worker verwendet, nutzt ./configure das hierfür performantere mod_ cgid in der Voreinstellung. Praxisbeispiel In der Praxis werden Sie, um Seiten dynamisch erzeugen zu können, auf SSI und zumindest eine Skriptsprache kaum verzichten wollen. Aufgrund der guten Absicherungsmöglichkeiten und der hohen Performance von mod_php ziehe ich PHP 4 und mod_so der Kombination von mod_cgid und mod_suexec vor. Wer die volle Kontrolle über seinen Webserver besitzt und somit weder Mitarbeitern, Bekannten, Freunden noch Kunden in irgendeiner Form Rechte (zum Beispiel für einen FTP-Zugang) bereitstellt, der kann gerne aus dem Vollen schöpfen und mod_cgi ohne oder mit mod_suexec aktivieren. Wer über den Browser Passwörter versenden möchte, sollte nach Möglichkeit auch auf mod_access verzichten und stattdessen lieber zu mod_ssl und einer Skriptsprache greifen. Die Datenübertragung mit SSL bringt selbst bei inoffiziellen Zertifikaten Sicherheitsvorteile gegenüber der Digest-Authentifizierung. Allerdings müssen Sie bei selbst erstellten Zertifikaten unschöne Warnmeldungen in Kauf nehmen. Manche Browser verweigern sogar grundsätzlich die Akzeptanz von inoffiziellen und daher als »unsicher« betrachteten Zertifikaten. Eine verschlüsselte Kommunikation ist dann nicht möglich. Falls Sie am Ver-
142
Wichtige Serverdienste
1 2 zeichnisschutz von mod_auth nicht vorbeikommen, sollten Sie sich überlegen, ob Digest-Verschlüsselung verwendet werden kann.
3
Beispiel für SSL mit dynamischen Modulen (für mod_php):
4
./configure --enable-ssl --enable-logio \ --disable-asis --disable-cgi \ --disable-imap --disable-actions \ --disable-userdir --disable-negotiation \ --enable-access=shared --enable-auth=shared \ --enable-auth-digest=shared --enable-so
5 6 7
Konfiguration für Buchbeispiele
8
Um sämtliche der folgenden Buchhinweise nachbauen zu können und die wichtigsten und interessantesten Möglichkeiten von Apache kennen zu lernen, ist der Webserver wie folgt zu kompilieren:
9
./configure --enable-auth-digest=shared --disable-actions \ --enable-logio -–disable-asis --disable-imap \ --disable-userdir --enable-so --enable-ssl \ -–enable-cgi=shared --disable-negotiation \ --enable-suexec=shared \ --with-suexec-caller=www-data \ --with-suexec-docroot=/home \ --with-suexec-logfile=/var/log/suexec.log
10
Als Shared Module kompilierte Erweiterungen aktivieren
14
11 12 13
Haben Sie sich für die Erstellung eines dynamischen Moduls (= shared) entschieden, finden Sie im Ordner /usr/local/apache2/modules/ die von Apache bei Bedarf zu ladende Moduldatei. Die Einbindung erfolgt über die Zeile:
LoadModule actions_module \ /usr/local/apache2/modules/mod_actions.so Hinweis Vom eigentlichen Modulnamen (mod_actions) müssen Sie sich die Kennung mod_ und das Suffix .so weg- sowie die neue Endung _module hinzudenken. Deshalb heißt die Zeile nicht LoadModule mod_actions /pfad/zur/datei.so, sondern LoadModule actions_module /pfad/zur/ datei.so.
Apache
143
Zu übergebende Option
Wirkung
--disable-access
Deaktiviert hostbasierte Zugriffsbeschränkungen (nach IPAdressen).
--disable-auth
Deaktiviert nutzerbasierte Zugriffsbeschränkungen (nach Nutzernamen und Passwort).
--enable-auth-digest
Ermöglicht eine Digest-verschlüsselte Passwortübertragung nach RFC2617 für mod_auth. Leider wird Digest noch immer nicht von allen Browsern unterstützt: Mit Internet Explorer, Amaya, Opera und Netscape (erst seit Version 7.0) beziehungsweise Mozilla funktioniert alles wunderbar. Allerdings müssen Besucher mit exotischeren oder älteren Browser-Versionen »draußen bleiben«.
--enable-auth-dbm
Wenn mit sehr vielen differenzierten Zugriffsbeschränkungen auf Nutzerebene (mod_auth) gearbeitet werden muss, empfiehlt sich der Einsatz einer BerkelyDB- oder DBM-Datei, um den Zugriff zu beschleunigen. Aktivieren Sie auth-dbm ab 100 eigenständigen Nutzerkennungen.
--enable-ldap
Aktiviert den LDAP-Support von Apache.
--enable-auth-ldap
Erlaubt Benutzerauthentifizierung über LDAP.
--disable-include
Deaktiviert Server Side Includes (SSI).
--enable-ssl
Ermöglicht es, Daten mit Secure Socket Layer (SSL) verschlüsselt zu übertragen. Benötigt und verwendet die OpenSSLLibrary. Als Alternative kann »die SSL-Version von Apache« http://www.apache-ssl.org installiert werden. Debian verwendet »zwei« Apaches: den herkömmlichen und Apache-SSL. Der Vorteil liegt in der flexibleren Konfiguration und der gezielteren Aktivierung benötigter Module. Der Nachteil liegt in den zwei zu pflegenden Apache-Installationen und entsprechend »doppelt« vorhandene Konfigurationsdateien.
--enable-dav
Bindet das WebDAV-Protokoll ein.
--enable-dav-fs
Aktiviert WebDAV mitsamt Versionsverwaltung und einem »eigenen Filesystem«. Allerdings sind die Clients für WebDAV derzeit noch nicht wirklich ausgereift. Das Apache-Modul ist jedoch bereits für den harten Einsatz geeignet.
--enable-ext-filter
Ein zusätzlicher Ausgabefilter, über den auch externe (also Apache-fremde) Befehle und Programme aufgerufen werden können. Weitere Hinweise unter: http://httpd.apache.org/docs2.0/mod/mod_ext_filter.html.
Tabelle 3.1 Die wichtigsten ./configure-Optionen für Apache 2
144
Wichtige Serverdienste
1 2 Zu übergebende Option
Wirkung
--enable-logio
Aktiviert Logmöglichkeiten für die tatsächliche Anzahl der einund ausgehenden Bytes (inklusive Headergrößen). So wird es dank Apache 2 endlich möglich, Traffic zuverlässig auszuwerten.
3 4
--disable-env
Verhindert das Setzen und Ändern neuer Umgebungsvariablen. In der Regel ist es wenig sinnvoll, auf mod_env zu verzichten.
5
--enable-mime-magic
Aktiviert die automatische Dateitypenerkennung, die auch ohne schlüssiges Suffix anhand des Dateiinhalts versucht, den Typ zuzuweisen.
6 7
Sehr Performance-hungrig. Nur gezielt für einzelne virtuelle Hosts freigeben, wenn darauf nicht verzichtet werden kann. --enable-charset-lite
Unterstützung für spezielle ISO-Zeichensätze (zum Beispiel Chinesisch, Kyrillisch, Russisch etc.). Siehe auch http://httpd.apache.org/docs-2.0/mod/mod_charset_lite.html.
--disable-status
Deaktiviert über einen Browser erreichbare Server-Hinweise. Hierzu zählt die Anzahl von aktiven wie inaktiven Eltern- und Kindprozessen (inklusive CPU-Auslastung, Prozesszeiten und Traffic in Byte).
8 9 10
Im Normalfall werden Sie diese Informationen nicht über einen Browser abfragen wollen. Falls Sie mod_status nutzen möchten, sollten Sie einen lokalen Text-Browser wie lynx mit ssh zur Abfrage nutzen und die Ausgabe von mod_status auf die lokale IP-Adresse beschränken (siehe mod_access).
11
--disable-autoindex
Deaktiviert die optionale Erzeugung von Verzeichnis-Listings. Im Normalfall ist es hilfreich, Verzeichnis-Listings selektiv aktivieren zu können.
13
--disable-negotiation
Versucht zu Browser-Anfragen, für die keine eindeutig passende Datei existiert, eine Auswahlliste möglicher Dateien, die der Anfrage entsprechen, zu erzeugen.
12
14
Aus Performance-Gründen sollten Sie auf mod_negotiation lieber verzichten. Weitere Informationen finden Sie unter: http://httpd.apache.org/docs-2.0/content-negotiation. html. --disable-asis
Deaktiviert die Option, Dateien mit ihrem Header unverändert (as-is) zu versenden.
--enable-info
Ermöglicht es, eine Übersicht der aktuellen Apache-Konfiguration über den Browser einsehen zu können. Die Ausgabe von mod_info sollte – wenn überhaupt – lediglich für localhost mit mod_access zugänglich sein.
--enable-cgid
Deaktiviert die Ausführung von CGI-Programmen über einen zusätzlichen Daemon (performanter, wenn ein Multi-Threading-MPM verwendet wird).
Tabelle 3.1 Die wichtigsten ./configure-Optionen für Apache 2 (Forts.)
Apache
145
Zu übergebende Option
Wirkung
--disable-cgi
Aktiviert die direkte Ausführung von CGI-Programmen durch den Apache. Unter dem Standard-MPM Prefork ist mod_cgi performanter als mod_cgid.
--enable-suexec
Ermöglicht es, CGI-Programme mit den Rechten des Eigentümers auszuführen, und verhindert so, dass Perl-, Python- oder PHP-Skripte automatisch mit den Rechten und Möglichkeiten des Webservers ausgeführt werden müssen. Damit suExec aktiviert wird, sind mindestens zwei with-suExec-Optionen zusätzlich zu übergeben. Dies ist ohnehin notwendig, da Sie zumindest die Optionen caller und docrot für ein sinnvolles suExec-Setup angeben müssen. Eine Beschreibung zu allen suExec-Optionen finden Sie unter: http://httpd.apache.org/docs-2.0/suexec.html.
--with-suexec-caller
User-Name, unter dem Ihr Webserver später laufen wird. Aufruf von suExec wird nur ihm gestattet.
--with-suexec-docroot
Geben Sie hier den Pfad zu dem Ordner an, in dem später Ihre Gast-Accounts liegen werden. Lediglich innerhalb des suExecdocroot wird der suExec-Wrapper zum Einsatz kommen.
--with-suexec-logfile
Pfad und Name des suExec-Logfiles
--with-suexec-userdir
Falls Sie die userdir-Optionen von Apache nutzen möchten (siehe - -disable-userdir), ist hier der Name des Webverzeichnisses anzugeben (Voreinstellung ist public_html).
--disable-imap
Deaktiviert serverseitige Image-Maps.
--disable-actions
Auf die Möglichkeit, externe Programme auszuführen, wenn ein bestimmter MIME Type/Handler aufgerufen wird, kann in der Regel verzichtet werden.
--enable-speling
Ermöglicht die Korrektur von Tippfehlern in URLs. Leider performancehungrig und daher nur eingeschränkt empfehlenswert.
--disable-userdir
Gestattet mit http://domain.de/~nutzername/datei.html den Aufruf von Webseiten, die in einem Ordner wie public_ html im Home-Verzeichnis eines Nutzers liegen. Die Nutzung virtueller Hosts ist dank Subdomains und flexiblerer Konfigurationsmöglichkeiten häufig auch für lokale Accounts die elegantere Lösung. http://nutzername.domain.de/datei.html wirkt zudem ungleich professioneller.
--disable-alias
Deaktiviert die Nutzung von Aliasen. In der Beispielkonfiguration werden Aliase genutzt, um das Icon-Verzeichnis bequemer zu verknüpfen.
Tabelle 3.1 Die wichtigsten ./configure-Optionen für Apache 2 (Forts.)
146
Wichtige Serverdienste
1 2 Zu übergebende Option
Wirkung
--enable-rewrite
Aktiviert das beliebte und von vielen als »magisch« bezeichnete mod_rewrite. Ermöglicht es, URLs mit regulären Ausdrücken zu verändern. Im Normalfall kann auf dieses sehr performancehungrige Modul verzichtet werden.
3
--enable-so
Gestattet die optionale und dynamische Einbindung von externen zusätzlichen Modulen. Wird beispielsweise für mod_php benötigt.
--with-mpm=worker
Kompiliert Apache mit dem performanteren MPM-Worker anstelle von Prefork. Die Nutzung ist leider nicht uneingeschränkt empfehlenswert (siehe in diesem Kapitel den Abschnitt Optimierung der Performance).
--with-mpm=perchild
4 5 6 7
Leider ist dieses MPM für die derzeit aktuelle Version 2.0.46 als experimentell eingestuft und sollte noch nicht zum Einsatz kommen. Das MPM ist nicht nur ein Kompromiss zwischen Worker und Prefork: Perchild ermöglicht es, neben CGI-Skripten auch statische HTML-Seiten oder PHP-Skripte lediglich mit den Nutzerrechten der ID des VirtualHosts auszuführen.
8 9 10
Der auszuführende Nutzer wird innerhalb der VirtualHost-Sektionen mit den User- und Group-Direktiven festgelegt. Damit die Ausführung möglich ist, müssen die Dateien natürlich mit den passenden Zugriffsrechten versehen sein.
11
Tabelle 3.1 Die wichtigsten ./configure-Optionen für Apache 2 (Forts.)
3.3.2
12
Grundkonfiguration
13
Bevor wir uns interessanten Detailfunktionen zuwenden können, gilt es, zunächst die Grundeinstellungen vorzunehmen. Für einen schnellen Test empfiehlt sich die Datei apache2/conf/highperformance.conf, die nach kleineren Anpassungen auch mit den minimalsten Apache-Einstellungen sofort zusammenarbeitet.
14
왘 Passen Sie den User- und den Group-Account-Namen gegebenenfalls an Ihr
System an. Am besten erstellen Sie für den Apache gleich einen eigenen Useraccount und eine besondere Gruppe. Wurde Apache mit suExec-Unterstützung kompiliert, ist der suExec-caller zwingend als User zu verwenden. 왘 Entfernen Sie das Kommentarzeichen vor den beiden Directory-Abschnitten
unterhalb »If this was a real server ...«:
Apache
147
왘 Überprüfen Sie, ob der Host-Name (/etc/hostname) auch korrekt über
/etc/hosts aufgelöst werden kann. Sonst beschwert sich Apache mit der Meldung »Could not determine the server's fully qualified domain name«. Gegebenenfalls ist /etc/hosts zu erweitern:
192.168.0.2 vollstaendige.domain hostname 왘 Nach dem Aufruf von
/usr/local/apache2/bin/httpd -f \ /usr/local/apache2/conf/highperformance.conf wird der httpd-Daemon starten, und Sie können die im Verzeichnis /usr/local/apache2/htdocs abgelegten Testseiten im Browser aufrufen: http://192.168.0.2/index.html.de. Hinweis Da mod_autoindex (noch) nicht zum Einsatz kommt, erhalten Sie bei Aufruf von http://192.168.0.2/ die Fehlermeldung »You don't have permission to access / on this server.« Globale Server-Einstellungen
ServerTokens Prod weist den Apache an, lediglich seinen Programmnamen im response header mitzusenden (Security by obscurity). In der Voreinstellung (wenn ServerToken als Full oder gar nicht definiert wurde), sendet der Apache neben seiner vollständigen Versionsangabe zudem Informationen zu den einkompilierten Modulen und zum genutzten Typ des Betriebssystems.
ServerName Name.domain:80 ermöglicht eine vom Host-Namen abweichende Server-Bezeichnung. Optional kann auch der Port angegeben werden. Dies ist interessant, wenn ServerSignature eingeschaltet wird.
ServerAdmin [email protected] Die Definition einer E-Mail-Adresse des zuständigen Server-Administrators ist bei Fehlermeldungen des Webservers und aktivierter ServerSignature nützlich.
ServerSignature [Off | On | eMail] ServerSignature Off unterbindet zusammen mit ServerTokens Prod die Kennzeichnung der Apache-Version vollständig. Andererseits ist die Option E-Mail sehr interessant, da der Apache dann in Verzeichnisübersichten (mod_autoin-
148
Wichtige Serverdienste
1 2 dex) und bei sämtlichen Fehlermeldungen nebst der Apache-Versionsnummer sowie dem Betriebssystemtyp zudem mit einem Hinweis auf die E-MailAdresse des zuständigen Administrators »unterschreibt« (siehe ServerAdmin). Wenn Sie ServerSignature auf On setzen, wird lediglich die Apache-Versionsnummer und der Typ des Betriebssystems ausgegeben.
3 4 5
listen 8080 listen 192.168.0.2:80
6
In der Voreinstellung lauscht der Apache auf dem Port 80 sämtlicher IP-Adressen und Netzwerk-Interfaces. Über die Listen-Direktive können Sie Apache 2 anweisen, nur noch Anfragen anzunehmen, die an eine bestimmte IP-Adresse gerichtet sind. Zusätzlich besteht die Möglichkeit, einen anderen Port festzulegen. Das ist notwendig, wenn zum Beispiel ein Loadbalancer neben dem Apache auf dem Server gleichzeitig laufen soll oder die Nutzung virtueller Server die Bindung des Apache an eine bestimmte IP-Adresse erfordert.
7 8 9
Beachten Sie, dass Mehrfachangaben erlaubt sind. Apache 2 würde in unserem Beispiel sämtliche Anfragen an Port 8080 sowie Anfragen an die IP-Adresse 192.168.0.2 auf Port 80 entgegennehmen.
10 11
Optimierung der Performance
12
Abgesehen von der Deaktivierung nicht benötigter Module und Funktionen können Sie über die Konfigurationsdatei weitere Optimierungen vornehmen. In der Voreinstellung wird Apache mit dem MPM-Prefork installiert. Leider sind noch nicht alle Apache-Erweiterungen für Worker geeignet. Deshalb wird für hohe Stabilität und Kompatibilität auf den Performance-Vorteil des MPMWorkers verzichtet.
13 14
Sicher ist Ihnen bereits aufgefallen, dass sich die Konfigurationsabschnitte zwischen Prefork und Worker innerhalb highperformance.conf massiv voneinander unterscheiden. Dies liegt grundsätzlich im anderen Konzept der beiden MPMs begründet. Vereinfacht ausgedrückt, startet der Apache bei Prefork für jede Anfrage einen neuen Fork, der die gewünschte Aufgabe erfüllt (Exec) und sich danach beendet. Worker arbeitet dagegen nur mit Threads und kommt gänzlich ohne das Erzeugen von Forks aus. Dies erklärt, wieso für Worker eine sehr hohe Anzahl laufender Threads benötigt wird. Nur so ist gewährleistet, dass alle Anfragen direkt entgegengenommen werden können. Leider ist es nicht möglich, eine Empfehlung für die optimalen Prozesseinstellungen zu erteilen, da sehr viel von Ihrem Server (genügend RAM- und CPULeistung neben schneller Festplatte) und den übrigen Gegebenheiten (statische oder dynamische Sites) abhängt.
Apache
149
Somit müssen Sie mit einem Tool wie Siege (siehe Abschnitt 4.9.2, Apache under Siege) experimentieren, um die für Ihren Server optimalen Werte zu finden. 왘 Unabhängig davon, dass der Server genügend physikalischen RAM besitzen
sollte (auf keinen Fall swappt) und unabhängig von der Optimierung von PHP- und CGI-Skripten, sollten Sie folgende Punkte beachten: 왘 Options FollowSymLinks steigert die Performance, da die Prüfung nach
SymLinks unterbleibt und Dateien direkt aufgerufen werden können. 왘 AllowOverride none unterbindet die aufwändige Suche nach .htaccess-
Dateien und verhindert gleichzeitig benutzerspezifische Änderungen. 왘 Die Angabe vollständiger Dateinamen (mit Suffix) wie beispielswiese
DirectoryIndex index.html index.php ist performanter als die Nutzung einer Wildcard wie DirectoryIndex index. Apache erkennt, dass auf das Suffix verzichtet wurde, und sucht nun nach index.*. 왘 mod_speling und mod_rewrite sind sehr ressourcenhungrig. In der Regel kön-
nen Sie ohne nennenswerte Unannehmlichkeiten auf beide verzichten. 왘 Generell sind, um die bestmögliche Performance zu erreichen, alle Erweite-
rungen statisch einzukompilieren und es sollte auf sämtliche nicht benötigten Module mit disable explizit verzichtet werden.
3.3.3
Default Server und virtuelle Hosts
Sobald die Grundeinstellungen vorgenommen worden sind, können Sie statische Seiten in /usr/local/apache2/htdocs/ nach Belieben ablegen und die Beispieldateien getrost ersetzen. Das Verzeichnis des Standard-Servers ist über die Zeile DocumentRoot/usr/local/apache2/htdocs übrigens frei definierbar. Selbstverständlich muss der Apache Leserechte für die dort abgelegten Daten besitzen, um die Dateien überhaupt öffnen zu können. 왘 Wer mit statischen Seiten auskommt, kann durch restriktive Rechtevergabe
ein deutliches Sicherheitsplus erlangen. Selbst wenn es einem Angreifer gelingen sollte, die Kontrolle über den Apache zu erhalten, wird er ohne jegliche Schreibrechte auf Dateien und Verzeichnisse nicht allzu großen Schaden anrichten können. Am effektivsten ist es, dem User die Gruppe des Webservers zuzuweisen und Verzeichnisse automatisch mit den Zugriffsrechten 750 und Dateien mit den Zugriffsrechten 740 zu versehen. Mit einem FTP-Server wie ProFTPD (siehe Abschnitt 3.12, Der FTP-Server ProfTPD) ist dies zum Beispiel recht einfach möglich. 왘 Der Default-Server wird derzeit bei jeder Kontaktaufnahme vom Apache
genutzt. Wird im Browser eine Domain aufgerufen, so bleibt die Domain-
150
Wichtige Serverdienste
1 2 Adresse selbst nach Auflösen in eine IP-Adresse im Header erhalten. Dies gestattet Ihnen, mit einem Apache-Server beliebig viele virtuelle Webserver zu betreiben, indem Sie in einem VirtualHost-Abschnitt einen entsprechenden DocumentRoot über den Domain-Namen (Server-Namen) festlegen. Über die optionale Direktive ServerAlias können Sie zusätzliche DomainNamen angeben, die ebenfalls von diesem VirtualHost beantwortet werden sollen. Sehr praktisch ist, dass innerhalb von ServerAlias mit Wildcards gearbeitet werden darf:
3 4 5 6
7 8 9
Am besten fügen Sie sämtliche VirtualHost-Abschnitte am Ende Ihrer ApacheKonfigurationsdatei ein. Beachten Sie, dass der erste VirtualHost den DocumentRoot des DefaultServers überschreibt, da die Wildcard schließlich auf sämtliche Anfragen (IP-Adresse:Port) passt. Sie müssen also den DefaultServer bei Nutzung mehrerer virtueller Hosts ebenfalls als VirtualHost definieren und diesen als Ersten nennen, wenn Sie nicht jedem VirtualHost eine eigene IPAdresse zuweisen und diese anstelle der Wildcard einsetzen können.
10 11 12
Der DocumentRoot steht für das Startverzeichnis. Bei Eingabe der Domain phantasiedomain.de landet der Besucher automatisch im Verzeichnis /home/accountname/ftp/www/.
13 14
Es ist sinnvoll, dem Nutzer accountname FTP-Zugriff auf /home/accountname/ftp/ zu gewähren und diesen Ordner gleichzeitig als sein Home-Verzeichnis festzulegen. accountname hat so die Möglichkeit, Daten, die über den Browser nicht zugänglich sein sollen (wie beispielsweise über Skripte inkludierte Zugangspasswörter oder von mod_auth angeforderte AuthUser- sowie AuthGroup-Dateien), abzulegen. Weiterhin bietet es sich an, mit Webalizer erzeugte Statistiken hier zu speichern, damit nicht gleich »das globale Internet« Zugriff auf die statistische Auswertung erlangt. Wenn Sie accountname keinen Zugriff auf /home/accountname, sondern lediglich auf /home/accountname/ftp gewähren, können Sie /home/accountname zum geordneten Ablegen noch nicht ausgewerteter Daten (wie zum Beispiel den Apache-Logfiles) effektiv verwenden.
Apache
151
3.3.4
Verzeichnis- und Datei-Optionen
Apache gestattet es, eine Vielzahl von Optionen global sowie in VirtualHost- oder Directory-Abschnitten verzeichnisbezogen festzulegen. Über Files ist es sogar möglich, Werte gezielt einzelnen Dateien zuzuordnen. In beiden Fällen werden zuvor definierte Optionen durch die neuen Werte überschrieben. Dies spart Arbeit und ermöglicht hohe Flexibilität, kann jedoch auch für Verwirrung sorgen. Um die Übersicht zu behalten, sollten Sie ein einheitliches Konzept bei der Vergabe von Direktiven verwenden. Sie könnten beispielsweise lediglich die Grundkonfiguration innerhalb von
DirectoryIndex index.html index.htm index.shtml index.shtm Aus Gründen der Performance sollten Sie immer vollständige Dateinamen eingeben (inklusive .suffix) und auf suchmuster (Apache erkennt, dass auf das Suffix verzichtet wurde, und sucht deshalb nach suchmuster.*) verzichten. Findet sich keine passende Datei, wird mit mod_autoindex (soweit aktiviert) eine Verzeichnisübersicht ausgegeben. Falls keine Startdatei gefunden werden konnte und mod_autoindex deaktiviert ist, konfrontiert Apache den Besucher mit einer Fehlermeldung (»Forbidden«). Alias | AliasMatch Global und in VirtualHost verwendbar Aliase können Sie sich als interne SymLinks des Apache vorstellen. Über AliasMatch können sogar reguläre Suchmuster angewandt werden. Selbstverständlich kostet dies mehr Performance als das Folgen von einfachen SymLinks, zudem wird mod_alias vorausgesetzt.
152
Wichtige Serverdienste
1 2 Um Dateianfragen an das Verzeichnis /bla (DocumentRoot) nach /home/bla (tatsächlicher System-Root) umzuleiten, genügt die Zeile:
3
Alias /bla /home/bla
4
Beachten Sie, dass am Ende des Verzeichnisnamens kein abschließender Schrägstrich folgen muss und Aliase nicht directory-spezifisch gesetzt werden können, da sie außerhalb von VirtualHosts global gelten müssen. Innerhalb von VirtualHosts können Aliase jedoch auf das Root-Verzeichnis und seine Unterordner beschränkt werden.
5 6
Wer auf AliasMatch nicht verzichten kann oder will, findet unter http://httpd.apache.org/docs-2.0/mod/mod_alias.html#aliasmatch ein Anwendungsbeispiel.
7
Options [+|-Direktive]
9
8
Verwendbar in Directory, Files, VirtualHost, .htaccess (AllowOverride Options)
10
Die Optionsdirektiven bieten umfangreiche Einstellungsmöglichkeiten und sollten deshalb nicht über .htaccess anpassbar sein. Die einzelnen Optionen können explizit deaktiviert (vorangestelltes Minuszeichen) oder aktiviert (vorangestelltes Pluszeichen) werden.
11 12
Options +ExecCGI
13
gestattet die Nutzung von CGI-Skripten. Benötigt mod_cgi beziehungsweise mod_cgid. Siehe auch Abschnitt 3.3.11, CGI für Perl, PHP, Python und Co.
14
Options [+FollowSymLinks | +SymLinksIfOwnerMatch] Apache folgt SymLinks generell oder lediglich, wenn der Eigentümer des SymLinks mit dem Eigentümer der Zieldatei übereinstimmt. Die Option -FollowSymLinks oder +SymLinksIfOwnerMatch ist aus Sicherheitsgründen empfehlenswert. Die Option +FollowSymLinks steigert die Server-Performance, ermöglicht aber Nutzern mit Zugang zum Server die theoretische Möglichkeit, via SymLinks an Dateien zu gelangen, die ihnen eigentlich (zum Beispiel. wegen chrooted FTP oder SSH) nicht zugänglich sind.
Options [+Includes | +IncludesNoExec] aktiviert SSI (ServerSideIncludes) – setzt mod_includes und den Abschnitt
AddType text/html .shtml # Nur ab Apache 2.0.x AddOutputFilter INCLUDES .shtml
Apache
153
# Alternative für Apache-Versionen ab 1.3.x AddHandler server-parsed .shtml innerhalb der Apache-Konfigurationsdatei voraus. Üblicherweise werden HTML-Dateien, die SSI-Befehle enthalten, mit dem Suffix .shtml benannt. Selbstverständlich können Sie Apache zudem einfach über AddOutputFilter INCLUDES .html anweisen, alle HTML- und/oder PHP-Dateien abschließend mit dem SSI-Output-Filter zu behandeln. Allerdings ist dies durch die zusätzlich benötigte Performance wenig empfehlenswert. Um die Nutzung von SSI nach außen dennoch zu verstecken, wäre es denkbar, sich auf .html oder .php für statische beziehungsweise dynamische PHP-Sites und auf .htm oder .php4 für statische beziehungsweise dynamische PHP-Seiten mit SSI zu einigen. Hinweis Erst seit Apache 2.0.x ist es dank OutputFilter möglich, PHP und SSI zu kombinieren. Über AddHandler funktioniert dieses Unterfangen leider nicht. Als weitere Aktivierungsmöglichkeit steht der XBitHack bereit. Die Direktive XBitHack [on | off | full] kann innerhalb von Directory, Virtual und .htaccess (Letzteres benötigt AllowOverrideOptions) gesetzt werden. XBitHack On aktiviert SSI bei ausführbaren Dateirechten auf den Eigentümer und bei einem als text/html spezifizierten Suffix. Mit XBitHack full wird das Ausführrecht auf die Gruppe erwartet. Das Suffix kann hier sogar beliebig ausfallen. Allerdings gilt es zu beachten, dass über ServerSideIncludes das Absetzen beliebiger Befehle mit den Rechten des Apache-Webservers ermöglicht wird. So kann beispielsweise mit die Datei /etc/passwd ausgelesen werden. Deshalb sollten Sie SSIs ausschließlich innerhalb der selbst genutzten Verzeichnisse aktivieren und Gast-Accounts lediglich +IncludesNoExec gewähren. Mit NoExec wird die Ausführung der Befehle unterbunden, die zweckentfremdet werden könnten. Weitere Informationen zum Thema ServerSideIncludes und Anwendungsbeispiele finden Sie unter: www.hacktik.com/linux/hilfe/ssikurs.php sowie httpd.apache.org/docs-2.0/howto/ssi.html.
Options +Indexes aktiviert die Erstellung von Verzeichnisübersichten, wenn ein Ordner in einem Browser aufgerufen wurde, in dem keine DirectoryIndex-Datei existiert.
154
Wichtige Serverdienste
1 2 Obwohl aus sicherheitstechnischen Gründen keine wirklichen Argumente gegen mod_autoindex vorzubringen sind, empfiehlt es sich, Indizes in der Voreinstellung zu deaktivieren. Doch kann es Benutzern erlaubt werden, Indizes über .htaccess (siehe auch AllowOverride) nach Bedarf zu aktivieren.
3 4
Options +MultiViews
5
aktiviert die als HTTP/1.1 spezifizierte »Content Negotiaton« des Apache. mod_ negotiation wird hierzu vorausgesetzt. Weitere Informationen unter http://httpd.apache.org/docs-2.0/content-negotiation.html.
6 7
Anpassen der automatisierten Verzeichnisdarstellung Verwendbar in Directory, VirtualHost und .htaccess (AllowOverride Indexes)
8
Wenn mod_autoindex installiert wurde, kann die automatische Erstellung einer Verzeichnisübersicht mit Options +Indexes aktiviert werden.
9
Doch mit diesem Schritt geht die eigentliche Arbeit erst los. Sie können und sollten die Anzeige von Dateien wie .htaccess im Verzeichnis-Listing unterbinden:
10 11
IndexIgnore .htaccess
12
Um Tipparbeit zu sparen, können Sie bei der Namensdefinition unerwünschter Files auch mit regulären Ausdrücken arbeiten und so die Ausklammerung sämtlicher über einen Punkt »versteckter« Files und aller Backup-Dateien (Endung üblicherweise mit ~) mit IndexIgnore .??* *~ ebenso einfach wie bequem erledigen.
13 14
Selbstverständlich kann .htaccess über die vollständige Angabe im URL weiterhin im Browser geöffnet werden. Im Abschnitt Konfigurationsbeispiel ist beschrieben, wie Sie die Anzeige einzelner Dateien verbieten können, ohne File in ein Verzeichnis unterhalb des DocumentRoot-Verzeichnisses verschieben zu müssen (Stichwort: »Deny from all« innerhalb eines
IndexOptions FancyIndexing Unter /usr/local/apache2/icons wurden bereits hübsche Grafiken abgelegt. Die Einbindung erfolgt beispielsweise mit
Apache
155
AddIcon /usr/local/apache2/icons/layout.gif .html .pdf für sämtliche Dateien, die auf .html oder .pdf enden. Unbekannte Typen erhalten mit
DefaultIcon /usr/local/apache2/icons/unknown.gif ein Standard-Icon. Sie können viel Zeit und Arbeit sparen, indem Sie die AddIcons-Zeilen aus der Standard-Konfigurationsdatei /usr/local/apache2/conf/ httpd.conf übernehmen und gegebenenfalls an Ihre Wünsche anpassen. Hinweis: In httpd.conf wird Alias /icons /usr/local/apache2/icons vorausgesetzt. Sie können die Icons auch mit der IndexOption IconsAreLinks mit den jeweiligen Dateien verlinken und die Pixelbreite (IconWidth=pixel) sowie Pixelhöhe (IconHeight=pixel) anpassen. Um bei der Sortierung der Dateinamen Groß- und Kleinschreibung zu ignorieren, wäre IgnoreCase als IndexOption zu übergeben. Mit VersionSort beachtet Apache 2 sogar Versionsnummern, um eine vernünftige Sortierung von unterschiedlichen Programmversionen zu erstellen. Mit FoldersFirst werden, wie unter Windows üblich, zunächst die Dateiordner aufgelistet, bevor die eigentlichen Dateien angezeigt werden. In der Regel werden Sie auch die Option SuppressDescription übergeben wollen, um Apache anzuweisen, auf die Description-Spalte zu verzichten. Besagte Spalte wäre ansonsten für jede einzelne Datei mit
AddDescription "Die aktuellsten Infos" /www/news.html zu definieren, was zu einem erheblichen Arbeitsaufwand führt und in der Regel nur einen unwesentlichen Komfortgewinn für den Besucher bedeutet. Häufig ist eine sinnvolle Benennung von Verzeichnissen und Dateien mehr als ausreichend, um Besuchern das schnelle Auffinden gewünschter Informationen zu ermöglichen. AllowOverride [All | None | directive-type] Verwendbar in Directory Legt fest, ob Apache nach .htaccess-Dateien suchen soll, und welche Direktiven durch Benutzereingaben überschrieben werden dürfen (entweder alle oder explizite Angabe der gewünschten Direktiven).
AllowOverride None erhöht die Geschwindigkeit des Webservers, da nicht nach .htaccess-Dateien innerhalb sämtlicher Unterverzeichnisse des entsprechenden Directory-Abschnittes gesucht werden muss. AllowOverride All ist
156
Wichtige Serverdienste
1 2 mit Vorsicht zu genießen, da Benutzer so auch Optionen wie SSI oder CGI – möglicherweise gegen Ihren Wunsch – vollständig aktivieren können.
3
Sinnvoll ist es, AllowOverride generell nur bei Bedarf (auf Nachfrage des Benutzers) zu aktivieren und auf die tatsächlich benötigten Optionen zu beschränken. Tabelle 3.2 gibt einen Überblick der einzelnen Direktiven, und welche Werte innerhalb .htaccess durch sie überschrieben werden dürfen.
4 5 6
Option
Wirkung
Indexes
Aktivierung und Konfiguration der automatischen Verzeichnisdarstellung. Siehe Abschnitt 3.3.4, Verzeichnis- und Datei-Optionen.
7
Limit
Gestattet Zugriffskontrolle anhand der IP-Adresse. Siehe Abschnitt 3.3.5, Hostbasierter Zugriffsschutz.
8
AuthConfig Erlaubt benutzerspezifische Zugriffskontrolle. Siehe Abschnitt 3.3.6, User-spezifischer Zugriffsschutz.
9
FileInfo
Options
Ermöglicht neben der Anpassung von Fehlermeldungen (siehe Abschnitt 3.3.8, Anpassung von serverseitigen Fehlermeldungen) leider auch die Definition von AddOutputFilter, was von Nutzern durchaus böswillig missbraucht werden könnte. Deshalb sollten Sie auf die Freischaltung von FileInfo für GastAccounts verzichten.
10 11
Gestattet umfangreiche Änderungen wie FollowSymLinks oder die vollständige Aktivierung von SSI. Aus Sicherheitsgründen sollten Sie Gast-Accounts die Freischaltung von Options untersagen.
12 13
Tabelle 3.2 Vorsicht: Die Optionen von AllowOverride gestatten Gast-Accounts, umfangreiche Änderungen vorzunehmen.
14
Konfigurationsbeispiel Directory-Direktiven sollten oberhalb der VirtualHost-Abschnitte eingefügt werden. Es empfiehlt sich, innerhalb von
Apache
157
einem Abschnitt für eigene Dateien (und gegebenenfalls den weiteren Administratoren oder Ihrem Partner). Eine Beispielkonfiguration könnte so aussehen (Gast-Accounts im Verzeichnis /home; der eigene Abschnitt in /usr/local/apache2/httpd):
# Standard-Einstellungen Listen 80 ServerRoot /usr/local/apache2 DocumentRoot /usr/local/apache2/htdocs User indianer Group webserver MaxClients 150 StartServers 10 MinSpareServers 10 MaxSpareServers 20 MaxRequestsPerChild 0 ErrorLog logs/error_log TransferLog logs/access_log # Globale Optionen
158
Wichtige Serverdienste
1 2 Im Abschnitt
3 4 5 6
Die Sperrung von Passwortdateien über einen
3.3.5
7 8 9
Hostbasierter Zugriffsschutz
Nutzbar in Directory, Files und .htaccess (AllowOverride Limit)
10
Für ein Intranet ist hostbasierter Zugriffsschutz mit mod_access im Handumdrehen zu realisieren. Sie können über
11
Order Deny,Allow Deny from all Allow from 192.168
12 13
innerhalb von Directory oder .htaccess (AllowOverride Limit vorausgesetzt), den Zugriff auf sämtliche lokale IP-Adressen, die mit 192.168 beginnen, begrenzen.
3.3.6
14
User-spezifischer Zugriffsschutz
Mit mod_auth können Sie den Zugriff auf Verzeichnisse durch User-Name- und Passwort-Abfragen sichern und nur für vertrauenswürdige Personen freischalten. Der Clou: Auch wenn Sie Verzeichnis- und File-Schutz auf mehrere Ordner beziehungsweise Dateien anwenden, wird nur eine Authentifizierung notwendig, da Browser die eingegebenen Zugangsdaten üblicherweise so lange im Arbeitsspeicher bereithalten, bis das Browser-Fenster geschlossen wird. Leider werden die Daten bei der Authentifizierung unverschlüsselt übertragen, so dass mod_auth nur eingeschränkt für unternehmenskritische Zwecke geeignet ist. Eine Verbesserung können Sie durch Installation von mod_auth_digest erzielen. Hier kann die Übertragung zwar noch immer abgehört werden. Allerdings wird zumindest das Passwort mit der Digest-Methode verschlüsselt, so
Apache
159
dass der Angreifer zunächst den Algorithmus der Digest-Verschlüsselung knacken müsste, um das Passwort nutzen zu können. Die Digest-Verschlüsselung wird jedoch nicht von allen Browsern unterstützt. Lediglich aktuelle Versionen von Internet Explorer, Opera und Netscape (erst seit Version 7.0) beziehungsweise Mozilla kommen mit der Digest-Authentifizierung zurecht. Deshalb sollten Sie dort, wo es wirklich darauf ankommt, lieber zu mod_ssl greifen (siehe den Abschnitt Secure Socket Layer). Trotz aller Gegenargumente wird mod_auth häufig im Web eingesetzt. Tatsächlich wünschen sich »Entscheider« bei manchen Inhalten den Schutz vor der breiten Masse, obwohl es kein Beinbruch wäre, wenn es einem Angreifer gelingen sollte, mod_auth zu überlisten. Als Beispiel mag ein Vereinsprotokoll über die letzte Weihnachtsfeier dienen, das eigentlich nur Mitgliedern vorbehalten sein soll. Falls ein Hacker auf das Dokument zugreifen sollte, wäre dies kaum als eine erfolgreiche Unternehmensspionage zu betrachten, die Kosten, Imageschaden oder einen Gewinnausfall verursacht. mod_auth im Einsatz Verwendbar in Directory, Files und .htaccess (AllowOverride AuthConfig) Um ein Verzeichnis abzusichern, genügen die Zeilen
AuthName secure AuthType Digest AuthDigestFile /home/accountname/ftp/secure/.digestpwd require user dummyaccount nocheiner Falls Sie auf hohe Kompatibilität Wert legen und es keine Rolle spielt, dass das Passwort im Klartext durch die Leitungen rauscht, sind die Zeilen Type und File anzupassen:
AuthType Basic AuthUserFile /home/accountname/ftp/secure/.basicpwd Beachten Sie, dass die Passwortdatei über AuthUserFile und nicht über AuthDigestFile anzugeben ist. Die Bezeichnung AuthName ist mehr als bloße Kosmetik für den Passwortdialog. Über AuthName erkennt der Browser, dass die gespeicherten Authentifizierungsdaten übereinstimmen, und erspart Nutzern die nochmalige Eingabe der User-Name- und Passwort-Kombination. Andererseits kann es erwünscht sein, dass der Dialog erzwungen wird. Hier sollten Sie dann darauf achten, einen anderen AuthName zu verwenden.
160
Wichtige Serverdienste
1 2 Unsere User dummyaccount und nocheiner müssen und sollten nicht als SystemAccounts vorhanden sein. Der Passwort-/User-Name-Abgleich erfolgt über die nach AuthUserFile angegebene Datei. Letztere muss über den Befehl
3 4
htpasswd -cb /home/accountname/ftp/secure/.basicpwd \ username password
5
für AuthType Basic beziehungsweise
6
htdigest -c /home/accountname/ftp/secure/.digestpwd \ realm username
7
für AuthType Digest angelegt werden. Wenn Sie htdigest für die DigestAuthentifizierung verwenden, ist zu beachten, dass als Realm der AuthName (secure in unserem Beispiel) zu verwenden ist.
8
Leider ist es derzeit lediglich mit htpasswd möglich, über die Option -b das Passwort direkt zu übergeben und die sonst übliche Eingabeaufforderung zu überspringen. Letzteres ist insbesondere dann praktisch, wenn der ausführende Nutzer keinen SSH- oder Telnet-Zugang besitzt und den Befehl über ein PHP- oder Perl-Skript ausführen muss.
9 10 11
Dennoch können Sie die Digest-Authentifizierung über eigene Skripte ohne Shell-Zugang managen. htdigest verwendet zur Passwortverschlüsselung den md5-Algorithmus. Das eigentliche Passwort setzt sich jedoch aus username:realm:password zusammen. Diese Kombination kann über echo an md5sum geschickt werden. Als Ergebnis erhalten Sie den von der DigestAuthentifizierung genutzten Wert, der wiederum automatisiert in Ihre Passwortdatei geschrieben werden kann: Sie finden das Beispielskript Digestpwd.sh auch auf der CD zum Buch.
12 13 14
#!/bin/sh username="user"; realm="secure"; pwd="geheim"; md5='echo -n "$username:$realm:$pwd" | md5sum' echo "$username:$realm:$md5" >> \ /home/accountname/ftp/secure/.digestpwd Listing 3.1 Beispielskript: Digestpwd.sh
Beachten Sie, dass der Apache weiterhin Schreibrecht auf das Verzeichnis besitzen muss, in dem unsere Passwortdatei abgelegt wird. Falls Sie suExec nutzen, genügt es allerdings, Apache Leserecht zu erteilen. Lediglich der Eigentümer des Skripts, mit dem die Passwortdatei angelegt beziehungsweise verwaltet
Apache
161
wird, benötigt in diesem Fall Schreibzugriff. Weiterhin sollte die Passwortdatei nicht in einem direkt über den Browser zugänglichen Webverzeichnis liegen, sondern wie in unserem Beispiel in einem secure-Verzeichnis. Dieses schaltet sozusagen die »unsicheren« Leserechte für den Apache auf »sichere« Art und Weise frei. Passwortänderungen eines bestehenden Accounts oder das Hinzufügen einer neuen User-Name-/Passwort-Kombination sind mit htpasswd im Handumdrehen erledigt:
htpasswd -b /home/accountname/ftp/secure/.basicpwd \ username password Beachten Sie, dass die Option -c hier wegzulassen ist. Sonst würde eine neue Datei erstellt werden und die neue User-Name-/Passwort-Kombination würde sämtliche bereits gespeicherten Account-Daten ersetzen. Htdigest arbeitet analog zu htpasswd, benötigt jedoch den bereits angesprochenen Realm. Da das Passwort nicht im Batch-Modus (Option –b) übergeben werden kann, hilft wiederum nur ein Shell-Skript weiter. Das Löschen eines Accounts ist nicht weiter schwierig: Entfernen Sie die entsprechende Zeile mit einem Texteditor wie vi einfach aus /home/accountname/ftp/secure/.htpasswds. Falls die manuelle Bearbeitung mangels SSH-/Telnet-Zugang nicht möglich sein sollte, können Sie zu sed greifen. Weitere Informationen hierzu finden Sie in Abschnitt 4.7, Automation. Zugriffsrechte gruppenbasiert erteilen Wer mit einem mehrstufigen Zugriffsmodell, vielen Usern sowie mehreren geschützten Verzeichnissen arbeiten muss, für den bedeutet die Gruppierung der Nutzer häufig eine deutliche Erleichterung der Administration. Sie können über die Zeile
AuthGroupFile /home/accountname/ftp/secure/.htgroups eine Gruppenliste einlesen, die im Format
admins: user1 user4 mitarbeiter: user2 user3 vorliegen muss. Der Gruppenname folgt vor der Auflistung der User-Namen und wird mit einem Doppelpunkt abgeschlossen. Die einzelnen User-Namen sind durch ein Leerzeichen zu trennen. Gruppen erhalten, wie einzelne User, ebenfalls über die Require-Direktive Zugriffsrechte auf geschützte Inhalte.
162
Wichtige Serverdienste
1 2 Selbstverständlich können Sie neben require user auch gleichzeitig mit require group arbeiten:
3
require group admins require user dummyaccount nocheiner
4
3.3.7
5
Secure Socket Layer
Die Konfigurationsoptionen für mod_ssl sind recht umfangreich. Glücklicherweise wird mit /usr/local/apache2/conf/ssl.conf eine ausführlich kommentierte Beispielkonfiguration mitgeliefert. Deren Zeilen sollten Sie, abgesehen vom einleitenden Tag
6 7 8
Um mod_ssl nutzen zu können, benötigen Sie ein SSL-Zertifikat und den entsprechenden Schlüssel. In der Beispielkonfiguration finden Sie die Zeilen
9
SSLCertificateFile \ /usr/local/apache2/conf/ssl.crt/server.crt SSLCertificateKeyFile \ /usr/local/apache2/conf/ssl.key/server.key
10 11
die allerdings auf ein nicht existentes Verzeichnis verweisen. Bevor Sie ein offizielles und kostenpflichtiges Zertifikat beantragen, werden Sie die SSL-Funktionen des Apache sicher kennen lernen wollen. Um ein selbst ausgestelltes Testzertifikat anzufertigen, muss zunächst der Schlüssel (server.key) erzeugt werden, bevor Sie das Zertifikat erstellen können. Dies geschieht mit
12 13 14
openssl genrsa -out /usr/local/apache2/conf/server.key 2048 openssl req -new -x509 -key \ /usr/local/apache2/conf/server.key -out \ /usr/local/apache2/conf/server.pem -days 1095 Beim Erzeugen des Schlüssels haben wir absichtlich auf die Absicherung durch ein Passwort (zusätzliche Option -des3) verzichtet. Sonst müssten Sie bei jedem Apache-Neustart ein Passwort eingeben. Letzteres würde spätestens bei einem unerwartet notwendigen Reset durch den Dienstleister vor Ort dazu führen, dass beim Start des Apache mangels Passwort die SSL-Verschlüsselung nicht aktiviert werden kann. Achten Sie darauf, dass der Apache eine eigene Benutzergruppe hat und der KeyRoot der Gruppe des Apache angehört, und wenden Sie chmod 740 auf den Key an. Bevor das Zertifikat erstellt wird, werden Ihre Daten (Land, Firma, Abteilung, Name = Domain et cetera) abgefragt. Die Beantwortung ist insbesondere bei
Apache
163
offiziellen Zertifikaten sinnvoll, da es Besuchern so gestattet wird, zu überprüfen, von wem und für wen das Zertifikat ausgestellt wurde. Beachten Sie, dass die Namensfrage sich nicht auf Ihren Namen bezieht. Nach einem Neustart stehen über https:// die Inhalte von /usr/local/apache/htdocs verschlüsselt zur Verfügung. Abschließend möchte ich auf wichtige Konfigurationszeilen für die SSL-Variablenbehandlung hinweisen:
ServerName new.host.name:443 auflösen lassen. Soweit lediglich ein Testzertifikat eingesetzt wird, können Sie das bereits erzeugte ruhig doppelt verwenden. Bei Nutzung eines offiziellen Zertifikats kann dasselbe Zertifikat lediglich über eine entsprechende Subdomain und eine Wildcard-Zertifizierung genutzt werden. Ansonsten ist für jede Domain ein eigenes Zertifikat zu beantragen.
164
Wichtige Serverdienste
1 2 Bezug eines offiziellen Zertifikats
3
Es gibt viele Vergabestellen für SSL-Zertifikate. Um mehrere virtuelle SSL-Server mit ein und demselben Zertifikat über Subdomains betreiben zu können, müssen Sie darauf achten, ein Wildcard-Zertifikat zu erwerben.
4
Hierbei ist darauf zu achten, dass gängige Browser wie Internet Explorer, Mozilla oder Opera die Vergabestelle als vertrauenswürdig ansehen. In Mozilla können Sie eine Liste dieser Stellen über das Preferences-Menü (Privacy & Security – Certificates; Button »Manage Certifikates ...«; Reiter »Authorities«) abrufen.
5 6 7
Zu den bekanntesten Stellen zählen wohl http://www.Verisign.com und http://www.Thawte.com. Einen recht guten Ruf genießt der verhältnismäßig günstige Anbieter Comodo (http://www.instantssl.com). Sehr interessant ist auch der ähnlich günstige deutsche Anbieter Webspace-Forum.de, über den mir aber keine Erfahrungswerte vorliegen. Ein Telefonat4 vermittelte jedoch Kompetenz. So wies mich der Anbieter darauf hin, dass bei Wildcard-Domains vereinzelt mit Problemen zu rechnen sei. Der IE 6.0sp1 unter Windows2000 konnte laut Webspace-Forum beispielsweise mit hauseigenen Wildcard-SSLZertifikaten nichts anfangen.
8 9 10 11
Möglicherweise können Sie die nicht ganz billigen SSL-Zertifikate über Ihren Dienstleister »als Großabnehmer« günstiger als durch einen direkten Erwerb beziehen. Achten Sie bei der Bestellung auf die Laufzeit des Zertifikats. Häufig lohnt es sich, für längere Projekte ein dreijähriges Zertifikat zu beziehen.
12 13 14
Vorbereitungen für den Bezug eines offiziellen Zertifikats Um ein offizielles Zertifikat zu erhalten, ist in der Regel der Befehl
openssl req -new -key /pfad/zum/server.key -out cert.csr aufzurufen und die Datei cert.csr der Vergabestelle zu übermitteln. Sie sollten dann ein offizielles Zertifikat erhalten, das Sie jedoch nur mit dem zuvor erstellten server.key nutzen können. Achten Sie also unbedingt auf die Sicherung des offiziellen Zertifikats zusammen mit dem Key. Wenn Sie eine Datei verlieren, wird ein neuer und kostenpflichtiger Antrag bei der Vergabestelle notwendig.
4 Laut Anbieter werden Webspace-Forum-Zertifikate von allen aktuellen Browsern erkannt. Auch ältere Browser wie Netscape 4.0, Opera 5.0 und Internet Explorer 5.01 sollen Webspace-Forum-Zertifikate klaglos akzeptieren.
Apache
165
3.3.8
Anpassung von serverseitigen Fehlermeldungen
Für VirtualHost, Directory, Files und .htaccess (AllowOverride FileInfo) Professionelle Webangebote lassen Besucher selbst nach dem Aufruf falscher URLs oder bereits gelöschter Dateien nicht einfach mit einer Standard-Fehlermeldung hängen. Häufig wird eine alternative Startseite mit Links zu den wesentlichen Rubriken, einer übersichtlichen Auswahl von Themen-Highlights oder eine Suchfunktion angezeigt, um die gewünschten Informationen doch noch nachträglich entdecken zu können. Über die ErrorDocument-Direktive können Sie die Error-Codes der Tabelle 3.3 neben dem Pfad zum auszugebenden Dokument (ausgehend vom jeweiligen DocumentRoot) angeben. Eine vollständige Liste aller Client-Request- und Server-Errors bietet http://www.bignosebird.com/apache/a5.shtml. Anfragen, die an gelöschte beziehungsweise umbenannte Dokumente gerichtet sind oder lediglich einen Tippfehler enthalten, werden beispielsweise als Error404-Seiten ausgegeben und können über die Zeile
ErrorDocument 404 /.nicht_gefunden.html eine schickere Fehlermeldung mit einem an das CID der Site angepassten Design erhalten. Dies zeigt auch eine Möglichkeit auf, Gast-Accounts das Modifizieren von Fehlermeldungen zu gestatten, ohne das wenig empfehlenswerte AllowOverride FileInfo (mit dem gleichzeitig auch Ein- und Ausgabefilter definiert werden können) setzen zu müssen. Stellen Sie einfach die Standard-Fehlermeldungen im DocumentRoot zum Anpassen bereit. Dies ermöglicht auch unbedarfteren Nutzern (nicht jeder kennt die .htaccess-Direktiven und entsprechende ErrorCodes) ein bequemes Anpassen der Fehlerseiten, ohne die Sicherheit des Servers untergraben zu müssen. Code
Bedeutung
401
Authorization Required: zum Beispiel bei Abbruch (Cancel) des mod_auth-Passwort-Prompts.
403
Forbidden: zum Beispiel fehlendes Leserecht oder keine DirctoryIndex Seite und mod_autoindex deaktiviert.
404
Not found: Seite nicht gefunden.
Tabelle 3.3 Übersicht über die wichtigsten ErrorCodes
166
Wichtige Serverdienste
1 2 Code
Bedeutung
500
Internal Server Error: Sehr unangenehme Meldung, da hier häufig ein Konfigurationsfehler des Admins vorliegt. Fehler tritt zum Beispiel auf, wenn Digest als Authentifizierungsmethode genutzt wird, obwohl mod_auth_digest nicht installiert ist.
3 4
Es kann sich aber auch um fehlerhafte Zugriffsrechte von CGI-Skripten, das Vergessen der #!/pfad/zum/interpreter-Angabe oder die berühmte und häufig vergessene Leerzeile nach der Interpreter- beziehungsweise Header-Angabe (wenn verwendet) handeln.
5 6
Tabelle 3.3 Übersicht über die wichtigsten ErrorCodes (Forts.)
7 3.3.9
Logfile-Erstellung und -Auswertung
8
Verwendbar für Global und VirtualHost
9
Der Apache ist in der Lage, Logfiles für jeden VirtualHost und/oder den StandardHost getrennt zu erstellen. Hierbei können Sie das Logformat und damit die geloggten Daten selbst bestimmen.
10
LogFormat "%a %t %T \"%r\" %>s \"%{Referer}i\" \ \"%{User-Agent}i\" %I %O" mylog CustomLog logs/access_log mylog
11 12
In diesem Beispiel wurden IP-Adresse, Anforderungszeitpunkt, benötigte Antwortzeit, Methode und Datei, StatusCode, gesendete Bytes (ohne Header), die Seite, von der gelinkt wurde (zum Beispiel für Links von Suchmaschinen interessant) und der Browser des Besuchers als Loginformationen für »mylog« festgelegt.
13 14
Eine Übersicht über alle Kürzel finden Sie in Tabelle 3.4. Beachten Sie, dass das Filtern und Aufzeichnen von Verbindungsdaten nicht nur datenschutzrechtlich problematisch sein kann, sondern auch Ressourcen verbraucht. Zeichnen Sie deshalb nur wirklich benötigte Daten auf. Das eigentliche Logging erfolgt mit der Direktive CustomLog Dateiname Formatname, die im globalen Bereich lediglich den Standard-Server überwacht. VirtualHosts werden hier nicht ausgewertet. Die Direktive CustomLog ist somit auch in jeden VirtualHost-Abschnitt aufzunehmen. Zur Account-spezifischen Auswertung ist es sinnvoll, kein großes Logfile anzulegen (denselben Pfad und Dateinamen zu verwenden), sondern für alle virtuellen Hosts jedes Accounts eigene Logfiles anzulegen (CustomLog/home/ accountname/access_log mylog).
Apache
167
Kürzel
Wirkung
%a
IP-Adresse des anfragenden Rechners. Datenschutzrechtlich bedenklich.
%A
IP-Adresse, an die sich die Anfrage gerichtet hat. Interessant, wenn Ihr Server mit mehreren IP-Adressen arbeitet.
%B
Versandte Bytes ohne Header.
%b
Versandte Bytes ohne Header im CLF-Format (anstelle von 0 Bytes wird ein Strich »-« verwendet).
%{Foo}C
Loggt den Inhalt des übermittelten Cookies foo. Datenschutzrechtlich äußerst bedenklich.
%D
Benötigte Antwortzeit in Mikrosekunden.
%{Foo}e
Zeichnet den Inhalt der Umgebungsvariable foo auf.
%f
Angeforderter Dateiname – meist ist %r empfehlenswerter.
%h
Gibt bei aktivierten Lookups (HostnameLookups On – global und in Directory sowie VirtualHost verwendbar) sowie einer rekursiv auflösbaren IP-Adresse den Host-Namen des anfragenden Rechners aus (ansonsten wird die IP-Adresse gespeichert). Benötigt viel Performance und ist datenschutzrechtlich sehr bedenklich. Nutzen Sie lieber %a.
%H
Das gewünschte Kommunikationsprotokoll ist auch in %r enthalten.
%{Foo}i
Speichert die Headerline foo (vom anfragenden Rechner).
%l
Startet identd-Abfrage: Datenschutzrechtlich bedenklich und hinsichtlich der Performance unsinnig.
%m
Methode, mit der die Daten übermittelt/angefragt wurden; in %r ebenfalls enthalten.
%{Foo}n
Inhalt des externen Moduls foo.
%{Foo}o
Die Headerline foo (der Server-Antwort auf eine Anfrage).
%P
Prozess-ID, mit der die Anfrage beantwortet wurde.
%q
Loggt bei Get-Methoden an Skripte übergebene Variablen.
%r
Erste Anfragezeile (enthält Anfragemethode, Dateinamen und genutztes Protokoll).
%s
StatusCode, der in der Anfrage des Clients übermittelt wurde.
%>s
StatusCode, mit dem Apache die Anfrage beantwortet hat (gestattet Erkennung, ob und welcher Fehler aufgetreten ist).
%t
Zeitpunkt der Anfrage (Datum und Uhrzeit).
%T
Benötigte Antwortzeit in Sekunden.
Tabelle 3.4 Sämtliche Log-Optionen des Apache-Webservers. Beachten Sie, dass %I und %O mod_logio Apache 2 voraussetzen.
168
Wichtige Serverdienste
1 2 Kürzel
Wirkung
%u
Nutzername (wenn Login über mod_auth).
%U
Angeforderter URL (Querys werden abgeschnitten).
4
%v
Name des beantworteten Servers; interessant in MultiDomain-Umgebungen; verwendet ServerName.
5
%V
3
Name des antwortenden Servers (über UseCanonicalName On Global oder VirtualHost- beziehungsweise Directory-bezogen zu aktivieren). Nutzen Sie lieber %v. Weitere Informationen unter http://httpd.apache.org/docs2.0/mod/core.html#usecanonicalname.
%I
Tatsächliche Datengröße der eingehenden Anfrage (inklusive Header).
%O
Tatsächliche Byteanzahl der Serverantwort (inklusive Header).
6 7 8
Tabelle 3.4 Sämtliche Log-Optionen des Apache-Webservers. Beachten Sie, dass %I und %O mod_logio Apache 2 voraussetzen. (Forts.)
9
Hinweis: Die Direktiven ErrorLog Dateiname und TransferLog Dateiname kommen ohne CombinedLog aus, da sie Standard-Optionen enthalten, die nicht veränderbar sind. Im Gegensatz zu ErrorLog erfüllt die Voreinstellung von TransferLog (%h %l %u %t \"%r\" %>s %b) jedoch meist nicht die eigenen Bedürfnisse.
10 11 12
Logauswertung mit Webalizer
13
Webalizer ist ein beliebter LogAnalyzer und kann dank des Patchs von rexursive.com ebenfalls mit den aktuellen mod_logio-Informationen umgehen. Allerdings gilt der Patch als noch nicht abschließend getestet. Aber die Korrektheit lässt sich durch simples Zusammenzählen der entsprechenden Spalten in einem kleinen Skript überprüfen.
14
Damit Webalizer 2.01–10 Apache-Logfiles auswertet, muss weiterhin ein bestimmtes Format eingehalten werden. Leider sind die Informationen der Webalizer-Dokumentation in diesem Punkt nicht sehr ergiebig. Es wird lediglich auf die Standard-Formatierung hingewiesen:
LogFormat "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \ \"%{User-agent}i\"" Tatsächlich kommt es bei einem Minimal-Log wie: LogFormat "%a %t \"%r\" %>s %b" mylog zu einer Arbeitsverweigerung und den unschönen Fehlermeldungen:
Apache
169
Warnung: Überlanges Benutzer-Feld abgeschnitten Überspringe ungültigen Eintrag. (1) ... Dennoch kann das Logfile an eigene Wünsche angepasst werden, wenn Sie darauf achten, zusätzliche Angaben am Ende des LogFormats anzuhängen. Weiterhin dürfen Sie %h durch %a sowie %s durch %>s ersetzen und auf %l und %u über den Platzhalter - verzichten. Der Abschnitt \"%{Referer}i\" \"%{Useragent}i\" kann zwar ersatzlos gestrichen werden, hält jedoch viele interessante Informationen bereit, die die Statistik von Webalizer bereichern. Wer mod_logio einsetzt und sich für die benötigte Antwortzeit einzelner Dokumente des Webservers interessiert, der könnte beispielsweise das folgende mit Webalizer kompatible LogFormat einsetzen:
LogFormat "%a - - %t \"%r\" %>s %b \"%{Referer}i\" \ \"%{User-agent}i\" %I %O %T" mylog Installation Webalizer 2.01–10 und den dazugehörigen Patch mod_logio finden Sie auf der CD zum Buch sowie unter http://www.webalizer.org beziehungsweise http://www.rexursive.com/software.html. Beachten Sie, dass die DeveloperPakete der PNG-, GD- und Zlib-Bibliotheken installiert sein müssen, um Webalizer kompilieren zu können (Debian: libpng-dev, libgd-dev, zlib1g-dev). Nach dem Entpacken der komprimierten Dateien ist der Patch einzuspielen sowie Webalizer zu installieren. Als sinnvolle ./configure-Option können Sie anstelle der englischen Beschriftungen der späteren Statistikdatei auch deutsche Texte wählen:
patch -p0 < webalizer-in-out.patch ./configure --with-language=german make && make install Anwendung Der Aufruf von Webalizer lässt sich als Cron-Job realisieren und mit den in Tabelle 3.5 aufgeführten Optionen verbinden. Empfehlenswert ist beispielsweise Folgendes:
webalizer -o /home/accountname/ftp/log/ \ /home/accountname/access_log \ -f -Y -C 0 -M 1 -R 50 -n account.domain
170
Wichtige Serverdienste
1 2 Webalizer erzeugt anhand des aktuellen Logfiles /host/accountname/access_log eine ausführliche Statistik, die über /home/accountname/ftp/log/index.html betrachtet werden kann. Für die Monatsübersicht werden bereits analysierte Zeiträume über webalizer.hist eingebunden. Die Datei wird beim ersten Aufruf von Webalizer erstellt oder erweitert und im Ausgabeverzeichnis abgelegt.
3 4 5
Hinweis: Falls Sie den Patch mod_logio eingespielt haben, kennt Webalizer die Werte KB D, KB In und KB Out. KB D ist der »alte Traffic-Wert«, der über %b von Apache geloggt wird und lediglich ausgehende KBytes ohne Header beinhaltet. KB In sind dagegen alle mit der Anfrage zusammenhängenden eingehenden und KB Out alle ausgehenden KBytes. Im Normalfall ist KB D völlig ausreichend, zumal viele Hoster die Unsitte nutzen, KBytes lediglich durch 1 000 anstatt durch 1 024 zu teilen (siehe Abschnitt 2.3.2, Dateigrößen und Zahlensysteme), um den Traffic in Megabyte zu erhalten. Durch diese großzügige Aufrundung wird das Fehlen eingehender Pakete sowie der vernachlässigte Header-Anteil der ausgehenden Pakete eher zu Gunsten als zu Ungunsten des Hosters »umgemünzt«.
6 7 8 9 10
Wer den effektiv entstandenen Traffic wirklich genau messen will, der kommt um eine gesonderte IP-Adresse für jeden zu messenden Zugang nicht herum. Nur so können geblockte oder ungültige Pakete neben DNS und Mail-Verkehr ebenfalls zuverlässig geloggt und auseinander gehalten werden. Weitere Informationen hierzu finden Sie in Abschnitt 4.5.1, Traffic-Analyse.
11 12 13 14
Abbildung 3.3 Webalizer-Statistiken bieten unter anderem durch nützliche Auslastungsgrafiken einen Überblick, zu welcher Tageszeit es stressig ist.
Apache
171
Option
Bedeutung
-n Foo
Der Domain-Name foo wird als Titelzusatz und zur Verknüpfung mit den Links zu abgerufenen Dateien verwendet.
-o Foo
Legt foo als das Ausgabeverzeichnis der von Webalizer erzeugten HTML-Seiten sowie Webalizer.hist fest. Letztere wird beim ersten Aufruf von Webalizer automatisch erstellt und bei jedem Webalizer-Aufruf benötigt, um bereits analysierte Monate in die Erstellung der Statistik einfließen lassen zu können.
-t Foo
Mit dieser Option können Sie foo als Seitenüberschrift anstelle von »AufrufStatistik für« verwenden.
-f
FoldSeqErr: In der Standard-Einstellung ignoriert Webalizer Logeinträge, die offensichtlich älteren Datums sind. Das heißt, dass der auf eine Logzeile folgende Eintrag nicht älter als der vorangegangene sein darf. Mit der Option -f verhindern Sie, dass Webalizer vermeintlich ältere Zeilen ignoriert. So wird die manuelle Kombination bereits rotierter Logfiles eines spezifischen Zeitraums für eine entsprechende Statistik stark vereinfacht, da Sie die Reihenfolge nicht mehr korrekt einhalten müssen. Selbst Einträge mit legitimer Zeitverschiebung (zum Beispiel durch Korrekturen der Systemzeit) werden so zuverlässig berücksichtigt.
-Y
Deaktiviert die Ausgabe der länderspezifischen Herkunftsstatistik. In der Regel sehr empfehlenswert, da die Erkennung unzuverlässig ist und somit lediglich unnötige Rechenleistung beansprucht.
-H
Webalizer verzichtet auf die Ausgabe der stündlichen Zugriffsinformationen (tabellarische Anzeige); siehe auch Option -G.
-G
Schaltet die Ausgabe der Grafik zur stündlichen Zugriffsstatistik ab, die jedoch nützlich ist, um Lastspitzen zu einzelnen Tageszeiten leicht erkennen zu können.
-a Foo
Gestattet das Ignorieren von Robots einiger Suchmaschinen, die sich mit der Kennung foo zu erkennnen geben.
-u Foo
Ignoriert den URL foo bei der Erstellung der Statistik.
-M [0–5]
In der Voreinstellung -M 0 werden alle verfügbaren Informationen über den User-Agenten ausgegeben (Beispiel: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.0.0) Gec). Empfehlenswert ist die Option -M 1. Hier werden lediglich die Browser-Version und das Betriebssystem ausgegeben, ohne in die Details abzusteigen (Beispiel: Mozilla/5.0 – Windows). Stufe 2 verzichtet auf das Betriebssystem, 3 reduziert die Versionsnummer auf zwei Stellen hinter dem Komma. 4 verwendet lediglich eine Stelle und 5 letztendlich nur noch die Versionsnummer vor dem Komma. Um Browser-Statistiken zu deaktivieren, verwenden Sie -A 0.
-A num
-A 0 deaktiviert die Ausgabe der browserspezifischen Zugriffstatistik. In der Voreinstellung wird -A 15 verwendet (Browser Top 15 erstellt).
Tabelle 3.5 Die wichtigsten Webalizer-Optionen in der Übersicht
172
Wichtige Serverdienste
1 2 Option
Bedeutung
-R num
-R 0 deaktiviert die Anzeige der Referer-Liste (Herkunftsites). Die Voreinstellung -R 30 ist in den Augen so mancher »Entscheider« etwas zu knapp bemessen.
-S num
-S 0 schaltet die Ausgabe der TopSites ab (Voreinstellung -S 10).
-U num
In der Standard-Einstellung werden die Top 30 der URLs ausgegeben.
-C num
Nutzen Sie -C 0, um die unzuverlässige Landesstatistik auszublenden.
-e num
Top 10 der Eingangsseiten.
-E num
Top 10 der Ausgangsseiten.
3 4 5 6 7
Tabelle 3.5 Die wichtigsten Webalizer-Optionen in der Übersicht (Forts.)
8
Beachten Sie, dass Webalizer einerseits historische Daten speichert, andererseits bereits ausgewertete Informationen des aktuell ausgewerteten Monats überschreibt. Lediglich Einträge eines vollständig analysierten und abgelaufenen Monats dürfen aus dem auszuwertenden Logfile »gestrichen werden«. Dies ist insofern problematisch, als Sie das Zugriffs-Log sicher nicht für immer und ewig aufbewahren wollen und regelmäßig rotieren möchten; siehe Abschnitt 4.2, Syslogd.
9 10 11 12
Um Manipulationen oder eine vollständige Löschung von accountname vor der Auswertung durch Webalizer zu verhindern, sollte im Gegensatz zur eigentlichen Statistik accountname keinen Zugriff auf die zur Auswertung genutzte access_log oder webalizer.hist erhalten. Dummerweise wird webalizer.hist jedoch in der Voreinstellung im Ausgabeverzeichnis der Statistiken abgelegt. Um dies zu ändern, müssen Sie die Zeile
13 14
HistoryName ../../webalizer.hist als Konfigurationsdatei /etc/webalizer.conf sichern und beim Webalizer-Aufruf mit -c /etc/webalizer.hist einbinden. Beachten Sie, dass ein relativer Pfad gewählt wurde, der die Datei webalizer.hist zwei Verzeichnisse unterhalb des Standard-Ausgabeordners ablegt. Durch diese Einstellungen ist gesichert, dass die Datei immer eine Stufe unterhalb des Home-Verzeichnisses des Nutzers landet und somit in unserem Beispiel anstelle von /home/accountname/ftp/log/webalizer.hist als /home/accountname/webalizer.hist gespeichert wird. Aus Datenschutzgründen müssen Sie bei aktivierter Aufzeichnung der IPAdressen von Besuchern das Logfile zuvor zu anonymisieren. Es spricht nichts dagegen, die Daten von accountname nach Anonymisierung und Auswertung eines vollständigen Monatszeitraums in den eigenen Zugriffsbereich zu kopieren oder zu verschieben.
Apache
173
Zusammenfassung: Das Logfile sollte zum Monatsersten rotiert und vor der Auswertung mit Webalizer anonymisiert werden. Weiterhin sind nach der Rotierung mit Shell-Skript die Einträge des aktuellen Monats in das neue Logfile zu übernehmen, bevor der Apache über kill -HUP angewiesen wird, das durch die Rotation gesperrte neue Logfile für weitere Logzeilen zu akzeptieren. Die Alternative wäre eine Logfile-Auswertung am Monatsersten um 0:00 Uhr, mit nachfolgender Rotierung kill -HUP und der Bereitschaft, die während der Analyse und bis zur Rotierung des Logs angefallenen Einträge unter den Tisch fallen zu lassen. Mir persönlich hat diese Idee nicht gut gefallen, so dass ich ein kleines ShellSkript geschrieben habe, um den doch recht umständlichen Prozess zu automatisieren und den einzelnen Accounts gleichzeitig das rotierte und anonymisierte Logfile in den Statistikordner zu verschieben.
#!/bin/sh # Aktueller Monat und Jahr tmpm='date +%b' tmpy='date +%Y' # Erstelle Verzeichnisliste – nur möglich, wenn in home # lediglich Ordner mit "Gast-Accounts" enthalten sind! kundendirs='ls /home/' ifs=" "; set -- $kundendirs while [ $1 ] do cd /home/$1/ mv access_log access_tmp # Übernehme Logzeilen des aktuellen Monats # in neue access_log grep "/$tmpm/$tmpy" access_tmp > access_log # Starte Apache neu, damit der Server das rotierte Logfile # für weitere Einträge akzeptiert kill -HUP 'pidof httpd' # Ignoriere laufenden Monat grep -v "/$tmpm/$tmpy" access_tmp > access_tmp2 # Anonymisiere "rotierte Datei" sed 's/\([[:digit:]]\{1,3\}\.[[:digit:]] \ \{1,3\}\.[[:digit:]]\{1,3\}\.\)[[:digit:]]\{1,3\} \ /\1000/' \ access_tmp2 > access_tmp rm access_tmp2
174
Wichtige Serverdienste
1 2 # Erzeuge Statistik /usr/local/bin/webalizer -o /home/$1/ftp/log/ \ /home/$1/access_tmp -c /etc/webalizer.conf \ -f -Y -C 0 -M 1 -R 50 -n $1.domain.de # Komprimiere und verschiebe access_tmp in ein # für $1 zugängliches Verzeichnis gzip access_tmp mv access_tmp.gz ftp/log/$tmpm$tmpy.gz shift done
3 4 5 6 7
Listing 3.2 Das Skript Auto-webalizer.sh
8
Das Skript Auto-webalizer.sh befindet sich auf der CD zum Buch und setzt voraus, dass im Ordner /home lediglich Heimatverzeichnisse der Gast-Accounts mit identischer Verzeichnisstruktur vorhanden sind.
9 10
Tipp Webalizer.hist lässt sich zudem nutzen, um den Traffic von GastAccounts in einem Report automatisiert an Ihre E-Mail-Adresse zu senden. Aus webalizer.hist kann die benötigte Bytezahl wesentlich bequemer entnommen werden als aus den eigentlichen Statistikdateien.
11 12
3.3.10 PHP 4/5
13
PHP unterstützt seit Version 4.3 offiziell Apache 2. Da die PHP-Unterstütztung des MPM-Workers noch auf wackeligen Füßen steht, sollten Sie sicherheitshalber das Standard-MPM Prefork einsetzen.
14
Wenn Sie für möglichst hohe Kompatibilität sorgen wollen, ist der Einsatz der neuesten PHP-4er-Version im Augenblick der noch jungen PHP-5er-Version vorzuziehen. Einige ältere Open-Source-PHP-Applikationen oder auch in PHP 3 beziehungsweise PHP 4 selbst geschriebene Programme werden nicht ohne Detailänderungen am Quellcode mit dem neuen PHP 5 korrekt zusammenarbeiten. Es ist eine Überlegung wert, PHP 4 und PHP 5 parallel auf einem Server-System laufen zu lassen. Hierzu ist eine der beiden PHP-Versionen über CGI einzubinden. Leider ist es nicht möglich, PHP 4 und PHP 5 gleichzeitig als ApacheModule zu betreiben. Bei der Installation des zweiten PHP Interpreters müssen Sie darauf achten, via --with-config-file-path ein anderes Verzeichnis für php.ini zu definieren.
Apache
175
Allerdings bringt der Betrieb von PHP als CGI Performance und Sicherheitsnachteile mit sich – wenn es nicht nur für eigene Testzwecke ist, würde ich empfehlen, PHP-5-Sites lieber über eine zweite, parallel betriebene ApacheInstallation auszuliefern, die lediglich auf Port 8080 lauscht. Auf diesem Port darf die erste Apache-Instanz natürlich nicht ebenfalls lauschen – was in vielen Konfigurationen in der Voreinstellung der Fall ist und entsprechend auskommentiert werden muss. Bei der Installation des »2. Apachen« müssten weiterhin sämtliche Installationspfade über ./configure-Optionen abgeändert werden. Alternativ könnten Sie auch zu der noch immer gepflegten Apache-1.3erVersion greifen, um sicher zu gehen, dass Sie nicht doch versehentlich beide Apache-Versionen mit identischem Konfigurationsverzeichnis oder ähnlich kritischen Überschneidungen aufsetzen. Die Installation der unter http://www.php.net/downloads.php erhältlichen Tarballs ist einfach:
./configure --with-mysql --disable-cgi --enable-safe-mode \ --enable-memory-limit --enable-magic-quotes \ --with-gettext --enable-calendar --with-gd \ --with-apxs2=/usr/local/apache2/bin/apxs\ --with-zlib make; make install Falls Sie PHP auch oder ausschließlich über CGI einsetzen möchten, ist auf --disable-cgi zu verzichten. Die Zeile --with-apxs2 sorgt für die Kompilierung des Apache-Moduls – verzichten Sie auf diese Option, wenn die PHP-Version nicht als Modul eingebunden werden soll. Gleichzeitig sollten Sie ./configure um die Option --enable-discard-path erweitern. Eine vollständige Liste aller ./configure-Optionen ist wie gewohnt über ./configure --help abrufbar. In Tabelle 3.6 finden Sie eine Beschreibung zu den wichtigsten Optionen. Beachten Sie, dass viele PHP-Programme Funktionen wie magic_qoutes, gettext, gd sowie calendar voraussetzen. Weitere Hinweise zu den einzelnen Optionen finden Sie unter http://de.php.net/manual/en/configure.php. Option
Bedeutung
--with-apxs=Foo
Kompiliert PHP als Modul für Apache 1.3. Anstelle von foo sind Pfad und Dateiname von apxs (also apxs ,-) des Apaches 1.3 anzugeben.
--with-apxs=Foo
Kompiliert PHP als Modul für Apache 1.3. Anstelle von Foo sind Pfad und Dateiname von apxs (also apxs ,-) von Apache 1.3 anzugeben.
Tabelle 3.6 Die wichtigsten Konfigurationsoptionen für PHP
176
Wichtige Serverdienste
1 2 Option
Bedeutung
--with-apxs2=Foo
Erstellt PHP als Modul für Apache 2.
--with-mysql
Mit MySQL-Support.
--with-pgsql
Mit PostgreSQL-Support.
--with-unixODBC
Aktiviert den ODBC-Support.
--with-mssql
Auch die Microsoft-SQL-Datenbank MS SQL kann von PHP direkt angesprochen werden. Diese Option ist auf einem Linux- oder BSD-System sinnvoll, wenn eine externe MS-SQL-Datenbank ferngesteuert werden soll.
--with-msql
Bindet Support für die mSQL-Datenbank ein.
--with-oracle
Oracle-oci7 Support.
--with-gd
Aktiviert Funktionen zur Bildbearbeitung mit PHP (gd-lib).
--enable-ftp
Aktiviert die FTP-Funktionen von PHP. Grundsätzlich sehr nützlich, bringt aber gewisse Unfeinheiten beim Aufsetzen von Paketfiltern mit sich. Nur verwenden, wenn tatsächlich benötigt.
3 4 5 6 7 8 9 10
--with-imap
IMAP-Support.
--with-imap-ssl
IMAP-SSL-Support.
--with-pear
Erleichtert das Einbinden von fertigen Pear-Klassen. Weitere Informationen unter http://pear.php.net.
12
--disable-cgi
Deaktiviert die Kompilierung des PHP-Binaries für CGISkripte.
13
--enable-discard-path
Nutzen Sie diese Option, um CGI-Skripte außerhalb der Homepage-Verzeichnisse ablegen zu können, ohne Gefahr zu laufen, dass .htaccess-Einstellungen untergraben werden.
14
11
--enable-force-cgi-redirect Verhindert, dass der Interpreter direkt über den Browser aufgerufen und genutzt werden kann. Allerdings sollte der PHP-Interpreter ohnehin außerhalb der Homepage-Verzeichnisse abgelegt werden, weshalb Sie diese Option in der Regel nicht nutzen müssen. --enable-fastcgi
Aktiviert die Unterstützung von fastcgi.
--enable-safe-mode
Aktiviert den Safe-Mode in der Voreinstellung. Verhindert u.a. die Ausführung von exec oder Systemcalls mit den Rechten des Webservers.
--enable-calendar
Die Kalenderfunktionen von PHP erleichtern die Programmierung von Funktionen für einen Terminplaner oder ähnliche Aufgaben.
Tabelle 3.6 Die wichtigsten Konfigurationsoptionen für PHP (Forts.)
Apache
177
Option
Bedeutung
--enable-magic-quotes
Magic Quotes sollten in der Voreinstellung aktiviert werden, da sie die Sicherheit erhöhen und die Übernahme von Benutzereingaben vereinfachen.
--enable-memory-limit
Begrenzt den von PHP-Skripten nutzbaren Arbeitsspeicher in der Voreinstellung auf 8 MB. Sehr sinnvoll, um Amok laufende Programme einzuschränken.
--with-gettext
Ein API für NLS (Native Language Support). Dienlich, um Oberflächen zu internationalisieren.
--with-zlib
Ermöglicht die Nutzung der zlib-Kompressionsbibliothek. Benötigt zlib >= 1.0.9.
--with-java=Foo
Java-Support: Anstelle von foo ist das JDK-Basisverzeichnis anzugeben.
--with-servlet=Foo
Aktiviert Servlet-Unterstützung. Foo = JSDK-Verzeichnis. Beachten Sie, dass die Java Extension als shared dl vorliegen muss.
--with-ldap
Aktiviert LDAP-Support.
--with-config-file-path=Foo Ändert den Pfad zur php.ini-Datei. Foo = absoluter Pfad Tabelle 3.6 Die wichtigsten Konfigurationsoptionen für PHP (Forts.)
Nach der Kompilierung müssen Sie über LoadModul das PHP-4-Modul einbinden und Apache über AddType mitteilen, welche Dateien mit dem PHP-Interpreter zu parsen sind:
LoadModule php4_module /usr/local/apache2/modules/libphp4.so AddType application/x-httpd-php .php .php3 .php4 Testlauf und Konfigurationsdetails Um die Konfigurationsoptionen und Funktionsfähigkeit von PHP innerhalb eines virtuellen oder Default-Servers zu testen, sollten die Skriptzeilen
als irgendwas.php gespeichert und im Browser aufgerufen werden. Beachten Sie, dass diese Datei sehr viel über PHP und Ihr System an sich verrät und deshalb nicht unbedingt »einfach so rumliegen« und für jedermann abrufbar sein sollte. Löschen Sie die Testdatei deshalb nach dem Aufruf wieder vom Server. Bei erneutem Bedarf ist der Dreizeiler schnell wieder eingegeben.
178
Wichtige Serverdienste
1 2 Ein im Internet erreichbarer Webserver mit mod_php ist selbst bei aktiviertem safe_mode, memory_limit und magic_quotes_gpc sehr kritisch zu betrachten. Obwohl Systembefehle über den safe_mode geblockt werden, kann mit PHP durch Funktionen wie fopen() auf Dateien lesend und schreibend zugegriffen werden, soweit dies der Nutzer darf, unter dem der Apache läuft.
3 4 5
Eine drastische Variante wäre es, die Voreinstellungen safe_mode zu verschärfen und Befehle wie fopen über disable_functions zu verbieten. Dies würde jedoch die Möglichkeiten bei der Programmierung von PHP-Skripten zu stark einschränken. Deshalb sollten Sie die Ausführung von PHP-Skripten in DocumentRoot Directory des Default- beziehungsweise VirtualHost einsperren.
6 7
8 9 10
Beachten Sie, dass PHP nicht auf das Verzeichnis /www, sondern mit open_ basedir auf das Unterverzeichnis /ftp beschränkt wurde. Dies ist sinnvoll, um so ebenfalls Skripte nutzen zu können, die Passwörter oder Ähnliches enthalten und außerhalb des über den Browser direkt erreichbaren Verzeichnisbaums abgelegt wurden.
11 12 13
Eine wichtige Funktion übernimmt auch php_admin_value beim Übertragen von Dateien via Browser. Ist der SafeMode aktiviert, ohne dass ein upload_ tmp_dir innerhalb des open_basedirs definiert wird, ist ein Dateiupload nicht möglich. Das Verzeichnis .tmp muss natürlich existieren und es müssen dem Webserver Schreibrechte darauf gewährt werden.
14
Falls Sie innerhalb Ihres eigenen VirtualHost auf die vollen Möglichkeiten von PHP zugreifen wollen, können Sie durchaus php_admin_flag safe_mode off verwenden, um den SafeMode zu deaktivieren, und auf open_basedir verzichten. Um die Sicherheit Ihres PHP-Webservers zu testen, sollten Sie folgende Zeilen speichern und im Browser aufrufen:
Prüfe ob safe_mode aktiviert ist
"; exec("cat /etc/passwd", $return); $nr=0; while ($return[$nr])
Apache
179
{ echo "$return[$nr]
"; $nr++; } echo "Prüfe ob Systemdateien beliebig \ ausgelesen werden können
"; $fopen=fopen("/etc/passwd", "r"); $fread=fread($fopen,10000); fclose ($fopen); echo "<pre>$fread"; ?> Listing 3.3 Das PHP-Skript Sicherheitstests.php
Das PHP-Skript Sicherheitstests.php finden Sie auch auf der CD zum Buch. Wurde PHP korrekt abgesichert, dann sollten Sie die Fehlermeldung »Warning: fopen() [function.fopen]: open_basedir restriction in effect. File(/etc/passwd) is not within the allowed path(s): (/home/accountname/ftp) in /home/accountname/ftp/www/seccheck.php on line 11« unterhalb des fopen-Tests wiederfinden. Der Befehl exec kommt im safe_mode zwar ohne Fehlermeldung aus, darf aber nicht ausgeführt worden sein (das heißt, der Inhalt der Datei /etc/passwd wird unterhalb von »Prüfe ob safe_mode aktiviert ist« nicht ausgegeben). Feintuning Die umfangreichen Konfigurationseinstellungen von PHP können über php.ini angepasst werden. Im Tarball finden Sie die Beispieldatei php.ini-dist, die Sie am besten ins Verzeichnis /usr/local/lib/php.ini kopieren. Im Folgenden möchte ich auf die wichtigsten Einstellungen näher eingehen.
disable_functions = fopen, fread, fputs, set_time_limit ... Über disable_functions können Sie, unabhängig vom safe_mode, einzelne Funktionen deaktivieren. Die Liste der unerwünschten Aufrufe ist durch Kommata zu trennen.
expose_php = Off entfernt den Hinweis, dass der Apache PHP aus den Header-Daten versandter Dokumente unterstützt.
max_execution_time = 30
180
Wichtige Serverdienste
1 2 In der Voreinstellung sind Skripte auf eine Laufzeit von 30 Sekunden beschränkt. In der Regel ist diese Zeitspanne mehr als ausreichend. Im Einzelfall kann über die Funktion set_time_limit(sekundenanzahl); innerhalb einzelner PHP-Skripte die Ausführungszeit verlängert werden. Tragen Sie gegebenenfalls set_time_limit in disable_functions ein, um diese Möglichkeit zu unterbinden. Hinweis: im safe_mode ist set_time_limit bereits deaktiviert.
3 4 5 6
max_input_time = 60 Bei der Übertragung von Formulardaten kann insbesondere dann einige Zeit verstreichen, wenn große Dateien übertragen werden oder der Besucher ein langsames analoges Modem nutzt. Dennoch ist die Zeitspanne von 60 Sekunden in der Regel mehr als ausreichend, da über Webformulare Dateien wie Bilder oder andere Dokumente aus Sicherheitsgründen nicht von jedermann auf den Server übertragen werden sollten. Autorisierte Personen benötigen ein Webinterface zum Upload nicht zwangsweise, da sie genauso FTP oder SCP nutzen können. Beachten Sie auch post_max_size.
7 8 9 10
memory_limit = 8M
11
beschränkt den Arbeitsspeicher, der PHP-Skripten zur Verfügung gestellt wird, auf maximal 8 MB. Auch diese Voreinstellung ist sehr großzügig und sollte ordentlich geschriebene Programme nicht behindern.
12
register_globals = Off
13
hat in der Vergangenheit für großen Unmut gesorgt, da register_globals bis zu PHP 4.1.2 in der Voreinstellung auf on gesetzt waren. Erst seit 4.1.3 ist diese Option standardmäßig auf off gesetzt. Dies ist insofern problematisch, weil ältere PHP-3-Programme nur wegen der »fehlenden« register_globals ihren Dienst unter PHP 4 verweigern. Sie könnten register_globals VirtualHost abhängig aktivieren (php_admin_flag register_globals On), um ältere Skripte zum Laufen zu bringen, ohne dass Sie Anpassungen am Quellcode vornehmen müssen. Falls dies nicht möglich sein sollte, bietet sich als schneller Hack an, die Zeilen
14
extract($_REQUEST); extract($_COOKIE); extract($_SESSION); am Anfang des PHP-Quelltextes jeder Datei einzufügen. Hintergrund: Steht register_globals auf on, können über Webformulare beliebig Variablen übergeben werden. In der Vergangenheit sind selbst erfahrenere Programmierer in die Falle getappt. Sie haben dies im Eifer des Gefechts übersehen und
Apache
181
schwere Sicherheitslücken in ihren Skripten hinterlassen. Durch register_ globals wird solchen Flüchtigkeitsfehlern (zumindest ohne Nutzung des schnellen Hacks) vorgebeugt, da der Programmierer Variablen, die von einer Benutzereingabe übernommen werden sollen, bewusst mit $foo=$HTTP_GET_ VARS['foo']; freischalten muss. Somit haben Programmierer nicht nur die volle Kontrolle darüber, welche Variablen vom Browser übernommen werden, sondern können die zulässige Übertragungsmethode auch auf REQUEST (beziehungsweise GET oder POST) sowie COOKIE und SESSION festlegen.
post_max_size = 8M schränkt die über Formulare durch method=post maximal versendbare Datenmenge auf 8 MB ein.
magic_quotes_gpc = On verhindert, dass Programmierer bei der Übernahme von Variablen aus Formularen Gefahr laufen, dass Angreifer über Escaping unerwünschte Befehle ausführen können. Magic-quotes-gpc hängt hierzu an alle Sonderzeichen einen Backslash, wie beispielsweise an Backslash oder Hochkomma-, Anführungsund Dollarzeichen. Gleichzeitig ist diese Funktion sehr nützlich, da viele Sonderzeichen von Besuchern ganz ohne bösen Willen eingegeben werden und Sie sich bei der nachträglichen, formatierten Ausgabe keine Gedanken um eine Bearbeitung mit Backslashes machen müssen. Leider ist magic_quotes_gpc frei konfigurierbar. Das führt dazu, dass einige Programme die Einstellung magic_quotes_gpc auf off und andere wiederum auf on voraussetzen. Glücklicherweise kann die Einstellung php.ini zu magic_ quotes_gpc mit php_admin_flag magic_quotes_gpc Off auch abhängig vom VirtualHost überschrieben werden.
file_uploads = On gestattet es, Dateien über http:// zu übertragen.
upload_max_filesize = 2M begrenzt die Dateigröße von file_uploads auf 2 MB.
allow_url_fopen = On gestattet es, selbst fremde Inhalte über http://www.anderswo.de/file.txt wie lokale Dateien mit fopen zu öffnen.
182
Wichtige Serverdienste
1 2 3.3.11 CGI für Perl, PHP, Python und Co.
3
Die Abkürzung CGI steht für Common Gateway Interface und ist keine Programmiersprache, sondern lediglich eine Schnittstelle, die es Programmen wie dem Apache-Webserver erlaubt, Skripte mit beliebigen Interpretern ausführen zu lassen und die Skriptausgabe an den Client zu senden.
4 5
Für den Apache spielt es daher prinzipiell keine Rolle, ob es sich um ein Shell-, Perl-, PHP- oder Python-Skript handelt. Voraussetzung ist lediglich, dass das Programm für den Webserver les- und ausführbar sein muss.
6 7
Bevor Sie CGI-Programme ausführen können, müssen Sie mod_cgi gegebenenfalls laden (LoadModule cgi_module /usr/local/apache2/modules/mod_ cgi.so) und die für CGI-Programme zu verwendenden Suffixe übergeben:
8
AddHandler cgi-script .py .php .php3 .php4 .pl .cgi
9
Abschließend gilt es, über die Abschnitte
10 11
Beachten Sie, dass der Handler nicht genutzt werden kann, um einzelne Interpreter zu deaktivieren. Apache liest die Information, welcher Interpreter aufzurufen ist, aus der ersten Zeile des CGI-Skripts selbst aus. Deshalb kann in cgi.php durchaus ein Perl-Programm aufgerufen werden. Das Suffix besitzt lediglich kosmetischen Charakter.
12 13 14
Natürlich muss der Interpreter installiert sein, um vom Apache überhaupt aufgerufen werden zu können. Dies ist bei PHP erst seit Version 4.1.3 in der Voreinstellung der Fall. Sind Sie sich nicht sicher, ob und wo der Interpreter auf Ihrem System installiert ist, können Sie über whereis interpretername den zu verwendenden Pfad erfragen. Beispiel eines über CGI auszuführenden PHP-Skripts:
#!/usr/local/bin/php Content-type: text/html hallo welt!"; ?>
Apache
183
Beachten Sie, dass nach dem Interpreteraufruf der optionale Header (Contenttype: text/html) definiert wird und danach unbedingt eine Leerzeile folgen muss. Falls Sie den eigentlichen Programmcode bereits in Zeile zwei anstatt in der dritten oder vierten Zeile (bei Angabe eines Headers) beginnen lassen, verweigert Apache mit Internal-Server-Error die Ausführung. Installation von Perl Die Installation von Perl stellt Sie keinesfalls vor eine unlösbare Aufgabe. Meist ist Perl sogar bereits installiert, so dass Sie sich darum keine Gedanken machen müssen. Falls whereis perl tatsächlich ins Leere laufen sollte, finden Sie für das Betriebssystem Ihrer Wahl bereits vorbereitete Perl-Pakete, nach deren Installation ein CGI-Skript im folgenden Stil aufgerufen werden kann:
#!/usr/bin/perl print "Content type: text/html\n\n"; print "Hallo Welt
"; Beachten Sie, dass die Ausgabe des eigentlichen Inhalts erst in der dritten Zeile erfolgt und nach dem Header eine Leerzeile durch doppelte Zeilenschaltung erzeugt wird. Dies ist auch dann notwendig, wenn Sie auf die Definition eines Headers gänzlich verzichten, da sonst ein Internal-Server-Error die Folge ist. Weitere Informationen zur Programmierung von Perl-Skripten finden Sie in Abschnitt 4.7.2, Einführung in die Perl-Programmierung. Installation von Python Die Installation von Python ist unter Debian, OpenBSD und SUSE dank vorbereiteter Pakete im Handumdrehen erledigt. Häufig wird Python bereits als Standard-Paket mit installiert. whereis python verschafft Klarheit. Für einen Testlauf gelten dieselben Regeln wie bei einem Perl-Skript, und sogar der Quellcode sieht (abgesehen vom Fehlen des abschließenden Semikolons) identisch aus:
#!/usr/bin/python2.1 print "Content type: text/html\n\n" print "Hallo Welt
" Eine Einführung in die immer beliebter werdende Skriptsprache Python würde den Rahmen des Buches sprengen. Interessierten empfehle ich das Buch »Einstieg in Python« von Thomas Theis (Galileo Computing).
184
Wichtige Serverdienste
1 2 Sicherheitshinweise
3
Die Aktivierung zur Ausführung von CGI-Programmen wird in Systemen mit vielen Gast-Accounts durch ein gewisses Sicherheitsrisiko erkauft. Die Skripte werden schließlich mit den Rechten des Apache ausgeführt und haben gleichzeitig Zugriff auf das gesamte Filesystem (sofern Sie Apache nicht chrooten oder in einer linux-vserver-Umgebung betreiben). Somit kann neben der berühmten User-Auflistung /etc/passwd auch auf Dateien in vermeintlich sicheren Verzeichnissen anderer Gast-Accounts gestöbert werden und es können dabei in Skripten abgelegte Passwortinformationen entdeckt werden.
4 5 6 7
Über die Konfigurationsdatei /usr/local/lib/php.ini können Sie durch Aktivieren von safe_mode in Kombination mit open_basedir zumindest CGI-Skripte, die mit PHP ausgeführt werden, absichern. Allerdings können Sie dann genauso gut mod_php direkt einsetzen. Das ermöglicht neben einer deutlichen Performance-Steigerung erheblich mehr Flexibilität, da die Optionen php.ini bei Einsatz von mod_php über die Konfigurationsdatei des Webservers gezielt an die Gegebenheiten jedes VirtualHost angepasst werden können.
8 9 10
Allerdings bedeutet safe_mode sehr restriktive Einschränkungen, weshalb einige Hoster auf die Aktivierung verzichten. In diesem Fall bietet der Einsatz von PHP über CGI den Vorteil, auf mod_suexec zurückgreifen zu können. Durch das MPM-Perchild wird dieser Umweg in einer zukünftigen Apache-Version (hoffentlich bald) nicht mehr nötig sein.
11 12 13
Absicherung mit suExec
14
Mit mod_suexec führt der Webserver CGI-Aufrufe nicht mit der Nutzerkennung des Webservers, sondern mit der des Users aus, dem die Datei gehört, so dass der Dateizugriff durch überlegt gesetzte Benutzerrechte untersagt werden kann. Wurde der Apache wie in Abschnitt 3.3.1, Installation, beschrieben kompiliert, ist mod_suexec über die Zeile
LoadModule suexec_module \ /usr/local/apache2/modules/mod_suexec.so zu laden. In Apache1.3 kann suExec unabhängig von Userdirs innerhalb der VirtualHosts über das Setzen der Direktive User username sowie Group gruppenname aktiviert werden. Seit Apache 2.0 ist dies wegen des Perchild-MPM so nicht mehr möglich (siehe Tabelle 3.1, --with-mpm=perchild). Deshalb wurde die neue Direktive
SuexecUserGroup accountname accountgroup
Apache
185
eingeführt. Der Clou von suExec liegt neben der Ausführung von Skripten mit den Rechten der in SuexecUserGroup beziehungsweise User und Group angegebenen Accounts insbesondere darin, dass die auszuführende Datei noch nicht einmal für den Webserver les- oder ausführbar sein muss. Das Gegenteil ist der Fall: Die auszuführende Datei muss dem in SuexecUserGroup beziehungsweise als User definierten Nutzer gehören und darf nur von ihm ausführbar sein. Leserechte für Group oder World sind zwar erlaubt, aber nicht sinnvoll. Zudem werden die Rechte für das Verzeichnis, in dem die auszuführende CGIDatei liegt, von suExec überprüft. Das Verzeichnis darf lediglich vom Eigentümer beschreibbar sein. Die Gruppe des Webservers benötigt auch das Lese- und Ausführrecht für das Verzeichnis. World dürfen ebenfalls diese Rechte eingeräumt werden. Im Sinne der Sicherheit sollten Sie jedoch zu einem chmod 750 greifen. Um zu überprüfen, ob suExec korrekt arbeitet, genügt ein kleines Shell-Skript:
#!/bin/sh echo echo Ich werde ausgeführt von: 'whoami' Falls der User-Name, der in VirtualHost definiert wurde und dem das Skript gehört, als whoami ausgegeben wird, haben Sie alles korrekt konfiguriert. Leider beginnt die eigentliche Arbeit erst jetzt, da in Ihrem System sicherlich viele Dateien für World readable sind. Alle diese Dateien können somit auch von einem Gast-Account über ein CGI-Skript weiterhin gelesen werden. Manchen Dateien, wie /etc/passwd, können Sie World readable zwar nicht entziehen, aber den meisten Dateien lassen sich durch korrektes Setzen von Userund Gruppenname die World-readable-Rechte vollständig entziehen. Weitere Informationen hierzu finden Sie in Abschnitt 2.3.9, Das UNIX-Rechtesystem. Damit in CGI-Skripten enthaltene Passwörter nicht von anderen Accounts gelesen werden können, stehen die Nutzer selbst in der Verantwortung. Sie müssen den Gast-Accounts erklären, dass CGI-Skripte mit den Zugriffsrechten 700 zu versehen sind. Über find können Sie schnell herausfinden, welche Dateien »mit falschen Rechten« erstellt wurden, und den Nutzer nochmals an die korrekte Rechtevergabe erinnern:
ls -l 'find /home/*/ftp/* -type f \ -perm -100' | grep -v " ...x\-\-\-\-\-\-" Die Ausführung von CGI-Skripten stellt auch mit suExec ein gewisses Sicherheitsrisiko dar, das lediglich durch korrekt gesetzte Dateirechte minimiert wer-
186
Wichtige Serverdienste
1 2 den kann. Bei jeder Programminstallation und Konfiguration ist sorgfältig zu prüfen, welche Rechte Logfiles, Programm- und Konfigurationsdateien besitzen. Denken Sie stets daran, dass suExec CGI-Skripte nicht in einem ChrootKäfig einsperrt, sondern lediglich mit einer anderen Nutzerkennung ausführt.
3 4
Selbst wenn Ihnen kein Flüchtigkeitsfehler unterlaufen sollte und alle Nutzer von Gast-Accounts sorgsam mit den Zugriffsrechten umgehen, wird mit CGI-Skripten immer mehr angestellt werden können, als einem Administrator lieb ist.
5 6
Sicherheitsbewusste Admins werden jeden CGI-Zugang deshalb in eine vollständig virtuelle Server-Umgebung verlegen wollen. Leider ist das in Kapitel 6 beschriebene linux-vserver-Projekt nur unter Linux-Systemen nutzbar und setzt für jede virtuelle Server-Umgebung eine eigene IP-Adresse voraus. Andererseits ist das linux-vserver-Projekt aufgrund des hohen Ressourcenbedarfs ohnehin nur auf Großrechnern für einen wirklichen Massenbetrieb geeignet. Bereits für zehn virtuelle Server-Umgebungen sollten mindestens 512 MB physikalischer Arbeitsspeicher und ein 2-GHZ-System zur Verfügung stehen.
7 8 9 10
Fazit: Sie sollten CGI-Anwendungen möglichst auf den eigengenutzten VirtualHost beschränken und Gast-Accounts PHP lediglich mit safe_mode und open_ basedir gestatten. Darüber hinaus bietet sich für Gast-Accounts der Einsatz einer abgesicherten Tomcat-Umgebung (siehe Abschnitt 3.4, Tomcat) für JavaServlets sowie ServerPages an.
11 12 13
Troubleshooting 왘 Ist die Datei für den Apache les- und ausführbar? Bei Nutzung von suExec
14
muss sie für den Eigentümer les- und ausführbar sein. Andere Rechte sind nicht erforderlich. Weiterhin darf bei suExec das Verzeichnis, in dem die CGI-Datei liegt, lediglich für den Eigentümer schreibbar sein. 왘 Ist der korrekte Pfad zum Interpreter in der ersten Zeile nach
#! ... ange-
geben (Prüfung mit whois interpretername)? 왘 Folgt in der Skriptausgabe nach der Interpreter- beziehungsweise der Hea-
der-Angabe eine Leerzeile? In PHP ist die Leerzeile einfach im Skript als solche zu übernehmen. In Perl ist sie am Ende der Header-Angabe oder über einen zusätzlichen Print-Befehl (durch die Steuerungszeichen \n\n) und in Shell-Skripten ist sie zwingend durch ein allein stehendes echo nach der optionalen Header-Zeile auszugeben. 왘 Ist
mod_cgi oder mod_cgid einkompiliert (siehe Ausgabe von /usr/local/apace2/bin/httpd –l) oder wurde es als Shared-Module geladen?
왘 Wurde
Options +ExecCGI im Skriptverzeichnis gesetzt?
왘 Ist das Dateisuffix über AddHandler als CGI-Skript deklariert?
Apache
187
왘 Erfolgt die Anzeige im Klartext (inklusive HTML-Tags) anstelle einer HTML-
Seite, dann haben Sie vergessen, den Header (Content-type: text/html) in der zweiten Zeile des Skripts zu definieren.
3.3.12 Apache enthält Sicherheitslücken Allein aufgrund der Größe und Komplexität des Quelltextes sind Sicherheitslücken vorprogrammiert und garantiert enthalten. Das Gefahrenpotenzial durch Sicherheitslücken steigert sich nochmals durch die Tatsache, dass Apache selbstverständlich direkt von außen erreichbar sein muss und somit direkt angreifbar ist. Da der Webserver obendrein auf mehr als 40 Prozent aller Internetserver läuft, sind zu aktuellen Sicherheitslücken automatisierte Exploits für Script Kiddies selbstverständlich zeitnah verfügbar. Haben Sie sich aus Gründen der Flexibilität und Performance zum Download und der manuellen Kompilierung des Quellcodes entschieden, müssen Sie in der Konsequenz regelmäßig – am besten täglich – nach Sicherheits-Updates unter http://www.apacheweek.com/features/security-20 fahnden. Ansonsten sind die in Abschnitt 5.2, Einspielen von Security-Updates beschriebenen Maßnahmen zu beachten, um Patches Ihres Distributors zum Apache in das System einzupflegen. In der OpenBSD-Standard-Installation wurde Apache 1.3.x in eine ChrootUmgebung integriert. Nützlich ist dies vor allem zur Ausgabe statischer Sites. In der Praxis ist ein Chroot des Apache in vielen Fällen wenig wirksam, da häufig über CGI- oder PHP-Skripte auf wichtige Server-Dienste wie IMAP (zum Beispiel um mit Squirrelmail Nutzerpostfächer abzufragen) oder die MySQLDatenbank direkt zugegriffen werden muss. Die Pflege einer Chroot-Umgebung ist weiterhin sehr aufwändig, da bei einem Sicherheits-Update von Systembibliotheken – die teilweise ebenfalls im Chroot des Apache als Duplikat vorhanden sein müssen – die Aktualisierung der Dateien im Chroot schnell vergessen oder übersehen werden kann. Falls Sie bei der Nutzung von OpenBSD nicht auf Chroot zurückgreifen, aber den bereits vorhandenen Apache nutzen möchten, können Sie über die Option -u beim Start von Apache die Aktivierung der Chroot-Umgebung unterdrücken (apachectl stop && httpd -u). Editieren Sie /etc/rc.config (httpd_flags="-u"), um die Chroot-Umgebung beim nächsten Neustart dauerhaft zu deaktivieren. Als Alternative zu einer Chroot-Umgebung (siehe Abschnitt 5.5, Chroot) möchte ich Ihnen Systrace empfehlen. In Abschnitt 5.4, Systrace, ist beschrieben, wie Sie den Zugriff beliebiger Programme gezielt auf benötigte Verzeichnisse oder Dateien beschränken können.
188
Wichtige Serverdienste
1 2
3.4
Tomcat
3
Obwohl Jakarta-Tomcat ein Apache-Projekt ist (http://jakarta.apache.org), handelt es sich bei Tomcat nicht um ein Modul für Apache, sondern um einen eigenständigen Server, der auch ohne Apache mit statischen Seiten, aber vor allem mit JavaServlets und JavaServer Pages (JSP) umgehen kann.
4 5
Tatsächlich sollten Sie aus Performance-Gründen für statische Seiten unbedingt neben Tomcat den Apache betreiben. Es ist sogar möglich, Tomcat und Apache zu einer Zusammenarbeit zu bewegen und so SSL-Verschlüsselung für von Tomcat ausgelieferte Servlets über den Apache zu bewerkstelligen. Alternativ können Sie die SSL-Verschlüsselung über JSSE auch nativ in Tomcat realisieren.
6 7 8
Warnhinweis für OpenBSD-Anwender Derzeit ist der Betrieb von Tomcat unter OpenBSD recht wackelig, und die Installation stellt selbst an fortgeschrittene Anwender höchste Anforderungen. Der Betrieb ist grundsätzlich über die Linux-Emulationsumgebung RedHat 6.2p6.tgz (offizielles Kompatibilitätspaket) möglich, allerdings fehlen mir eigene Erfahrungen hierzu im harten Server-Betrieb.
9 10 11
Der Quelltext von Servlets kann nicht – wie bei JSP – zur Laufzeit interpretiert werden und muss daher als kompiliertes Programm vorliegen. Anstelle des bekannten Dreisatzes ./configure; make; make install sind die KompilierungsOptionen für Ant in einer XML-Datei abzulegen. Ant können Sie über http://ant.apache.org beziehen und auf dem Server installieren. Aber ohne SSH- oder Telnet-Zugang lässt es sich einerseits nicht betreiben, andererseits sollten Sie Ihrem Server das Kompilieren ohnehin nicht aufbürden, sondern dies bereits auf dem Entwicklungsrechner durchführen.
12 13 14
Ant unterstützt neben dem Kompilieren und Erstellen einer Standard-Verzeichnisstruktur (siehe: http://localhost:8080/tomcat-docs/appdev/deployment. html) das Zusammenfassen sämtlicher Programmdaten in ein komprimiertes WAR- beziehungsweise JAR-Archiv. Ist die Auto-Deployment-Option innerhalb des Kontexts gesetzt, wird beim nächsten Neustart von Tomcat das Programmpaket automatisch ausgepackt und aktiviert. Auf die Programmierung von JSP und Servlets kann im Rahmen dieses Buches leider nicht eingegangen werden. Wer sich eingehender mit Java beschäftigen möchte, dem sei neben der in Tomcat mitgelieferten Dokumentation (http://localhost:8080/tomcat-docs/appdev/index.html) das Buch »Java ist auch eine Insel« von Christian Ullenboom (Galileo Computing) empfohlen.
Tomcat
189
3.4.1
Installation
Sie finden die aktuellen Tomcat-Binaries (wählen Sie ein Release Build) unter http://jakarta.apache.org/site/binindex.cgi zum Download und auch als vorgefertigte Pakete für Debian, SUSE und OpenBSD. Die folgenden Konfigurationsschritte können am besten mit dem Originalpaket nachvollzogen werden. Die Versionen der Distributoren erleichtern das Einspielen von Sicherheits-Updates, sind jedoch teilweise stark an das hauseigene System angepasst. Sobald Sie die Grundlagen von Tomcat kennen gelernt haben, werden Sie jedoch sehr schnell mit den Eigenheiten »Ihrer« Distributionsversion zurechtkommen. Um Tomcat betreiben zu können, benötigen Sie neben der Programmdatei Tomcat*.tar.gz auch das Java-Development-Kit (JDK) von Sun. Es ist im J2SEPaket enthalten und kann über http://java.sun.com/j2se/downloads.html als »Linux-Self-Extracting-File« (wählen Sie das SDK-Paket) bezogen werden. Die zu bestätigende Lizenz sorgt unter anderem mit dem Passus »Einsatz nur für interne Zwecke« für Verwirrung. Tatsächlich dürfen Sie Tomcat laut offizieller Auskunft der Rechtsabteilung von Sun Microsystems auch auf kommerziell genutzten Webservern einsetzen: Sie dürfen J2sdk kostenlos auf einem Webserver benutzen. Dies können Sie unter folgendem Link nachlesen: http://servlet.java.sun.com/help/legal_and_licensing/#63 Dort besagt insbesondere FAQ Nr. 4, dass J2sdk kostenfrei für kommerzielle Zwecke eingesetzt werden darf. Der Passus »only for internal purposes« in unseren JDK-Lizenzbedingungen soll ausdrücken, dass Sie JDK nur innerhalb Ihrer geschäftlichen Infrastruktur nutzen sollen, egal ob für interne Zwecke oder für die Öffentlichkeit zugänglich. Lediglich der Wiederverkauf unserer Software-Produkte unter java.sun.com download ist kostenpflichtig. Die eigentliche Installation der beiden Pakete ist vollständig automatisiert und sehr bequem zu erledigen. Zunächst sollten Sie den Nutzer Tomcat anlegen und die Installationsdateien gleich innerhalb seines Home-Verzeichnisses ablegen. Danach ist das j2sdk-Binary gegebenenfalls auf ausführbar zu setzen und einfach mit dem Nutzer-Tomcat aufzurufen: ./j2sdk-1_4_1_01-linuxi586.bin. Nachdem Sie more über die Taste (Q) beendet und die Lizenz abgesegnet haben, wird das Archiv entpackt. Setzen Sie für Root und den Nutzer-Tomcat die Umgebungsvariable JAVA_HOME auf den DocumentRoot des entpackten Verzeichnisses durch Eingabe von
190
Wichtige Serverdienste
1 2 JAVA_HOME=/home/tomcat/j2sdk1.4.1_01 export JAVA_HOME
3 4
Wie Sie Umgebungsvariablen dauerhaft festlegen können, wurde in Abschnitt 2.4.7, Setzen von Umgebungsvariablen erklärt. Nun gilt es, mit dem Nutzer-Tomcat das eigentliche Tomcat-Paket tar.gz zu entpacken. Danach kann der Server bereits gestartet werden:
5 6
/home/tomcat/jakarta-tomcat-4.1.24/bin/startup.sh
7
Dieser Aufruf sollte als User-Tomcat ausgeführt werden. Tomcat muss und sollte deshalb nicht unter Root-Rechten laufen. Um den Start zu automatisieren, können Sie su -c verwenden.
8 9
su tomcat –c \ /home/tomcat/jakarta-tomcat-4.1.24/bin/startup.sh
10
Voraussetzung für einen sauberen Start ist neben der JAVA_HOME-Umgebungsvariablen, dass die von Tomcat in der Voreinstellung genutzten Ports 8005, 8009 und 8080 noch nicht belegt sind. Rufen Sie http:// 192.168.0.2:8080 in einem Browser auf, um die Tomcat-Installation zu testen. Die Anfrage wird einige Sekunden beanspruchen, da Tomcat die notwendigen Dienste und Daten erst bei der ersten Anfrage lädt.
11 12 13
In der Standard-Installation werden einige Beispiel-Servlets und ServerPages mitgeliefert, die es Ihnen gestatten, auch ohne Java-Kenntnisse die grundsätzliche Funktionsfähigkeit des Tomcat-Servers zu überprüfen.
3.4.2
14
Grundkonfiguration
Leider ist die Konfiguration von Tomcat alles andere als einfach. Die ohnehin komplexe Materie wird durch eine eigenwillige Begriffsvergabe erschwert. Die verteilten Konfigurationsdateien im XML-Format tragen auch nicht gerade zu einer übersichtlichen und schnellen Konfiguration bei. Die Verschachtelung von Service über Server zu Connectoren bis hin zum eigentlichen Host und den zugehörigen Kontexten sorgt beim Tomcat-Einsteiger für weitere Verwirrung und erschwert die Suche nach Konfigurationsfehlern. In der Regel kommen Sie mit den Standard-Abschnitten Server und Service ohne das Anlegen zusätzlicher Server (unabhängige Instanzen mit eigenen Connectoren und Hosts) zurecht. Vereinfacht gesagt, wird über die Connectoren bestimmt, über welche Ports Verbindungen akzeptiert werden. Die HostAbschnitte sind – wie die Bereiche
Tomcat
191
domainbezogene Zuordnung zuständig. Innerhalb eines Hosts werden über Kontexte applikationsbezogene Pfade zugewiesen. Jeder Host benötigt mindestens einen Kontext, damit Tomcat JSP und Servlets überhaupt ausführt. Glücklicherweise erleichtert das Webinterface Tomcat-Administration den Einstieg in die Tomcat-Verwaltung erheblich. Andererseits zerstört es Formatierungen in der Datei server.xml, was eine spätere manuelle Bearbeitung erschwert. Der Tomcat-Manager ist ein weiteres Webinterface, das einzelne Applikationen starten oder stoppen sowie neue WAR-, JAR- oder auch entpackte Entwicklungsverzeichnisse als Applikationen (ohne einen Tomcat-Neustart) innerhalb des webapp-Kontextes einbinden kann. Der Manager erlaubt zudem den Stopp der Anzeige der lokalen Dokumentation sowie die Ausführung des ManagerWebinterfaces und der Beispielprogramme, ohne die entsprechenden Dateien vom Server entfernen zu müssen. Um das Manager- und Admin-Interface nutzen zu können, sind innerhalb von ./conf/tomcat-users.xml die Roles Admin und Manager zu definieren und diese einem passwortgeschützten Account zuzuweisen:
./bin/shutdown.sh ./bin/startup.sh ist es dem Nutzer admin möglich, mit dem Passwort xy sowohl auf http://192.168.0.2:8080/manager/ als auch auf http://192.168.0.2:8080/ admin/ zuzugreifen. Um einem Gast-Account einen Tomcat-Ordner zuzuweisen, sind Änderungen an tomcat-users.xml nicht notwendig. Vielmehr gilt es, einen neuen Host mit Standard-Kontext anzulegen. Sie können dies manuell über das Einfügen von
192
Wichtige Serverdienste
1 2 innerhalb
des
Abschnitts
<Engine name="Standalone" defaultHost="localhost" debug="0"> von conf/server.xml oder über das angesprochene Admin-Webinterface unterhalb von »Service (Tomcat-Standalone)« erledigen.
3 4
In beiden Fällen sollten Sie darauf achten, dass als Name die Domain des Hosts einzutragen ist und der Pfad (Application Base) in das Root-Verzeichnis des eigentlichen Nutzers verweisen sollte. Falls Sie SSL-Verschlüsselung oder die Ausgabe statischer Seiten innerhalb von Tomcat-Applikationen über Apache realisieren möchten, ist weiterhin darauf zu achten, dass die Application-Base innerhalb eines über den Browser erreichbaren Apache-Verzeichnisses liegt.
5 6 7
Beachten Sie, dass path lediglich einen Alias für docBase darstellt. Das heißt, bei path="/tomcat" wird beim Aufruf von http://tomcat.home:8080/tomcat das unter docBase angegebene Verzeichnis aufgerufen. Sie können über das Offenlassen des path-Parameters (also path="") einen Standard-Kontext festlegen. Falls Sie keinen Standard-Kontext definieren und der Aliasname von path nicht im Browser aufgerufen wird, sehen Sie sich mit der Fehlermeldung »No Context configured to process this request« konfrontiert.
8 9 10 11 12 13 14
Abbildung 3.4 Die komplexe Verwaltung von Tomcat wird Einsteigern mit dem Webinterface »Tomcat Web Server Administration Tool« etwas vereinfacht, das über http://192.168.0.2:8080 /admin/ erreichbar ist.
Tomcat
193
Eigene Fehlermeldungen Die Definition eigener Fehlermeldungen ist deutlich einfacher. Für jeden Fehlercode kann über die hostbasierte Datei web.xml eine beliebige Site aufgerufen werden:
<error-page> <error-code>404
Absicherung von Tomcat
Die Ausführung von JSP und Servlets ist auf das Application-Base-Verzeichnis des Kontextes eingeschränkt. Es ist daher nicht möglich, über die File-Funktionen von Java auf /etc/passwd zuzugreifen. Gleichzeitig müssen benötigte Klassen (siehe Verzeichnis WEB-INF) innerhalb jedes einzelnen Kontextes vorliegen, was zwangsläufig zu einigen Dubletten führt sowie dafür sorgt, dass Sie in jedem Kontext mit den benötigten Bibliotheken sehr flexibel umgehen und gegebenenfalls unterschiedliche Varianten verwenden können. Trotz des restriktiven Application-Base-Pfades ist Ihr System vor Missbrauch durch Tomcat-Applikationen noch nicht sicher, da es über Runtime.getRuntime().exec möglich ist, beliebige Systembefehle abzusetzen:
<%@ page import="java.io.*"%> <% String txt = null; Process exec = Runtime.getRuntime().exec(new String[] \ {"/bin/sh","-c","cat /etc/passwd"}); BufferedReader input = new BufferedReader(new \ InputStreamReader(exec.getInputStream())); while ((txt=input.readLine()) != null) { out.print(txt); out.print("
"); } %> Speichern Sie das Testprogramm Sicherheitstests.jsp innerhalb des Verzeichnisses webapps/examples/ oder innerhalb des Beispielkontextes ab5. Nach dem Aufruf in einem Browser wird die Passwortdatei ausgelesen. Falls Sie verse-
5 Sie finden das Programm unter: http://www.msh-webservice/dews/ Sicherheitstests.jps.
194
Wichtige Serverdienste
1 2 hentlich Tomcat als Root gestartet haben, steht über Runtime.getRuntime().exec somit Ihr gesamter Server jedem mit Zugriff auf ein Verzeichnis, in dem Tomcat-Programme ausführt, zur freien Verfügung. Neben dem Löschen aller Server-Daten rm –fr / wäre selbstverständlich auch das Anlegen eines weiteren Accounts mit Root-Rechten (lediglich uid=0 erforderlich) oder das Installieren eines RootKits und anderer fragwürdiger Programme möglich.
3 4 5
Der Security-Manager von Tomcat ist bereits sehr sicher und restriktiv eingestellt. Sie finden seine Konfigurationsdatei unter conf/catalina.policy. Ausführliche Informationen zu den einzelnen Parametern bietet http://tomcatdocs/security-manager-howto.html. Um den Security-Manager aktivieren zu können, gilt es, Tomcat mit der Option -security erneut zu starten. Wie bereits angesprochen, sollten Sie Tomcat keinesfalls als Root, sondern mit einem unprivilegierten Account starten:
6 7 8 9
su tomcat -c "/home/tomcat/jakarta-tomcat-\ 4.1.24/bin/startup.sh -security"
10
Der erneute Aufruf unserer Datei Sicherheitstests.jsp sollte nun zu einer langen Fehlermeldung »org.apache.jasper.JasperException: access denied ...« führen.
11
Wem der Tomcat-Security-Manager zu restriktiv arbeitet, der sollte darüber nachdenken, den Tomcat-Server in eine virtuelle Root-Umgebung (siehe Kapitel 6, linux-vserver) zu stecken, bevor er Änderungen an conf/catalina.policy vornimmt, die die Sicherheit des Servers untergraben können.
12 13
3.4.4 Tomcat-Seiten über Apache ausliefern
14
Dank mod_jk2 ist es sehr einfach, JSP und Servlets über den Apache ausliefern zu lassen. Da die eigentliche Kommunikation mit dem Client über den Apache als Zwischenfilter läuft, ist es nicht notwendig, den Port 8080 für TomcatAnfragen im Browser zu übergeben, aber es ist darüber hinaus möglich, Tomcat-Seiten über https:// SSL verschlüsselt anzubieten. Sie finden mod_jk2 unter http://jakarta.apache.org/site/sourceindex.cgi. Obwohl die Versionsnummer die ausschließliche Nutzung für 2.043 suggeriert, arbeitet mod_jk2–2.0.43.so auch mit Apache 2.0.X einwandfrei zusammen. Einzige Voraussetzung ist, dass Apache mit mod_so kompiliert wurde. Nachdem Sie mod_jk2 nach /usr/local/apache2/modules verschoben haben, gilt es, die Konfigurationsdatei des Apache anzupassen:
LoadModule jk2_module \ /usr/local/apache2/modules/mod_jk2–2.0.43.so
Tomcat
195
[shm] file=/usr/local/apache2/logs/shm.file size=1048576 [channel.socket:localhost:8009] port=8009 host=127.0.0.1 [modjk:localhost:8009] channel=channel.socket:localhost:8009 Damit Tomcat auf Port 8009 überhaupt lokale Anfragen entgegennimmt, muss abschließend ein entsprechender Connector in server.xml eingetragen werden. Die Standard-Konfigurationsdatei von Tomcat 4.1.24 sieht dafür bereits die Ports 8009 und 8010 vor. Falls Sie eine andere Version nutzen, sollten Sie überprüfen, ob bereits ein ajp13-Connector auf Port 8009 angesetzt ist:
196
Wichtige Serverdienste
1 2 cat-Seiten aufrufen. Wie Sie SSL in einem VirtualHost aktivieren, ist in Abschnitt 3.3.7, Secure Socket Layer, beschrieben.
3
3.5
4
MySQL oder PostgreSQL?
Eigentlich stellt sich die Frage »MySQL oder PostgreSQL« nicht, da Sie im Zweifelsfall einfach beide Datenbanken anbieten und die Wahl dem Endanwender überlassen können. Der Administrationsaufwand ist etwa gleich hoch und nach der Einarbeitung in die Thematik und dem Aufsetzen der Datenbanken werden Sie in beiden Fällen eher selten mit Wartungsarbeiten konfrontiert werden.
5 6 7
Allerdings sollten Sie beachten, dass beide Datenbanken besondere Befehle, die nicht im SQL-Standard definiert sind, bereitstellen. Insbesondere weil sich die interne Struktur und Rechteverwaltung wesentlich unterscheiden, können administrative Befehle in den wenigsten Fällen von MySQL auf PostgreSQL übertragen werden.
8 9
MySQL ist vor allem für seine Geschwindigkeit und Stabilität bekannt und – seit SAP DB als Max DB in MySQL enthalten ist – auch für SAP-Freunde interessant. PostgreSQL wird dagegen als eine »fully featured« Datenbank beschrieben – alle wichtigen und weniger wichtigen Funktionen des SQL-Standards stehen in PostgreSQL bereit. Das heißt jedoch nicht, dass PostgreSQL generell mehr kann als MySQL – so ist zum Beispiel eine MySQL ähnliche match ... against Relevanz-Suche derzeit in PostgreSQL nur über die Integration des noch in Entwicklung befindlichen Modules tsearch6 möglich. Auch die transparente Dateistruktur und Handhabung von Zugriffsrechten ist ein Pluspunkt von MySQL.
10 11 12 13 14
Allerdings hat sich MySQL AB (die Firma hinter MySQL) dazu entschlossen, die Lizenzbestimmungen der aktuellen Version 4 zu ändern. Wer eine Applikation betreibt, die auf MySQL zurückgreift und nicht unter einer der in http://www.mysql.de/products/foss-exception.html genannten Lizenzen veröffentlicht wurde, muss eine so genannte »kommerzielle Lizenz« für die Nutzung der MySQL-Datenbank erwerben. Im Endeffekt bedeutet die Lizenzänderung für Sie, dass alle genutzten Programme – auch eigene und vielleicht nur sehr kleine PHP- oder Perl-Lösungen – unter einer der von MySQL AB »anerkannten Lizenzen« veröffentlicht sein müssen. Können dritte die MySQL-Datenbank nutzen, sollten Sie auch diese Personen über die Lizenzfrage informieren oder eine an die Versionsnummer der MySQL-Datenbank gekoppelte Lizenz erwerben. Bedenken Sie, dass der 6 http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/
MySQL oder PostgreSQL?
197
Griff zu MySQL in Version 3 nur einen kurzfristigen Aufschub der Lizenzproblematik bedeutet – spätestens wenn Version 3 nicht mehr mit Sicherheitsupdates bedacht wird, werden Sie ein Upgrade vornehmen müssen. Schieben wir die juristischen Merkmale beiseite, um den Blick auf die interessanteren technischen Details beider Datenbanken zu richten. Tatsächlich ist die Frage nach der »besseren« Datenbank in erster Linie von den Projekterfordernissen abhängig. MySQL ist aufgrund der sehr hohen Performance von MyISAM-Tabellen für die meisten Webprojekte die erste Wahl. Allerdings wird die hohe Geschwindigkeit von MyISAM Tabellen durch das Fehlen einiger aufwendiger Funktionen wie Transaktionskontrolle, referenzielle Integrität, Subselects oder stored procedures erkauft. Ein Großteil der »fehlenden« Funktionen steht seit MySQL 4.07 in InnoDB-Tabellen zur Verfügung. Tatsächlich werden Features wie stored procedures oder referenzielle Integrität in den meisten Webprojekten nicht benötigt und lassen sich im Einzelfall über eine Skriptsprache wie PHP oder Perl durch zusätzliche SQL-Abfragen lösen. Weiterhin können MyISAM- und InnoDB-Tabellen in einer Datenbank »vermischt« werden, sodass der Entwickler stets entscheiden kann, was für den jeweiligen Einsatzzweck die optimale Lösung ist. Wer überwiegend auf InnoDB-Tabellen zurückgreifen muss oder möchte, verzichtet damit jedoch auf den Performance-Vorteil von MyISAM-Tabellen und sieht sich auch mit höheren Preisen für eine »kommerzielle Lizenz« konfrontiert. Ob MySQL (mit InnoDB) oder PostgreSQL in der Praxis schneller sind, lässt sich nicht pauschal beantworten. Sehr viel hängt vom Datenbankdesign und den tatsächlich genutzten Features ab. Auch der verwendete Compiler und die Art und Weise, wie die Datenbank angesprochen wird, wirken sich sehr deutlich auf die Geschwindigkeit aus. Für einen realistischen Test müsste das jeweilige Projekt somit für PostgreSQL und MySQL »doppelt« entwickelt und mehrere tausend Zeilen realistischer Nutzdaten in die Haupttabellen eingepflegt werden. Bei langfristigen, größeren kommerziellen Projekten mag dieser Aufwand jedoch gerechtfertigt sein. Kleinere Projekte, die weniger als 5 000 Datensätze in einer Tabelle speichern, werden nur bei äußerst komplexen, verketteten Abfragen überhaupt eine spürbare Antwortzeit, die über einer Sekunde liegt und nicht nur einen Bruchteil einer Millisekunde beansprucht, feststellen. Auch die Stabilität von MySQL und PostgreSQL ist durchaus vergleichbar. In beiden Fällen werden Probleme in der Regel durch Hardware-Defekte (insbe7 Transaktions-Kontrolle ist bereits seit Version 3.23.34a in MySQL verfügbar. Stored Procedures sind in der allerdings noch in Entwicklung befindlichen Version 5 verfügbar. Trigger werden wohl erst in Version 5.1 unterstützt werden.
198
Wichtige Serverdienste
1 2 sondere durch Schreib- oder Lesefehler der Festplatte) verursacht. Natürlich sollte auch der Server genügend Ressourcen für den Datenbankbetrieb besitzen. Unter dauerhafter Volllast oder bei zu wenig Arbeits- oder Festplattenspeicher könnte es durchaus zu einem Absturz oder dem Einfrieren der Datenbank kommen.
3 4 5
MySQL 4
PostgreSQL
+ Performance (nur bei MyISAM)
+ Alle Features des SQL-Standards
6
+ Relevanz-Suche (match ... against)
+ BSD-Lizenz gestattet auch den kommerziellen Einsatz über eigene Applikationen oder Programme Dritter.
7
+ Verschiedene Datenbanktypen gestatten es, für verschiedene Zwecke den optimalen Typ zu wählen.
+ Schemas gestatten übersichtliche Organisation und Trennung verschiedener SQL Projekte ohne eigenständige Datenbanken anlegen zu müssen.
+ Flexible und leicht nachvollziehbare Nutzerverwaltung
+ Point-In-Time Recovery automatisches Backup-System, erlaubt Wiederherstellung zeitspezifisch vor Auftreten eines Fehlers oder transaktionsspezifisch.
– Ab Version 4 können Lizenzgebühren und sogar juristische Probleme entstehen.
– Immer volle Funktionalität; keine verschiedenen SQL-Tabellentypen wählbar.
– (noch) keine Stored Procedures
– Relevanz-Suche nur über Zusatzmodul
8 9 10 11 12 13
Tabelle 3.7 Vor- und Nachteile von MySQL und PostgreSQL in der Übersicht
3.6
14
MySQL
Zur Installation von MySQL stehen unter http://www.mysql.de/downloads/index.html bereits für das von Ihnen eingesetzte System optimierte Binärpakete zum Download bereit. Falls Sie nicht unbedingt auf die aktuellste stabile Version von MySQL setzen möchten, empfiehlt es sich jedoch. die MySQL-Pakete Ihrer Distribution zu verwenden und so Zeit beim Einpflegen von Sicherheitsupdates zu sparen. Neben dem Server-Paket sollten Sie zudem das Client-Paket installieren. Im Folgenden werde ich auf die Absicherung und Administration von MySQL eingehen. An dieser Stelle würde eine Einführung in das Datenbank-Design sowie die Erläuterung sämtlicher SQL-Befehle zu weit führen. Wer sich näher mit der Thematik beschäftigen möchte, dem seien die Links http:// www.mysql.de/doc/de/index.html und http://www.little-idiot.de/mysql/ empfohlen.
MySQL
199
3.6.1
Absicherung
Häufig steht nach der MySQL-Installation der Datenbank-Server offen wie ein Scheunentor. Er ist nicht nur von außen ansprechbar, sondern steht über den User-Namen Root und ein leeres Passwort vollständig zur Verfügung. Sie sollten beides unbedingt ändern. Loggen Sie sich über mysql -u root in die Datenbank ein und wechseln Sie in die MySQL-Datenbank: use mysql;. Zunächst sollten Sie ein Passwort für den Nutzer Root festlegen: update user set Password=password('neues_passwort') where User='root';. Nun gilt es, die Rechtetabelle neu zu laden, da diese Informationen von MySQL in einem Cache bereitgehalten werden: flush privileges;. Von welchem Server aus welcher User auf die MySQL-Datenbank zugreifen kann, wird auch in der Tabelle User (Spalte Host) festgelegt:
mysql> select Host, User from user; +-----------+-------------+ | Host | User | +-----------+-------------+ | % | root | +-----------+-------------+ Das %-Zeichen lässt Anfragen von jedem beliebigen Rechner zu, obwohl Sie im Normalfall keine äußeren Zugriffsmöglichkeiten auf die MySQL-Datenbank benötigen. Dynamische PHP- oder Perl-Sites greifen lokal auf die MySQLDatenbank zu, und für manuelle Änderungsarbeiten können Sie sich ebenso gut über SSH einloggen, um danach ebenfalls »lokal« die MySQL-Datenbank aufzurufen. Als weitere Alternative wäre es denkbar, auf PHPMyAdmin (siehe Abschnitt 3.6.9, phpMyAdmin) zurückzugreifen. Um externe Logins zu unterbinden, genügt der MySQL-Befehl update user set Host='localhost';. Vergessen Sie nicht, den MySQL-Cache mit flush privileges; erneut zu aktualisieren. Innerhalb des MySQL-Servers können mehrere MySQL-Datenbanken verwaltet werden. Es ist sinnvoll, für jedes Projekt und jeden Datenbank-User eine eigene MySQL-Datenbank anzulegen. Üblicherweise wird MySQL in der Voreinstellung mit den Datenbanken test und mysql (Administration) installiert. Die Datenbank test wird auf einem Webserver sicher nicht benötigt. Sie ist dafür gedacht, unerfahrenen Usern die Möglichkeit zu bieten, MySQL-Befehle mit vollen Rechten in dieser Datenbank testweise auszuführen.
200
Wichtige Serverdienste
1 2 Da es innerhalb der Test-Datenbank zu Datenmissbrauch kommen kann, sollten Sie auf die Erzeugung einer Testtabelle innerhalb der jeweiligen UserDatenbanken bestehen und die Datenbank test mit: drop database test; löschen. Eine neue Datenbank können Sie übrigens mit create database datenbankname; erzeugen.
3.6.2
3 4 5
User-Verwaltung und Rechtemodelle
6
GRANT ALL ON datenbankname.* to dbuser@localhost identified by 'sein_passwort'; legt den Nutzer dbuser an und erteilt ihm sämtliche Rechte für die Datenbank: datenbankname. Beachten Sie, dass der neue Account erst mit flush privileges; bereitsteht.
7 8
Die Abfrage select * from db where User='dbuser'; verschafft Klarheit über die erteilten Rechte (zur besseren Übersicht anders formatiert):
9
+-----------------+-----------------+ | Host | localhost | | Db | datenbankname | | User | dbuser | | Select_priv | Y | | Insert_priv | Y | | Update_priv | Y | | Delete_priv | Y | | Create_priv | Y | | Drop_priv | Y | | Grant_priv | N | | References_priv | Y | | Index_priv | Y | | Alter_priv | Y | +-----------------+-----------------+
10 11 12 13 14
Innerhalb der Datenbank datenbankname stehen dem User dbuser sämtliche Privilegien bis auf Grant_priv zu. Tabelle 3.7 erläutert die einzelnen Privilegien und ihre Bedeutung. In der globalen Rechtetabelle User wurden dem Nutzer dbuser jedoch keinerlei Rechte eingeräumt. Wenn Sie an dieser Stelle Select_priv auf Y ändern (update user set where User='dbuser';), erhält der User das Recht, in sämtlichen Datenbanken zu stöbern (Selects abzusetzen). Dennoch ist es ihm weiterhin lediglich innerhalb von datenbankname erlaubt, Änderungen vorzunehmen.
MySQL
201
Um einen vollwertigen Administrator-Account anzulegen, der wie Ihr RootAccount sämtliche Rechte genießt, ist der Befehl: GRANT ALL ON *.* to
admin@localhost identified by 'sein_passwort' with grant option; abzusetzen. Der Zusatz with grant option aktiviert hier die Möglichkeit, selbst Accounts anlegen zu können. Die Wildcards *.* stehen für jede Datenbank und alle Tabellen. Ein Blick in die Tabelle Users verrät, dass dem neuen Administrations-Account tatsächlich sämtliche Rechte – inklusive Dateisystemzugriff, Prozessinformationen und Beenden der Datenbank – eingeräumt wurden. Das Entziehen unerwünschter Zugriffsrechte ist dank des Revoke-Kommandos ebenso einfach wie das Erteilen einzelner Rechte: revoke Shutdown, Process, File on *.* from admin@localhost; nimmt dem Nutzer-Admin die Privilegien für einen Dateizugriff und zum Beenden der Datenbank sowie das Recht zur Einsicht in die laufenden Prozesse. Beachten Sie den Unterschied zwischen grant und revoke: Bei grant sieht die Syntax ein to username@hostname vor. Bei revoke heißt es dagegen from username@hostname. Hinweis Die Grant- und Revoke-Befehle sind lediglich Hilfsmittel, um die entsprechenden Werte bequemer in die MySQL-Datenbank einzutragen. Sie können die MySQL-Datenbank auch vollständig manuell administrieren.
3.6.3
Interne Vorgehensweise bei einer Zugriffsprüfung
MySQL prüft bei einer Rechtekontrolle zunächst die Tabelle User. Sind dem anfragenden Nutzer hier noch keine entsprechenden Rechte eingeräumt worden, wird in der Tabelle db nachgesehen und danach gegebenenfalls ein Blick auf tables_priv und columns_priv geworfen. Das bedeutet, dass Einträge in User global gültig sind und nicht von Werten innerhalb db überschrieben werden können. Daher sollten Sie bei NutzerAccounts die globale User-Tabelle sehr vorsichtig behandeln. Alle hier erteilten Rechte gelten schließlich für sämtliche vorhandene Datenbanken. Erteilen Sie deshalb lediglich Administratoren über die User-Tabelle Privilegien und achten Sie darauf, dass sämtliche Nutzer-Accounts keine Privilegien innerhalb der User-Tabelle erhalten. Einen Sonderfall stellt die Tabelle columns_priv dar. Hier können Sie Einzelrechte spaltenbezogen vergeben. Dies ist mit den Kommandos Grant und
202
Wichtige Serverdienste
1 2 Revoke derzeit nicht möglich. Nutzen Sie manuelle SQL-Befehle, um einzelnen Accounts gezielt Privilegien für bestimmte Spalten einer Tabelle zu gewähren.
3
Eine Übersicht über alle MySQL-Privilegien und ihre Bedeutungen finden Sie in Tabelle 3.8. Beachten Sie, dass einige Privilegien funktionsbedingt lediglich in der User- oder db-Tabelle, nicht aber in tables_priv oder columns_priv zur Verfügung stehen.
4 5 6
Privileg
Bedeutung
Select_priv
Gestattet Select-Abfragen.
Insert_priv
Erlaubt das Anlegen neuer Einträge.
Update_priv
Ermöglicht das Ändern bestehender Datensätze.
Delete_priv
Ist zum Löschen einzelner Datensätze notwendig.
Create_priv
Erlaubt das Anlegen neuer Tabellen.
Drop_priv
Gestattet das Löschen einer bestehenden Tabelle.
Reload_priv
Erlaubt die Befehle reload, refresh, flush-privileges, flush-hosts, flushlogs sowie flush-tables.
Shutdown_priv
Gestattet das Beenden der MySQL-Datenbank.
Process_priv
Stellt alle laufenden MySQL-Prozesse dar.
12
File_priv
Gestattet schreibenden und lesenden Dateizugriff auf Systemdateien. Wird benötigt, wenn MySQL spezielle Abfrageergebnisse direkt in eine Datei schreiben soll, ohne eine Programmiersprache bemühen zu müssen, um die Ausgabe formatiert in eine Datei zu schreiben.
13
7 8 9 10
Grant_priv
Ermöglicht die Erzeugung weiterer Nutzer-Accounts (natürlich können lediglich die eigenen Rechte weitergegeben werden).
References_priv
Derzeit noch nicht in Verwendung.
Index_priv
Gestattet das Erstellen und Löschen bestehender Indizes.
Alter_priv
Ermöglicht Änderungen am Datenbank-Design einer Tabelle (zum Beispiel das Anlegen neuer Spalten oder Änderung von Spaltennamen und Feldtypen)
11
14
Tabelle 3.8 Übersicht über alle MySQL-Privilegien mit ihrer Bedeutung
3.6.4 Tabellen optimieren Eigentlich ist die MySQL-Datenbank sehr pflegeleicht. Dennoch kommt es nach längerem Betrieb der Standard-MyISAM-Tabellen bei Verwendung von Indizes oder durch häufiges Löschen zu übergroßen Datenbankdateien.
MySQL
203
Da unnötig große Dateien nicht nur zusätzlichen Platz auf der Festplatte benötigen, sondern auch die Arbeitsgeschwindigkeit der MySQL-Datenbank beeinträchtigen, nutzen aufmerksame Programmierer den Befehl optimize table tabellenname, um die Dateien der Datenbank automatisiert zu optimieren. Für diese Aufgabe ist ein Perl-Skript, das einmal monatlich als Cron-Job gestartet wird und sämtliche Tabellen aller Datenbanken optimiert, geradezu prädestiniert. Sie finden das Perl-Skript OptimizeSQL.pl auch im Ordner Beispielskripte auf der CD zum Buch.
#!/usr/bin/perl -w use DBI; $dbh = DBI->connect("DBI:mysql:database=mysql", "root", \ "passwort", {'RaiseError' => 1}); $query = $dbh->prepare("show databases") \ or die $dbh->errstr(); $query->execute() or die $dbh->errstr; while ($dbase = $query->fetchrow_hashref()) { print "\nOptimiere Datenbank: $dbase->{'Database'}\n"; print "-----------------------------------------\n"; $to_optimize = DBI->connect("DBI:mysql:database=\ $dbase->{'Database'}\n", "root", "", {'RaiseError' => 1}); $tabellen = $to_optimize->prepare("show tables") \ or die $to_optimize->errstr(); $tabellen->execute() or die $to_optimize->errstr(); while ($tabelle = $tabellen->fetchrow_arrayref()) { print "optimize table $tabelle->[0]\n"; $to_optimize->do("optimize table $tabelle->[0]") \ or die $dbh->errstr(); } } $query->finish(); $tabellen->finish(); $dbh->disconnect(); $to_optimize->disconnect(); Listing 3.4 Perl-Skript OptimizeSQL.pl
204
Wichtige Serverdienste
1 2 3.6.5
Backups und Wiederherstellung
3
Grundsätzlich lässt sich eine MySQL-Datenbank kinderleicht sichern: Berücksichtigen Sie einfach in Ihrem Backup-Programm das Verzeichnis /var/lib/mysql inklusive seiner Unterverzeichnisse.
4
Allerdings wird das Rückspielen dieser Backup-Daten durch simples Kopieren in das entsprechende Verzeichnis nicht möglich sein, wenn Sie unterschiedliche Betriebssysteme (MySQL läuft neben Linux, BSD oder kommerziellen UNIX-Systemen auch unter Windows) oder verschiedene MySQL-Versionen einsetzen.
5 6 7
Weiterhin könnte die Sicherung fehlerhaft ausfallen, wenn gleichzeitige Schreiboperationen in der MySQL-Datenbank vorgenommen werden. Um dies ausschließen zu können, muss die Datenbank für die Zeitspanne des Backups gestoppt werden. Bedenken Sie, dass ein Backup durch simples Kopieren mehr Platz als notwendig veranschlagt, da auch interne MySQL-Daten wie Indizes mit kopiert werden. Die etwas komplexere Alternative mysqldump ist somit einem simplen Kopiervorgang in der Regel vorzuziehen. Steht ein VersionsUpdate oder ein Wechsel des Betriebssystems des Webservers bevor oder sind die Daten auf einem anderen MySQL-Server einzuspielen, dann führt an mysqldump ebenfalls kein Weg vorbei. Mit
8 9 10 11 12
mysqldump -u root –p 'passwort' datenbankname > backupname
13
wird eine Textdatei mit sämtlichen MySQL-Datenbankbefehlen erstellt, um den Datenbanknamen inklusive der Tabellenstruktur und der Datenbankeinträge wiederherstellen zu können. Allerdings fehlt der Befehl create database. Bevor die Daten zurückgespielt werden können, müssen Sie deshalb eine Datenbank anlegen und danach den Befehl mysqldump aufrufen:
14
mysqldump -u root –p 'passwort' neuedb < backupname Bedenken Sie, dass ein Backup durch simples kopieren nicht nur zu Inkompatibilitäten führen kann sondern auch mehr Platz als notwendig veranschlagt, da auch interne MySQL Daten wie indexe mit kopiert werden. Die etwas komplexere Alternative mysqldump ist somit einem simplen Kopiervorgang in der Regel vorzuziehen.
3.6.6 Tabellen reparieren Im harten Betrieb können – wenn auch sehr selten – Schwierigkeiten beim Einlesen einer Tabelle auftreten. In der Regel ist der Grund hierfür in einer korrupten Tabellendatei zu suchen, die durch einen fehlerhaften Schreibvorgang entstanden ist. Zum Glück lassen sich derartige Problem bei MyISAM Tabellen mit
MySQL
205
dem SQL Befehl repair table tabellenname oder dem Shell Befehl myisamchk -r tabelle in den meisten Fällen lösen, ohne den letzten Backup der betroffenen Tabellendatei einspielen zu müssen. InnoDB-Tabellen besitzen eine so genannte Auto-crash-recovery-Funktionalität, die bei einem Absturz fehlerhaft geschriebene Tabellendaten automatisiert bereinigt. Falls Sie tatsächlich auf eine korrupte InnoDB-Datei stoßen sollten, hilft momentan nur das Einspielen eines Backups weiter.
3.6.7
Passwort des Administrators vergessen?
Falls Sie den Server lediglich verwalten, ohne die MySQL-Datenbank selbst intensiver zu nutzen, mag es vorkommen, dass Sie sich nach einiger Zeit nicht mehr an das Root-Passwort erinnern können. Mit dem Befehl /usr/sbin/mysqld -u mysql --skip-grant-tables; können Sie die MySQL-Datenbank starten, ohne die MySQL-Zugangsdatenbank mysql zu verwenden. Sie können sich nun ohne Passwort (mysql –u root) einloggen und danach ein neues Passwort vergeben (use mysql; update user set password=password('neues_passwort') where User='root';).
3.6.8 Logging Durch Loggen abgesetzter Datenbank-Befehle können Sie bei einem möglichen Missbrauch nachsehen, wann welche Befehle mit welchem Account durchgeführt wurden. Falls Sie, was durchaus empfehlenswert ist, für Programme wie Redaktionssysteme oder schlichte Foren und Börsen zusätzliche MySQLAccounts erzeugen, können Sie weiter nachvollziehen, ob der Vorgang eventuell auf einen Programmfehler zurückzuführen ist oder ob ein manueller Eingabefehler vorliegt. In Debian Woody ist das Logging von Verbindungen und MySQL-Befehlen in der Voreinstellung aktiviert, in den anderen Systemen müssen Sie die gewünschten Logoptionen explizit beim Start übergeben. Zur Wahl stehen die in Tabelle 3.8 aufgeführten Optionen. Ich empfehle die MySQL-Datenbank mit dem Befehl
/usr/libexec/mysqld --user=mysql -l \ --log=/var/log/foo.log --warnings & zu starten (in OpenBSD finden Sie mysqld unter /usr/local/libexec, in Debian und SUSE dagegen innerhalb von /usr/sbin). Unter SUSE 8.1 ist zusätzlich die Angabe der Option --datadir=/var/lib/mysql notwendig, um die Datenbank initialisieren zu können.
206
Wichtige Serverdienste
1 2 Beachten Sie, dass user mysql natürlich keinen Schreibzugriff auf das Verzeichnis /var/log haben sollte. In der Folge wird es MySQL nicht möglich sein, die Datei foo.log selbstständig anzulegen. Rufen Sie daher
3 4
# touch /var/log/foo.log # chown mysql /var/log/foo.log # chmod 600 /var/log/foo.log
5
auf und starten Sie die Datenbank neu. Möchten Sie das Logging in Debian deaktivieren, ist die Datenbank mit:
6
/usr/sbin/mysqld --user=mysql –l &
7
zu starten.
8
Option
Bedeutung
--log=/foo
Zeichnet alle MySQL-Befehle und Verbindungs-anfragen (zum Beispiel Logins) in der Datei foo auf.
--log-bin=/foo
Speichert sämtliche MySQL-Befehle in der Binärdatei /foo.
--log-update=/foo
Logt nur update-Befehle.
--log-long-format
Erweitert die Loginformationen um zusätzliche Details. Kann für Debugging sinnvoll sein.
--log-slow-queries=/foo
Zeichnet alle MySQL-Befehle, die überdurchschnittlich viel Zeit beansprucht haben, in /foo auf.
-W | --warnings
Erweitert das Logfile um Warnmeldungen.
9 10 11 12 13 14
Tabelle 3.9 Die Logoptionen sind über -l einzuleiten. Auf einem Webserver sollten Sie die Logoptionen -l log=/foo --warnings verwenden.
3.6.9 phpMyAdmin Aus Sicherheitsgründen sollte die MySQL-Datenbank von außen nicht erreichbar sein. Sobald Sie Kollegen, Bekannten oder Kunden jedoch eine MySQLDatenbank bereitstellen, wird auch ein Zugang zur Administration benötigt. Ein SSH-Zugang ist dafür nicht unbedingt notwendig. Mit phpMyAdmin steht ein relativ komfortables Webinterface auf der Basis der beliebten Skriptsprache PHP zur Verfügung. Nachdem Sie die aktuelle phpMyAdmin-Version der CD zum Buch oder von http://www.phpmyadmin.net bezogen und in einem über Apache erreichbaren Verzeichnis entpackt haben, gilt es, die Datei config.inc.php anzupassen.
MySQL
207
Um die Passwortübertragung durch SSL absichern zu können, sollten Sie bei der Konfiguration sowohl cookie als auth_type wählen und $cfgPmaAbsoluteUri mit https://servername/phpMyAdmin/ definieren. Da Nutzernamen und Passwort mit phpMyAdmin bei jedem Login zu übergeben sind und kein automatisierter Login erwünscht ist, dürfen und müssen Sie das Root-Passwort nicht in config.inc.php eintragen. Die password-Arrays können ruhig leer bleiben.
Abbildung 3.5 PhpMyAdmin ist ein praktisches Webinterface zur Administration von MySQLDatenbanken.
3.7
PostgreSQL
Zur Installation von PostgreSQL finden Sie für Ihr Betriebssystem ein vorbereitetes PostgreSQL-Paket. Dennoch möchte ich auf die manuelle Installation eingehen, da nur so spezielle Compiler-Optionen übergeben und Zusatzmodule wie tsearch eingebunden und die SSL Verschlüsselung aktiviert werden können. Weiterhin war die aktuelle und sehr empfehlenswerte 8er-Version zum Zeitpunkt der Drucklegung noch nicht als offizielles SUSE-, Debian- oder OpenBSD-Paket verfügbar. PostgreSQL ist jedoch unproblematisch zu kompilieren und über folgenden Link zu beziehen: http://www.postgresql.org/download/ Wenn keine zusätzlichen Patches für PostgreSQL einzuspielen sind, dann genügt zur Kompilierung des Pakets der bekannte ./configure && make && make install-Dreisatz. Ein Blick auf die Konfigurationsoptionen mit ./con-
208
Wichtige Serverdienste
1 2 figure --help ist dennoch lohnend. Tabelle 3.10 listet die interessantesten Zusatzoptionen auf.
3 4
Option
Wirkung
--with-tcl
Fügt PL/TCL-Modul hinzu.
--with-perl
Fügt Perl-Modul hinzu.
--with-python
Kompiliert das Python-Modul.
--with-krb4 | --with-krb5
Stattet PostgreSQL mit Support für kerberos 4 beziehungsweise 5 aus.
5 6
--with-pam
Aktiviert den PAM-Support von PostgreSQL.
--with-openssl
Ermöglicht SSL.verschlüsselte Übertragung – wichtig, wenn PostgreSQL von außen erreichbar sein soll!
7 8 9
Tabelle 3.10 Übersicht der wichtigsten ./configure-Optionen von PostgreSQL 8.
3.7.1
10
Start von PostgreSQL
Richten Sie für PostgreSQL einen neuen System-Account (im Folgenden wird pgsql als Name verwendet) ein und erstellen Sie nach dem Identitätswechsel mit su – pgsql über
11 12
/usr/local/pgsql/bin/initdb -D /home/pgsql/foo
13
die notwendigen Dateien zum Datenbankbetrieb im neuen Verzeichnis /home/pgsql/foo. Neben den Konfigurationsdateien und internen Verwaltungstabellen wird auch der interne Account pgsql neu erstellt. Der Account-Name richtet sich nach dem User-Namen, der den initdb-Befehl ausführt.
14
In der PostgreSQL-Dokumentation werden die von initdb ausgeführten Schritte als Erstellung eines Datenbank-Clusters beschrieben, da es möglich ist, mehrere »Cluster« auf einem Rechner gleichzeitig zu betreiben, und in jedem »Cluster« beliebig viele Datenbanken gleichzeitig bereitgestellt werden können. Der Start des »Clusters« foo wird über
/usr/local/pgsql/bin/postmaster -ip 5432 -D /home/pgsql/foo \ 2>> /home/pgsql/foo_log >> /home/pgsql/foo_log & erledigt. Die Option –ip 5432 bindet den »Cluster« an die Standard-TCP-Portnummer 5432 und erstellt gleichzeitig einen Socket mit dieser Nummer: /tmp/.s.PGSQL.5432. Sie können und sollten auf die Option -i verzichten, wenn die Datenbank nur lokal genutzt werden soll und die Applikationen
PostgreSQL
209
alternativ eine Verbindung über den PostgreSQL-Socket aufbauen können (Option -p 5432 erstellt nur den Socket: /tmp/.s.PGSQL.5432). Beachten Sie, dass immer nur ein »Cluster« eine Port- beziehungsweise Socketnummer nutzen kann. Es ist also nicht möglich, zwei »Cluster« über die Standard-Port- und Socketnummer 5432 gleichzeitig zu betreiben – jeder »Cluster« benötigt seine eigene Port- und Socketnummer. Der gleichzeitige Betrieb mehrerer PostgreSQL-»Cluster« ist nur bedingt empfehlenswert, da jeder »Cluster« eine erhebliche Menge Arbeitsspeicher beansprucht und diesen bereits beim Start für sich reserviert. Daher werden Sie bei gleichzeitigen Betrieb weiterer PostgreSQL-»Cluster« früher oder später mit der Meldung:
FATAL: could not create shared memory segment: Cannot allocate memory konfrontiert werden. Um das Problem zu beheben, muss der Arbeitsspeicher des Servers aufgestockt werden. Auf einem Testsystem ist hohe Performance nicht unbedingt zwingend erforderlich und Sie können beim Start eines »Clusters« ausnahmsweise die Zusatzoptionen –B 16 –N 8 übergeben und so den Speicherbedarf auf ein Minimum reduzieren. Diese Zusatzoptionen bieten sich beim Start von PostgreSQL auf einem lokalen Testserver oder innerhalb eines kleineren Intranets eigentlich generell an.
3.7.2
Verbindungsaufbau und psql-Befehle
Bevor Sie mit dem »Cluster« arbeiten können, müssen Sie noch eine Datenbank anlegen, was nach dem Start des Clusters von createdb übernommen wird:
/usr/local/pgsql/bin/createdb pgsql_dbase Anstelle von pgsql_dbase können Sie natürlich auch eine andere DatenbankBezeichnung wählen. Zur Verwaltung des PostgreSQL-»Clusters« steht mit psql ein direktes Interface zwischen Shell und Datenbank bereit. Der Befehl
/usr/local/pgsql/bin/psql versucht eine Verbindung zum Datenbank-Server über den Standard-Socket herzustellen. In unserem Fall kann das nicht funktionieren, da psql als userund Datenbanknamen die User-Bezeichnung des Accounts verwendet, der den Befehl ausführt. Sie können psql den zu nutzenden User-Namen (Option -U) und Datenbanknamen (Option –d) jedoch auch explizit übergeben:
210
Wichtige Serverdienste
1 2 /usr/local/pgsql/bin/psql -U pgsql -d pgsql_dbase
3
Um eine Verbindung zu einem anderen PostgreSQL Server und nicht dem »Standard-Cluster« aufzubauen, gibt es die Zusatzoption -h /path/socket oder -h HOSTNAME [-p PORT]. Praktisch ist auch die Option -f foo, die nach Ausführung der in der Datei foo gespeicherten SQL-Befehle die Verbindung abbricht. Eine Übersicht über alle psql-Optionen erhalten Sie mit /usr/local/pgsql/bin/psql --help.
4 5 6
Konnte psql eine Verbindung zur PostgreSQL-Datenbank herstellen, stehen Ihnen neben SQL-Befehle auch interne psql-Befehle, wie \q zum Beenden der Verbindung, zur Verfügung. Eine Übersicht der wichtigsten Kürzel finden Sie in der Tabelle 3.11. Kürzel
Bedeutung
\c foo
Baut Verbindung zur Datenbank foo auf.
\q
Beendet die Verbindung zur PostgreSQL-Datenbank.
\l
Liste sämtliche Datenbanken und ihrer Eigentümer.
\dn
Liste sämtlicher Schemen und ihrer Eigentümer der aktuellen Datenbank.
\du
Übersicht über vorhandene Accounts und ihre Grundrechte.
\dp schema.tabelle
Ausgabe der auf schema.tabelle gewährten Einzelrechte.
\d foo
Gibt Informationen zu foo aus, wenn foo eine Tabelle, View, Index oder Sequenz ist.
\x
Schaltet »Expanded display« ein beziehungsweise aus. Kann sich bei Tabellen mit sehr vielen Spalten als praktisch erweisen.
\i foo
Führt die in der Datei foo gespeicherten SQL Anweisungen so aus.
\!
Wechselt in die Shell, ohne die Verbindung zur Datenbank zu beenden. Nach exit; gelangen Sie wieder »zurück« in den interaktiven psql-Modus.
\! Foo
Führt den nach \! angegebenen Befehl in der Shell aus.
\?
Liste und Hinweise zu allen internen psql-Befehlen.
\h
Übersicht über verfügbare SQL-Befehle.
\h foo
Gibt eine Hilfe zum SQL-Befehl foo aus.
7 8 9 10 11 12 13 14
Tabelle 3.11 Übersicht über die wichtigsten psql-Kürzel
PostgreSQL
211
3.7.3
Absicherung
Sicher ist Ihnen aufgefallen, dass keine Passworteingabe erforderlich ist, bevor psql eine Verbindung zu PostgreSQL herstellt und gleichzeitig Zugriff mit sämtlichen Administratorrechten auf die Datenbank gestattet. Dieses Verhalten mag zu Testzwecken sinnvoll sein, hat aber auf einem Webserver nichts verloren. Deshalb sollten Sie nach dem Verbindungsaufbau ein Passwort für den automatisch angelegten Account festlegen:
alter user pgsql password 'geheim'; und die Datei pg_hba.conf im neu angelegten Datenbankverzeichnis /home/pgsql/foo anpassen. Die Authentifizierungs-Methode ist von trust auf md5 zu setzen:
# TYPE DATABASE USER CIDR-ADDRESS METHOD local all all md5 # IPv4-style local connections: host all all 192.168.0.33 255.255.255
md5
Beachten Sie, dass die host-Zeile meinem lokalen Rechner 192.168.0.33 den Zugriff gestattet und anstelle der IPV4-Variante auch IPV6 genutzt werden könnte. Sie können beliebig viele weitere host-Zeilen in diesem Muster hinzufügen. Um generell allen Rechnern einen Login zu ermöglichen, könnten Sie 0.0.0.0 0.0.0.0 für IP-Adresse und Subnetmask verwenden. Aus Sicherheitsgründen sollten Sie dies nicht tun und stattdessen lieber eine feste IP-Adresse für Ihr lokales Netzwerk beantragen oder einfach über die SSH beziehungsweise phpPgAdmin auf PostgreSQL zugreifen. Damit die Änderungen in pg_ hba.conf aktiv werden, ist der PostgreSQL-«Cluster« neu zu starten oder auf pg_ ctl zurückzugreifen:
/usr/local/pgsql/bin/pg_ctl reload -D /home/pgsql/foo Beachten Sie, dass die Umstellung auf md5 die Passwortabfrage aktiviert. Leere Passwörter werden nicht akzeptiert. Deshalb müssen Sie zunächst mit alter user ein Passwort definieren wie am Abschnittsanfang beschrieben. Superuser Zugangsdaten vergessen? Wurde das Admin-Passwort vergessen, ist die Methode des local Types auf trust zu setzen und die Konfigurationsdatei neu zu laden, um über pgsql erneut Vollzugriff erlangen zu können. Selbst wenn Sie den User-Namen nicht mehr wissen, mit dem initdb ausgeführt wurde, können Sie dann eine Verbindung zur
212
Wichtige Serverdienste
1 2 Datenbank aufbauen und den User-Namen über select username from pg_ user where usesysid=1; erfragen. Allerdings müssen Sie psql eine gültige Datenbank mit der Option -d übergeben, damit eine Verbindung hergestellt werden kann. Eine Liste aller vorhandenen Datenbank wird über /usr/local/pgsql/bin/psql -l ausgegeben. Nach dem Verbindungsaufbau mit einer beliebigen Datenbank können Sie ein neues Passwort mit alter user foo password 'new_pwd'; definieren.
3.7.4
3 4 5 6
User anlegen
7
Sie können weitere PostgreSQL-Accounts mit einem SQL-Kommando über pgsql oder über createuser von der Shell aus anlegen. Einen neuen Superuser (Administrator) legen sie mit
8
/usr/local/pgsql/bin/createuser -P –a -D super
9
an. Alternativ kann das SQL-Kommando
10
CREATE USER super WITH PASSWORD 'pwd' CREATEUSER; verwendet werden. Beachten Sie, dass nach WITH mehrere Parameter (hier PASSWORD und CREATEUSER) aufgezählt werden können und als Trennung lediglich ein Leerzeichen zu verwenden ist.
11 12
Die Rückfrage von createuser, ob User »super« eigene Datenbanken anlegen können soll, ist unsinnig, da User, die berechtigt sind weitere Accounts anzulegen (Option -a), von PostgreSQL automatisch als Superuser betrachtet werden und somit alles dürfen.
13 14
createuser kann auch die von pgsql bekannten Optionen -U USERNAME -h HOSTNAME [-p PORT] übergeben werden, um den User-Namen, mit dem eine Verbindung hergestellt wird, anzupassen sowie um eine Verbindung zu einer externen Datenbank aufbauen zu können. In der Regel ist es sinnvoll, Usern die Möglichkeit, Datenbanken anzulegen, zu verweigern. Beachten Sie, dass die Schemen von PostgreSQL eine weitere Verschachtelung und somit die saubere Trennung von verschiedenen Projekten innerhalb einer einzelnen Datenbank ermöglichen.
PostgreSQL
213
Aufgabe
./createuser
SQL CREATE USER
Passwort festlegen
-P (wird später abgefragt)
PASSWORD 'foo'
Superuser-Status erteilen
-a (Verneinung: –A)
CREATEUSER
Recht, Datenbanken anzulegen
-d (Verneinung: –D)
CREATEDB
Tabelle 3.12 Übersicht der createuser-Optionen für Shell und SQL. Verneinungen unterdrücken die Nachfrage von createuser bei einem Direktaufruf über die Shell.
3.7.5
User löschen
Das Löschen eines Users kann nur durch einen Superuser über den SQL Befehl DROP USER foo oder usr/local/pgsql/bin/dropuser foo vorgenommen werden. Allerdings wird der Befehl nur erfolgreich sein, wenn dem User keine Datenbank gehört. Falls der zu löschende Account eine Datenbank besitzt, wird der Befehl nicht ausgeführt werden:
ERROR: user "foo" cannot be dropped DETAIL: The user owns database "foo_db". Soll die bestehende Datenbank nicht gelöscht werden, ist ein neuer Eigentümer festzulegen (siehe Abschnitt 3.7.8).
3.7.6
Datenbanken anlegen und löschen
Datenbanken sollten bereits beim Anlegen dem späteren User zugewiesen werden. Dies geschieht über psql mit der CREATE DATABASE-Anweisung und der Option OWNER:
create database new_db_name owner=foo; Alternativ können Sie /usr/local/pgsql/bin/createdb die Option -O übergeben:
/usr/local/pgsql/bin/createdb -U username -O foo new_db_name Das Löschen ist ebenfalls keine Hexerei und mit
drop database new_db_name; beziehungsweise
/usr/local/pgsql/bin/dropdb -U username new_db_name zu erledigen.
214
Wichtige Serverdienste
1 2 3.7.7
Rechtemodell von PostgreSQL
3
Vereinfacht gesagt wurde in PostgreSQL ein dreistufiges Rechtesystem implementiert. Superuser dürfen grundsätzlich alles und nur sie können neue Accounts erzeugen. Eigentümer einer Datenbank dürfen in dieser beliebig viele Schemen anlegen, den Eigentümer der Schemen ändern sowie auf sämtliche Datenzurückgreifen, die innerhalb ihrer Datenbanken angelegt sind. Accounts, denen keine Datenbank gehört, dürfen nur auf Informationen zurückgreifen, für die sie explizit Rechte erhalten haben. Wurde ihnen ein Schema oder eine Tabelle zugewiesen, dürfen sie in dem Schema beziehungsweise der Tabelle wiederum alles.
4 5 6 7
Beachten Sie, dass in der Voreinstellung jeder User Vollzugriff auf das Schema public besitzt. public wird bei Erzeugung einer Datenbank automatisiert angelegt. Wird Ihre PostgreSQL-Datenbank von mehreren Personen genutzt, ist dies wahrscheinlich nicht erwünscht und Sie sollten das Schema löschen, um Nutzer, denen dieser Umstand vielleicht nicht bekannt ist, vor einem möglicherweise unerwünschten Datenzugriff durch Dritte zu schützen.
10
Abfrage und Anpassung der Grundrechte
11
Ob ein Account Superuser-Status besitzt, auf Systemkataloge zugreifen oder Datenbanken anlegen kann, ist über pg_user zu erfragen:
12
8 9
select usename, usecreatedb, usesuper, usecatupd from pg_user;
13
Die Wertekürzel 't' und 'f' von usecreatedb, usesuper und usecatupd stehen für true beziehungsweise false. Sitzt usesuper auf 't', ist der Account ein Superuser und darf unabhängig von anderslautenden Werten in usecreatedb oder usecatupd generell alles. Die einzige Ausnahme, die die Regel bestätigt, ist die Möglichkeit, die Systemkataloge zu aktualisieren (usecatupd). Dies deutet bereits darauf hin, dass lediglich Administratoren, die sich sehr gut mit PostgreSQL auskennen, das Privileg zur Anpassung interner PostgreSQL-Verwaltungstabellen besitzen sollten. Eigentlich sollten alle, die mit Systemkatalogen umgehen können, auch zu dieser Gruppe zählen. Im Zweifelsfall können Sie einzelnen Personen dieses Privileg mit
14
update pg_shadow set usecatupd='f' where usename='foo'; entziehen. Der Schönheitsfehler ist, dass unser User foo zwar für sich selbst das usecatupd nicht wieder auf 't' setzen kann, da er aber selbst einen Superuser Account anlegen darf und diesem von PostgreSQL automatisiert usecatupd='t' zugewiesen werden würde, müsste er lediglich eine Verbindung mit
PostgreSQL
215
dem neuen Account zu PostgreSQL aufbauen, und schon wäre usecatupd='f' ausgehebelt. Auf der anderen Seite sollten Sie Superusern blind vertrauen – falls Sie das nicht können, dann dürften Sie den Superuser-Status eigentlich nicht zuweisen. Als Sicherung gegen den beschriebenen »Hack« könnten Sie ausführliches Logging in PostgreSQL aktivieren, und sobald eine Logzeile verrät, dass User foo einen neuen Superuser-Account erstellt hat, müsste ein Skript diesen Account automatisiert auf usecatupd='f' setzen. Zur Realisation dieser Aufgabe könnten Sie das in Abschnitt 5.13, Logfile-Analyse, vorgestellte Tool Logsurfer einsetzen. Übrigens wird usecatupd generell nur bei Zuweisung des Superuser Status automatisiert von PostgreSQL zugewiesen und beim Entziehen des SuperuserStatus (alter user foo nocreateuser;) auch automatisiert entfernt. Eigentümer von Datenbanken, Schemen und Tabellen Über die usesysid von pg_user können Sie herausfinden, ob und welche Datenbanken einem Account zugewiesen wurden:
select datname, usename from pg_database, pg_user where datname='usesysid'; Falls Sie eine Liste aller Datenbanken und ihrer Eigentümer sehen möchten, ist auf die where-Klausel zu verzichten oder einfach der interne psql-Befehl \l zu verwenden. Bevor Sie Detailinformationen über die vergebenen Rechte einer Datenbank erhalten können, müssen Sie in diese wechseln. Danach können Sie mit \dn eine Liste aller vorhandenen Schemen anzeigen lassen. Die SQL-Variante dieses internen psql-Kommandos lautet:
SELECT distinct(schemaname), tableowner \ FROM pg_catalog.pg_tables; Alle Tabelleneigentümer eines Schemas werden mit
SELECT schemaname, tablename, tableowner FROM pg_catalog.pg_tables where schemaname='foo'; abgefragt.
216
Wichtige Serverdienste
1 2 3.7.8
Bestehende Datenbank einem neuem Eigentümer zuweisen
3
Die umständliche Methode ist, ein Dump anzulegen, die Datenbank zu löschen und danach den Dump mit dem Account des gewünschten Eigentümers einzuspielen.
4
Die schnellere, aber schlecht zu merkende Lösung besteht darin, die internen PostgreSQL-Informationen zum Eigentümer der Datenbank umzuschreiben. Allerdings ist diese Methode nicht ganz ungefährlich, wenn kein Backup der internen Datenbank pg_database vorliegt und viele verschiedene User Eigentümer von Datenbanken sind. Testen Sie vor dem SQL-Update-Befehl mit einer entsprechenden select-Abfrage (select datname from pg_database where datdba=UID;) daher sorgsam, ob nur die Datenbanken betroffen sein werden, die auch tatsächlich dem zu löschenden User gehören, bevor Sie zur Tat schreiten.
5 6 7 8 9
Zunächst müssen Sie die UID des zu löschenden Accounts sowie die UID des Accounts herausfinden, dem die Datenbank und alle enthaltenen Informationen übertragen werden sollen:
10 11
select usename, usesysid from pg_user; usename | usesysid -------------+---------foo | 106 michael | 1
12 13
Der zu löschende User foo wird unter der ID 106 geführt. Der neue Eigentümer soll michael werden, der die ID 1 besitzt. Diese ID erhält übrigens stets der Account, der über initdb erzeugt wurde.
14
Die ID des Users ist in pg_database unter datdba gespeichert und wäre für unser Beispiel wie folgt änderbar:
update pg_database set datdba=1 where datdba=106; 3.7.9
Struktur und Datenbankinformationen abfragen
Leider stehen in PostgreSQL die praktischen MySQL-Befehle view columns from foo, show tables oder show databases nicht zur Verfügung. Ich möchte Ihnen die entsprechenden »SQL-Befehlsumschreibungen für PostgreSQL« deshalb nicht vorenthalten. Zeige alle Datenbanken und ihre Eigentümer (Kürzel: \l):
PostgreSQL
217
select datname, usename from pg_database, pg_user where datdba=usesysid; Die nächste Hierarchiestufe unterhalb von Datenbanken sind Schemen (\dn):
select DISTINCT(table_schema) from information_schema.columns; Dieser Datenbankbefehl gibt jedes in der Datenbank pgsql vorhandene Schema aus. Die Schemen information_schema und pg_catalog sind übrigens interne Schemen von PostgreSQL, die automatisch für jede neue Datenbank angelegt und auch benötigt werden. public ist ein Standard-Schema, das verwendet oder gelöscht werden darf. Beachten Sie, dass information_schema ein der Datenbank untergeordnetes Schema ist und keine Daten über Schemen anderer Datenbanken enthält. DISTINCT wurde verwendet, um die Mehrfachnennung von Schemen zu verhindern, da für jede vorhandene column einer table ein table_schema-Eintrag in information_schema.columns gespeichert ist. Dies gestattet aber auch die Anzeige aller vorhandenen Schemen, Tabellen und Columns in einem einzigen Abwasch:
select table_schema, table_name, column_name, data_type from information_schema.columns where table_schema <> 'information_ schema' and table_schema <> 'pg_catalog'; Leider enthält data_type keine vollständigen Informationen zu den columnDetails – diese sind unter anderem in column_default, is_nullable, character_ maximum_length und datetime_precision abgelegt. Der SQL-Befehl, mit dem Sie die wichtigsten Column-Informationen abfragen könnten, würde lauten:
select column_name, data_type, column_default, is_nullable, character_maximum_length, datetime_precision from information_ schema.columns where table_schema ='schemaname' and table_name = 'tabellenname'; Bequemer geht es mit dem Kürzel \d schemaname.tabellenname. Der Nachteil ist, dass die Ausgabe auf eine Tabelle beschränkt ist und so gegebenenfalls für jede Tabelle eines Schemas entsprechende Anfragen zu wiederholen sind.
3.7.10 Backup mit pg_dump und pg_restore Wie bei MySQL können Sie natürlich die Verzeichnisse der »Cluster« einfach kopieren, aber um Inkompatibiltäten bei einem Versionswechsel der Datenbank zu vermeiden und nicht unnötig Speicherplatz zu vergeuden, sollten Sie lieber zu pg_dump greifen. Ärgerlicherweise gibt es noch keine Option, um
218
Wichtige Serverdienste
1 2 pg_dump das Passwort beispielsweise über ein Backup-Skript einfach übergeben zu können, aber das gelungene Shell-Skript pg_backup.sh (über http://freshmeat.net/projects/database/ zu beziehen und auch auf der CD zum Buch enthalten) kann nicht nur mit diesem Hindernis umgehen, sondern übernimmt auch Wartungsaufgaben (vacuum_db). Um vor speziellen Änderungen an einer Datenbank mal schnell ein Backup anzufertigen oder um eine bestehende Datenbank zu duplizieren, stellen pg_dump und pg_restore auch eine elegante Möglichkeit dar:
3 4 5 6
/usr/local/pgsql/bin/pg_dump -Fcbc -Z1 -f dumpfile pgsql
7
Die Zusatzoption -Fc sorgt dafür, dass die Datei im pg_dump-eigenen »custom« Format gespeichert wird, das zusammen mit dem tar-Format (Option -Ft) von pg_restore gelesen werden kann. Im Klartextmodus können keine Blob-Felder berücksichtigt werden, weshalb vorsichtshalber immer -Fc oder -Ft generell mit der Option -b für die Berücksichtigung von Blob-Feldern verwendet werden sollte.
8 9 10
Durch -c erzeugt pg_dump vor jeder create-table- oder create-schema-Zeile einen entsprechenden drop-Befehl. Sehr nützlich ist auch die Option -Z[0–9] die für eine Kompression mit variabler Stärke sorgt. Ich nehme gerne -Z1, wer möglichst viel Platz sparen möchte, wird von -Z9 übrigens wenig begeistert sein und sollte die Datei lieber nach Erstellung mit –Z1 durch bzip oder zip »zusätzlich« komprimieren. Die Option -f Dateiname sorgt dafür, dass die Ausgabe von pg_dump in eine Datei geschrieben wird, anstatt auf STDIN zu landen. Die Bezeichnung der zu dumpenden Datenbank ist am Ende des pg_dumpBefehls anzugeben – in unserem Beispiel wurde die Datenbank pgsql gesichert. Wer sich für sämtliche pg_dump-Optionen interessiert, kann pg_dump --help aufrufen.
11 12 13 14
Das Einspielen einer mit pg_dump erzeugten Datei ist nicht kompliziert:
/usr/local/pgsql/bin/pg_restore -cd pgsql dumpfile Die Option -c sorgt dafür, dass vor jeder create-schema beziehungsweise create-database-Anweisung ein entsprechender drop-Befehl ausgeführt wird. Die Option -d Datenbankname ist selbsterklärend und am Befehlsende ist der Dateiname des einzuspielenden dumps anzugeben. Alle übrigen Funktionen von pg_restore können über die Option --help aufgelistet werden.
PostgreSQL
219
3.7.11 phpPgAdmin phpPgAdmin ist ein PHP-basiertes Webinterface für PostgreSQL, das abgesehen von der Namensgebung und der verwendeten Programmiersprache keine weiteren Gemeinsamkeiten zu phpMyAdmin aufweist. Mangels praktischer MySQL-Befehle wie show columns oder show tables und der sehr komplexen Benutzerverwaltung von PostgreSQL ist phpPgAdmin ein sehr angenehmes Webinterface, das einen deutlichen Mehrwert gegenüber der Ansteuerung der Datenbank via Terminal bietet. Auch das Wechseln zwischen den Datenbanken scheint phpPgAdmin ohne neuen Login zu erledigen.8 Sie erhalten die neueste Version von phpPgAdmin über http://phppgadmin.sourceforge.net/?page=download. Auf der CD zum Buch finden Sie die Version 3.5.1. Die Installation erschließt sich im Auspacken des Tarballs in einem Verzeichnis, das über den Browser erreichbar ist. Natürlich muss PHP ebenfalls mit der ./configure-Option --with-pgsql für PostgreSQL-Support kompiliert worden sein. Sämtliche Datenbanken, zu denen phpPgAdmin eine Verbindung aufbauen soll, sind in conf/config.inc.php als mehrdimensionales Array einzutragen. Folgende Zeilen sind bereits vorhanden und müssen an die eigenen Erfordernisse angepasst werden:
$conf['servers'][0]['desc'] = 'PostgreSQL'; $conf['servers'][0]['host'] = '192.168.0.33'; $conf['servers'][0]['port'] = 5432; $conf['servers'][0]['defaultdb'] = 'template1'; Um einen weiteren Server über das Select-Feld beim Login auswählen zu können, können Sie diese Zeilen duplizieren und die [0] in [1] ändern sowie Bezeichnung, IP und gegebenenfalls auch den Port anpassen. Auf diese Weise können Sie beliebig viele Server definieren. Der Wert von defaultdb ist nur dann anzupassen, wenn zum Anlegen neuer Datenbanken nicht template1 verwendet werden soll oder Sie das template1 gelöscht beziehungsweise den Zugriff eingeschränkt haben.
8 Im Hintergrund ist natürlich ein entsprechender Login wie in pgsql notwendig, aber dieser Prozess wird für den Anwender automatisiert. Bei einem PHP Webinterface ist ohnehin bei jedem Seitenaufruf ein erneuter Login erforderlich …
220
Wichtige Serverdienste
1 2 3 4 5 6 7 8 Abbildung 3.6 phpPgAdmin ist ein nutzerfreundliches Interface, das auch bequemes Browsen durch die gesamte Datenbank ermöglicht.
9 10
Die Version 3.5.1 von phpPgAdmin weigert sich übrigens, den User-Namen pgsql für den Login zu verwenden – das heißt, phpPgAdmin versucht noch nicht einmal, mit diesem Namen eine Verbindung zur PostgreSQL-Datenbank aufzubauen, sondern gibt lapidar »Anmelden nicht erlaubt« aus. In der Datei classes/Misc.php findet sich die Zeile
11 12
$bad_usernames = array('pgsql', 'postgres', 'root', 'administrator');
13
Wer diese Sicherheitsmaßnahme übertrieben oder gar hinderlich findet, könnte den User-Namen aus dem Array entfernen oder die Prüfung des UserNamens über Anpassen von
14
$conf['extra_login_security'] = true; in der Datei conf/config.inc.php zu
$conf['extra_login_security'] = false; deaktivieren. Leider kämpft phpPgAdmin noch mit Kinderkrankheiten. So ist das Erstellen von Backups in der Version 3.5.1 fehleranfällig und arbeitet unter vielen Systemkonstellationen nicht korrekt beziehungsweise überhaupt nicht. Im Zweifelsfall können Sie jedoch über phpPgAdmin auch direkt PostgreSQL-Befehle übergeben. Das entsprechende Popup-Fenster öffnet sich nach Klick auf den Menüpunkt SQL, der sich im oberen Frame befindet.
PostgreSQL
221
3.8
Die Komponenten eines Mailservers
Ein Mailserver wird häufig als eine Kombination von MTA-(Mail Transfer Agent-) und einem POP3-(Post Office Protocol-) und/oder IMAP-(Internet Mail Access Protocol-)Server verstanden. Der eigentliche Mailserver ist der MTA und er ist lediglich für das Empfangen und Versenden der Nachrichten zuständig. Nur beim Nachrichtenversand kommuniziert der MUA (Mail User Agent – ein Programm wie Outlook Express) direkt mit dem MTA über SMTP (Simple Message Transfer Protocol). Da zum Abholen der Nachrichten ein zweiter Dienst benötigt wird, müssen Mail- und POP3- beziehungsweise IMAP-Server reibungslos zusammenarbeiten. Bei den MTAs zählen Sendmail, Postfix, Exim und Qmail zu den bekanntesten Vertretern. Ich habe mich für Postfix entschieden, weil es sehr stabil und performant sowie deutlich einfacher als das bekannte Sendmail zu konfigurieren ist. Sicherheitsfragen wurden ebenfalls besser gelöst, als das bei seinem großen Bruder der Fall ist. Die Möglichkeit, wichtige Konfigurationsdateien über MySQL zu verwalten, prädestiniert Postfix für die Erstellung eigener Webinterfaces zur bequemen Postfachverwaltung. Die IMAP/POP3-Server Cyrus und Courier-IMAP sind wohl am häufigsten anzutreffen. In sehr großen Umgebungen wird gerne Cyrus eingesetzt, allerdings ist Courier schlanker, einfach zu kompilieren und zu konfigurieren und bringt ebenfalls MySQL-Unterstützung mit. Es mag spezielle Aufgaben geben, für die Cyrus besser geeignet ist, aber der Einsatz von Courier-IMAP wird bei vergleichsweise geringem Administrationsaufwand in den meisten Fällen alle Wünsche erfüllen. Die Kombination aus Postfix und Courier-IMAP gestattet eine Absicherung des Mail-Versands mit POP-before-SMTP und eine bequeme Verwaltung über die MySQL-Datenbank. SMTP-Auth (Passwortabfrage, bevor von Mail-Clients Nachrichten zum Versand angenommen werden) ist mit der SASL-Auth-Komponente von Cyrus realisierbar. Der kombinierte Betrieb von Postfix mit CyrusSASL und Courier-IMAP ist reibungslos möglich. Die Nutzung von Cyrus-SASL zwingt Sie also nicht zur Integration von Cyrus als POP- und IMAP-Server. Allerdings unterstützen nicht alle Mail-Clients SMTP-Auth, weshalb Sie aus Kompatibilitätsgründen lieber ausschließlich POP-before-SMTP oder SASLAuth zusätzlich zu POP-before-SMTP installieren sollten. Bedenken Sie, dass die Entwickler von Postfix Sicherheitsbedenken gegenüber SASL-Auth haben. Tatsächlich ist SASL-Auth ein äußerst umfangreiches Paket, dessen Integration insbesondere bei manueller Kompilierung nicht gerade trivial ist und selbst Insidern Schwierigkeiten bereitet. Zum Beispiel arbeitet saslpasswd2 nach
222
Wichtige Serverdienste
1 2 Installation des offiziellen OpenBSD- 3.6er-Pakets cyrus-sasl-2.1.19.tgz nicht korrekt.
3
phpMyWebhosting
4
phpMyWebhosting ist ein Open-Source-Projekt, das sich mit dem Thema Webinterface zur Verwaltung von Postfix, Courier, Apache und auch ProFTPD über MySQL auseinander setzt. Leider ist die aktuelle »stable« Version (zum Druckzeitpunkt Version 0.3.4) nur bedingt für Produktivumgebungen geeignet.
5 6
Dennoch ist phpmywebhosting.sourceforge.net einen Blick wert. Wenn Sie PHP beherrschen, können Sie das Projekt an die eigenen Anforderungen anpassen und müssen nicht von vorn beginnen.
7 8
3.9
Postfix 9
Da für SUSE 9.2 kein vorbereitetes Postfix-Paket mit MySQL-Support existiert, müssen Sie zur manuellen Kompilierung greifen, falls Sie Ihren Mailserver über die Datenbank pflegen möchten. Das Gleiche gilt auch für alle, die aus Sicherheitsgründen auf SASL-Auth verzichten möchten, da die Cyrus SASL-Auth Komponente im SUSE-9.2-Postfix-Paket enthalten ist.
10
OpenBSD-Nutzer können zwar Postfix mit MySQL- oder auch SASL-Support installieren, finden aber kein Paket, das beide Komponenten beinhaltet.
12
11
Lediglich Debian-Nutzer haben die Möglichkeit, Postfix zusammen mit MySQL- und SASL-Auth Support über dselect bequem zu installieren.
13
Zunächst werde ich die Grundfunktionen von Postfix erläutern. In kleineren Umgebungen geht es natürlich auch ohne Datenbank. Für das Abholen von EMails echter Systemaccounts genügt der altbekannte POP3-Daemon via inetd vollauf – die Auseinandersetzung mit Courier-IMAP können Sie sich dann sparen.
14
Installieren Sie Postfix zunächst im Standard-Paket Ihrer Distribution, außer Sie wissen bereits jetzt, dass Sie MySQL und oder Cyrus-SASL-Unterstützung benötigen. Hinweise für Nutzer des SUSE-Standard-Pakets Damit fremde Rechner mit Postfix überhaupt kommunizieren können, müssen Sie zunächst in /etc/postfix/main.cf die Zeile
inet_interfaces = 127.0.0.1 ::1 in
Postfix
223
inet_interfaces = all abändern. Damit nun nicht alle Rechner E-Mails ohne Authentifizierung über Ihren Server versenden können, ist weiterhin die Zeile
mynetworks = 127.0.0.1 einzufügen und postfix reload ausführen. Im SUSE-Paket wurde wohl aus Vereinfachungsgründen komplett auf die Chroot-Umgebung verzichtet. Tatsächlich ist insbesondere die Handhabung von SASL in einer Chroot-Umgebung nicht ganz trivial. Wer höhere Sicherheitsanforderungen stellt und alle Bestandteile von Postfix, soweit möglich, chrooten möchte, wird mit der Kompilierung der Originalquellen, in denen diese Aufgabe bereits in Angriff genommen wurde, schneller ans Ziel gelangen.
3.9.1
Manuelle Kompilierung von Postfix mit MySQL und SASLSupport
Postfix ist über http://postfix.org zu beziehen. Auf der CD zum Buch finden Sie die Version postfix-2.1.5. Wer Postfix selbst kompilieren will oder muss, benötigt grundsätzlich das db-devel-Paket sowie für MySQL-Support zusätzlich das mysql-devel-Paket beziehungsweise für SASL die SASL-Library von http://freshmeat.net/projects/cyrussasl/. Der ./configure-Schritt entfällt; alle benötigten Optionen sind mit dem Make-Aufruf zu verbinden. Zur Kompilierung von Postfix mit MySQL-Support:
make makefiles CCARGS="-DHAS_MYSQL -I/usr/include/mysql" \ AUXLIBS="-L/var/lib/mysql -lmysqlclient -lz -lm" Zur Kompilierung von Postfix mit SASL-Support:
make makefiles \ CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \ AUXLIBS="-L/usr/local/lib -lsasl2" Postfix mit MySQL- als auch SASL-Support:
make makefiles CCARGS="-DUSE_SASL_AUTH \ -I/usr/local/include/sasl, \ -DHAS_MYSQL -I/usr/include/mysql" \ AUXLIBS="-L/usr/local/lib -lsasl2, \ -L/var/lib/mysql -lmysqlclient -lz -lm" Die Verzeichnisangaben sind gegebenenfalls an Ihr System anzupassen, das Beispiel bezieht sich auf SUSE.
224
Wichtige Serverdienste
1 2 Bevor die Installation mit make install abgeschlossen werden kann, benötigt Postfix die Gruppe postdrop, eine eigene UID und GID:
3
groupadd postfix useradd –g postfix postfix groupadd postdrop
4 5
Ob die Installation von MySQL funktioniert hat, lässt sich mit dem Befehl
6
postconf -m unmittelbar prüfen. Die Ausgabe sollte eine Zeile mit dem Wort mysql enthalten. Falls diese Zeile fehlt, konnte make bei der Kompilierung die benötigten Bibliotheken oder das MySQL-Verzeichnis nicht finden. Korrigieren Sie die Pfadangaben Ihres make-Aufrufs und versuchen Sie es erneut.
3.9.2
7 8 9
Grundkonfiguration
Im Verzeichnis /etc/postfix/ finden Sie die Programmeinstellungen in main.cf und die Daemon-Einstellungen (Prozessanzahl, chroot ...) in master.cf.
10
Wenden wir uns zunächst main.cf zu. Die Programmvoreinstellungen sind bereits sehr gut und nur noch an die eigenen Bedürfnisse anzupassen. Im Folgenden gehe ich daher lediglich auf die zu ändernden Zeilen ein.
11 12
myhostname = virtual.domain.tld
13
Die Variable myhostname ist auf den vollständigen Domain-Namen des Mailservers (der in den Zonendateien des Nameservers als MX-Record verwendet wird) zu setzen.
14
mydomain = domain.tld Mit der Maildomain werden E-Mails versandt, wenn keine andere angegeben ist. Gleichzeitig werden Nachrichten ebenfalls an dieser Domain angenommen. Beachten Sie den Unterschied zu myhostname. Über telnet myhostname 25 ist der Mailserver zu erreichen. Hier kann auch eine Subdomain verwendet werden.
mydestination = domain1.de, domain2.de Postfix betrachtet sich für die als mydestination definierten Domains als zuständig und nimmt Nachrichten an diese Domains entgegen. Nicht alle Domains müssen die IP-Adresse des Servers besitzen, Postfix kann auch Nachrichten an eine Domain entgegennehmen, deren IP-Adresse auf einem anderen Server liegt. Beachten Sie hierzu Abschnitt 3.2.3, Bind im harten Server-Einsatz. Sind viele Domains zu verwalten, bietet sich alternativ Table Transport an.
Postfix
225
myorigin = $myhostname In der Voreinstellung verwendet Postfix beim Nachrichtenversand den Wert von myhostname zur Vervollständigung der Absenderadresse, wenn lediglich der User-Name angegeben wurde.
mynetworks = 127.0.0.1 Die Variable mynetworks legt fest, von welchen Rechnern Postfix E-Mails generell akzeptiert und gegebenenfalls an den zuständigen Mailserver weiterleitet (dies wird als Relay bezeichnet). Nutzen Sie hier unbedingt 127.0.0.1, um E-Mails lediglich von localhost automatisch zu akzeptieren. In einem Intranet könnte 192.168.0/24 für das gesamte lokale Netzwerk eventuell sinnvoll sein.
qmgr_fudge_factor = 70 Nun verwendet Postfix maximal 70 Prozent seiner Ressourcen für die Bearbeitung von ausgehenden Mails. In der Voreinstellung werden 100 Prozent genutzt, was theoretisch für DOS-Attacken nutzbar ist. Die Zeile
qmgr_site_hog_factor = 40 setzt die maximal verfügbaren Ressourcen einer Zieladresse auf höchstens 40 Prozent fest. Dies verhindert, dass beispielsweise eine große Nachricht, die gleichzeitig an viele t-online.de- oder aol.de-Adressen geht, den Nachrichtenversand anderer Mails ausbremst. Auch hier ist die Voreinstellung von 90 Prozent etwas zu großzügig.
qmgr_message_active_limit = 3000 erlaubt maximal 3 000 gleichzeitige Nachrichten in der active-Queue (Mails zur sofortigen Bearbeitung). Die Voreinstellung von 10 000 ist für einen kombinierten Mail- und Webserver zu freizügig.
smtpd_banner = $myhostname ESMTP Verwenden Sie als Banner lediglich $myhostname und die Protokollbezeichnung ESMTP (Postfix beherrscht das so genannte enhanced simple message transfer protocol). Das Banner wird bei einer Kontaktaufnahme ausgegeben und muss keine weiteren Informationen enthalten (Security by obscurity).
3.9.3
Lokale Mail-Adressen
In der Datenbank aliases.db werden üblicherweise zu wichtigen System- und sämtlichen User-Accounts die zuständigen Mail-Adressen festgelegt. In der Regel werden alle System-Accounts an Root geleitet. Werfen Sie einen Blick in /etc/aliases:
226
Wichtige Serverdienste
1 2 root: [email protected], [email protected] daemon: root ...
3 4
Mails an Daemon oder Root werden an die Adressen [email protected] und [email protected] geleitet. Sie können beliebig viele Adressen durch Kommata getrennt angeben. Es empfiehlt sich, zumindest eine »externe« Adresse für Nachrichten an Root festzulegen, um so wichtige Systemnachrichten sicherheitshalber sofort an einen anderen Rechner zu senden. Nachrichten an Accounts, die nicht in aliases.db aufgeführt sind, werden dagegen direkt in das lokale Postfach des Nutzers geliefert. Diese Nachrichten können über das jeweilige Nutzerpasswort dann mit Pop3 abgeholt oder mit IMAP eingesehen werden.
5 6 7 8
Nach der Installation von Postfix und Änderungen an /etc/aliases ist der Befehl newaliases aufzurufen, um die Datei /etc/aliases.db aus /etc/aliases neu zu erzeugen. Dieser Schritt ist auch dann notwendig, wenn aliases.db bereits existieren sollte (das Format der Datenbankdatei ist bei Sendmail, Exim und Postfix unterschiedlich).
9 10 11
3.9.4 Testlauf und Einblick in das SMTP
12
Bevor Sie Postfix starten können, sollten Sie überprüfen, ob bereits ein anderer MTA auf Port 25 lauscht. Dies geschieht mit lsof -i :25. Beenden Sie gegebenenfalls einen bereits laufenden Prozess.
13
Postfix kann über postfix start gestartet werden. Um die Funktionsweise überprüfen zu können, ist es notwendig, die Eckpfeiler des SMTP zu kennen.
14
Sobald eine Verbindung zum Mailserver hergestellt ist, wird die eigene Identität, also die Domain, über helo mitgeteilt. Danach ist die Mail-Adresse des Absenders (rcpt from:) zu übergeben. Bevor der eigentliche Nachrichtentext mit optionalem Subjekt übermittelt wird (data), muss dem Mailserver die Zieladresse (rcpt to:) übergeben werden. Abgesehen vom helo, das lediglich beim Verbindungsaufbau zu übergeben ist, sind diese Schritte für jede zu übermittelnde Nachricht auszuführen. Wie bereits angedeutet, können Sie die Kommunikation über Telnet manuell führen und so feststellen, bei welchen Schritten Probleme auftreten.
macvampi@linbook:~> telnet 192.168.0.2 25 Trying 192.168.0.2... Connected to 192.168.0.2. Escape character is '^]'.
Postfix
227
220 DebGal.home ESMTP Postfix helo a3s.home 250 DebGal.home mail from: [email protected] 250 Ok rcpt to: [email protected] 250 Ok data 354 End data with
mail from: [email protected] 250 Ok rcpt to: [email protected] 554
228
Wichtige Serverdienste
1 2 3.9.5
Restriktionen
3
Es ist empfehlenswert, Nachrichten, die an einen gültigen Account gerichtet sind, weiteren Prüfungen zu unterziehen und so ungültige oder nicht korrekte Adressen vollständig herauszufiltern. Mit Postfix ist es unter anderem möglich, unbekannte Host-Namen oder die Domain-Adresse des Senders (Mail Header, Adresse für Fehlermeldungen und Bounces ...) sowie Adressen, die keinen vollständigen Domain-Namen (fqdn) besitzen, abzulehnen:
4 5 6
smtpd_recipient_restrictions = reject_unknown_hostname, \ reject_unknown_sender_domain, reject_non_fqdn_sender
7
Der Parameter smtpd_recipient_restrictions trägt einen verwirrenden Namen. Die Prüfung bezieht sich nicht auf den Mail-Empfänger, sondern wird erst nach Übergabe von rcpt to: angestoßen. Auch wenn wir unsere Prüfungen bereits beim mail from: vollständig durchführen konnten, ist es dennoch sinnvoll, die Übergabe des letzten Wertes vor Übermittlung des eigentlichen Nachrichtentextes abzuwarten, da dies die Kommunikation verlängert und Spammern das Leben etwas schwerer macht. smtpd_parameter_restrictions
Prüfung nach
smtpd_helo_ restritions
helo from foo
smtpd_sender_ restritions
mail from: foo
smtpd_recipient_restritions
rcpt to: foo
8 9 10 11 12 13
Tabelle 3.13 Prüfungszeitpunkt von Restriktionen
14
3.9.6 Einrichten von Postfächern, Aliasen sowie Weiterleitungen Aliases.db zur Verwaltung und Weiterleitung der Mail-Adressen von SystemAccounts haben Sie bereits kennen gelernt. Allerdings ist aliases.db für viele Aufgaben zu unflexibel. Glücklicherweise kennt Postfix weitere Datenbanken (Lookup-Tables). Wie die aliases-Datenbank können auch die übrigen Lookup-Tables über eine Textdatei im Verzeichnis /etc/postfix generiert werden. Abgesehen von aliases.db sind die Lookup-Tables Postfix spezifisch. Die Formatierung weicht von der als historisch zu betrachtenden und durch alle beliebten Mailserver unterstützten aliases.db ab. Die einzelnen Felder werden lediglich über ein Leerzeichen getrennt; der Doppelpunkt der aliases-Datei wird nicht benötigt. Weiterhin sind die eigentlichen Datenbankdateien über das Kommando postmap /etc/postfix/tablename zu erzeugen.
Postfix
229
Name
Funktion
access
Erlaubt ausgewählten Host-Namen sowie bestimmten Absender- oder Empfängeradressen einen Relay. Da diese Informationen leicht gefälscht werden können, sollten Sie auf access verzichten und POP-before-SMTP verwenden.
aliases
Datenbank, um lokale E-Mail-Adressen umzuleiten oder System-Accounts über Aliase gesammelt an den Administrator zu senden.
canonical
Ermöglicht es, Absender- (sender_canonical_maps) und Empfängeradressen (recipient_canonical_maps) umzuschreiben. Beachten Sie, dass diese HeaderInformationen nichts mit den Feldern From: oder To: zu tun haben und bei einem Fehler als Rücksendeadresse genutzt werden. Manipulationen sollten daher nur mit Bedacht erfolgen.
relocated
Bounced umgezogene Adressen mit der neuen Mail-Adresse an den Absender zurück.
transport
Legt unabhängig von mydestination fest, dass Domains akzeptiert werden sollen, und bestimmt den weiteren Transport (zum Beispiel virtual oder smtp).
virtual
Eine erweiterte aliases-Table, die unabhängig von System-Accounts arbeitet.
Tabelle 3.14 Übersicht über die verschiedenen Postfix-Lookup-Tables (Forts.)
virtual, canonical und relocated
[email protected] [email protected] Die Tables bestehen aus zwei Spalten, die durch Leerzeichen zu trennen sind. Bei virtual kann in der ersten Spalte auch mit einem Suchmuster gearbeitet werden: »alteMail« würde auf sämtliche Domains passen, insofern alteMail vor dem @-Zeichen steht. Selbstverständlich können Sie das Suchmuster zudem für Catchall-Adressen auf eine Domain anwenden (@alteDomain.de). Hinweis Mail-Accounts werden von Postfix unabhängig von ihrer tatsächlichen Schreibweise ausschließlich in Kleinbuchstaben betrachtet. Dies bedeutet, dass in unserem Beispiel der System-Account neuemail existieren muss. Postfix versucht, selbst E-Mails an neueMail@localhost an den Account neuemail auszuliefern. Somit kann der Account neueMail keinerlei Nachrichten erhalten. Falls der Account neuemail nicht existiert, werden die E-Mails als unzustellbar gebouncet. Wird beim Einsatz von virtual der User-Account (der Name vor dem @-Zeichen) der Adresse geändert, muss zumindest der neue Account auf dem Server existieren, damit Mails überhaupt angenommen und nicht mit der Meldung
230
Wichtige Serverdienste
1 2 »User unknown in local recipient table« zurückgewiesen werden. Außerdem muss die alte und neue Domain vom Mailserver akzeptiert werden. Dies könnte durch Erweiterung von mydestination erreicht werden. Damit mydestination bei vielen zu verarbeitenden Domains nicht unübersichtlich wird, können Sie alternativ virtual um eine zusätzliche Zeile für die zu akzeptierende Domain ergänzen:
deb.home Unsinn [email protected]
3 4 5 6
[email protected]
In diesem Beispiel würde deb.home als zusätzliche Domain akzeptiert, selbst wenn in mydestination lediglich debgal.home gesetzt ist. Das Wort Unsinn fungiert lediglich als Platzhalter, um die zweispaltige Struktur der Datenbank aufrecht zu erhalten.
7 8
Weiterhin müssen Sie Postfix am Ende der Konfigurationsdatei main.cf mitteilen, dass Ihre Table beachtet werden soll. Hierbei ist die Syntax Tablename_ maps = hash:/etc/postfix/tablename zu verwenden. Ein Beispiel für relocated.db: relocated_maps = hash:/etc/postfix/relocated. Damit die Anpassungen aktiv werden, müssen Sie die Konfigurationsdatei nach jeder Änderung mit postfix reload selbstverständlich neu laden.
10
transport
12
9
11
Über die transport-Table können Nachrichten an externe Mailserver über ein beliebiges Protokoll (SMTP oder UUCP) geleitet sowie virtuellen Mailboxen (siehe Abschnitt 3.9.12, Virtuelle Accounts über MySQL) oder anderen Diensten (wie beispielsweise lmtp, cyrus) zugeordnet werden.
13 14
hauptdomain.de smtp:lokaler.mailserver.home domainxy.com virtual: Nach Erzeugen der Hash-Datenbank mit postmap /etc/postfix/transport ist Postfix zur Nutzung der Table transport über den Eintrag
transport_maps = hash:/etc/postfix/transport in der /etc/postfix/main.cf anzuweisen. access Ich möchte Sie nochmals darauf hinweisen, dass die Nutzung der access-Tabelle sehr einfach zu missbrauchen ist und Sie daher lieber POP-before-SMTP oder SMTP-Auth verwenden sollten. Dennoch möchte ich Ihnen die Möglichkeiten dieser Tabelle nicht vorenthalten. Die access-Tabelle sieht, wie die übrigen Lookup-Tabellen, ebenfalls zwei Spalten vor: Die erste enthält das Suchmuster
Postfix
231
(für Empfänger- oder Absenderadresse sowie die Host-Namen) und die zweite die Aktion (Akzeptieren, Ablehnen oder begründete Ablehnung).
sex.toplevel REJECT server.home OK some.spam 550 This Postbox does not support Spam Delivery Auch der Einsatz der access-Tabelle muss Postfix mitgeteilt werden. Fügen Sie die Zeile
smtpd_sender_restrictions = check_sender_access \ hash:/etc/postfix/access am Ende der Datei main.cf ein und rufen Sie postfix reload auf. Nun wird die Absenderadresse überprüft. Mails der Domain some.spam werden mit der zuvor festgelegten Begründung abgelehnt:
mail from: [email protected] 250 Ok rcpt to: [email protected] 550
smtpd_helo_restrictions = check_helo_access \ hash:/etc/postfix/access2 die Prüfung nicht auf mail from zu beschränken, sondern auch auf helo anzuwenden. Access2 sollte selbstverständlich nur Domain-Namen als Suchmuster enthalten:
spam.home 550 Leave me alone! Interessanterweise lehnt Postfix die Mail-Annahme wie beim vorangegangenen Beispiel erst nach rcpt to: und einer kurzen Pause ab. Dies ist kein Fehlverhalten, sondern hilft, die Kommunikation von Spammern mit Mailservern zu verlängern und so die Spam-Flut zu verringern.
helo spam.home 250 DebGal.home mail from: [email protected] 250 Ok rcpt to: [email protected] 550 <spam.home>: Helo command rejected: Leave me alone!
232
Wichtige Serverdienste
1 2 3.9.7
POP-before-SMTP
3
Wie der Name vermuten lässt, sichert POP-before-SMTP Ihren Mailserver vor Spammern ab, indem ein Mail-Versand erst nach dem Nachrichtenabruf anhand der IP-Adresse gestattet wird. Das Perl-Skript POP-before-SMTP sucht die IP-Adresse erfolgreicher POP3-/IMAP-Zugriffe aus dem Logfile heraus und legt sie für die spätere Auswertung durch Postfix in einer Datenbank ab.
4 5
Bevor Sie POP-before-SMTP nutzen können, ist daher Courier-IMAP wie im Abschnitt 3.10 beschrieben aufzusetzen oder der schlanke qpopper zu installieren (siehe Abschnitt 3.9.9, Abschluss der Mailserver-Basiskonfiguration mit qpopper). Das Perl-Programm finden Sie auf der CD-ROM und über http://popbsmtp.sourceforge.net.
6 7 8
POP-before-SMTP setzt außerdem die CPAN-Module Time::HiRes, File::Tail, Date::Parse und Net::Netmask voraus. Üblicherweise sind diese Module als vorbereitetes Paket für Ihr System erhältlich (Debian: libtime-hires, libfile-tail, libtimedate-perl und libnet-netmask-perl). Notfalls können Sie fehlende Module über http://search.cpan.org beziehen und über ./Makefile.PL && make install installieren.
9 10 11
Zur eigentlichen Installation von POP-before-SMTP genügt es, pop-before-smtp nach /usr/sbin und pop-before-smtp-conf.pl in /etc zu kopieren. Danach ist popbefore-smtp.init in das Verzeichnis init.d Ihrer Linux-Distribution zu kopieren und ein Runlevel-Link zum automatisierten Start von POP-before-SMTP einzufügen.
12 13
Editieren Sie /etc/ und entfernen Sie das Kommentarzeichen am Zeilenanfang von
14
$dbfile = '/etc/postfix/pop-before-smtp'; Nun müssen Sie pop-before-smtp noch verraten, nach welchem POP beziehungsweise IMAP-Dienst er im Logfile zu suchen hat. Auch hier sind lediglich die Kommentarzeilen unterhalb des Abschnitts »For Courier-POP3 ...« beziehungsweise »For Qpopper ... » zu entfernen:
# For Courier-POP3 and Courier-IMAP: $pat='^(... .. ..:..:..) \ \S+(?:courier)?(?:pop3|imap)(?:login|d|d-ssl): ' . 'LOGIN, user=\S+, ip=\[[:f]*(\d+\.\d+\.\d+\.\d+)\]$'; oder:
# For Qpopper POP/APOP Server (matches in.qpopper, \ qpopper, and popper).
Postfix
233
$pat = '^(... .. ..:..:..) \S+ \ (?:in\.q|q)?popper\[\d+\]: Stats: \S+ ' \ . '\d+ \d+ \d+ \d+ (?:\S+ )?(\d+\.\d+\.\d+\.\d+)'; Weiterhin ist zu prüfen, ob die Variable $file_tail die richtige Maillog-Datei zur Untersuchung enthält. Je nach Syslog-Einstellungen ist der Name der Logdatei anzupassen, beispielsweise in mail.log anstelle von maillog. Falls Sie vom Wert Ihres Systems abweicht, ist das Kommentarzeichen zu entfernen und die Zeile entsprechend anzupassen:
$file_tail{'name'} = '/var/log/mail.log'; Hinweis: Wenn Sie Syslog nicht angepasst haben, wird unter SUSE 9.2 das Logfile als /var/log/maillog gespeichert. Damit Postfix die Datenbank von pop-before-smtp berücksichtigt, ist die Variable smtpd_recipient_restrictions der /etc/postfix/main.cf-Datei um check_ client_access hash:/etc/postfix/pop-before-smtp zu erweitern.:
smtpd_recipient_restrictions = reject_unknown_hostname, \ reject_unknown_sender_domain, reject_non_fqdn_sender, \ check_relay_domains, \ check_client_access hash:/etc/postfix/pop-before-smtp Danach ist pop-before-smtp zu starten:
pop-before-smtp --logto=/var/ log/pop-before-smtp.log Prüfen Sie, ob nach dem Start /etc/postfix/pop-before-smtp.db angelegt wurde, und rufen Sie postfix reload auf, bevor Sie E-Mails von einem anderen Rechner testweise abholen. Nun müssten Sie mit diesem Rechner innerhalb der nächsten 30 Minuten Mails über den Server versenden dürfen (solange Sie keine andere IP-Adresse von Ihrem Zugangs-Provider erhalten, zum Beispiel nach einem Offline-Modus). Troubleshooting Falls Sie wider Erwarten keine Nachrichten absenden können, prüfen Sie, ob pop-before-smtp läuft (ps –aux | grep pop-before), /etc/postfix/pop-beforesmtp.db angelegt und die IP-Adresse des Clients beim POP3/IMAP-Login von POP-before-SMTP aus dem Mail.log (less /var/log/pop-before-smtp.log) herausgefischt wurde. Wer qpopper lokal nutzt, wird eventuell über eine Zeile wie
Unable to get canonical name of client 192.168.0.3
234
Wichtige Serverdienste
1 2 im Maillog stolpern. Qpopper verweigert hier den Betrieb, wenn er die IP Adresse nicht auflösen kann. Lösung: Tragen Sie die IP einfach in /etc/hosts mit einem Fantasienamen wie »Testsystem« ein.
3 4
Auf ein weitaus diffizileres Problem deutet die Meldung »fatal: open database /etc/postfix/pop-before-smtp.db: Unknown error 4294936306« im Maillog hin. In diesem Fall erzeugt pop-before-smtp die Hash-Datei in einer anderen BerkelyDB-Version, als Postfix sie verwendet.
5 6
Die Version 1.30 von POP-before-SMTP (auf der CD zum Buch) und ihre Vorgänger erstellen DB2-Datenbanken. Postfix muss mit denselben BerkelyDBDevelopment-Versionen kompiliert werden; für DB2 mit libdb2-dev. Deinstallieren Sie libdb3.dev, um sicherzugehen, dass Postfix mit den richtigen Bibliotheken kompiliert wird. Kehren Sie diesen Schritt um, falls Ihre Version von POP-before-SMTP mit DB3 arbeiten sollte.
7 8 9
Damit Postfix überhaupt mit veränderten DB-Bibliotheks-Versionen kompiliert werden kann, ist make clean vor dem Make-Aufruf abzusetzen. Sobald Postfix neu kompiliert wurde, schafft postmap –q bla /etc/postfix/pop-beforesmtp über den Erfolg sofort Klarheit. Erscheint keine Fehlermeldung, dann kann Postfix die POP-before-SMTP-Datei lesen. Allerdings müssen Sie bereits angelegte Hash-Datenbanken wie aliases.db oder virtual.db nun nochmals erstellen, da diese noch in der »vorherigen« DB-Version gespeichert wurden und somit von Postfix wiederum nicht mehr gelesen werden können.
10 11 12 13
3.9.8 Wichtig: Reversen DNS-Eintrag für Ihren Mailserver
14
Üblicherweise akzeptieren Mailserver die im helo übermittelte Maildomain anderer ohne eine Reverse-Abfrage (dig -x IP-Adresse). Dieses Verhalten sollte nicht verändert werden, da eine Reverse-Abfrage zusätzliche Zeit benötigt und unnötigen Traffic generiert. Tatsächlich sind insbesondere Domains von gemieteten Root-Webservern nicht über eine Reverse-Abfrage auflösbar. Leider können Sie einen Reverse-DNS-Eintrag in der Regel nicht selbst vornehmen, da diese Aufgabe von einem speziellen Server, der für den gesamten Adressraum des jeweiligen Subnetzes zuständig ist, übernommen wird. Prüfen Sie zunächst, ob Sie die Domain, mit der sich Ihr Mailserver meldet (als myhostname in /etc/postfix/main.cf eingetragen und auch nach einem telnet IP-Adresse 25 ersichtlich), über eine Reverse-DNS-Abfrage via dig -x IPAdresse ermitteln können. Ist im Abschnitt »ANSWER SECTION« Ihre Maildomain aufgeführt, können andere Mailserver Ihre Domain via Reverse-DNS-Abfrage verifizieren. Falls nicht, gilt es den Abschnitt »Authority Section« zu beachten. Wahrscheinlich
Postfix
235
sind hier die DNS Ihres Hosters aufgeführt. Bitten Sie diesen darum, einen PTRRecord für Ihre Maildomain zu setzen:
102.789.456.123.in-addr.arpa. 14140 IN PTR mail.domain.de. Hinweis: Beim Reverse-DNS-Eintrag setzt sich der Zonenname aus der umgedrehten IP-Adresse und ».in-addr.arpa.« zusammen. Beim Umdrehen sind die letzten drei Ziffern als Erstes, die zweiten drei Ziffern als Zweites und so weiter zu notieren. Die Reihenfolge innerhalb der einzelnen Ziffernfolgen bleibt gleich. Aus der IP-Adresse 123.456.789.102 wird somit 102.789.456.123.inaddr.arpa. Falls Sie die Autorität (also Zuständigkeit) für eine IP-Adresse selbst besitzen, können Sie den in-addr.arpa Eintrag wie eine herkömmliche Zone einrichten. Abgesehen vom umgedrehten Zusammensetzen der IP-Adresse und ».inaddr.arpa.« als Zonenname sind keine weiteren Besonderheiten zu beachten. Ein vollständiger Reverse-DNS-Zoneneintrag würde für die IP-Adresse 123.456.789.102 deshalb wie folgt lauten:
$TTL 2D 102.789.456.123.in-addr.arpa. IN \ SOA mailboxname-nsadmin.domain.de. ( 2003082101 ;serial 1D ;refresh 2H ;retry 1W ;expiry 1D ;Negative C-TTL ) 102.789.456.123.in-addr.arpa. 102.789.456.123.in-addr.arpa. 102.789.456.123.in-addr.arpa. 102.789.456.123.in-addr.arpa.
IN NS nameserver1.de. IN NS nameserver2.de. PTR mail.domain.de. PTR noch-eine-domain.de.
3.9.9 Abschluss der Mailserver-Basiskonfiguration mit qpopper Wer seinen Mailserver vollständig über die internen Postfix-Tabellen verwalten möchte und nicht davor zurückscheut, für sämtliche eigenständige Mailboxen eigene Systemaccounts anzulegen, muss lediglich einen schlanken POP3-Dienst wie qpopper, der als fertiges Paket für SUSE-, Debian- beziehungsweise OpenBSD-Systeme verfügbar ist, installieren. Der Start von qpopper kann über den inetd beziehungsweise xinetd übernommen werden. Kommentieren Sie hierzu einfach die entsprechende Zeile aus
236
Wichtige Serverdienste
1 2 /etc/inetd.conf aus und starten Sie den inetd neu. Um qpopper via xinetd zu aktivieren, ist in /etc/xinetd.d/qpopper die Zeile disable = yes in
3
disable = no
4
zu ändern und xinetd neu zu starten.
5
3.9.10 Authentifizierung für Nachrichtenversand über Cyrus SASLAuth
6
Wie mehrfach erwähnt, ist die Implementierung einer SASL-Auth-Identifikation eine problematische Aufgabe. Ich habe mich deshalb entschlossen, die Installation von SASL-Auth mit der systemspezifisch am einfachsten beziehungsweise sinnvollsten umsetzbaren Variante näher zu beschreiben.
7 8
Wer sich durch die Kompilierung von Cyrus-SASL kämpft, kann natürlich völlig frei wählen. Mir persönlich sagt die Debian beziehungsweise SUSE-Variante am ehesten zu, da durch Kopieren der sasldb die Postfix-Chroot-Umgebung ohne großen Aufwand beibehalten werden kann.
9 10 11 12 13 14
Abbildung 3.7 In den Konteneinstellungen von Mozilla kann SASL-Auth über Aktivierung von »Use name and password« genutzt werden. Als User Name ist die SASL-Account-Bezeichnung zu wählen.
Postfix
237
Änderungen an main.cf Um SASL-Auth in Postfix einzubinden, ist /etc/postfix/main.cf wie folgt anzupassen:
smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $myhostname smtpd_recipient_restrictions = \ [ ... ], permit_sasl_authenticated, [ ... ] smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes Beachten Sie, dass einige Zeilen in Ihrer Konfigurationsdatei bereits enthalten sein könnten und lediglich verändert werden müssen. Der smtpd_recipient_ restrictions-Parameter permit_sasl_authenticated erlaubt Clients, die sich authentifiziert haben, den Mailversand an fremde Server. Erweitern Sie Ihre in smtpd_recipient_restrictions bereits gesetzten Parameter entsprechend. Debian Woody Installieren Sie via dselect das Zusatzpaket postfix-tls von Postfix. Editieren Sie danach /etc/postfix/sasl/smtpd.conf oder legen Sie die Datei gegebenenfalls mit folgendem Inhalt neu an:
pwcheck_method: sasldb Mit SASL können unabhängig von Systemaccounts eigene User, denen der SMTP-Versand erlaubt werden soll, verwaltet werden. Hierzu dient saslpasswd:
saslpasswd foo Das Passwort kann, mit der Zusatzoption -p, auch über ein Skript saslpasswd via echo übergeben werden:
echo testpassword | saslpasswd -p username Eine Liste bisher angelegter User gibt sasldblistusers aus:
user: user: user: user: user: user:
238
foo realm: debian mech: DIGEST-MD5 username realm: debian mech: DIGEST-MD5 foo realm: debian mech: PLAIN foo realm: debian mech: CRAM-MD5 username realm: debian mech: PLAIN username realm: debian mech: CRAM-MD5
Wichtige Serverdienste
1 2 Beachten Sie die Angabe realm: debian hinter den User-Namen foo und username. Der realm wird bei allen sasldb-Abfragen mit dem User-Namen verbunden und muss als »Domain« in smtpd_sasl_local_domain der Datei /etc/postfix/main.cf eingetragen werden, damit die SASL-Auth-Identifikation funktionieren kann.
3 4
Um das Passwort eines bestehenden Users zu ändern, kann auch saslpasswd username (gegebenenfalls mit der Option -p) verwendet werden. Das Löschen von Accounts erfolgt mit der Option -d:
5
saslpasswd -d username
7
6
Von saslpasswd wird die Datei /etc/sasldb geschrieben, die nach /var/spool/postfix/etc/ zu kopieren ist und dort für Postfix lesbar sein muss. Im Zweifelsfall hilft chmod 644 /var/spool/postfix/etc/sasldb weiter.
8 9
OpenBSD 3.6 Installieren Sie die offiziellen Pakete postfix-2.1.4-sasl2.tgz und cyrus-sasl2.1.19.tgz. Legen Sie im Verzeichnis /usr/local/lib/sasl2/ die neue Datei smtpd.conf mit folgendem Inhalt an:
10 11
pwcheck_method:saslauthd mech_list: plain login
12
Führen Sie chmod 644 smtpd.conf aus. Nun ist der saslauthd wie folgt zu starten:
13
/usr/local/sbin/saslauthd -a getpwent
14
saslauthd fragt die Systemaccounts von OpenBSD ab. Dies kann jedoch nicht funktionieren, wenn der smtp-Dienst über die /etc/postfix/master.cf-Datei in eine Chroot-Umgebung eingesperrt wird. Deshalb müssen wir die Zeile
# service type private unpriv chroot wakeup maxproc cmd # (yes) (yes) (yes) (never) (100) =========================================================== smtp inet n smtpd so ändern, dass smtpd nicht gechrootet wird. Dies geschieht durch Ersetzen des Minuszeichens »-« in ein »n« unterhalb der entsprechenden »gedachten Spalte«:
smtp
inet
n
-
n
-
-
smtpd
Postfix
239
Nach diesem Schritt ist Postfix via postfix stop und postfix start neu zu starten. Falls der Testlauf nicht funktionieren sollte, werfen Sie einen Blick in /var/log/maillog. Die Zeile:
cannot connect to saslauthd server: \ No such file or directory würde bedeuten, dass die Chroot-Umgebung noch aktiv ist oder der saslauthdDaemon nicht gestartet beziehungsweise nach Änderung der /usr/local/lib/sasl2/smtpd.conf-Datei nicht neu gestartet wurde. SUSE 9.2 Editieren Sie /usr/lib/sasl2/smtpd.conf oder legen Sie die Datei gegebenenfalls mit folgendem Inhalt neu an:
pwcheck_method: auxprop mech_list: plain login Mit SASL können unabhängig von Systemaccounts eigene User, denen SMTPVersand erlaubt werden soll, verwaltet werden. Hierzu dient saslpasswd2:
saslpasswd2 foo Das Passwort kann, mit der Zusatzoption -p, auch über ein Skript einfach saslpasswd2 via echo übergeben werden:
echo testpassword | saslpasswd2 -p username Eine Liste bisher angelegter User gibt sasldblistusers2 aus:
foo@linux: userPassword username@linux: userPassword Beachten Sie die Angabe @linux hinter den User-Namen foo und username. Mit linux ist hier nicht die Domain einer E-Mail oder Internet-Adresse gemeint, sondern »linux« fungiert in unserem Beispiel als interne Domain, die bei allen sasldb2-Abfragen verwendet wird und deshalb auch als smtpd_sasl_local_ domain in /etc/postfix/main.cf eingetragen sein muss. Um das Passwort eines bestehenden Users zu ändern, kann auch saslpasswd2 username (gegebenenfalls mit der Option -p) verwendet werden. Das Löschen von Accounts erfolgt mit der Option -d: saslpasswd2 -d username Von saslpasswd2 wird die Datei /etc/sasldb2 geschrieben, die für Postfix lesbar sein muss. Im Zweifelsfall hilft chmod 644 /etc/sasldb2 weiter. Falls der Postfix-smtp-Dienst von Ihnen in eine Chroot-Umgebung eingesperrt wurde,
240
Wichtige Serverdienste
1 2 wäre /etc/sasldb2 in das entsprechende Verzeichnis der Chroot-Umgebung zu kopieren. In der Voreinstellung ist dies /var/spool/postfix/etc/.
3
3.9.11 Effektive Spam-Blockade durch RBLs
4
Bevor Sie sich mit dem Thema RBL beschäftigen, sollten Sie beachten, dass EMails dem Fernmeldegeheimnis unterliegen, weshalb die Unterdrückung übermittelter Sendungen nur auf ausdrücklichen Wunsch des Mailbox-Inhabers zulässig ist. Siehe auch Abschnitt 8.5, Spam nur auf ausdrücklichen Wunsch blocken.
5 6 7
Ein Großteil der Spam-Nachrichten wird entweder von offenen Relays oder Dialup-Zugängen versandt. Über so genannte Realtime Blacklists ist es möglich, Nachrichten bereits vor Prüfung von Betreff oder dem Nachrichtentext als Spam zu blocken. Hierdurch werden gleich zwei Fliegen mit einer Klappe geschlagen: Die zu übermittelnden Nachrichten verschlingen nicht unnötig Bandbreite, da vor der eigentlichen Übermittlung der Datenübertragung ein Riegel vorgeschoben wird, und Betreiber von schlecht konfigurierten Mailservern, die gerne von Spammern missbraucht werden, geraten in den Leidensdruck, ihre Hausaufgaben nachzuholen und den Mailserver sauber zu konfigurieren.
8 9 10 11
Häufig genügt es, eine E-Mail an den Robot des Betreibers der jeweiligen Blacklist zu senden, um den Server einer automatischen Konfigurationsprüfung zu unterziehen. Wurde die Prüfung bestanden, wird der Mailserver aus der Blacklist entfernt und er darf fortan wieder Nachrichten an fremde Mailserver senden, die bisher Mails aufgrund der Blacklist-Notierung abgelehnt haben.
12 13 14
Einen umfassenden Überblick über Blacklist-Anbieter bietet http:// moensted.dk/spam/. Hier findet sich auch eine Suchmöglichkeit über IPbeziehungsweise Domainadresse, die sämtliche vorgestellten RBLs auf eine Listung durchsucht. Dieser Service ist sehr nützlich, um den eigenen Mailserver auf Listung untersuchen zu können. Die auf http://moensted.dk/spam/ genannten RBL Listen sind in der Regel kostenlos nutzbar, dennoch sollten Sie die Websites verwendeter RBLs regelmäßig besuchen und sich auf dem Laufenden halten. Immerhin könnte der Anbieter seine Konditionen ändern und die Liste für kostenlose Nutzung deaktivieren oder seinen Service generell einstellen. Im schlimmsten Fall werden gar alle angefragten Adressen als zu blocken betrachtet und Ihr Server wird gar keine E-Mails mehr akzeptieren. Dieses Worst-Case-Szenario ist leider nicht so unwahrscheinlich, wie es auf den ersten Blick wirken mag. Der ehemals sehr beliebte RBL-Anbieter Osirusoft stellte aufgrund eines schweren DDOS-Angriffs seinen RBL-Dienst ein. Kurzzei-
Postfix
241
tig antwortete relays.osirusoft.com sogar mit 127.0.0.2 auf Anfragen. Im Logfile fand sich zusätzlich der Hinweis: »blocked using relays.osirusoft.com; Please stop using relays.osirusoft.com«. Die Praxistauglichkeit von RBL-Listen steht deshalb grundsätzlich in Frage. Einerseits sind RBLs wohl die wirksamste Maßnahme im Kampf gegen Spam, andererseits müssen Sie regelmäßig das Maillog auf Fehlverhalten durchforsten und die Websites aller verwendeten RBL Anbieter regelmäßig besuchen, um die Gefahr eines Amok laufenden RBL-Dienstes gering zu halten. In diesem Zusammenhang ist erwähnenswert, dass ein über RBL geblockter Mailserver die zu übermittelnde Nachricht in der Regel als temporär unzustellbar betrachtet (Spam wird in den meisten Fällen nur einmal versucht zuzustellen) und es später nochmals probiert. Falls eine RBL-Liste tatsächlich Nachrichten unrichtigerweise blockt, aber dieses Fehlverhalten von Ihnen frühzeitig erkannt wird und Sie die RBL daraufhin deaktivieren, wird die Nachricht im zweiten oder dritten Anlauf zugestellt werden, ohne dass eine Fehlermeldung an den Absender erstellt wird. Damit RBL-Mailboxen spezifisch aktiviert werden können, ist mit smtpd_ restriction_classes zu arbeiten:
smtpd_restriction_classes = check_rbls check_rbls = reject_rbl_client dynablock.njabl.org, \ reject_rbl_client relays.ordb.org, \ reject_rbl_client sbl.spamhaus.org, \ reject_rbl_client cbl.abuseat.org check_rbls ist ein Platzhalter, dessen Bezeichnung beliebig wählbar ist. Tatsächlich handelt es sich um frei definierbare Sets von Anweisungsblöcken, die anstelle von reject_rbl_client foo ebenfalls Parameter wie reject_ unauth_destination enthalten können und so unabhängig von RBLs generell für Mailbox spezifische Regelblöcke verwendet werden können. Nun müssen Sie noch die Liste der Mailboxen beziehungsweise Domains definieren, bei denen eine RBL-Prüfung gewünscht ist, indem Sie die Datei /etc/postfix/check-rbls wie folgt anlegen:
[email protected] check_rbls michael-hilscher.de check_rbls Beachten Sie, dass hier gezielt einzelne Adressen oder lediglich die Domain definierbar ist. Bei Firmen mit mehreren Mitarbeitern ist dies gefährlich, da ja von allen Mitarbeitern die Nutzung der RBLs explizit gewünscht sein muss und
242
Wichtige Serverdienste
1 2 bei der Definition einer Domain automatisch sämtliche an diese E-Mail Adresse gerichteten Nachrichten erst nach der RBL-Prüfung zugestellt werden würden.
3
Damit check-rbls von Postfix genutzt wird, müssen Sie aus der Datei eine HashTabelle erstellen:
4
debian:/etc/postfix# postmap check-rbls
5
und die Prüfung via hash:/etc/postfix/check-rbls innerhalb des smtpd_ recipient_restrictions-Parameters aktivieren. Um die Konfiguration sinnvoll testen zu können, sollten Sie zumindest eine Dial-up-RBL verwenden, der Ihre vom Zugangs-Provider erteilte dynamische IP-Adresse kennt. Nachdem Postfix neu gestartet wurde, bauen Sie mit Telnet eine Verbindung zu Ihrem EMail-Server auf, bevor Sie mit Ihrer IP-Adresse Nachrichten abgeholt und sich damit über einen eventuell integrierten POP-before-SMTP-Dienst zum Nachrichtenversand legitimierten haben:
6 7 8 9
user@linbook:~> telnet mail.mshwebservice.de 25 220 mail.mshwebservice.de ESMTP Postfix helo a3s.de 250 mail.mshwebservice.de mail from: [email protected] 250 Ok rcpt to: [email protected] 554 Service unavailable; Client host [217.94.43.51] blocked using dynablock.njabl.org; Dynamic/Residential IP range listed by NJABL dynablock - http://njabl.org/dynablock.html quit 221 Bye Connection closed by foreign host.
10 11 12 13 14
Im nächsten Test sollten Sie versuchen, eine Adresse, deren Empfänger nicht mit RBL geprüft wird, zuzustellen. Dies muss nun ohne Fehlermeldung gehen. Wenn Sie POP-before-SMTP verwenden, dann ist noch ein letzter Test notwendig: Holen Sie Nachrichten ab und versuchen Sie erneut die Zustellung an eine RBL-Liste – natürlich muss der Versand nun erlaubt werden, damit so authentifizierte Nutzer direkt E-Mails an Ihren Server senden können.
3.9.12 Virtuelle Accounts über MySQL Es ist sehr umständlich, für jedes Postfach einen System-Account anzulegen und die entsprechenden Datenbankdateien für Aliase oder Catchall entsprechend anzupassen. Viel bequemer ist die Verwaltung über die MySQL-Datenbank. So können Sie mit phpMyAdmin über eine SSL-gesicherte Verbindung
Postfix
243
selbst ohne einen SSH-Login neue Postfächer anlegen und verwalten. Allerdings muss der IMAP-/POP3-Server, wie in Abschnitt 3.10, Courier-IMAP, beschrieben, für die Kommunikation mit der MySQL-Datenbank konfiguriert werden. Grundsätzlich können sämtliche Lookup-Tabellen auch mit MySQL-Tabellen realisiert werden. Auch die Verwaltung der im vorangegangenen Abschnitt beschriebenen Nutzung von RBL-Listen kann über die MySQL-Datenbank dynamisch erfolgen. Da MySQL jedoch mit beliebig vielen Spalten arbeitet, sind neben den Zugangsinformationen zu jeder Lookup-Tabelle auch die verwendeten Spaltennamen zu definieren. Wie eingangs erwähnt, ist es über die MySQL-Datenbank möglich, virtuelle Postfächer ohne System-Accounts zu verwalten. Tatsächlich ist es nicht möglich, die herkömmliche Transportmethode »local« zu verwenden, wenn MySQL genutzt wird. Deshalb ist ein zusätzlicher Eintrag virtual: innerhalb der Transporttabelle für jede über MySQL verwaltete Domain unerlässlich. Anpassung von main.cf Um eine Postfach-Grundkonfiguration mit Postfix und MySQL zu realisieren, werden transport, virtual und eine Mailbox-Datenbank benötigt. Weiterhin muss main.cf entsprechend angepasst werden:
relay_domains = $mydestination, \ mysql:/etc/postfix/transport.mysql smtpd_recipient_restrictions = reject_unknown_hostname, \ reject_unknown_sender_domain, reject_non_fqdn_sender, \ check_relay_domains virtual_mailbox_maps = mysql:/etc/postfix/virtboxes.mysql virtual_maps = mysql:/etc/postfix/virtual.mysql transport_maps = mysql:/etc/postfix/transport.mysql virtual_mailbox_base = /var/spool/virtboxes virtual_uid_maps = mysql:/etc/postfix/uid.mysql virtual_gid_maps = mysql:/etc/postfix/gid.mysql virtual_minimum_uid = 500 Beachten Sie, dass Postfix erst durch relay_domains und smtpd_recipient_ restrictions = check_relay_domains die MySQL-Datenbank konsultiert, um zu prüfen, ob Nachrichten an die Domain-Adresse entgegengenommen werden dürfen. Hinweis: Restriktionsregeln können auch Prüfungsanweisungen enthalten, um den Nachrichtenversand oder -empfang ausdrücklich zu erlauben. Beachten Sie, dass vor relay_domains die Kennung check_ anstelle
244
Wichtige Serverdienste
1 2 von reject_ verwendet wurde und somit das Gegenteil (Akzeptanz anstelle von Ablehnung) erzielt wird.
3
Da auch für virtuelle Postfächer E-Mails in Dateien abgelegt werden, führt an der Vergabe einer UID und einer GID für diese Daten kein Weg vorbei. Sie sollten einen Dummy-Account anlegen (über ein Sternchen in /etc/shadow ist ein ungültiges Passwort und als Shell /bin/false zu setzen), um die Mail-Daten mit UID und GID mit restriktiven Rechten versehen zu können.
4 5 6
Wer sich vor denkbaren Fehlern im POP3/IMAP-Server zusätzlich schützen möchte, sollte darüber nachdenken, für jeden Mail-Account einen eigenen Dummy-Account anzulegen. Um diesen Weg gehen zu können, müssen Sie UID – wie in unserem Beispiel – über virtual_uid_maps aus einer Datenbank gewinnen. Leider können Sie die virtuelle Gruppen-ID nicht pauschal allen virtuellen Accounts zuweisen. Postfix besteht auf dem Feld GID und einer zusätzlichen Abfrage, um die Gruppen-ID zuzuweisen.
7 8 9 10
Die MySQL-Tabellen Mit den folgenden MySQL-Befehlen werden die notwendigen Datenbanktabellen für Postfix und Courier-IMAP erstellt. Tabellen- und Datenbankname sind natürlich frei wählbar. Allerdings müssen Sie dann die Konfigurationsdateien entsprechend anpassen.
11 12
create database mailer; use mailer; CREATE TABLE transport (domain char(100) NOT NULL, transport cha r(100) NOT NULL, UNIQUE KEY domain (domain)); CREATE TABLE virtual (old char(100) NOT NULL, new char(100) NOT NULL, UNIQUE KEY old (old)); CREATE TABLE virtboxes (adresse char(50) NOT NULL, dir char(50) NOT NULL, uid int(4) NOT NULL, password char(50) NOT NULL, gid i nt(4) DEFAULT '5000' NOT NULL, home char(20) DEFAULT '/var/spool /virtboxes' NOT NULL, UNIQUE KEY uid(uid));
13 14
Die so erzeugte Datenbank eignet sich zur zentralen Administration über eine Person. Sollen die einzelnen Nutzer zudem selbst in der Lage sein, Alias- oder Catchall-Adressen über virtual anzulegen, empfiehlt sich die Erweiterung um eine zusätzliche Account-Datenbank, die über ein PHP- oder Perl-Webinterface anhand einer eindeutigen ID (zusätzliches Datenfeld) lediglich die jeweiligen Postfächer eines Accounts zuverlässig anzeigt und eine Bearbeitung dieser Einträge ermöglicht.
Postfix
245
Die Funktion der Felder erklärt sich überwiegend selbst. Die Adresse der Tabelle virtboxes wird später die Hauptadresse einer Domain ([email protected]) enthalten. Nachrichten werden im mit dir definierten Verzeichnis abgelegt, wobei dieses Feld den Pfad von $virtual_mailbox_ base erweitert. Steht hier der Wert Demo.de/postmaster/, landen Nachrichten im Verzeichnis: /var/spool/virtboxes/Demo.de/postmaster/. Mit UNIQUE KEY uid(uid) wird verhindert, dass mehrere Einträge mit der gleichen UID angelegt werden können. Je nach Konfiguration von Postfix und angedachtem Einsatzzweck kann dies jedoch erwünscht sein. Gegebenenfalls können Sie im SQL-Statement auf ", UNIQUE KEY uid(uid)" verzichten. Leider können wir Courier-IMAP nicht ebenfalls eine feste Variable ($virtual_ mailbox_base) übergeben, sondern müssen dieses Verzeichnis in ein extra Datenfeld übernehmen und somit eine – hinsichtlich des Datenbank-Designs – unnötige Spalte aufnehmen, in der immer derselbe Inhalt steht. Die MySQL-Zugangsdateien Damit Postfix auf die Datenbankinformationen zugreifen kann, sind zu jeder Datenbanktabelle entsprechende Zugangsinformationen mit den abzufragenden Spaltennamen einzutragen.
cat /etc/postfix/transport.mysql user=mailer password=accountpassword dbname=mailer table=transport select_field=transport where_field=domain hosts=localhost Interessant sind die Felder where_field (Spalte, in der Suchübereinstimmung vorhanden sein muss) und select_field (Feld, das bei einer Übereinstimmung des Suchbegriffs ausgelesen wird) sowie hosts (localhost für lokalen MySQL-Server. Optional können auch externe MySQL-Server angesprochen werden). Das Beispiel unserer Transportdatenbank bildet somit die Hash-Variante ebenso nachvollziehbar nach wie die für Alias- und Catchall-Adressen notwendige Datei virtual.mysql:
246
Wichtige Serverdienste
1 2 # /etc/postfix/virtual.mysql user=mailer password=accountpassword dbname=mailer table=virtual select_field=new where_field=old hosts=localhost
3 4 5 6
Virtual.mysql und transport.mysql unterscheiden sich lediglich in den Werten zu table, select_field und where field. Dies trifft auch auf die übrigen Dateien virtboxes.mysql, uid.mysql und gid.mysql zu:
7 8
# /etc/postfix/virtboxes.mysql table=virtboxes select_field=dir where_field=adresse # /etc/postfix/uid.mysql table=virtboxes select_field=uid where_field=adresse # /etc/postfix/gid.mysql table=virtboxes select_field=gid where_field=adresse
9 10 11 12 13 14
Testlauf Um die MySQL-Konfigurationstabellen testen zu können, benötigen Sie lediglich einige Datenbankbefehle, um einen Test-Account anzulegen:
insert virtboxes values ('[email protected]', \ 'mail.test/postmaster/', '1006', 'test', \ '5000', '/var/spool/virtboxes'); insert transport values ('mail.test', 'virtual:'); Damit nach einem postfix reload Nachrichten an [email protected] von Postfix entgegengenommen werden können, müssen Sie das Verzeichnis erstellen und es dem User mit der virtuellen UID der Tabelle virtboxes überschreiben. Es genügt, wenn der Eigentümer Lese- und Schreibrechte besitzt:
mkdir –p /var/spool/virtboxes/mail.test; chown testmail /var/spool/virtboxes/mail.test; chmod 700 /var/spool/virtboxes/mail.test.
Postfix
247
Troubleshooting Postfix stellt umfangreiche Fehlerhinweise in seiner Logdatei /var/log/mail.log bereit. Häufige Fehler bei der Nutzung einer MySQL-Datenbank sind: 왘 Postfix kann auf die MySQL-Datenbank nicht zugreifen. Falsches Passwort
oder User-Name in den Konfigurationsdateien? Prüfen Sie, ob Sie die Datenbank mit verwendeten User-Namen und Passwortkombination manuell nutzen können. Haben Sie den benötigten MySQL-Zugang bereits angelegt (grant all on mailer.* to mailer@localhost identified by 'accountpassword';)? Wurde die Zugriffsdatenbank mit flush privileges neu geladen? 왘 Wurde Postfix mit MySQL-Unterstützung kompiliert (postconf
–m)?
왘 Beachten Sie den Abschnitt Anpassen von main.cf. Wurde auch an die Erwei-
terung von relay_domains gedacht? 왘 Ist virtual in der Konfigurationsdatei master.cf aktiviert (Voreinstellung neu-
erer Postfix-Versionen; virtual ist erst ab Version 1.1.x verfügbar)? 왘 Existiert die in virtboxes angegebene UID als realer Account, und hat dieser
die alleinigen Zugriffsreche (700) auf sein Mailbox-Verzeichnis (/var/ spool/virtboxes/domainname)?
3.9.13 Steuerung und Optimierung des Prozessverhaltens mit master.cf Postfix wurde aus Performance- und Sicherheitsgründen in viele Einzelprogramme zerlegt, die erst bei Bedarf mit den notwendigen Rechten gestartet werden. Sie können über /etc/postfix/master.cf festlegen, ob ein Programm chrooted arbeiten, zusätzliche Kommandoparameter (command + args) übergeben und die maximale Prozessanzahl (maxproc) festlegen soll. In den Spalten service, type, private, unpriv und wakeup sollten Sie die Standard-Einstellungen belassen. Dies gilt teilweise auch für die Spalte maxproc (maximale Prozessanzahl). Belassen Sie die Werte für pickup (1), cleanup (0), qmgr (1), bounce (0), defer (0) und flush (0) in der Voreinstellung. Maxproc 0 steht übrigens für eine unbegrenzte Prozessanzahl. Das Minuszeichen symbolisiert die Voreinstellung (50 Prozesse beziehungsweise yes oder never). Die übrigen Werte laden jedoch zu Experimenten ein. Falls Ihr Webserver hohem Mail-Verkehr standhalten muss und zugunsten einer durchweg guten Performance des Apache Verzögerungen im Mail-Versand und der Nachrichtenannahme in Kauf genommen werden können, bietet es sich an, maxproc für
248
Wichtige Serverdienste
1 2 smtpd (Empfang) und smtp (Versand) auf jeweils fünf bis zwölf Prozesse zu limitieren.
3 4
Hinweis Beschränken Sie bei Performance-Problemen zunächst den Nachrichtenversand. Dies ist sinnvoll, da bei schlechter Erreichbarkeit Ihres Mailservers Nachrichten eventuell als unzustellbar an den Absender zurückgesandt werden.
5 6
Ein weiterer Performance-Gewinn wird durch die Nutzung von nqmgr anstelle von qmgr erzielt. In der Konfigurationsdatei von Postfix 2.0.6 ist in der Voreinstellung nqmgr auskommentiert und qmgr genutzt:
qmgr #qmgr
fifo fifo
n n
-
n n
300 300
1 1
7 8
qmgr nqmgr
9
Entfernen Sie das Kommentarzeichen aus der nqmgr-Zeile und fügen Sie ein Kommentarzeichen am Anfang der qmgr-Zeile ein. Hinweis: nqmgr ist bereits längere Zeit als Alternative zu qmgr verfügbar und kann als stabil betrachtet werden. Dennoch haben sich die Maintainer von Postfix noch nicht zur Änderung von master.cf durchringen können.
10 11 12
Haben Sie sich entschlossen, Postfix-Programme durch eine Chroot-Umgebung zusätzlich abzusichern, finden Sie im Verzeichnis examples/chroot-setup des Tarballs ein Shell-Skript, das sämtliche benötigten Bibliotheken in die richtigen Chroot-Verzeichnisse kopiert. Beachten Sie weiterhin, dass pipe, virtual und local nicht gechrootet werden können. Falls Sie auf die MySQL-Datenbank über einen Socket auf localhost zugreifen möchten, muss sich die MySQLDatenbank ebenfalls im Chroot-Käfig befinden oder es muss auf das Chrooten von smtpd verzichtet werden. Weitere Hinweise finden Sie in Abschnitt 5.5, Chroot.
13 14
3.9.14 Feintuning der main.cf Mit dem Befehl postconf können Sie eine Liste aller Variablen der main.cf abfragen. Das Setzen neuer und das Ändern bestehender Werte ist ebenfalls möglich:
postconf -e 'virtual_minimum_uid = 500' erlaubt die Nutzung sämtlicher UIDs ab 500 für virtuelle Mailboxen. Falls die Variable virtual_minimum_uid noch nicht in main.cf enthalten sein sollte, wird sie nachträglich eingefügt.
Postfix
249
Im Folgenden möchte ich Ihnen die wichtigsten der gut 300 Konfigurationsparameter vorstellen, die noch nicht im Rahmen der vorangegangenen Abschnitte angesprochen worden sind. Falls Sie Konfigurationsoptionen für eine spezielle Aufgabe vermissen sollten, wird ein Blick auf http://www.postfix.org eventuell weiterhelfen.
2bounce_notice_recipient Als Wert können Sie hier eine Mail-Adresse oder einen System-Account einsetzen, an den Postfix Nachrichten sendet, die bereits zum zweiten Mal gebouncet werden.
allow_untrusted_routing = no verhindert die Bearbeitung von Nachrichten oder die Bearbeitung von Nachrichten mit doppelten @-Zeichen oder anderen gravierenden Unstimmigkeiten.
always_bcc legt optional eine Adresse fest, an die sämtliche Nachrichten mit bcc »im Hintergrund« weitergeleitet werden. Dieses Feld ist datenschutzrechtlich sehr bedenklich und könnte vielleicht schon zur Pflicht geworden sein; siehe Abschnitt 8.6, Fällt das Datenschutzrecht für den Zwang zur personenbezogenen Vorratsdatenspeicherung?
append_at_myorigin = yes Beim Versand von E-Mails ohne Domain-Namen im Absender wird myorigin angehängt.
append_dot_mydomain = yes Fehlt in der E-Mail-Adresse des Absenders die Toplevel-Domain (beispielsweise .de oder .com), wird mydomain vor dem Versand angehängt.
bounce_size_limit = 10000 schränkt die maximale Größe von Anhängen bei Bounces (an Absender zurück, weil unzustellbar) auf 10 000 Bytes ein.
default_recipient_limit = 100 erlaubt bei eingehenden Nachrichten maximal 100 gleichzeitige Empfängeradressen.
default_destination_recipient_limit = 30
250
Wichtige Serverdienste
1 2 beschränkt die maximale Anzahl gleichzeitiger Empfängeradressen pro ausgehender Nachricht (to, cc und bcc) auf 30. Falls die Zahl überschritten wird, teilt Postfix die Nachricht in mehrere kleinere auf.
3 4
disable_dns_lookups = no Das Abschalten von dns lookups sollte bei lokalen Mailservern (im Intranet) mit Dial-up-Anbindung oder kleiner Bandbreite (Modem/ISDN) erfolgen. Auf dem Mailserver Ihres Internetservers sind dns_lookups hingegen sinnvoll.
5 6
empty_address_recipient
7
Werden Nachrichten ohne User-Namen versendet, erscheint der berüchtigte MAILER-DAEMON als Absender. Über empty_address_recipient können Sie eine andere Adresse festlegen.
8
error_notice_recipient
9
In der Voreinstellung wird bei Fehlern der Postmaster benachrichtigt. Dies ist sinnvoll, da sich hinter [email protected] der zuständige Administrator für die Postfächer einer Domain verbergen sollte.
10
mail_owner = postfix
11
Der Account, unter dem das Postfix-Hauptprogramm gestartet wird.
12
mailbox_size_limit
13
Die Byte-Anzahl, die ein User-Postfach erreichen darf. In der Voreinstellung sind 50 MB erlaubt. Falls das Postfach diese Grenze erreichen sollte, werden alle weiteren Nachrichten, die die Postfachgröße weiter steigern würden, gebouncet. Beachten Sie, dass virtuelle Mailboxen von dieser Prüfung ausgenommen werden. Als Alternative bietet sich die Nutzung von Quotas an (siehe Abschnitt 4.6, Speicherplatz mit Quotas beschränken).
14
maximal_queue_lifetime = 4d Anzahl von Tagen, nach denen eine unzustellbare Nachricht (zuständiger Mailserver nicht erreichbar) gebouncet wird. Sie sollten einen Wert zwischen drei und sieben Tagen wählen. Unter drei Tage sollten Sie wegen eines denkbaren Server-Ausfalls am Wochenende nicht gehen.
message_size_limit Erlaubte Maximalgröße ein- und ausgehender Nachrichten. Der Wert ist in Byte anzugeben. Bei Überschreitung wird die Annahme beziehungsweise der Versand verweigert. In der Voreinstellung sind bis zu 10 MB erlaubt.
Postfix
251
minimal_backoff_time = 600s Frühestens nach Ablauf von sechs Minuten versucht Postfix, eine unzustellbare Nachricht erneut abzuliefern. Im Normalfall wird die minimal_backoff_time zum Einsatz kommen. Lediglich wenn Postfix stark ausgelastet ist, wird das Programm den Versand einer unzustellbaren Nachricht weiter verzögern. Beachten Sie den Parameter maximal_backoff_time.
maximal_backoff_time = 6000s Spätestens nach einer Stunde versucht Postfix unzustellbare Nachrichten erneut zuzustellen. Siehe auch minimal_backoff_time.
smtp_bind_address bindet Postfix an die angegebene IP-Adresse. Insbesondere beim Einsatz von linux-vserver interessant.
smtp_destination_concurrency_limit = 4 erlaubt maximal vier gleichzeitige Verbindungen mit einem einzelnen Host. In der Voreinstellung sind zehn Verbindungen gestattet. Das erscheint für eine Kombination aus Mail- und Webserver etwas großzügig.
strict_rfc8212_envelopes = no In der Voreinstellung (no) nimmt Postfix auch Adressen an, die nach rfc8212 eigentlich als ungültig zu betrachten wären. Allerdings ist rfc8212 sehr streng und wird von vielen Clients häufig nicht korrekt angewandt. Deshalb sollten Sie den Wert auf no belassen.
3.9.15 Traffic-Auswertung Es gibt einige Logfile-Analyseprogramme zur Traffic-Auswertung. Für Postfix zählen Isoqlog und Pflogsumm wohl zu den bekanntesten. Im Folgenden möchte ich Ihnen das Perl-Skript Pflogsumm näher vorstellen. Sie finden es auf der CD zum Buch und über http://jimsun.linxnet.com/postfix_contrib.html. Damit Sie Pflogsumm einsetzen können, müssen Sie das CPAN-Modul Date::Calc installieren (Debian: libdate-calc-perl). Allerdings ist die Lesart des Logfiles erklärungsbedürftig. Obwohl das Ergebnis auf den ersten Blick schlüssig erscheint, müssen Sie beachten, dass Pflogsumm bei ein- und ausgehenden Nachrichten sowohl den Absender als auch den Empfänger in die Statistik aufnimmt. Der von Postfix insgesamt erzeugte Traffic lässt sich aus der Gesamtübersicht ermitteln, doch um den domainbezogenen Traffic auszuwerten, müssen sämtliche Bytes der einzelnen Mail-Adressen
252
Wichtige Serverdienste
1 2 einer Domain sowohl unter »Größe der Mails pro Sender« als auch unter »Größe der Mails pro Empfänger« addiert werden.
3
Dennoch bleibt ein Problem übrig: Die Auswertung des Traffics ist domainbezogen unsicher, da beim Nachrichtenversand eine beliebige Absenderadresse verwendet werden kann. Falls Sie feststellen müssen, dass eine große Datenmenge oder viele E-Mails mit einer »unbekannten« Domain versandt worden sind, hilft bei Verwendung von POP-before-SMTP ein Blick in das Logfile mail.log weiter. Anhand des Zeitraums und der IP-Adresse können Sie so feststellen, welcher User sich über POP3/IMAP für den Nachrichtenversand der ominösen E-Mails legitimiert hat.
4 5 6 7
Genug der grauen Theorie; rufen Sie den Befehl ./pflogsumm-de.pl
-ignore_case -q --verp_mung=2 /var/log/mail.log > /tmp/pflogstats auf und werfen Sie einen Blick in die von Pflogsumm erstellte Datei /tmp/pfogstats ...
8 9
Gesamtübersicht: -----------Mails 12662 empfangen 12384 versendet ... 163580k Bytes empfangen 122442k Bytes versendet ... Host/Domänen Übersicht: Mailversand anz.Mails Bytes aufgesch. Verzg. max.Verzg. Host/Domäne -------- ------- ------- ------- ------- -------------98 34413k 0 0.6 s 4.1 m michael-hilscher.de 26 25966k 0 9.6 s 5.0 m msh-webservice.de ... Host/Domänen Übersicht: Mailempfang anz.Mails Bytes Host/Domäne -------- ------- ----------4004 10347k suse.com 3300 12622k lists.debian.org ... Größe der Mails pro Sender ----------------------6771k [email protected] 3863k [email protected]
Postfix
10 11 12 13 14
253
1608k [email protected] ... Größe der Mails pro Emfänger ------------------------34413k [email protected] 9230k [email protected] Gesamtübersicht: In der Gesamtübersicht unseres Beispiels entstanden durch Postfix 286 022 KByte (163.580 KByte empfangen + 122 442 KByte versendet sind circa 280 Megabyte) Traffic. Größe der Mails: Die Domain michael-hilscher.de ist am entstandenen Traffic mit insgesamt 42 792 KByte Traffic (34 413 KByte eingehend und 1 608 KByte sowie 6 771 KByte ausgehend) beteiligt. Host-/Domain-Übersicht: Die meisten E-Mails wurden an die lokal geführte (virtual) Domain michael-hilscher.de gesendet. Wie bereits erwähnt, wertet Pflogsumm Absender- und Empfängeradressen »doppelt« aus und zählt selbst lokale Zustellungen als einen erfolgten Versand. Als Abonnent der SUSE- und Debian-Mailinglisten zählen die Maildomains dieser Listserver selbstverständlich zu den Servern, von denen die meisten Nachrichten an den Mailserver zugestellt wurden. Um Pflogsumm-Statistiken domainbezogen auszuwerten, ist die Host-/ Domain-Übersicht leider ungeeignet. Zudem mag es der Fall sein, dass nicht jeder Account eine eigene Domain besitzt, und es notwendig wird, den Traffic einer bestimmten Mail-Adresse wie [email protected] auszuwerten. Zur Automation dieser Aufgabe habe ich Pflogsumm angepasst und hierfür »unnötige« Codezeilen entfernt sowie die Ausgabe lediglich auf Byte-Anzahl, Mail-Adressen und die Zusammenfassung des Ergebnisses reduziert. Sie finden das modifizierte Programm littlesumm.pl auf der CD zum Buch. Damit littlesumm.pl seine Aufgabe erfüllen kann, sind sämtliche auszuwertenden Accounts mit ihren Mail-Adressen über ein Array zu definieren. Das erste Element enthält die Nutzerbezeichnung und das zweite eine durch Kommata getrennte Liste der Suchbegriffe. Beachten Sie, dass bei der Aufzählung der Suchbegriffe kein Leerzeichen nach dem Komma folgen darf:
# mih: new vars for analysing traffic account specific my @array=( "mitarbeiter1","[email protected],[email protected]", \
254
Wichtige Serverdienste
1 2 "kunde1", "kundendomain.de" );
3
ittlesumm.pl ist wie Pflogsumm am besten mit perl /path/littlesumm.pl /var/log/mail.log aufzurufen. Das Perl-Skript ist, ebenso wie Pflogsumm, ressourcenhungrig und sollte deshalb nicht auf dem eigentlichen Webserver laufen, sondern am besten auf dem lokalen Arbeitsrechner ausgeführt werden.
4 5 6
3.10 Courier-IMAP Courier-IMAP zeichnet sich durch die gleichzeitige Unterstützung von IMAP2 (Port: 143) und POP3 (Port: 110) aus und ist optional in der Lage, verschlüsselte Kommunikation über POP3s (Port: 995) oder IMAPs (Port 993) anzubieten.
7 8
Beide Methoden lassen sich kombinieren, um ein Webinterface wie Squirrelmail über IMAP zur Online-Mail-Verwaltung anzubieten, jedoch den Nachrichtenbezug von MUAs auf POP3 zu beschränken (zum Beispiel indem die entsprechenden IMAP-Ports über den Paketfilter geblockt werden). Dies bietet den Vorteil, dass E-Mails direkt nach dem Empfang auf dem Server gelöscht werden und somit Festplattenplatz gespart wird.9
9 10 11
3.10.1 Installation
12
Courier-IMAP ist für Debian und OpenBSD als offizielles Paket inklusive dem MySQL-Auth-Modul verfügbar. Lediglich SUSE-Anwender müssen den Tarball von http://www.inter7.com/courierimap.html oder der CD zum Buch für MySQL-Support mit einem User-Account entpacken und über ./configure && make kompilieren. Sobald das Programm kompiliert wurde, können Sie zum Root-Account wechseln und die Installation mit make install && make install-configure abschließen.
13 14
Im Tarball finden Sie auch vorbereitete Startskripte, die in den Init-Ordner Ihrer Linux-Distribution kopiert und danach mit Softlinks in den gewünschten Runleveln verknüpft werden können:
suse@linux:~/courier-imap-4.0.1> ls *rc* imapd.rc.in imapd-ssl.rc.in pop3d.rc.in pop3d-ssl.rc.in Damit die Skripte ausgeführt werden können, sind die Zugriffsrechte abschließend anzupassen: chmod 755 *rc.
9 In der Voreinstellung löschen Mail-Clients die empfangenen Nachrichten auf dem Server automatisch. Üblicherweise setzen versiertere Anwender die Keep-Option von Fetchmail oder »Leave Messages on Server« (Mozilla) lediglich vorübergehend zu Testzwecken ein.
Courier-IMAP
255
3.10.2 Konfiguration Sofern Sie die Installationsverzeichnisse nicht angepasst haben, finden Sie sämtliche Programmdateien, inklusive der Konfigurationsdateien und Binaries, von Courier-IMAP im Verzeichnis /usr/lib/courier-imap. Courier-IMAP benötigt als IMAP-Server eine entsprechende Verzeichnisstruktur. Postfix legt diese bei virtuellen Mailboxen bereits bei der Nachrichtenzustellung korrekt im Verzeichnis /mailverzeichnis/accountname/postfach/new ab. Die Verwaltung und Administration virtueller Mailboxen mit Postfix ist in Abschnitt 3.9.11, Virtuelle Accounts über MySQL beschrieben. Nachrichtenbezug über bestehende System-Accounts Möchten Sie Nachrichten über bestehende System-Accounts beziehen, ist es am einfachsten, einen Softlink auf das gewünschte Postfach zu legen:
ln -s /home/accountname/Maildir \ /var/spool/virtboxes/mail.test/postmaster/ Selbstverständlich muss das Postfach dem System-Account gehören, damit er darauf zugreifen kann. Dies ist innerhalb der Postfix-Konfiguration entsprechend zu berücksichtigen. Zu guter Letzt gilt es authdaemond.plain sowie pop3d und/oder imapd zu starten, damit es möglich wird, Nachrichten über einen System-Account und das entsprechende Passwort über POP3 beziehungsweise IMAP abzurufen. Nachrichtenbezug mit MySQL über virtuelle Accounts Im Postfix-Abschnitt Virtuelle Accounts über MySQL wurde die Tabelle Virtboxes bereits mit den von Courier-IMAP benötigten Datenfeldern angelegt. Bis auf das Passwort-Feld werden sämtliche Daten auch von Postfix benötigt. Das Passwort können Sie sowohl im Klartext (plain) als auch verschlüsselt (crypt; password=password('test')) in der Datenbank ablegen. Die gewählte Methode ist neben den Zugangsdaten sowie Tabellen- und Feldnamen innerhalb /usr/lib/courier-imap/etc/authmysqlrc festzulegen:
MYSQL_SERVER MYSQL_USERNAME MYSQL_PASSWORD MYSQL_PORT MYSQL_DATABASE MYSQL_USER_TABLE
256
Wichtige Serverdienste
localhost mailer geheimes_passwort 3306 mailer virtboxes
1 2 MYSQL_CRYPT_PWFIELD MYSQL_CLEAR_PWFIELD MYSQL_UID_FIELD MYSQL_GID_FIELD MYSQL_LOGIN_FIELD MYSQL_HOME_FIELD MYSQL_MAILDIR_FIELD #MYSQL_NAME_FIELD
password #bei plain auskommentieren! password #bei crypt auskommentieren! uid gid adresse home dir name #Feld auskommentieren!
3 4 5 6
Wichtig Beachten Sie, dass die Leerzeichenanzahl vor MYSQL_USERNAME und MYSQL_PASSWORT unbedingt beizubehalten ist, da Courier-IMAP sich sonst nicht korrekt in die MySQL-Datenbank einloggen kann. Falls Sie lediglich den Namen und nichts an der Formatierung verändern, müssen Sie sich jedoch keine Sorgen machen (es sind genau zehn Leerzeichen).
7 8 9
Sichere Passwort- und Nachrichtenübertragung mit SSL
10
Da neben den eigentlichen Nachrichten über POP3 und IMAP sogar das Passwort im Klartext übertragen wird, verwenden umsichtige Administratoren lieber mit POP3s und/oder IMAPs gesicherte SSL-Verbindungen.
11 12
Um IMAPs und POP3s nutzen zu können, muss OpenSSL vor der Kompilierung von Courier-IMAP installiert sein. Im Normalfall ist dies bei Ihnen der Fall. Nach dem Aufruf von
13
/usr/lib/courier-imap/sbin/mkpop3dcert /usr/lib/courier-imap/sbin/mkimapdcert
14
sind die benötigten .pem-Dateien für eine SSL-Verschlüsselung im Verzeichnis /usr/lib/courier-imap/share/ erzeugt. Courier-IMAP kann selbstverständlich keine offiziellen Zertifikate erzeugen, so dass E-Mail-Clients die Kommunikation mit einer Warnmeldung und einer Nachfrage quittieren oder direkt beenden. In Abschnitt 3.3.7, Secure Socket Layer, ist beschrieben, wie Sie ein offizielles Zertifikat erwerben können. Hinweis für Fetchmail-Nutzer Sie können die Optionen SSL und den Fingerprint des Courier-Imap-Servers in die .fetchmailrc-Zeile aufnehmen, um die SSL-Kommunikation zu aktivieren:
... is "accountname" here, ssl, sslfingerprint \ "60:0B:F4:48:FB:5A:62:68:EE:45:F6:71:73:AE:40:B0"
Courier-IMAP
257
Sslfingerprint des Mailservers können Sie ebenfalls über fetchmail abfragen – hierzu ist weder ein gültiger User-Name noch ein Passwort notwendig (geben Sie einfach irgendetwas ein): user@linbook:~> fetchmail ihr_mail.server.de --ssl \ --username egal --protocol pop3 Enter password for egal@ihr_mail.server.de: fetchmail: ihr_mail.server.de key fingerprint: \ 60:0B:F4:48:FB:5A:62:68:EE:45:F6:71:73:AE:40:B0 fetchmail: Authorization failure ...
3.11
Das Webinterface SquirrelMail
Horde-IMP und SquirrelMail sind die wohl bekanntesten Mail-Webinterfaces. Ich möchte Ihnen SquirrelMail vorstellen, da es recht schnell und unkompliziert zu installieren ist und hervorragend mit Courier-IMAP zusammenarbeitet. Sie finden SquirrelMail unter http://www.squirrelmail.org sowie auf der CD zum Buch. Entpacken Sie den Tarball direkt im gewünschten Verzeichnis (auf das per Apache zugegriffen werden kann) und rufen Sie ./squirrelmail-1.4.0 /config/ conf.pl auf. Über das Perl-Menü des aufgerufenen Skripts können Sie SquirrelMail bequem an Ihre Wünsche und Bedürfnisse anpassen. Nehmen Sie sich ruhig etwas Zeit, um in den einzelnen Menüpunkten zu stöbern. Im Folgenden möchte ich lediglich auf notwendige Anpassungen eingehen, um das Webinterface für CourierIMAP vorzubereiten: 왘 Unter Server-Settings (2) finden Sie neben grundsätzlichen Informationen
zudem den gewünschten IMAP-Server. In der Voreinstellung wird Cyrus verwendet. Ändern Sie dies über Update IMAP Settings (A), Server software (8) und die Eingabe von courier. Speichern Sie die Anpassungen über (S) und beenden Sie das Perl-Programm (Q). 왘 SquirrelMail speichert Nutzereinstellungen im Verzeichnis data. Damit dies
überhaupt möglich ist, müssen Sie das Verzeichnis dem Apache-User mit chown überschreiben. Es empfiehlt sich, das Verzeichnis auszulagern (in ein Verzeichnis außerhalb der per Browser erreichbaren Ordner zu verschieben). Falls Sie sich zu diesem Schritt entschließen, müssen Sie das Perl-Konfigurationsprogramm erneut aufrufen und über General Options (4) den korrekten Pfad unter Data Directory (2) speichern.
258
Wichtige Serverdienste
1 2 3 4 5 6 7 8 9 Abbildung 3.8 Das Online-Webinterface-SquirrelMail ist im Handumdrehen installiert und ermöglicht es, das eigene Postfach auf fremden Rechnern einzusehen.
10
Nun können Sie squirrelmail-1.4.4/index.php in einem Browser aufrufen und sich über SquirrelMail mit Eingabe der Mail-Adresse ([email protected]) und des entsprechenden Courier-IMAP-Passworts einloggen. Voraussetzung ist lediglich, dass neben Apache mit PHP 4 auch IMAP läuft und für localhost erreichbar ist.
11 12 13
3.12
Der FTP-Server ProFTPD 14
Heute ist es üblich, Usern einen FTP-Zugang für den Upload der eigenen Webseite bereitzustellen. Leider weist das File-Transfer-Protokoll (FTP) diverse Mängel auf. So erfolgt zum Beispiel die Passwortübertragung im Klartext. Ein Tunneln des Protokolls über SSH ist dank seiner Verbindungscharakteristik nicht möglich. Wie in Abschnitt 5.3.9, FTP, beschrieben, erschwert dies die Erstellung von Regeln für den Paketfilter. Tatsächlich gibt es empfehlenswerte Alternativen: Über den Secure-Shell-Server sshd kann eine sftp-(Secure-FTP-)Verbindung aufgebaut oder direkt zu scp (secure copy) gegriffen werden. Für Windows sind neben einem textbasierten OpenSSH-Client durchaus grafische scp- und sftp-Programme verfügbar. Allerdings muss für jeden sftp-Nutzer ein vollständiger Shell-Account vorhanden sein. Im Gegensatz zu einem FTP-Server kann das Home-Verzeichnis des Nutzers nicht ohne einen Patch des Secure-Shell-Servers gechrootet werden (siehe Abschnitt 3.1.3, User-Homeverzeichnis chrooten).
Der FTP-Server ProFTPD
259
Indes stößt sftp beziehungsweise scp bei »Otto Normalverbraucher« ohnehin auf Ablehnung, da die lieb gewonnene Software XY mangels Unterstützung der notwendigen Protokolle nicht verwendet werden kann. Eine weitere interessante Alternative sind webbasierte FTP-Clients wie http2ftp, die über SSL abgesichert werden können. Da FTP-Webinterfaces umständlich zu bedienen sind, eignen sie sich lediglich für den Up- oder Download weniger Dateien. Natürlich müssen FTP-Webinterfaces vollen Zugriff auf die Dateien und Ordner der jeweiligen User erhalten, was wiederum zu Sicherheitsproblemen führt. Unter diesen Gesichtspunkten erscheint die Sicherung der FTP-Passwortübertragung durch Einmalpasswörter als beste Lösung. Nutzer werden sich zwar über den zusätzlichen Schritt der Passwortabfrage ärgern, können so aber ihren vertrauten FTP-Client weiter nutzen. Im Folgenden wird die Installation und Konfiguration des ProFTPD-Servers mit Einmalpasswörtern und Traffic-Protokollierung mit MySQL beschreiben.
3.12.1 Installation von ProFTPD mit MySQL-Support Bevor Sie ProFTPD installieren, sollte ein bereits installierter FTP-Server zunächst gestoppt und deinstalliert werden. Weiterhin muss die MySQL-Datenbank installiert und konfiguriert (siehe Abschnitt 3.6, MySQL) sowie das MySQL-Developer-Paket (mysql-devel) eingespielt sein. Lediglich Debian-Nutzer können auf ein offizielles ProFTPD-Paket mit MySQLUnterstützung zurückgreifen. Anwender von SUSE und OpenBSD finden auf der Homepage http://proftpd.org ein aktuelles Tarball, das nach dem Entpacken mit
./configure --with-modules=mod_sql:mod_sql_mysql make && make install installiert werden kann.
3.12.2 Konfiguration von ProFTPD Im Verzeichnis /usr/local/etc finden Sie die ProFTPD-Konfigurationsdatei proftpd.conf. Derzeit stehen mehr als 200 Parameter zur Verfügung. Die wichtigsten werden nachfolgend erläutert. Eine Liste sämtlicher Direktiven, inklusive des LDAP-Supports, finden Sie unter http://www.proftpd.de/direktive_ de.php.
260
Wichtige Serverdienste
1 2 Allgemeine Konfigurationsparameter
3
ServerIdent Off Der Server gibt sich nicht als »ProFTPD Version XY« zu erkennen und erschwert dadurch gezielte Angriffe (Security by Obscurity :-)
4 5
ServerType standalone4 Aus Performance-Gründen sollte ProFTPD als eigenständiger Hintergrundprozess gestartet werden. Falls Sie tatsächlich tcpd-wrapper nutzen wollen, ist inetd anstelle von standalone einzutragen.
6 7
DefaultServer on
8
Nur so werden sämtliche Server-Namen akzeptiert. Wenn Sie DefaultServer auf off stellen oder diese Zeile auskommentieren, werden lediglich Verbindungen zu $HOSTNAME (cat /etc/HOSTNAME) akzeptiert und sogar ein Verbindungsaufbau zur IP-Adresse abgelehnt. Die Deaktivierung ist lediglich für virtuelle ProFTPD-Server notwendig und sinnvoll.
9 10
Port 21
11
FTP-Clients versuchen, über Port 21 eine Verbindung aufzubauen. Falls notwendig, können Sie jedoch einen anderen Port wählen. Sicherheitstechnisch ist dies nur bedingt sinnvoll, da Angreifer über Scans prüfen, welche Ports offen sind, und diese »abklopfen«.
12 13
MaxInstances 30
14
Maximal 30 gleichzeitige FTP-Verbindungen sind erlaubt. Verhindert Denialof-Service-Angriffe und sollte nur dann erhöht werden, wenn tatsächlich mehr als 30 Nutzer zeitgleich auf den Server zugreifen müssen. Selbst wenn auf Ihrem Server 100 FTP-Accounts vorhanden sind, ist dieses Szenario, solange Sie keine anonymen Logins erlauben, eher unwahrscheinlich.
TimeoutLogin 300 Zeit in Sekunden, die bis zur Passworteingabe gewährt wird, bevor die Verbindung unterbrochen wird. Im Default wartet ProFTPD ganze 300 Sekunden (fünf Minuten). Diesen großzügigen Timeout sollten Sie ruhig deutlich nach unten korrigieren.
TimeoutNoTransfer 300 In der Standard-Einstellung bricht ProFTPD eine bestehende Verbindung nach fünf Minuten Inaktivität ab.
Der FTP-Server ProFTPD
261
Verschiedene Konfigurationsbereiche
Parameter für
262
Wichtige Serverdienste
1 2 User, unter dem die Hauptinstanz von ProFTPD läuft. Sie sollten einen eigenen, unprivilegierten Account anlegen und diesen hier angeben.
3
Group nogroup
4
ProFTPD wird beim Start die angegebene Gruppe zugewiesen. Es ist sehr sinnvoll, hier die Gruppe des FTP-Webservers zu vergeben, da so die Zugriffsrechte auf Eigentümer und Group beschränkt werden können und keinerlei Rechte für World zur Anzeige von Websites benötigt werden.
5 6
Umask 026 027
7
Umask bestimmt die Zugriffsrechte, die Dateien und Ordner beim Anlegen automatisch zugewiesen werden. Umask 000 bewirkt, dass Dateien, die über ProFTPD gespeichert werden, automatisch die Zugriffsrechte 666 (-rw-rw-rw-) erhalten. Tipp: Ziehen Sie vom »Standard-Dateirecht« (666) Umask ab. Aus Umask 026 (6–0=6; 6–2=4; 6–6=0) wird somit 640 (-rw-r-----). Die Ziffern 027 setzen die Ordnerrechte auf 750 (drwxr-x---). Im Gegensatz zu den Dateirechten ist bei Ordnern das Standard-Recht 777. Wenn Sie den Umask-Parameter weglassen, geht ProFTPD von einer Umask von 022 sowohl für Dateien als auch für Ordner aus.
8 9 10 11
RequireValidShell off
12
Shell-Accounts sollten nur den Personen erteilt werden, die tatsächlich einen SSH-Zugriff benötigen. Für FTP-Zugriff ist ein vollständiger User-Account jedoch nicht notwendig. Deshalb können Sie auf die Prüfung nach einer gültigen Shell verzichten und User-Accounts wie in Abschnitt 3.7.4, Erzeugen von FTP-Accounts, beschrieben anlegen.
13 14
DefaultRoot ~ sperrt den User in seinem Home-Verzeichnis ein. Verzichten Sie nicht auf diese Möglichkeit.
AllowOverwrite Fehlt diese Direktive, können bestehende Dateien nicht ohne voriges Löschen durch neue Files ersetzt werden.
Der FTP-Server ProFTPD
263
SQLConnectInfo proftp@localhost:3306 proftpd "dummy" baut eine Verbindung zur lokalen MySQL-Datenbank proftp über den Standard-Port (3306) als user proftpd mit dem Passwort dummy auf.
SQLAuthTypes Plaintext Die Passwörter der User-Accounts werden aus Vereinfachungsgründen im Klartext und unverschlüsselt gespeichert. Dies ist nicht weiter tragisch, da wir Einmalpasswörter verwenden und Angreifer, die Zugriff auf die MySQL-Datenbank erhalten, ohnehin selbst ein Passwort vergeben könn(t)en.
SQLAuthenticate users* weist ProFTPD an, ausschließlich MySQL zur Authentifizierung zu nutzen.
SQLUserInfo users username password uid gid homedir shell Zur Authentifizierung werden die Felder username und password der MySQLTabelle Users genutzt. Bei erfolgreicher Authentifizierung erteilt ProFTPD die UID anhand des gleichnamigen Datenbankfeldes und verwendet homedir als Startverzeichnis. Die Gruppen-ID werden wir pauschal über SQLDefaultGID zuweisen. Deshalb sollte GID durch den Platzhalter NULL ersetzt werden. Auf die Abfrage nach einer benutzerspezifischen Shell sollte mit NULL verzichtet werden.
SQLUserWhereClause "count='0'" erlaubt einen Login nur dann, wenn zusätzlich zum korrekten User-Namen und Passwort das Datenbankfeld count auf 0 steht.
SQLLog PASS counter SQLNamedQuery counter UPDATE "count=1 WHERE \ username='%u'" users setzt nach einem erfolgreichen Login das Feld count auf 1 und verhindert damit über die SQLUserWhereClause jeden weiteren Login.
SQLLog RETR,STOR insertfileinfo SQLNamedQuery insertfileinfo UPDATE "size=size+'%b' \ where username='%u'" users
264
Wichtige Serverdienste
1 2 loggt die Bytegröße (%b) der von einem User (%u) hoch- (STOR) beziehungsweise heruntergeladenen (RETR) Dateien.
3
SQLMinUserUID 500
4
User-Accounts besitzen UIDs > 499. Durch das Festlegen einer MinUserID von 500 verhindern Sie zum Beispiel einen Root-Zugriff (UID = 0).
5
SQLDefaultUID 500
6
weist FTP-Usern UID 500 als Default zu. Durch Nutzung einer SQLDefaultUID wird SQLMinUserID uninteressant.
7
SQLMinUserGID 100 verlangt eine Gruppen-ID, die größer als 99 ist.
8
SQLDefaultGID 65534
9
weist FTP-Usern automatisch eine Gruppen-ID zu. Für unser Beispiel sollten Sie hier die Gruppen-ID des Webservers eintragen (siehe auch Umask).
10
So könnte Ihre vollständige Datei proftpd.conf aussehen
11
ServerIdent Off ServerType standalone DefaultServer on Port 21 MaxInstances 20 TimeoutLogin 30 User proftpd Group ftpgroup DefaultRoot ~ Umask 026 027 AllowOverwrite on RequireValidShell off SQLConnectInfo proftp@localhost:3306 proftpd "dummy" SQLAuthTypes Plaintext SQLAuthenticate users* SQLUserInfo users username password uid NULL homedir NULL SQLUserWhereClause "count='0'" SQLLog PASS counter SQLNamedQuery counter UPDATE "count=1 WHERE \ username='%u'" users SQLLog RETR,STOR insertfileinfo
Der FTP-Server ProFTPD
12 13 14
265
SQLNamedQuery insertfileinfo UPDATE "size=size+'%b' \ where username='%u'" users SQLMinUserUID 500 SQLDefaultGID 65534 Achten Sie darauf, dass die ProFTPD-Konfigurationsdatei nur für Root schreibund lesbar ist: chown root proftpd.conf && chmod 600 proftpd.conf.
3.12.3 Vorbereiten der MySQL-Datenbank Rufen Sie den MySQL-Monitor über die Eingabe von mysql -u root -p auf. Nach Eingabe des Passworts können Sie über create database proftp; die Datenbank proftp anlegen. Wechseln Sie mit use proftp; in diese neue Datenbank und erzeugen Sie die Tabelle users:
CREATE TABLE users (username char(50) NOT NULL, password \ char(10) NOT NULL, uid int(5) NOT NULL, homedir char(200) \ NOT NULL, count int(1) default '1', size int(11) NOT NULL \ default '0', UNIQUE KEY username (username)); Gestatten Sie ProFTPD in einem eigenen MySQL-Account Zugriff auf die neue Datenbank und die darin enthaltene Tabelle: GRANT ALL ON proftp.* to "proftpd" identified by 'dummy' und laden Sie die Rechtetabelle neu, da MySQL diese Angaben in einem Cache bereithält: flush privileges Loggen Sie sich mit exit aus und testen Sie den Account: mysql -u proftpd -p Prüfen Sie, ob sich die Datenbank proftp nutzen lässt und use proftp und alle anderen Datenbanken für diesen Account nicht zugänglich sind.
3.12.4 Erzeugen von FTP-Accounts Obwohl Sie natürlich jedem FTP-Nutzer neben GID dieselbe UID zuweisen könnten, ist es empfehlenswert, einen eigenen System-Account für jeden Nutzer anzulegen, da Sie beispielweise Quotas nur so innerhalb von FTP-Zugängen vernünftig einsetzen können. Das Erzeugen eines speziellen FTP-Accounts wird mit folgenden Shell-Befehlen erledigt:
useradd ftpuser
-g webserver \ -d /home/ftpuser/ftp –s /bin/false mkdir –p /home/ftpuser/ftp cd /home/ftpuser chown ftpuser ftp chgrp webserver ftp chmod 750 ftp
266
Wichtige Serverdienste
1 2 In unserem Beispiel wird der neue Nutzer ftpuser mit der Gruppe webserver sowie dem Home-Verzeichnis /home/ftpuser/ftp angelegt. Ein Login über SSH oder Telnet wird durch die ungültige Shell (Option –s /bin/false) zuverlässig verhindert. Dies klappt selbst unter OpenBSD (obwohl hier /bin/false nicht existiert):
# Jun
3 4 5
5 11:24:34 obsd sshd[31250]: User user not allowed \ because shell /bin/false does not exist
6
Im nächsten Schritt wird das Home-Verzeichnis für ftpuser erstellt und ihm mit chown übertragen. Die Gruppe des Webservers darf Files innerhalb des Verzeichnisses ftp lesen und den Ordnerinhalt betrachten. Ob das Verzeichnis-Listing in einem Browser dargestellt wird, ist jedoch eine Frage der Konfiguration des Webservers (siehe Abschnitt 3.3.4, Verzeichnis- und Datei-Optionen).
7 8
Der Apache kann im Ordner ftp des ftpusers weder Dateien löschen noch überschreiben, da nur der lesende Zugriff erlaubt ist. Soweit unser ftpuser nicht so unvorsichtig ist, die Zugriffsrechte aufzuweichen, können alle Websites dargestellt werden, ohne bei einem erfolgreichen Angriff auf den Apache manipuliert, geändert oder gelöscht werden zu können.
9 10 11
Um den FTP-Account in die MySQL-Datenbank aufnehmen zu können, fehlt uns nur noch die UID des neuen Nutzers, die von useradd automatisch vergeben wurde. Außerdem hat der Account noch kein Passwort erhalten. Geben Sie tail -1 /etc/passwd | cut -d ":" -f 3 ein, um die UID zu erhalten. Nun können Sie in die User-Tabelle der MySQL-Datenbank proftp den Account eintragen:
12 13 14
Insert proftp.users (username, password, uid, homedir) \ values ('ftpuser', 'test', '505', '/home/ftpuser/ftp') Abschließend ist es empfehlenswert, das leere Passwort des Nutzers durch ein ungültiges zu ersetzen. Öffnen Sie hierzu die Datei /etc/shadow in einem Editor und ersetzen Sie :!: neben dem Benutzernamen durch :*:. Nun wäre ein Login selbst mit einer gültigen Shell für den Nutzer ftpuser nicht mehr möglich.
3.12.5 Testen der FTP-Installation Nun ist es so weit; Sie können Ihr FTP-System auf Funktionstüchtigkeit prüfen. Setzen Sie den Count-Zähler Ihres FTP-Test-Accounts auf 0:
update proftp.users set count='0' where username='ftpuser'
Der FTP-Server ProFTPD
267
und starten Sie ProFTPD im Debug-Modus:
/usr/local/sbin/proftpd -n -d 5 Jetzt kommt der entscheidende Moment: Versuchen Sie mit Ihrem bevorzugten FTP-Client eine Verbindung aufzubauen. Wenn der Login funktioniert hat, laden Sie eine Testdatei hoch und versuchen Sie, sich neu einzuloggen. Der zweite Login müsste verweigert werden, da ja der SQL-Zähler Count beim Erstlogin auf den Wert 1 gesetzt wurde. Werfen Sie zu guter Letzt nochmals einen Blick in die User-Tabelle der MySQLDatenbank proftp: Steht unter Size die Dateigröße der insgesamt übertragenen Dateien?
3.12.6 Fehlerteufel Obwohl der Debug-Modus von ProFTPD überwiegend verständliche Fehlermeldungen ausgibt, sei kurz auf die drei häufigsten Probleme hingewiesen:
unrecoverable backend error Es kann keine Verbindung zur Datenbank hergestellt werden. Überprüfen Sie User-Name, Passwort und Datenbankname sowie ob SQLAuthTypes, SQLAuthenticate users* und SQLUserInfo korrekt definiert wurden.
unable to chdir to / Überprüfen Sie, ob der Eigentümer und die Zugriffsrechte des Verzeichnisses richtig gesetzt sind. Kontrollieren Sie, ob die UID des Eigentümers mit dem Eintrag in der MySQL-Datenbank übereinstimmt. Läuft ProFTPD überhaupt? Die Frage mag sich zunächst trivial anhören, sollte jedoch überprüft werden:
ps -aux grep | grep "proftpd" proftpd 1223 0.0 0.4 3488 1284 ? S 17:13 0:00 proftpd (accepting connections) Falls die Meldung »proftpd (accepting connections)« nicht erscheint, könnte ein anderer Prozess Port 21 bereits für sich beanspruchen.
lsof -i :21 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME ftpd 1223 root 0u IPv4 16033 TCP *:ftp (LISTEN)
268
Wichtige Serverdienste
1 2 Hier läuft bereits ein anderer FTP-Server. Nachdem Sie den laufenden Prozess mit kill 1223 (die PID wird bei Ihnen abweichen) beendet haben, sollten Sie ProFTPD starten können.
3 4
3.12.7 Freischalten eines FTP-Zugangs mit Einmalpasswörtern über Perl
5
Theoretisch benötigen Sie kein Passwort, da nach jedem Login der FTP-Zugang gesperrt wird. Allerdings können Sie sich nicht darauf verlassen, dass User sich tatsächlich sofort einloggen, nachdem Sie den FTP-Zugang freigeschaltet haben. Vielleicht verabschiedet sich Windows, die Internet-Verbindung bricht zusammen oder ein Telefonanruf kommt dazwischen. Es gibt viele Gründe, warum User selbst nach einer manuellen Freischaltung keine FTP-Verbindung aufbauen. Zur automatischen Passwortgenerierung bietet sich unter Linux die Nutzung von pwgen an, für OpenBSD steht ppgen bereit, das allerdings mit Wörterbuchdateien arbeitet.
6 7 8 9 10
Mit pwgen 8 erzeugen Sie ein acht Zeichen langes Passwort, das ausschließlich aus Buchstaben besteht und für unsere Zwecke völlig ausreicht. Weitere Informationen finden Sie in der gleichnamigen Manpage.
11
Über ein Perl-Webinterface könnte der FTP-Zugang durch folgende Zeilen aktiviert werden:
12
#!/usr/bin/perl –w use DBI; use CGI qw(param); print "Content-type: text/html\n\n"; # Datenbank Zugangsinformationen $USER = "proftpd"; $PASSWORD = "dummy"; $DBASE = "proftp"; $ftp_pwd = 'pwgen 8'; $username = "ftpuser"; # Verbindungsaufbau $dbh = DBI->connect("DBI:mysql:database=$DBASE", \ "$USER", "$PASSWORD", {'RaiseError' => 1}); $dbh->do("update users set password='$ftp_pwd', count='0' \ where username='$username'") or die $dbh->errstr(); print "Ihr FTP-Passwort lautet: $ftp_pwd"; $dbh->disconnect();
13 14
Listing 3.5 Den Quellcode von FTPeinmalPwd.pl finden Sie auch auf der CD zum Buch.
Der FTP-Server ProFTPD
269
Nachdem das Zufallspasswort über den Systembefehl erzeugt wurde, wird der Login-Zähler unseres $usernamen auf 0 zurückgesetzt sowie das Zufallspasswort für den nächsten Login gespeichert. Zu guter Letzt gibt der Print-Befehl dem User das zu verwendende Passwort aus. Natürlich sollten Sie $username dem FTP-Programm dynamisch übergeben, um nicht für jeden Account ein eigenes Login-Skript anlegen und verlinken zu müssen. Noch wichtiger als dieses Detail ist jedoch die Absicherung des Programms selbst. Selbstverständlich darf dieses Perl-Programm erst nach einer Nutzerprüfung ausgeführt und nicht einfach von jedem Surfer aufgerufen werden können. In Abschnitt 4.7.2, CGI-Skripte für das Web, finden Sie weitere Informationen zu einer sicheren Authentifizierung. Als schnelle Alternative ist zudem die Nutzung der Digest-Authentifizierung (siehe Abschnitt 3.3.6, Userspezifischer Zugriffsschutz) mit Apache denkbar. Allerdings bietet die Authentifizierung über ein Perl-Skript höhere Flexibilität und bei Verwendung von SSL zudem ein Sicherheitsplus gegenüber Digest.
3.12.8 Traffic-Auswertung Detaillierte Loginformationen werden von ProFTPD in der Datei /var/log/xferlog gesichert. Wir haben in der Konfiguration jedoch festgelegt, dass übertragene Bytes zusätzlich im Feld Size unserer proftp-MySQL-Datenbank gesichert werden. Nun müssen Sie das Feld nur noch monatlich automatisch auslesen und auf 0 zurücksetzen. Für diese Aufgabe bietet sich ein Perl-Skript an, das über einen Cron-Job einmal monatlich aufgerufen wird und das Size-Feld vor dem Zurücksetzen monatsspezifisch in einer weiteren MySQL-Tabelle sichert. Um die Verbindungsdetails im Bedarfsfall für Beweiszwecke heranziehen zu können, ist es jedoch empfehlenswert, das xferlog unabhängig von einer automatisierten MySQL-Auswertung weiterhin zu erzeugen und regelmäßig zu sichern. Für unser Perl-Skript ist zunächst die neue Tabelle statistik in der propftpDatenbank anzulegen:
create table "stats" (username char(50), month int(2), \ year int(4), bytes int); Als Nächstes können wir uns dem Perl-Skript selbst zuwenden: Sie finden die Datei FTPtraffic.pl auch auf der CD zum Buch.
270
Wichtige Serverdienste
1 2 #!/usr/bin/perl use DBI; # Datenbank Zugangsinformationen $USER = "proftpd"; $PASSWORD = "dummy"; $DBASE = "proftp"; # Ermittle vergangenen Monat. $monat = 'date +%m -d '1 month ago''; chomp($monat); $year = 'date +%Y -d '1 month ago''; chomp($year); $printout = "FTP-Monatsstatistik für: $monat.$year\n\n"; # Baue Verbindung zur Datenbank auf: $dbh = DBI->connect("DBI:mysql:database=" . "$DBASE" \ .";host=localhost", "$USER", \ "$PASSWORD", {'RaiseError' => 1}); # Frage User und Traffic ab, speichere Ergebnis in stats $gettraffic = $dbh->prepare("select username, size \ from users") or die $dbh->errstr(); $gettraffic->execute() or die $dbh->errstr; while ($res = $gettraffic->fetchrow_hashref()) { $printout.="$res->{'username'}: $res->{'size'} bytes\n"; $dbh->do("insert stats values ('$res->{'username'}', \ '$monat', '$year', '$res->{'size'}')") or die $dbh->errstr(); } $gettraffic->finish(); # Setze Bytezähler von Tabelle users auf 0 $dbh->do("update users set size='0'") or die $dbh->errstr(); # Beende Datenbankverbindung. $dbh->disconnect(); # Versende Statistik per E-Mail an Root: open MAIL, "|mail -s 'FTP-Statistik $monat.$year' root"; print MAIL "$printout"; close MAIL;
3 4 5 6 7 8 9 10 11 12 13 14
Listing 3.6 FTPtraffic.pl
Der FTP-Server ProFTPD
271
Nun ist lediglich noch ein entsprechender Crontab-Eintrag notwendig:
01 0 1 * * root /usr/bin/perl /.scripte/ftpstats.pl Das Perl-Skript ftpstats.pl (siehe CD zum Buch) wird dadurch jeden Monatsersten um 01:00 Uhr aufgerufen. Sie sollten unbedingt darauf achten, dass ftpstats.pl nur von Root schreib-, les- und ausführbar ist: chmod 700
/.scripte/ftpstats.pl 3.12.9 xferlog Falls Sie »anonymous FTP« einsetzen, werden Sie an einer Auswertung über die am häufigsten abgerufenen Files interessiert sein. Das Perl-Skript xfersumm.pl erspart Ihnen die mühselige Erstellung eines eigenen Auswertungsprogramms und kann über http://jimsun.linxnet.com/unix_utils_by_jim.html bezogen werden. Es ist zudem auf der CD zum Buch enthalten. Hinweis ProFTPD sichert xferlog im wu-ftpd-Stil. Deshalb hat xfersumm.pl keine Probleme mit der Auswertung. Nach dem Download können Sie das Programm über perl xfersumm.pl /var/log/xferlog | less testen. Wird xfersumm.pl mit der Option -d yesterday aufgerufen, ist die Auswertung auf den gestrigen Tag beschränkt. Weitere Hinweise finden Sie in der kommentierten Programmdatei.
272
Wichtige Serverdienste
1 2
4 Verwaltung und Administration
3 4 5
4.1
Automatische Jobsteuerung ..................................... 275
4.2
Syslogd..................................................................... 278
4.3
Logfiles verwalten .................................................... 283
4.4
Systemzeit ................................................................ 288
4.5
Systemüberwachung ................................................ 289
4.6
Speicherplatz mit Quotas beschränken .................... 303
4.7
Automation .............................................................. 306
4.8
Backup ..................................................................... 328
4.9
Stresstests................................................................ 335
4.10 Ressourcen beschränken .......................................... 338 4.11 Loadbalancing .......................................................... 341 4.12 Hochverfügbarkeit.................................................... 342 4.13 Festplatte prüfen...................................................... 344 4.14 Das Rettungssystem................................................. 348 4.15 Raid-Systeme ........................................................... 351 4.16 Vorstellung verschiedener Admintools..................... 353
6 7 8
1
Einführung
2
Erste Schritte
3
Wichtige Serverdienste
4
Verwaltung und Administration
5
Server absichern
6
Linux-Vserver
7
Der eigene Server
8
Bürokratisches
1 2
4
Verwaltung und Administration
3
Management ist die Kunst, drei Leute dazu zu bringen, die Arbeit von drei Leuten zu machen. William Faulkner
4 5
Sobald Ihr System eingerichtet ist, beginnt die eigentliche Arbeit. Der Server möchte ständig beobachtet und gewartet werden, und dem Wildwuchs bei den Logdaten ist durch regelmäßige komprimierte Sicherung älterer Daten entgegenzuwirken. Festplatten- sowie RAM- und CPU-Auslastung sind darüber hinaus regelmäßig zu kontrollieren, um Probleme im Vorfeld zu erkennen.
6 7 8
UNIX-Systeme enthalten von Haus aus alle wichtigen Werkzeuge, die Sie zur sorgsamen Pflege des Systems benötigen. Darüber hinaus ist die Automation langwieriger Arbeitsprozesse durch Shell- und Perl-Skripte selbst ohne Informatik-Diplom schnell erlernbar.
9 10
Doch mit Wartung, Überwachung und Automation ist Ihr Aufgabenbereich noch nicht erschöpft. Verantwortungsbewusste Systemadministratoren planen voraus und prüfen laufende Prozesse durch Stresstests auf Stabilität und Belastungsgrenzen und überwachen den Server-Traffic. Lediglich ein sorgfältiges Backup-Konzept hilft nach einem Festplatten-Crash, die Server-Ausfallzeit möglichst kurz zu halten und einen Großteil der Daten zurückzuspielen.
4.1
11 12 13
Automatische Jobsteuerung
14
Cron dient zur regelmäßigen Ausführung von Programmen. Mit at werden einmalige Aufgaben zu einem bestimmten Zeitpunkt ausgeführt. Die Handhabung der beiden Programme ist jedoch recht unterschiedlich. Um einen at-Job anzumelden, genügt:
linbook:/ # echo "touch /atjobdone" | at 09:15 warning: commands will be executed using /bin/sh job 50 at 2003–05–29 09:15 Um 9:15 würde der Befehl touch /atjobdone mit den Rechten des Nutzers, der den at-Job veranlasst hat, ausgeführt. Natürlich könnten Sie anstelle von touch auch einen anderen Programmaufruf starten oder über die zusätzliche Option -f eine Datei übergeben, in der mehrere Shell-Anweisungen gelistet sind:
Automatische Jobsteuerung
275
linbook:/ # at 09:29 052903 -f atjob.tmp warning: commands will be executed using /bin/sh job 57 at 2003–05–29 09:29 Die Liste offen stehender Jobs kann über atq eingesehen werden. Wer oft mit at arbeitet, kommt vielleicht in die Verlegenheit, einen Job vor seiner Ausführung löschen zu müssen. Via at –c nr wird das vom Job ausgeführte ShellSkript eingesehen. Ist der zu löschende Job gefunden, können Sie den Auftrag mit atrm nr aus der qoue löschen:
linbook:~ # atq 57 2003–05–29 09:29 a root linbook:~ # atrm 57 Beachten Sie, dass at mögliche Ausgaben des Jobs an Accountname per E-Mail sendet. Sie können stdout und stderr jedoch wie in Abschnitt 2.4.4, Umleitung von Ein- und Ausgabe, beschrieben an /dev/null leiten, um eine Ausgabe zu unterdrücken. Weiterhin besteht die Möglichkeit, mit der Option -m eine beliebige E-Mail-Adresse anzugeben. Allerdings sendet at dann immer E-Mails an die angegebene Adresse, auch wenn der Job gänzlich ohne Hinweismeldungen ausgeführt wurde.
4.1.1
Cron-Jobs
Die Konfiguration von Cron-Jobs können Sie am besten via manueller Bearbeitung von /etc/crontab erledigen. Darüber hinaus besteht die Möglichkeit, CronJobs userspezifisch (Jobs, die mit den Rechten eines Accounts ausgeführt werden sollen) über crontab -e [username] zu editieren. Nutzer, die in /etc/cron.allow aufgeführt sind, sind so in der Lage, eigene Cron-Jobs zu definieren, ohne direkten Schreibzugriff auf /etc/crontab besitzen zu müssen. Die optionale Angabe eines Nutzernamens gestattet es Root, die Einträge eines spezifischen Accounts gezielt zu bearbeiten. Mit crontab -l [username] werden sämtliche Jobs aufgelistet. Beachten Sie weiterhin, dass crontab nicht auf /etc/crontab zurückgreift, sondern nutzerbezogene Dateien in /var/cron/tabs (oder /var/spool/cron/tabs) anlegt.
linbook:/etc # cat /etc/crontab SHELL=/bin/sh PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin MAILTO=user #m h dom mon dow user command 01 * * * * root run-parts /etc/cron.hourly
276
Verwaltung und Administration
1 2 Beachten Sie, dass /etc/crontab Root gehört und auf 600 sitzen sollte (unter OpenBSD wird die Datei sonst ignoriert – siehe /var/cron/log/: (*system*) BAD FILE MODE (/etc/crontab)). Die Syntax der Crontab ist einfacher zu verstehen, als es den Anschein hat. Die ersten fünf Felder dienen zur Definition des Intervalls (Minute, Stunde, Monatstag, Monat und Wochentag).
3 4 5
Nach dem Intervall folgt der User-Name, unter dem der Prozess ausgeführt werden soll, und letztendlich der Befehl selbst. Beim Editieren einer userspezifischen Crontab fällt die Spalte User natürlich weg. Der auszuführende Befehl ist direkt nach dem Zeitintervall festzulegen. Im Folgenden möchte ich Ihnen anhand einiger Beispiele erklären, wie Sie bei der Definition des Zeitintervalls vorgehen sollten.
#m 15
h *
6 7 8
dom mon dow * * *
9
Da die Wildcards generell zutreffen, würde dieser Cron-Job stündlich um 0:15, 1:15, 02:15 Uhr und so weiter ausgeführt werden. Beachten Sie, dass Minutenangaben von 0–59 vorzunehmen sind. Cron überprüft übrigens minütlich, ob ein Job auszuführen ist. Somit würde die Definition von
#m *
h *
10 11
dom mon dow * * *
12
den angegebenen Cron-Job zu jeder vollen Minute einmal ausführen. Überlegen Sie sich gut, ob es tatsächlich notwendig und sinnvoll ist, den entsprechenden Befehl jeden Tag 1 440 Mal von cron aufrufen zu lassen.
#m *
h *
13 14
dom mon dow * 1 *
Dieser Cron-Job würde nicht einmalig, sondern in jeder vollen Minute des Monats Januar und damit 44 640 Mal ausgeführt werden. Wer lediglich am 01. Januar einen Cron-Job einmalig aufrufen möchte, muss somit zusätzlich Minute, Stunde und Tag festlegen:
#m 23
h dom mon dow 10 1 1 *
Dieser Job würde jeweils am 01. Januar um 10:23 Uhr einmalig ausgeführt. Um einen Befehl einmal pro Tag auszuführen, müssen also lediglich Minute und Stunde festgelegt werden.
#m 0
h 7
dom mon dow * * 1
Automatische Jobsteuerung
277
Der Wertebereich von day of week reicht von 0–6, wobei 0 für Sonntag steht. Somit würde dieser Cron-Job jeden Montag um 7:00 Uhr morgens ausgeführt.
#m 22
h dom mon dow 7,16 * * *
Zeitangaben können durch Kommata ergänzt werden. Dieser Job würde um 7:22 sowie um 16:22 Uhr aufgerufen.
#m 0
h dom mon dow 7–16 * * *
Dieser Job würde zwischen 7:00 und 16:00 Uhr zu jeder vollen Stunde einmal aufgerufen.
#m */5
h *
dom mon dow * * *
Der Cron-Job wird alle fünf Minuten einmal aufgerufen. Das Sternchen steht für 0–59. Folgerichtig lässt sich der Zeitraum, in dem der Cron-Job alle fünf Minuten ausgeführt wird, auf einen Abschnitt begrenzen, der zwischen X:10– 50 Uhr liegt. Das kann insbesondere für die Angabe eines Tageszeitraums sinnvoll sein:
#m 9
h dom mon dow 7–16/2 * * *
Dieser Cron-Job würde täglich zwischen 7:09 und 16:09 Uhr im Abstand von zwei Stunden (also um 7:09, 9:09 ... bis 15:09 Uhr) ausgeführt werden. Beachten Sie, dass die Ausgabe jedes Jobs an die unter MAILTO definierte EMail-Adresse geschickt wird. Falls Sie stdout auf /dev/null leiten, würden nur noch Fehlermeldungen gepostet. Jobs, die mehr als einmal täglich ausgeführt werden müssen, buhlen dann lediglich im Fehlerfall um Ihre Aufmerksamkeit. Selbst wenn Sie neben stdout auch stderr an /dev/null leiten, haben Sie nachträglich die Möglichkeit zu kontrollieren, ob (und warum) ein Job (nicht) ausgeführt wurde, da cron seine eigene Syslogd-Facility besitzt. Weitere Informationen hierzu finden Sie im folgenden Abschnitt.
4.2
Syslogd
Der Syslog-Daemon wird üblicherweise mit jeder UNIX-Standardinstallation ausgeliefert und sollte in Ihrem System bereits im Hintergrund Informationen anderer Programme und des Kernels in Logfiles aufzeichnen.
278
Verwaltung und Administration
1 2 In der Syslogd-Konfigurationsdatei (siehe /etc/syslogd.conf) werden Einträge zeilenweise vorgenommen. Neben dem Logfile, in dem die Angaben gesichert werden, sind hier insbesondere Facility und Priority aufzuführen. Facility beschreibt den Programmtyp der Logmeldung (beispielsweise mail oder cron). Sämtliche Facilities sind in Tabelle 4.1 aufgeführt. Priority bestimmt die Sicherheitsstufe, die eine Meldung mindestens erreichen muss, um vom Syslogd geloggt zu werden. Der Umgang mit den verschiedenen Priority-Leveln ist in Abschnitt 4.2.2, Das Priority-Konzept, näher beschrieben.
3 4 5 6
Unter Linux können Sie als zusätzliche Option vor Angabe des zu sichernden Logfiles ein »–« (Minuszeichen) angeben. Dies ist sinnvoll, wenn häufig mit neuen Einträgen zu rechnen ist. Vereinfacht ausgedrückt, verzögert Syslogd die Sicherung entsprechender Logzeilen leicht, um so einige Zeilen gesammelt zu schreiben. Dies schont Systemressourcen, hat jedoch eine leichte Verzögerung beim Speichern der Logdaten zur Folge. In der Manpage wird darauf hingewiesen, dass ein Systemabsturz den Verlust dieser noch nicht geschriebenen Daten zur Folge hätte. Tatsächlich ist es sehr unwahrscheinlich, dass Ihnen wichtige Loginformationen durch einen Absturz verloren gehen. Das ist mindestens ebenso unwahrscheinlich wie ein Systemabsturz Ihres Servers.
4.2.1
7 8 9 10 11
Ein einfaches Beispiel
authpriv.* *.*;authpriv,cron.none cron.*
12 /var/log/auth.log -/var/log/syslog /var/log/cron.log
13 14
Sämtliche Meldungen der Facility cron (alle vom Cron an den Syslogd Daemon übertragenen Nachrichten) werden in das Logfile cron.log geschrieben. Im Logfile auth.log finden Sie dagegen Informationen zu erfolgreichen und fehlgeschlagenen Autorisierungen – sowohl über einen direkten Login am Terminal als auch über SSH. Zudem werden Benutzerwechsel und Passwortfehler von su und sudo in auth.log verzeichnet. Sie können zur Auszeichnung von Facility sowie Priority ein Sternchen verwenden. Die Aufzählung mehrerer Facilities kann über ein Komma an ein Loglevel gebunden werden: authpriv,cron.* bedeutet somit das Gleiche wie
authpriv.*;cron.*. Die Priority none ist nützlich, um einzelne Facilities zu ignorieren. Dies erklärt die Verwendung von *.*;authpriv,cron.none in der Zeile /var/log/syslog. Unsere drei kurzen Beispielzeilen sind somit bereits eine vollständige SyslogdKonfiguration: Sämtliche Autorisierungsmeldungen werden in auth.log und
Syslogd
279
alle Nachrichten des Cron-Jobs in cron.log gesichert. Die übrigen Loginformationen werden in /var/log/syslog gesammelt. Facility
Beschreibung
authpriv
Informationen zu erfolgreichen und fehlgeschlagenen Autorisierungen. Sowohl direkte SSH-Logins als auch Benutzerwechsel und Passwortfehler von su und sudo.
cron
Facility für cron- und at-Jobs.
daemon
Alle Programme, die keine eigene Facility besitzen, verwenden Daemon, um Syslogd Meldung zu erstatten.
kern
Nachrichten, die auf Kernel-Ebene erzeugt werden, erhalten diese Facility. Da der Paketfilter in den Kernel integriert ist, finden Sie auch iptables beziehungsweise pf-Meldungen in der Facility kern.
local[0–7]
Die so genannten lokalen (Terminal-) Meldungen. Meist handelt es sich um wichtige Nachrichten, die zur schnellen Kenntnisnahme direkt an den lokal eingesetzten Admin gesendet werden.
lpr
Logmeldungen vom Line-Printer-Subsystem. Da Sie Ihren Webserver wohl kaum zum Drucken verwenden, sollten keine Logmeldungen anfallen (deinstallieren Sie alle lpr*-Pakete).
mail
Der Mailserver hat eine eigene Facility.
news
Meldungen des Newsservers.
user
Die Default-Log-Facility für Nachrichten, die durch einen über Anwender erzeugten Programmaufruf entstehen. Zudem finden sich Autorisierungsmeldungen für direkten Login (am Terminal, nicht übers Netzwerk) unter diesem Facility.
uucp
Meldungen des UNIX-to-UNIXCopy-Systems – siehe Glossar.
Tabelle 4.1 Alle Facilities in der Übersicht
4.2.2
Das Priority-Konzept
Der Umgang mit den Facilities ist recht intuitiv. Bei der Nutzung der Priorities gilt es jedoch zu verstehen, dass die Priorität eine Mindeststufe darstellt; none ist sozusagen die höchste Stufe. Kein Logfile erreicht diese Priorität, und deshalb werden alle Informationen ignoriert. In der Stufe debug werden wie bei Verwendung des Sternchens, alle Informationen berücksichtigt. Die Priority crit sorgt dagegen lediglich für ein Login ernstzunehmender Fehlermeldungen der Level crit, alert und emerg. Sämtliche Priorities finden Sie in Tabelle 4.2.
280
Verwaltung und Administration
1 2 Priority
Beschreibung
debug
Sehr ausführliche Meldungen, die bei der Beseitigung auftretender Probleme helfen. Das jeweilige Programm ist im Debug-Modus zu starten, sonst werden Debug-Meldungen nicht versandt.
info
3 4
Info-Meldungen können recht ausführlich sein und sind für wichtige Systemdienste wie den Mailserver häufig sinnvoll.
notice
5
Wichtigere oder interessante Info-Meldungen. Allerdings keine Hinweise zu Programmproblemen oder dergleichen.
warning
6
Meldungen, die auf ein Problem oder einen Konfigurationsfehler hinweisen können. Allerdings kein Programmfehler. Empfehlenswerte Stufe für Logfiles, mit denen Sie sich nicht näher befassen möchten.
7
err
Meldung über einen aufgetretenen Programmfehler.
crit
Bei Auftreten ernstzunehmender Fehler oder anderer Probleme.
alert
Weist auf Störungen hin, die zum Absturz des Dienstes führen können. Sehen Sie möglichst sofort nach dem Rechten.
emerg
Notfallmeldungen, Dienst ist nicht mehr erreichbar.
10
none
Diese Priority wird von keiner Logmeldung erreicht. Somit werden bei »der höchsten Priorität« keine Logmeldungen der jeweiligen Facility berücksichtigt.
11
8 9
12
Tabelle 4.2 Nach Prioritätslevel sortiert: debug stellt die niedrigste Priorität dar (alle Meldungen werden geloggt) und none die höchste (keine Meldung wird geloggt).
4.2.3
13
Kombinationen von Facility und Priority in der Praxis
14
Sie werden den richtigen Umgang mit der Datei syslog.conf mit der Zeit erlernen. Es lässt sich pauschal schwer beurteilen, welches Login für Sie am effektivsten oder übersichtlichsten ist. Manche mögen es leichter finden, einzelne Facilities strikt für sich getrennt zu bewerten. Die folgenden Zeilen
authpriv.* cron.err ... uucp.*
/var/log/authpriv /var/log/cron /var/log/uucp
sind ebenso wenig falsch wie das Einführungsbeispiel von Abschnitt 4.2.1, Ein einfaches Beispiel. Viele Administratoren sehen es als sinnvoll an, Logmeldungen ab der Priorität err über die zusätzliche Zeile
*.err
/var/log/errors
Syslogd
281
in einem weiteren Logfile zu sichern, um so Fehlermeldungen aller Programme in einem Logfile überprüfen zu können. Andererseits ist es kein nennenswerter Aufwand, Logfiles mit grep zu durchsuchen. Ob eine zusätzliche Datei für Fehlermeldungen tatsächlich notwendig und sinnvoll ist, muss jeder Administrator selbst entscheiden. Falls Sie Logrotate nutzen, um E-Mail-Benachrichtigungen mit wichtigen Logzeilen automatisiert zu versenden, sollten Sie ein auf die für Logrotate relevanten Facilities und Priorities beschränktes Logfile von Syslog generieren lassen. Für Logcheck bietet sich *.info an. Weiterhin erweist es sich häufig als praktisch, wichtige und in größeren Mengen auftretende Loginformationen in eigene Dateien auszulagern. Insbesondere die Mail-, Auth- und Kernel-Facility bietet sich für eine Auslagerung an. Falls Sie noch keine näheren Vorstellungen zu einer eigenen syslog.conf-Datei haben und mit den Standardeinstellungen Ihres Systems unzufrieden sind, werden Sie vielleicht an folgendem Konfigurationsbeispiel Gefallen finden.
# Logfiles für manuelle Prüfung authpriv.* /var/log/authpriv cron.err /var/log/cron mail.* -/var/log/mail.log kern.notice /var/log/kern *.warning;authpriv,cron,mail,kern.none -/var/log/stuff # Für einfachere, automatisierte Auswertung durch logcheck *.info -/home/logcheck/.hidden/all # Für direkte Benachrichtigung über logsurfer *.crit /var/log/critmsg Um Platz zu sparen, könnten die Logfiles /home/logcheck/.hidden/all und /var/log/critmsg täglich (nach der Auswertung durch logcheck) archiviert und bereits nach der zweiten Rotation gelöscht werden. Damit Logsurfer keine komplexen, regulären Ausdrücke zur Suche nach ernstzunehmenden Hinweisen benötigt, werden Meldungen zu allen Facilities ab Priorität crit zusätzlich in /var/log/critmsg gesichert. Falls Sie ungewöhnliche Verzeichnisse verwenden, um Logdaten beispielsweise für eine automatisierte Prüfung auszulagern, sollten Sie darauf achten, dass /etc/syslogd.conf lediglich für Root lesbar ist. Sie erreichen hierdurch einen kleinen (aber schnell erzielbaren) Sicherheitsgewinn gegenüber Angreifern, die Ihre Logdaten verändern oder löschen wollen.
282
Verwaltung und Administration
1 2 Tipp Nutzen Sie in der ersten Zeit die Priority notice, um kleinere »Problemchen« einzelner Programme in Ruhe zu deaktivieren. Später können Sie bei weniger interessanten Facilities beruhigt auf die Stufe warning umsteigen. Verwenden Sie »-« nicht generell. Es nützt tatsächlich nur bei häufigem Schreibzugriff auf Logfiles und ist für die Facilities authpriv, cron oder andere in der Priority eingeschränkte Facilities eigentlich nicht notwendig.
3 4 5 6
4.2.4 Zugriffsrechte der Logdateien In der Voreinstellung sind die Zugriffsrechte der Syslog-Files sehr freizügig. Dank World readable kann sogar jeder lesend auf diese Daten zugreifen. Dies ist nicht nur aus Sicherheits- sondern auch aus Datenschutzgründen (insbesondere beim Maillog) bedenklich.
7
Ändern Sie die Zugriffsrechte ruhig massiv und entfernen Sie das globale Leserecht. Es empfiehlt sich, eine zusätzliche Gruppe für Programme, die lesenden Zugriff auf die Logfiles erhalten sollen, anzulegen oder das globale Leserecht selektiv freizugeben. Mehr zu dieser Problematik finden Sie in Abschnitt 5.12, Absicherung von Logfiles.
9 10
4.3
12
8
11
Logfiles verwalten
Auf einem UNIX-System wachsen die Logfiles mit der Zeit rapide an. Wer ein System vor sich hin arbeiten lässt, ohne auf die Logfiles zu achten, steht irgendwann vor einer vollen Server-Platte. In der Folge können E-Mails, Websites und andere Daten »plötzlich« nicht mehr gesichert werden.
13 14
Administratoren sollten deshalb die Details zu den Systemprogrammen Logrotate (Linux) oder Newsyslog (Net-, Free- und OpenBSD) kennen. Mit diesen Tools können Sie Logfiles automatisiert in einer neuen Datei komprimiert archivieren und eine neue (leere) Logdatei erstellen. Bei dieser Gelegenheit bietet sich der E-Mail-Versand des komprimierten Logs zur lokalen Archivierung an. Aus Platz- und Sicherheitsgründen sollten die komprimierten Logfiles nicht langfristig auf dem Server gelagert werden. Einige Programme, wie beispielsweise Postfix oder MySQL, mögen es nicht, wenn das bestehende Logfile »unter ihren Füßen« weggezogen wird. Nach der Logfile-Archivierung gilt es, Dienste, die ihr neues Logfile partout nicht nutzen wollen, neu zu starten. Logfiles wachsen nicht in gleichem Maße an. Deshalb sind unterschiedliche Intervalle zur Erstellung komprimierter Archivdaten sinnvoll. Damit nicht immer gleichzeitig sämtliche Programme neu gestartet werden müssen, emp-
Logfiles verwalten
283
fiehlt sich die Aufteilung in mehrere Konfigurationsdateien für einen täglichen, wöchentlichen oder monatlichen Aufruf. Dies fördert gleichzeitig die Übersicht. Da Sie im Normalfall die Konfigurationsdatei /etc/syslog.conf an Ihre Wünsche anpassen werden und zusätzlich programmspezifische Logfiles rotieren lassen möchten, die nicht über den Syslog erzeugt wurden, kommen Sie an einer Anpassung der Konfigurationsdatei von logrotate beziehungsweise newsyslog nicht vorbei.
4.3.1
Logrotate (Linux)
Logrotate ist flexibel und kann mit zusätzlichen Befehlen nach Belieben erweitert werden. Zudem ist eine Funktion, mit deren Hilfe sie archivierte Logfiles nach Erstellung oder vor automatisierter Löschung per E-Mail übersenden können, bereits enthalten. In der Konfigurationsdatei etc/logrotate.conf sind die einzelnen Optionen in einem globalen Bereich sowie logspezifisch definierbar. Globale Optionen können – bei Bedarf – im logspezifischen Abschnitt geändert werden.
monthly rotate 4 compress create 0640 root adm mailfirst /var/log/mail.log { postrotate /usr/sbin/postfix stop && /usr/sbin/postfix start endscript } /var/log/critmsg { daily mail root } /var/log/authpriv Die wichtigsten Logrotate-Optionen sind in Tabelle 4.3 aufgeführt. Über man logrotate finden Sie sämtliche vom Programm unterstützten Konfigurationsund Startoptionen. Sehr interessant ist der Abschnitt »postrotate ... endscript«. Alles, was zwischen diesen Zeilen steht, wird – wie in einem Shell-Skript – direkt nach dem Erzeugen der neuen (leeren) Logdatei ausgeführt. So können einzelne Programme, die in ein »plötzlich neu erstelltes« Logfile nicht schrei-
284
Verwaltung und Administration
1 2 ben wollen, durch den Neustart zum Akzeptieren der neuen Logdatei bewogen werden.
3
Spezifische Logfile-Optionen müssen in eine geschweifte Klammer gestellt werden. Logs, die lediglich mit den globalen Optionen behandelt werden, benötigen natürlich keine geschweifte Klammer.
4 5
So praktisch der direkte Mailbefehl über Logrotate auch sein mag, die Praxistauglichkeit hält sich dank der Übersendung der Logzeilen im Klartext (nicht im komprimierten Archiv) leider in Grenzen. In Abschnitt 4.3.3, Archivierte Logfiles mit mpack versenden, wird erläutert, wie komprimierte Logfiles automatisiert verschickt werden können.
6 7
Der Befehl mpack kann übrigens nicht in postrotate aufgenommen werden, da diese Zeilen noch vor der Komprimierung des Logfiles ausgeführt werden. Dies ist durchaus sinnvoll, da so wertvolle Zeit für den Neustart einzelner Dienste gespart wird.
8
Falls Sie Logrotate nicht mindestens einmal täglich aufrufen, ist es wichtig, die Option -f zu übergeben und die einzelnen Konfigurationsdateien strikt nach wöchentlicher oder monatlicher Ausführung zu trennen:
10
9
11
#crontab Eintrag: weekly logrotation 09 02 * 1 * root /usr/sbin/logrotate –f /etc/lr_weekly.conf
12
In der Testphase sollten Sie zusätzlich die Option -v nutzen, um die Arbeitsweise von Logrotate leichter überprüfen zu können.
13 14
Zeitpunkt
Beschreibung
daily
Tägliche Rotation.
weekly
Wöchentliche Rotation.
monthly
Monatliche Rotation.
size w [M||k]
Ist die Datei größer als die über w angegebene Grenze, erfolgt die Rotation des Logfiles. Werden die zusätzlichen Optionen M oder k verwendet, berechnet Logrotate die Dateigröße in Megabyte beziehungsweise Kilobyte. Ansonsten geht Logrotate bei der Angabe der Dateigröße von Byte aus.
Datei Optionen Beschreibung compress
Komprimiert das erzeugte Archiv.
create
Mit create 0640 root adm wird das neu erzeugte Logfile mit Lese- und Schreibrecht für Root sowie einem Leserecht für die Gruppe adm erstellt.
Tabelle 4.3 Die nützlichsten Konfigurationsoptionen von Logrotate in der Übersicht
Logfiles verwalten
285
Zeitpunkt
Beschreibung
compressext zip
Legt als Dateisuffix zip fest. Falls Sie die Logfiles auf einem WindowsRechner archivieren möchten, erspart Ihnen dies das spätere Umbenennen des Dateisuffixes.
olddir /pfad
Rotiert das Logfile im angegebenen Archiv. Diese Option ist dann notwendig, wenn bei der Definition von zu rotierenden Logfiles das Sternchen verwendet wird.
ifempty
Rotiert das Logfile selbst dann, wenn es leer ist.
Zus. Optionen
Beschreibung
rotate
Legt die Anzahl der Rotationen fest. rotate 4 erzeugt vier Archivdateien. Sobald die fünfte erstellt wird, löscht Logrotate das älteste Archiv.
sharedscripts
Sinnvoll, wenn über die Wildcard mehrere Logfiles angesprochen werden und die Funktionen innerhalb postrotate nicht jedes Mal, sondern nur einmal aufgerufen werden müssen; siehe auch olddir.
mailfirst
Sendet das gerade rotierte Logfile bei Aufruf des Mail-Befehls.
maillast
Sendet beim Überschreiten des Rotationslimits das Logfile vor seiner Löschung per E-Mail an den Administrator.
mail adresse
Schickt die Logzeilen an die anzugebende »Adresse«.
Tabelle 4.3 Die nützlichsten Konfigurationsoptionen von Logrotate in der Übersicht (Forts.)
4.3.2
Newsyslog (OpenBSD)
Auf einem OpenBSD-3.2-System wird nach der Standardinstallation newsyslog bereits stündlich über einen entsprechenden Eintrag in /var/cron/tabs/root aufgerufen. Werfen wir einen Blick in die übersichtliche Konfigurationsdatei (/etc/newsyslog.conf):
# logfilename /var/cron/log /var/log/maillog /var/log/pflog
owner.group root.wheel
mode ngen size 600 3 10 600 7 * 600 3 250 /var/run/pflogd.pid SIGHUP
time [ZB] * Z 24 Z * ZB \
Newsyslog ist recht einfach und verständlich zu konfigurieren. Das Kürzel ngen steht für die Anzahl der zu archivierenden Logfiles. Sobald das vierte Archiv erstellt wird, löscht Newsyslog das älteste Archiv. Die Logfiles /var/cron/log und /var/log/pflog werden getrimmt (rotiert), sobald die Dateigröße 10 Kilobyte beziehungsweise 250 Kilobyte überschritten hat. Rotationen nach Zeitraum sind über die Spalte time möglich. Das Sternchen steht für »nicht verwendet«. Es dient also nicht als Wildcard, sondern dazu, die
286
Verwaltung und Administration
1 2 Rotation lediglich von der Dateigröße abhängig zu machen. Sie können anstelle des Sternchens die Zeit in Stunden eintragen, die bis zur nächsten Rotation mindestens vergehen soll.
3 4
Tragen Sie in die Spalte size ein Sternchen ein, wenn Newsyslog bei der Überprüfung, welche Dateien zu rotieren sind, nicht auf die Dateigröße eines Logfiles achten soll.
5
In der letzten Spalte können Sie festlegen, ob das rotierte Archiv komprimiert werden soll (Z), und ob es sich um eine Binärdatei handelt (B). Wie bereits erwähnt, mögen es manche Programme nicht, wenn ihnen das Logfile »weggerissen« wird. Häufig genügt es, der Pid des Programms SIGHUP über kill zu senden. Sie können hierzu nach der Spalte [ZB] den Pfad zur Pid-Datei angeben. SIGHUP muss nicht angegeben werden, da es in der Voreinstellung von Newsyslog genutzt wird.
6 7 8 9
Falls ein SIGHUP nicht genügt, kommen Sie meist um einen zusätzlichen CronJob, der das jeweilige Programm mit den benötigten Optionen beendet und wieder neu startet, nicht herum. Falls Sie lediglich ein anderes kill-Signal benötigen, können Sie anstelle von SIGHUP jedes unter man sigaciton aufgeführte Signal optional verwenden.
10 11
In der Voreinstellung sind die Dateigrößen recht klein gewählt. Hängen Sie ruhig eine zusätzliche 0 an. Die tägliche Rotation des Maillogs wird zudem in den meisten Fällen nicht sehr praktikabel sein.
12 13
Damit nicht bei jedem Aufruf von Newsyslog die gesamte Konfigurationsdatei abgearbeitet werden muss, können Sie die Datei gegebenenfalls zerlegen und Newsyslog über die Option -f aufrufen: newsyslog -f /pfad/nslog_
14
monthly.conf. 4.3.3
Archivierte Logfiles mit mpack versenden
Logdateien können nach dem Rotieren direkt per E-Mail versandt werden. So sind Logfiles bequem archivierbar, ohne auf dem Webserver Platz durch unzählige komprimierte Logfiles zu verschwenden. Am einfachsten ist das Versenden über das Programm mpack möglich. Ein vorbereitetes mpack-Paket ist für Debian, OpenBSD und SUSE bereits erhältlich, so dass die Installation im Handumdrehen erledigt werden kann. Der Befehl mpack -s "mail.log" /var/log/mail.log.1.gz [email protected] sendet das Archiv /var/log/mail.log.1.gz als angehängte Datei an das Postfach name der Domain site.de.
Logfiles verwalten
287
Verknüpfen Sie den mpack-Aufruf am besten über && mit dem Cron-Job zur Rotation der entsprechenden Logfiles. Sollen mehrere Dateien übermittelt werden, bietet sich zwecks besserer Übersicht ein kurzes Shell-Skript an. Zudem ließe sich der Nachrichtenempfang automatisieren: Das Perl-Skript mimeStrip.pl ist in der Lage, Mail-Anhänge in einen Ordner extrahiert zu speichern, und ist über http://www.freshmeat.net erhältlich.
4.4
Systemzeit
Nur wenn die Systemzeit richtig tickt, können Logfiles bei Problemen auf Grund des Zeitraums gezielt durchsucht werden. Auch für die weitere Verfolgung von Angreifern ist, insbesondere bei Nutzung eines Dial-up-Providers (dynamische IP-Adresse) der »Gegenstelle«, eine exakte Systemzeit unverzichtbar. Damit die Uhr nach einem Neustart weiter richtig tickt, sollte die HardwareClock man hwclock (Linux) regelmäßig (ein bis zwei Mal monatlich genügt) per Cron-Job auf die Systemzeit gestellt werden. Dies geschieht durch hwclock -w. Nutzer von OpenBSD müssen sich mit derartigen Peanuts nicht beschäftigen. Die Hardware-Clock wird hier bereits automatisch aktualisiert (siehe man hardclock). Neben dem Datum können Sie auch die Systemzeit über date manuell korrigieren. Diese Aufgabe erfolgt unter Linux mit der Option -s im Format MM/DD/YY (date –s 06/25/03 für 25.06.2003) sowie HH:MM:SS (Beispiel: date -s 08:44:56). Unter OpenBSD werden Datum und Uhrzeit ohne zusätzliche Option im Format yymmddHHMM.SS (Beispiel: date 0301081555.35 für 08. Januar 2003, 15:09:35 Uhr) gesetzt.
4.4.1
Automatisierte Korrektur der Systemzeit
Eine manuelle Korrektur der Systemzeit wird kaum zu einer sekundengenauen Systemzeit führen. Deshalb sollten Sie die manuelle Methode nur in Notfällen verwenden. Kostenlos nutzbare Time-Server ermöglichen es, die Server-Zeit auf Millisekunden genau einzustellen. Diese Aufgabe kann von ntpdate als Cron-Job vollständig und automatisiert erledigt werden. Falls ntpdate in Ihrer Linux-Distribution nicht als eigenständiges Paket enthalten ist, können Sie es wie unter OpenBSD über das ntp-Paket installieren. Üblicherweise stellt der Dienstleister innerhalb des Subnetzes Ihres Servers einen Time-Server zur Verfügung. Falls dieser einmal ausfallen oder manipu-
288
Verwaltung und Administration
1 2 liert werden sollte, ist es ratsam, gleichzeitig mehrere Time-Server über ntpdate anzusprechen. In der Tabelle 4.4 finden Sie einige kostenlos nutzbare Time-Server. Unter http://www.eecis.udel.edu/~mills/ntp/servers.html steht eine aktuelle Liste öffentlicher Time-Server bereit.
3 4
Rufen Sie ntpdate als Cron-Job mit der Option -s auf, um eventuelle Ausgaben über Syslogd zu protokollieren. Am besten nutzen Sie vier – durch ein Leerzeichen getrennte – Time-Server. Nur so ist gewährleistet, dass nicht nur der Ausfall eines einzelnen Time-Servers unproblematisch ist, sondern darüber hinaus ein falsch tickender Time-Server von ntpdate anhand der Zeitwerte der anderen erkannt werden kann.
5 6 7
ntpdate -s time1.de time2.de time3.de time4.de
8
Gleichen Sie die Zeit alle zwei bis vier Stunden mit den Time-Servern ab, um eine möglichst genaue Systemzeit zu gewährleisten. Es ist ebenso sinnvoll, bei einem Neustart die Zeit abzugleichen. Verwenden Sie im Startskript zusätzlich die Option -b, um die Zeit unmittelbar, anstelle der sonst vorgenommenen »sanfteren« Angleichung, zu ändern.
9 10 11
Name
Homepage
ntp.heh.uni-oldenburg.de
http://www.heh.uni-oldenburg.de/konfig/ntp.html
time.fu-berlin.de
http://www.zedat.fu-berlin.de/services/time.html
ptbtime1.ptb.de ptbtime2.ptb.de
http://www.ptb.de/de/org/q/q4/q42/ntp/ntp_main.htm
13
ntps1–0.cs.tu-berlin.de ntps1–1.cs.tu-berlin.de
http://irb.cs.tu-berlin.de/dienste/ntp/
14
12
Tabelle 4.4 Einige der empfehlenswerten öffentlichen Time-Server. Eine vollständige Liste finden Sie unter http://www.eecis.udel.edu/~mills/ntp/servers.html
4.5
Systemüberwachung
Es kommt immer wieder vor, dass Server kurzzeitig vom Netz getrennt oder sogar neu gestartet werden müssen. Der Hoster Ihres Vertrauens sollte dies jedoch vorher ankündigen und den Rechner nicht einfach per Power-Knopf ein- und ausschalten. Um den Zeitpunkt und die Länge des »Systemausfalls« rudimentär bestimmen zu können, empfiehlt sich der simple Versand einer Infomail über ein K99Stoppskript. Nur wenn der Dienstleister den Rechner ordnungsgemäß herunterfährt, wird diese in Ihrem Postfach landen. Nach dem (erneuten) Start des Servers und sämtlicher Dienste bietet sich eine weitere Infomail an.
Systemüberwachung
289
Hier sollte nicht nur eine date-Abfrage erfolgen, sondern nach allen wichtigen Systemdiensten per ps –aux | cat | grep Prozessname gefragt werden (beispielsweise Web-, FTP-, MySQL-Server und Syslogd). Falls ein Programm nicht gestartet werden konnte, sehen Sie dies bereits in der E-Mail, ohne sich auf dem Server einloggen oder die einzelnen Dienste direkt ansprechen zu müssen. Darüber hinaus sollte täglich per Cron-Job der Festplattenplatz df -h, die mailq und optional die Größe einzelner Verzeichnisse per du -hcs /pfad/dir überprüft werden. Bei dieser Gelegenheit bieten sich verschiedene Anfragen wie top -n 1 -b | head –20 und netstat –tul (Linux) beziehungsweise top -n 15 –b und netstat -anf inet (OpenBSD) an. So erhalten Sie eine Liste der aktivsten Prozesse (nach CPU-Ressourcenverbrauch), neben allen lauschenden oder aktiven TCP- und UPD-Server-Prozessen. Unter Linux empfiehlt sich zusätzlich der Befehl procinfo.
4.5.1
Traffic-Analyse
Neben Diensten wie Apache oder FTP entsteht weiterer Traffic durch SSH, DNS oder unerfreuliche Portscans. Um ein- oder ausgehenden Traffic zuverlässig zu bewerten, gilt es, den Datenverkehr der Netzwerkkarte zu loggen. Hierbei ist darauf zu achten, dass das verwendete Tool unbedingt auf der Systemebene vor dem Paketfilter ansetzt. Auch Pakete, die geblockt werden, sind als eingehender Traffic zu bewerten. Der Befehl ifconfig eth0 zeigt unter Linux bereits sämtliche ein- (RX bytes) und ausgegangenen (TX bytes) Pakete an. Unter OpenBSD erhalten Sie diese Information am einfachsten über netstat -nbI sis0. Diese Informationen werden Ihnen in der Praxis jedoch wenig dienlich sein. Einerseits gehen die Daten bei einem Neustart verloren (unter Linux setzt sich der Zähler nach dem Erreichen von über 4 GB RX/TX sogar selbst auf null), andererseits können Sie so kaum ermitteln, wie viel Datentransfer in einem bestimmten Monat, einer Woche oder einem Tag angefallen ist. ipac-ng für Linux Ipac-ng ergänzt die iptables-Einstellungen um die Regeln zur Traffic-Überwachung. Zusätzlich sichert das Programm die Verbindungsdaten regelmäßig und bietet über ipacsum die Möglichkeit, den angefallenen Traffic eines beliebigen Zeitraums auszugeben. Ipac-ng ist sicher als vorbereitetes Paket für Ihre LinuxDistribution erhältlich und somit einfach zu installieren. Ein 2.4er-Kernel mit iptables-Support wird jedoch vorausgesetzt. In Abschnitt 2.9.1, Linux, ist beschrieben, mit welchen Optionen Sie den Kernel kompilieren sollten.
290
Verwaltung und Administration
1 2 Im Verzeichnis /etc/ipac-ng/ipac.conf finden Sie die Konfigurationsdatei. In der Grundeinstellung wird nicht nur der gesamte Traffic überwacht, sondern zusätzlich die an einzelne Dienste gerichteten Datenmengen. Die für Sie uninteressanten Zeilen können mit dem Zeichen # einfach auskommentiert werden.
3 4
Wichtig ist die Konfiguration der IP-Adressen des Servers. Sie können mehrere Adressen überwachen und den Traffic spezifisch auswerten lassen:
5
#192.168.0.100 = Root Server 192.168.0.100 in|in|+|all|0/0|192.168.0.100 192.168.0.100 out|out|+|all|192.168.0.100|0/0 # 192.168.0.102 = Virtueller Server 192.168.0.102 in|in|+|all|0/0|192.168.0.102 192.168.0.102 out|out|+|all|192.168.0.102|0/0
6
Nach den Änderungen ist ipac-ng neu zu starten. Den erfassten Traffic des aktuellen Monats können Sie sich über ipacsum -t "this month" ausgeben lassen. Der Befehl ipacsum -t "last month" bietet sich als Cron-Job zum Monatsende an, um so bequem über den insgesamt entstandenen Traffic des vergangenen Monats informiert zu werden. Fügen Sie dem Befehl die Option -f neben der IP-Adresse hinzu, um lediglich den Traffic einer bestimmten IPAdresse zu erhalten:
9
7 8
10 11 12
spiegel:~# ipacsum -t "last month" -f 192.168.0.100 IP accounting summary Host: spiegel / Time created: 2003/01/13 17:21:12 CE Data from 2002/12/01 00:00:00 CE to 2002/12/31 23:59:59 CE * 192.168.0.100 in : 75M * 192.168.0.100 out : 1657M
13 14
Hinweis Da ipac-ng auf Paketfilter-Regeln angewiesen ist, müssen Sie bei einem Flush der Filterregeln auch die ipac-ng-Regeln wiederherstellen. Der Befehl fetchipac -S sollte deshalb nach dem Paketfilterskript aufgerufen werden. Da Sie diesen »Fehler« möglicherweise erst am Ende eines Monats feststellen, wenn ipacsum ungewöhnlich wenig Datentransfer berechnet, wurde mit dem ipac-ng-Paket ein Cron-Job unter /etc/cron.d/ipac-ng eingerichtet, der ipac-ng mit dem Befehl /usr/sbin/fetchipac alle zehn Minuten auf seine Funktionstüchtigkeit überprüft. So erhalten Sie gegebenenfalls rechtzeitig eine E-Mail mit dem Body »ipac-ng chains or rules corrupted, fix this with fetchipac -S«.
Systemüberwachung
291
IPA-IP Accounting System für OpenBSD Unter http://ipa-system.sourceforge.net/ finden Sie die aktuellste Version des IPA-Traffic-Analyse-Systems für die BSD-Paketfilter PF, IPFW(2) sowie IPF. Die Installation gestaltet sich über make && make install denkbar unproblematisch. Zunächst gilt es, die Konfigurationsdatei /usr/local/etc/ipa.conf mit den Zeilen
global { update_db_time = 5m append_db_time = 1h } rule all { pf = 0 1 } rule 32 { pf = 2 3 } anzulegen. Der globale Parameter update_db_time 1m sorgt für eine fünfminütige Aktualisierung der Übertragungsdaten. Jede Stunde wird (append_db_ time) ein neuer Eintrag geschrieben. Dies ermöglicht es Ihnen, Traffic-Spitzen zu erkennen, ohne unnötig viele Dateneinträge zu erzeugen. Beachten Sie, dass der Parameter pf = [numbers] auf die Nummern der gewünschten Regeln (durch Leertaste zu trennen) verweist: ipfctl –s rule:
@0 @1 @2 @3
pass pass pass pass
in all out all in inet from any to 192.168.0.32 out inet from 192.168.0.32 to any
Sie sollten die IPA-Regeln als einfache »pass in rules« am Anfang Ihres Regelwerkes definieren, bevor Sie mit den eigentlichen Regeln beginnen. Nur so ist gewährleistet, dass sämtliche aufzuzeichnenden Pakete tatsächlich von ipa-ip aufgezeichnet werden. Auch eingehender Traffic, der geblockt wird, verursacht Traffic. Tipp: Um die einzelnen Regeln schneller zu finden, bietet sich die Namensvergabe gemäß der Endung der IP-Adresse an. Informationen zum Erstellen von Paketfilterregeln für OpenBSD finden Sie in Abschnitt 5.3, Paketfilter. Über ipastat können Sie die ipa-ip-Datenbank gezielt nach einzelnen Regelgruppen abfragen und den gewünschten Zeitraum flexibel festlegen:
ipastat -r 32 -p 1m
292
Verwaltung und Administration
1 2 zeigt den gesamten Traffic der Regel 32 des vergangenen Monats an. Sie können Jahr und Monat zudem gezielt über die Option -i ansprechen:
3
ipastat -r all -i 2003.01
4
Hinweis Mit der Option -b werden die Statistiken nach der Anzahl der übertragenen Bytes sortiert, dadurch können Sie Traffic-Spitzen leicht erkennen. Falls Sie einzelne Regeln entfernen oder umbenennen, sind die Verzeichnisse unter /var/ipa ebenfalls umzubenennen oder zu löschen. Tipp: Sie können sämtliche gespeicherten Einträge über ipastat –a bequem abfragen, ohne einen Blick in das Verzeichnis werfen zu müssen.
4.5.2
5 6 7 8
Überwachung von CPU, Load, RAM und verfügbarer Bandbreite
9
Um feststellen zu können, ob der Server seinen Aufgaben gerecht wird und genügend Leistungsreserven besitzt, sollten Sie die Auslastung der CPU und des Arbeitsspeichers unbedingt überwachen.
10 11
Insbesondere bei kleineren Anbindungen ist die Überwachung der genutzten Bandbreite wichtig. Selbst für Rechner, die mit vollen 100 Mbit an einem deutlich größeren Backbone hängen, ist die Überwachung der Bandbreite nicht nur für statistische Zwecke interessant.
12 13
Manche Dienstleister schränken die maximale Datentransfer-Rate ein. Sollte die Statistik für einige Minuten einen konstant gleichen Höchstwert anzeigen, deutet dies darauf hin, dass Seitenanfragen nicht prompt, sondern erst mit spürbarer Verzögerung beantwortet werden. Sprechen Sie mit Ihrem Dienstleister über dieses Problem. Hat er keine Lösung, bietet sich als Konsequenz – neben der Nutzung einer zweiten Netzwerkkarte oder Auslagerung einzelner Domains auf einen zweiten Server – ein Wechsel des Dienstleisters an.
14
Grundlagen Die Pakete ucd-snmp und mrtg sind bereits für OpenBSD und Ihre Linux-Distribution erhältlich. Die Installation gestaltet sich daher unproblematisch. Über das Simple Network Message Protocol (kurz SNMP) werden die wichtigsten Systemdaten gesammelt und auf Anfrage fremden Rechnern zur Verfügung gestellt. Die Kommunikation zwischen Systemprozessen (in der SNMP-Sprache Agenten genannt), ist in einem wahren Bündel von RFC-Dokumenten geregelt. Wer
Systemüberwachung
293
sich für die Details interessiert, findet unter http://www.netsnmp.org sowie http://www.hio.hen.nl/rfc/snmp/ einen guten Überblick. Leider ist die Handhabung von SNMP alles andere als simpel. Nachdem der smtpd-Daemon gestartet ist, werden die einzelnen Dateien in einem MIB-Tree gesichert. Aus der »Management Information Base« können die Daten über snmpget anhand der Objekt-ID (OID) abgefragt werden. Das klingt einfacher, als es ist. Die richtige OID muss erst herausgefunden werden. Grundsätzlich sollte dies mit snmpwalk und etwas Geduld möglich sein. Etwas bequemer geht es mit dem Mbrowser, der allerdings eine grafische Oberfläche zum Betrieb benötigt. In der Testphase ist dies nicht weiter schlimm, da Sie die SNMP-Daten (ausnahmsweise) über das Netzwerk abfragen können. Dies ist jedoch nicht alles: Über snmpset ist es sogar möglich, schreibend auf Systemdaten zuzugreifen und so beispielsweise die Uhrzeit oder ein NetzwerkInterface zu manipulieren. Wie Sie snmp absichern, wird im folgenden Abschnitt behandelt. Konfiguration von snmpd Um Anfragen an den snmpd stellen zu können, gilt es, zunächst eine Konfigurationsdatei anzulegen. Man snmpd.conf erklärt die umfangreichen Möglichkeiten. Für unsere Zwecke genügen für /etc/snmpd.conf bereits folgende Zeilen:
# sec.name source community com2sec readonly 127.0.0.1 compass # name sec.model sec.name group MyROSystem v1 paranoid group MyROGroup v1 readonly # name inc/excl subtree view sys included .1 # context sec.level match read write notif access MyROSystem "" v1 noauth exact sys none access MyROGroup "" v1 noauth exact sys none
none none
Der Community-Name compass ist gleichzeitig als Passwort zu verstehen. Sie können hier einen kryptischen Begriff wie ewrKLsdf verwenden. Um snmpd keinen Missbrauchsversuchen auszusetzen, wird der Zugriff lediglich lokal (127.0.0.1) gestattet, das heißt, dass weder Anfragen aus dem Subnetz noch dem Internet entgegengenommen werden.
294
Verwaltung und Administration
1 2 Um mit Mbrowser auf einem grafischen System auf den smtp-Daemon unseres Testservers zugreifen zu können, steht es Ihnen frei, die Konfiguration vorübergehend um eine zusätzliche com2sec-Zeile für das lokale Netzwerk oder eine einzelne IP-Adresse zu erweitern:
com2sec readonly 192.168.0/24
3 4
compare
5
Achten Sie darauf, in der smtpd-Konfiguration ausschließlich lesenden Zugriff (readonly) zu erlauben. Im letzten Abschnitt der Konfigurationsdatei gilt es, in der Spalte write unbedingt none zu verwenden.
6
Da die Kennungen compass sowie compare im Klartext gespeichert werden, muss die Konfigurationsdatei unbedingt vor globalem Zugriff geschützt werden. chmod 600 und chown root sollten auf die Konfigurationsdatei angewandt werden.
7
Zusätzlich empfiehlt es sich, die UDP-Ports 161 und 162 ein- und ausgehend über den Paketfilter, wie in Abschnitt 5.2, Paketfilter, beschrieben, zu blocken.
9
8
10 snmpd mit snmptranslate, snmpget und snmpwalk nutzen
11
Bevor Sie snmpd-Anfragen absetzen können, ist der Daemon mit snmpd –c /pfad/konfigurations.datei zu starten. Als erster Test bietet sich eine snmpget-Abfrage nach dem Host-Namen (MIB-OID = sysName.0) an:
12
linbook:~ # snmpget 192.168.0.32 compare sysName.0 system.sysName.0 = openbsd.home
13
Nach der IP-Adresse (127.0.0.1 für localhost) ist die community (Passwort) anzugeben. Danach folgt die gewünschte MIB-OID. Über den Befehl snmptranslate –Tp | less erhalten Sie eine Übersicht der einzelnen MIB-Elemente. Hier finden Sie zudem den Eintrag sysName:
+-- -RW- String | | | | | |
14
sysName(5) Textual Convention: DisplayString Size: 0..255
Das Suffix .0 steht für das erste gespeicherte Objekt. Zu manchen Einträgen gibt es weitere Elemente, die über ».1, .2, ... .99«, abgefragt werden können. Die manuelle Anpassung des Suffixes ist recht umständlich. Glücklicherweise können Sie alternativ auf die Funktion snmpwalk zurückgreifen, um sämtliche Elemente eines Zweiges bequem anzeigen zu lassen:
-bash-2.05b# snmpwalk 127.0.0.1 compass load enterprises.ucdavis.laTable.laEntry.laLoadFloat.1 \ = Opaque: Float: 0.224121
Systemüberwachung
295
enterprises.ucdavis.laTable.laEntry.laLoadFloat.2 \ = Opaque: Float: 0.151367 enterprises.ucdavis.laTable.laEntry.laLoadFloat.3 \ = Opaque: Float: 0.092773 Auswertung der Bandbreite mit SNMP und MRTG Das Kürzel MRTG steht für »Multi Router Traffic Grapher«. Wie bereits angesprochen, können Sie über das UDP fremde snmpd-Server abfragen. MRTG lässt sich natürlich auf dem eigentlichen Webserver auch direkt einsetzen. Die Installation ist dank vorbereiteter Pakete für gängige Linux-Distributionen und OpenBSD-Systeme kein Problem. Mit cfgmaker können Sie das Grundgerüst Ihrer späteren Konfiguration erstellen und gleichzeitig die Einstellungen zur Überwachung der Auslastung Ihrer Netzwerkkarte erzeugen:
cfgmaker [email protected] --ifref=eth0 \ --output=/etc/mrtg.conf Beachten Sie, dass MRTG entgegen der eigentlichen SNMP-Sprache [email protected] verwendet. Werfen wir nun einen Blick auf die Zeilen der frisch erstellten Konfigurationsdatei:
### Global Config Options # for UNIX # WorkDir: /home/http/mrtg Das Verzeichnis mit den mrtg-Ausgabedaten sollten Sie über mod_auth oder eine andere Methode vor allgemeinem Zugriff schützen. Selbstverständlich ist der Pfad an Ihr System anzupassen und das Kommentarzeichen zu entfernen.
# get bits instead of bytes and graphs growing to the right # Options[_]: growright, bits In der Voreinstellung zeichnet MRTG seine Diagramme von rechts nach links. Um diese merkwürdige Voreinstellung richtig zu stellen, ist Options[_]: growright zu verwenden.
### Interface 3 >> Descr: 'sis0' | Name: '' | \ Ip: '192.168.0.32' | Eth: '00–02-e3–22-a7-b0' ### Target[127.0.0.1_3]: 3:[email protected]:
296
Verwaltung und Administration
1 2 Über die Target-Zeile werden die eigentlichen Informationen bezogen. In der spitzen Klammer steht lediglich ein Name zum späteren Zugriff. Sie könnten hier auch netzwerk-interface oder etwas anderes eintragen.
3 4
SetEnv[127.0.0.1_3]: MRTG_INT_IP="192.168.0.32" MRTG_INT_ DESCR="sis0" MaxBytes[127.0.0.1_3]: 12500000
5
Der Netzwerkkarte steht eine Bandbreite von insgesamt 12 500 000 Byte alias 100 Mbit zur Verfügung. Achten Sie auf korrekte Umrechnung (siehe Abschnitt 2.3.2, Dateigrößen und Zahlensysteme), wenn Sie diesen Wert anpassen müssen.
6 7
Title[127.0.0.1_3]: Traffic Analysis for 3 -- openbsd.home PageTop[127.0.0.1_3]: Traffic Analysis for 3 -- openbsd.home
...
8 9 10
Ab Title werden lediglich grundsätzliche Informationen über eine simple HTML-Tabelle formatiert. Die eigentlichen Diagramme werden unterhalb dieser Informationen ausgegeben. Die Angabe einer Überschrift (PageTOP und Title) ist Pflicht. Die Tabelle kann jedoch auch einfach auskommentiert oder gelöscht werden.
11 12 13
Hinweis Fügen Sie die Zeile:
14
LoadMIBs: /usr/share/snmp/mibs/UCD-SNMP-MIB.txt am Anfang Ihrer mrtg.conf-Datei ein, da mrtg sonst eventuell einige SNMPWerte nicht finden kann. Der Pfad zu UCD-SNMP-MIB.txt kann auf Ihrem System abweichen. Nutzen Sie gegebenenfalls locate oder find, um den korrekten Pfad in Erfahrung zu bringen. Starten Sie mrtg über mrtg /etc/mrtg.conf. Keine Sorge, die Fehlermeldungen (could not read the primary log file) besagen lediglich, dass keine vorherigen Informationen vorlagen. Ein Blick in das mrtg-Verzeichnis bringt Aufklärung:
-bash-2.05b# ls /var/www/htdocs/mrtg/ 127.0.0.1_3-day.png 127.0.0.1_3-week.png 127.0.0.1_3.html 127.0.0.1_3-month.png 127.0.0.1_3-year.png 127.0.0.1_3.log
Systemüberwachung
297
Rufen Sie mrtg /etc/mrtg.conf erneut auf. Nun werden Sie nochmals mit einer Fehlermeldung konfrontiert, da noch keine Altdaten vorlagen: »Rateup WARNING: /usr/local/bin/rateup Can't remove 127.0.0.1_3.old updating log file« ist daher keine weitere Beachtung zu schenken. Erst nach dem dritten mrtg /etc/mrtg.conf-Aufruf wird sich das Programm nicht mehr beschweren, da sämtliche Daten geschrieben wurden. Rufen Sie die Bandbreitenstatistik im Browser auf. Selbstverständlich werden Sie noch keine Daten entdecken können. Dazu gilt es, mrtg alle fünf Minuten über einen Cron-Job aufzurufen oder als Hintergrundprozess zu starten (siehe Abschnitt Inbetriebnahme von MRTG in diesem Kapitel). Die fehlenden PNGBilddaten sind im mrtg-Paket Ihrer Distribution bereits enthalten. Kopieren Sie die Grafiken einfach ins gewünschte Verzeichnis.
Abbildung 4.1 Die mühevolle Konfiguration von MRTG wird mit aussagekräftigen Systemstatistiken, die detailliert auf Leistungsspitzen und Engpässe im Server-Betrieb hinweisen, belohnt.
Auswertung der CPU-Last Die MIB-OID ssCpuRawSystem.0 enthält Informationen zur CPU-Auslastung durch Systemprozesse. Über ssCpuRawUser.0 wird die CPU-Belastung durch User-Prozesse erfasst. MRTG bietet Ihnen die Möglichkeit, snmpd-Anfragen zu kombinieren und so ein Diagramm über die Gesamtauslastung der CPU zu erstellen:
298
Verwaltung und Administration
1 2 Target[cpu_check]: .1.3.6.1.4.1.2021.11.50.0& \ .1.3.6.1.4.1.2021.11.52.0:[email protected] MaxBytes[cpu_check]: 100 PageTop[cpu_check]: CPU Auslastung in Prozent
ShortLegend[cpu_check]: % Title[cpu_check]: CPU Belastung Legend1[cpu_check]: user CPU time Legend2[cpu_check]: system CPU time
3 4 5 6
Sie ahnen es bereits: Der Wert 100 unter MaxBytes wurde verwendet, weil wir mit Prozent arbeiten und 100 Prozent der maximal Wert ist. Sie könnten ebenso gut Promille zur Berechnung verwenden, indem Sie unter MaxBytes den Wert 1 000 eintragen.
7 8
Gewöhnungsbedürftig ist, dass der grüne, mit »user CPU time« beschriftete Wert, eigentlich zusammen mit dem als »system CPU time« titulierten blauen Wert die gesamte Systemauslastung darstellt. In der Grafik werden diese beiden Werte jedoch kombiniert. Der Rand wird lediglich zur besseren Visualisierung blau gezeichnet. Wer tiefer in MRTG einsteigt, wird sicher Möglichkeiten finden, diesen Schönheitsfehler in Beschriftung und Darstellung auszugleichen.
9 10 11 12
Wichtiger sind jedoch die merkwürdigen Zahlenkombinationen der ersten Zeile Target. Da MRTG Probleme mit den Kürzeln ssCpuRaw*.0 hat (Unknown SNMP var), sind die MIB-OIDs über smtptranslate zu ermitteln:
13
-bash-2.05b# snmptranslate -Td -Ib 'ssCPURawSystem' .1.3.6.1.4.1.2021.11.52 ssCpuRawSystem OBJECT-TYPE -- FROM UCD-SNMP-MIB SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "system CPU time." -bash-2.05b# snmptranslate -Td -Ib 'ssCPURawUser' .1.3.6.1.4.1.2021.11.50 ssCpuRawUser OBJECT-TYPE -- FROM UCD-SNMP-MIB SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "user CPU time."
Systemüberwachung
14
299
Wie Sie sehen, ist dies alles keine Hexerei. Nach dem Speichern der Zeilen in der Konfigurationsdatei müssen Sie mrtg /etc/mrtg.conf erneut zweimal aufrufen, um die Grunddaten zu erstellen. Die System-Load Über den Befehl uptime erhalten Sie nicht nur Informationen über die erreichte Online-Zeit seit dem letzten Reboot, sondern auch über die Systembelastung (Load), die sich aus der Prozessbelastung, der Festplattenaktivität und der Speicherverwaltung zusammensetzt:
-bash-2.05b# uptime 9:08PM up 13:43, 1 user, load averages: 0.57, 0.29, 0.08 Load Avarage wird für 1 Minute (0.57), 5 Minuten (0.29) sowie 15 Minuten (0.08) ermittelt. Solange der Wert unter 1.00 liegt, entstehen keine Verzögerungen bei der Bearbeitung von Anfragen. UNIX-Systeme kommen durchaus mit permanent hohen Belastungen und Load-Werten von über 25.00 im 15Minuten-Durchschnitt zurecht. Allerdings sollte ein Webserver nur kurzfristig mehr als 1.0 erreichen.
Target[load]: .1.3.6.1.4.1.2021.10.1.5.2& \ .1.3.6.1.4.1.2021.10.1.5.2:compass@localhost Options[load]: nopercent,gauge,noinfo,growright Title[load]: System Load * 100 PageTop[load]: System Load * 100
MaxBytes[load]: 100 YLegend[load]: Load * 100 ShortLegend[load]: (wert = *100) Legend1[load]: System load * 100 Legend3[load]: Maximum system load * 100 LegendI[load]: Sys load LegendO[load]: Sys load Mit diesen Konfigurationsoptionen können Sie in MRTG System-Load zuverlässig ermitteln. Es ist notwendig, System-Load mit dem Faktor 100 zu multiplizieren, da MRTG mit der Darstellung kleinerer Werte nicht gut zurechtkommt. Die doppelte Nennung von laLoadInt.2 (.1.3.6.1.4.1.2021.10.1.5.2) unter Target ist notwendig, da MRTG mit zwei Werten arbeitet (ein- und ausgehender Traffic). Ist Ihr Server tatsächlich längere Zeit belastet, ohne dass viel »geswappt« wird, und sind die CPU-Ressourcen ebenfalls nicht voll ausgelastet, dann liegt eine hohe Load höchstwahrscheinlich an einer zu langsamen Festplatte (prüfen Sie
300
Verwaltung und Administration
1 2 bei einer IDE-Platte, ob DMA aktiviert wurde – siehe Abschnitt 2.1.8, So helfen Sie lahmen IDE-Festplatten auf die Sprünge (DMA-Modus)). In diesem Moment stehen Ihnen mehrere Möglichkeiten offen, die bei Bedarf kombiniert werden können:
3 4
왘 Eine schnellere Festplatte einbauen oder eine zweite Festplatte nutzen und
5
lediglich die Homepage-Daten über die neue Harddisk mounten. 왘 Ein Raid-0-System verwenden (siehe Abschnitt 4.15, Raid-Systeme).
6
왘 Dienste wie DNS- und Mailserver oder gut besuchte Homepages selektiv auf
einen zweiten Server auslagern.
7
왘 Wenn zwei Rechner nicht mehr ausreichen, um die Systemlast zu bewälti-
gen, wird ab dem dritten die Möglichkeit des Loadbalancings (siehe Abschnitt 4.11, Loadbalancing) interessant.
8 9
Überwachung von Arbeits- und Swap-Speicher Der Arbeitsspeicher ist in Server-Systemen üblicherweise kleiner als der zur Verfügung stehende Speicherriegel vermuten lässt. Dies liegt daran, dass im Normalfall ein kleiner Teil als Grafikkartenspeicher ausgelagert werden muss.
10 11
enterprises.ucdavis.memory.memTotalReal.0 = 2613801 enterprises.ucdavis.memory.memAvailReal.0 = 214516
12
Der tatsächlich genutzte Arbeitsspeicher ist die Differenz zwischen memTotalReal und memAvailReal. Die entsprechenden MRTG-Konfigurationszeilen sehen wie folgt aus:
13 14
Target[ram_used]: memTotalReal.0&memTotalReal.0: \ [email protected] - memAvailReal.0&\ memAvailReal.0:[email protected] MaxBytes[ram_used]: 261380 Title[ram_used]: Genutzter Arbeitsspeicher PageTop[ram_used]: genutzter Arbeitsspeicher
YLegend[ram_used]: Arbeitsspeicher ShortLegend[ram_used]: B kMG[ram_used]: K,M,G Options[ram_used]: growright,gauge,nopercent Analog zur Überwachung des Arbeitsspeichers sollten Sie den Swap-Verbrauch mit MRTG messen. Falls der tatsächlich genutzte Swap-Speicher längere Zeit über 64 MB liegt, bei gleichzeitiger voller Auslastung des Arbeitsspeichers, sollten Sie eine RAM-Erweiterung in Betracht ziehen. Die Konfiguration von
Systemüberwachung
301
MRTG zur SWAP-Überwachung ist analog zu der des Arbeitsspeichers vorzunehmen. Lediglich Beschriftungen sind neben Target anzupassen:
enterprises.ucdavis.memory.memTotalSwap.0 = 307436 enterprises.ucdavis.memory.memAvailSwap.0 = 298217 Inbetriebnahme von MRTG MRTG muss alle fünf Minuten ausgeführt werden, um die benötigten Systemdaten regelmäßig sammeln und auswerten zu können. Dies ist über einen Cron-Job möglich, doch ist es aus Gründen der Ressourcen besser, MRTG als Daemon zu starten. Ergänzen Sie deshalb Ihre mrtg.conf um die Zeilen
RunAsDaemon:Yes Interval:5 Rufen Sie danach MRTG wie gewohnt auf. Nun startet MRTG mit der Meldung »Daemonizing MRTG ...« als Hintergrundprozess. Es ist mühevoll, die einzelnen Statistiken manuell im Browser aufrufen zu müssen. Trotzdem ist es oft hilfreich, alle Tagesstatistiken auf einen Blick im Browser zu sehen, um so gegebenenfalls ungewöhnliche Werte sofort erkennen zu können. Zusammen mit dem MRTG-Paket wurde das Programm indexmaker installiert, das genau diese Aufgabe meistert. Ein simpler Aufruf von indexmaker /etc/mrtg.conf > /pfad/mrtg_webdaten/index.html genügt, um eine übersichtliche Startseite zu generieren, die mit den aktuellsten Tagesdiagrammen verknüpft wird. Abschließende Hinweise zu MRTG Die bisher gezeigten Beispiele sollten Ihnen die Überwachung aller für Sie interessanten und über snmpd verfügbaren Systeminformationen ermöglichen. Häufig ist http://crc.somix.com/cgi-bin/Mib2Mrtg.exe eine hilfreiche Anlaufstelle. Hier finden Sie viele gute Beispiele. Die Beispielkonfigurationen von http://www.laukas.com/mrtg/index.php gefallen mir auch sehr gut. Hier finden Sie zudem umfangreiche Denkanstöße zum Anpassen von Farben und Legenden. Wer eine detaillierte Anleitung zu MRTG sucht, sollte einen Blick auf http://www.enterastream.com/whitepapers/mrtg/mrtg-manual.html und http://www.netmon.org/mrtg/dummies/default.htm werfen. Ausfälle Ihres Servers entstehen häufig durch externe Schwierigkeiten mit Switches oder Routern. Im Normalfall können Sie sich auf die Hardware Ihres
302
Verwaltung und Administration
1 2 Servers recht gut verlassen. Da ein ausfallsicheres Raid-System die Server-Kosten nach oben treiben würde, liegt die größte Gefahr in der Nutzung einer einzelnen Festplatte.
3 4
Eine Überprüfung von Lüfterdrehzahl und CPU-Temperatur ist nicht unbedingt notwendig. Wer jedoch einen älteren Server besitzt oder ein hochwertiges RAID-System nutzt, sollte mit MRTG die CPU-Temperatur neben der Lüfterdrehzahl überprüfen. Installieren Sie dazu unter Linux die Pakete mrtgutils und lm-sensors. Für OpenBSD steht healthhdc (http://healthd.thehousleys.net) bereit.
5 6 7
4.6
Speicherplatz mit Quotas beschränken 8
Häufig werden Sie den Speicherplatz einzelner Nutzer-Accounts einschränken wollen. Doch ist diese Aufgabe nicht ganz einfach. Unter Linux muss der Kernel mit Quota-Support kompiliert worden sein (siehe Abschnitt 2.9.1, So helfen Sie lahmen IDE-Festplatten auf die Sprünge (DMA-Modus)). Außerdem sind beim Setzen von Quotas einige Regeln zu beachten:
9 10
왘 Quotas können lediglich auf einzelne Partitionen angewandt werden. Eine
11
maximale Obergrenze, die den insgesamt zur Verfügung stehenden Platz aller Partitionen limitiert, gibt es nicht. 왘 Die gewünschte Partition muss mit der Option
12
usrquota und/oder
grpquota gemountet werden.
13
왘 Softlimits dürfen kurzfristig (bis zum Hardlimit) überschritten werden. 왘 Einige Programme, wie die MySQL-Datenbank, kommen mit Quotas nicht
14
zurecht. Sie sollten Quotas deshalb gezielt auf User- und Gruppen-Accounts »echter« Benutzer einschränken. Werden auf einem Webserver gesonderte Partitionen für home, mail und webverzeichnis genutzt, können Sie den Benutzer XY nicht auf maximal 500 MB Festplattenkapazität einschränken, da es festzulegen gilt, wie viel Speicher dem Benutzer XY auf /dev/hda1, /dev/hda2 und so weiter zur Verfügung steht. Weiterhin ist es teilweise problematisch, den Applikationen Speicherplatz über Hardlimits zu entziehen. Insbesondere bei Gruppen-Quotas auf MySQL-Tabellen (Gruppe der jeweiligen MySQL-Datenbank ändern und Quotas für diese Sondergruppe definieren) sollte nur zu Softlimits gegriffen werden. Hardlimits lassen die einzelnen MySQL-Anfragen »hängen« und verbrauchen somit unnötig System-Ressourcen. Andere Applikationen mögen da nicht ganz so empfindlich sein, doch sollten Sie dies vorher sorgfältig testen. Am sichersten ist es deshalb, Quotas auf »echte« User- und Gruppen-Accounts zu
Speicherplatz mit Quotas beschränken
303
beschränken und System-Accounts (wie mysql oder daemon) außen vor zu lassen. Dies zeigt ein weiteres Problem auf: Dateien, die über den Webserver (zum Beispiel durch von Nutzern aufgespielte PHP-Skripte, die ohne suExec ausgeführt werden) erzeugt werden, bleiben bei der Quota-Prüfung außen vor. Theoretisch könnten über ein simples PHP-Skript Dateien durch den User-Account des Webservers einfach dupliziert werden. Danach ist es möglich, die ursprünglichen Dateien zu löschen – und schon steht wieder ausreichend Platz zu Verfügung. Die einzige verlässliche Methode besteht im manuellen Überprüfen durch du -hcf /pfad_zum/userverzeichnis. Falls ein Nutzer die maximal zulässige Größe überschritten hat, können Sie ihn automatisiert auffordern, nicht mehr benötigte Daten zu löschen.
4.6.1
Partition für Quotas vorbereiten
Ergänzen Sie die /etc/fstab um Quota-Optionen für die gewünschten Partitionen: /dev/hda6 /var ext3 defaults,usrquota,grpqoata 0 1 und mounten Sie das Dateisystem neu: mount /var –o remount. Um die Partition /dev/hda6 für den Quota-Support vorzubereiten, sind folgende Befehle auszuführen:
touch /var/quota.group touch /var/quota.user chmod 600 /var/quota.* quotacheck -vug /var Grundsätzlich sind die genannten Schritte für jede Partition, die Quota-Support benötigt, auszuführen. Sie sollten über ein Startskript beim Boot-Vorgang automatisiert erledigt werden. Zum Deaktivieren des Quota-Supports können Sie den Befehl quotaoff /var verwenden.
4.6.2 Quotas erstellen und verwalten Über das Programm edquota sind Quotas user- und gruppenspezifisch editierbar. Geben Sie nach dem Programmnamen -u beziehungsweise nach dem Nutzernamen -g und die Gruppenbezeichnung ein. Zur Bearbeitung öffnet edquota den Editor vi.
Disk quotas for user suse (uid 500): Filesystem blocks soft hard /dev/hda6 4296 0 0
304
Verwaltung und Administration
inodes 104
soft 0
hard 0
1 2 Sie können Soft- und Hardlimits neben dem Speicherplatz auch für die Dateianzahl (inodes) erteilen. Über den Wert 0 wird die Quota-Prüfung eines Wertes deaktiviert. Wie bereits erwähnt, dürfen Softlimits kurzfristig bis zum Hardlimit überschritten werden. Der Zeitraum, der bis zur Ablehnung einer Speicherung weiterer Daten vergehen darf, ist über edquota –t festzulegen:
3 4 5
Time units may be: days, hours, minutes, or seconds Filesystem Block grace period Inode grace period /dev/hda6 7days 7days
6
Die Zeitspanne von sieben Tagen erscheint für ein Webserver-System als zu knapp gewählt. Anstelle von sieben Tagen sind eher 21days empfehlenswert. Das Softlimit sollte als automatische Warnmeldung verstanden werden. Für eine echte Limitierung ist ein Hardlimit zu verwenden.
7 8
4.6.3 Quotas im Betrieb: Übersicht und automatisierte Infomails
9
Eine praktische Übersicht über alle User- und Group-Quotas können Sie über den Befehl repquota –aug aufrufen.
10 11
*** Report for user quotas on device /dev/hda6 Block grace time: 7days; Inode grace time: 7days Block limits File limits User used soft hard grace used soft hard grace -----------------------------------------------------------root -- 1609632 0 0 99263 0 0 ... suse -- 8308 9000 10200 212 0 0
12 13 14
Der Nutzer suse hat in diesem Beispiel das Softlimit fast erreicht. Sobald das Limit vom Nutzer überschritten wird, erhält er die Meldung: »ide0(3,6): warning, user block quota exceeded.« Da diese Terminalnachricht vom User eventuell nicht bemerkt wird (weil er zum Beispiel die Daten per FTP übermittelt und nicht auf die Logmeldungen achtet), bietet sich die automatische Versendung von Infonachrichten über warnquota an. Leider sind die von warnquota erstellten E-Mails in Englisch gehalten. Immerhin besteht die Möglichkeit, Betreff- und Kontaktdaten (E-Mail sowie Telefon) über die Datei /etc/warnquota.conf anzupassen. Danach sollten Sie das Programm als täglichen Cron-Job ausführen.
Speicherplatz mit Quotas beschränken
305
4.7
Automation
Administratoren müssen eine Programmiersprache nicht blind beherrschen. Dennoch gilt es, die Grundlagen der Programmierung in Shell und Perl zu verstehen, um tägliche Arbeitsabläufe so weit als möglich automatisieren zu können. Im Folgenden möchte ich Ihnen die grundlegende Syntax von Shell und Perl näher bringen, ohne auf Besonderheiten wie ncurses (Menüsteuerung für Konsole) oder objektorientierte Programmierung eingehen zu können. Wer aufwändige Programme erstellen will, kommt an einer zusätzlichen Lektüre nicht vorbei.1 Wahrscheinlich fragen Sie sich, warum Sie gleich zwei Skriptsprachen zur Automatisierung von regelmäßigen Arbeitsprozessen erlernen sollen. Prinzipiell können Sie jede Aufgabe ausschließlich mit Shell oder Perl lösen. Leider muss die Shell-Syntax als hässlich bezeichnet werden. Die Möglichkeiten im Umgang mit Variablen sind recht speziell, und obendrein gibt es gravierende Unterschiede zwischen den verschiedenen Shells. Glücklicherweise stehen sämtliche Standard-Shells der unterschiedlichen UNIX-Systeme auf jeder Plattform zur Verfügung. Gegebenenfalls sind zsh, csh, bash oder ksh als zusätzliche Pakete installierbar. Die folgenden Beispiele beziehen sich auf die Linux-StandardShell Bash, die unter OpenBSD nachträglich zu installieren ist. Perl weist ebenfalls mehrere Nachteile auf: Erstens muss vor der Programmausführung der Perl-Interpreter geladen werden (bei Shell ist dies nicht notwendig, da er bereits läuft); zweitens ist es nicht sinnvoll, eine Latte von Systembefehlen in einer simplen Schleife herunterzuleiern, da Perl die Systembefehle über eine zusätzliche Funktion (System oder Exec) ausführen muss und nicht (wie Shell) direkt aufruft. Grundsätzlich gilt: Startskripte und Systembefehle, wie zum Beispiel das Anlegen eines Nutzers, das Kopieren einer »Baustellen-Homepage« oder kleinere Überwachungsskripte, die per Cron-Job Ausgaben zu df -h, mailq und Ähnliches per E-Mail versenden, sind als Shell-Skripte zu realisieren. Perl ist dagegen dank seiner konkurrenzlos schnellen und flexiblen regulären Ausdrücke für die Auswertung von Logfiles prädestiniert. Weiterhin steht über das Modul DBI eine bequeme Schnittstelle zur MySQL-Datenbank bereit, die insbesondere bei komplexeren Abfragen wesentlich praktikabler ist als die Shell-Methode (echo "show databases" | mysql -u root -p=dummy -B). 1 Besonders empfehlenswert sind die Bücher »Shell-Programmierung in UNIX« (Computer & Literatur) sowie »Programmieren mit Perl« (O’Reilly).
306
Verwaltung und Administration
1 2 Für komplexere Aufgaben können Sie Skripte auch kombinieren und über ein Shell-Skript ein Perl-Skript (oder umgekehrt) aufrufen.
3
Die Grundlagen der Programmierung sind einfacher zu erlernen, als es den Anschein hat. Für die meisten administrativen Aufgaben genügt bereits Grundwissen zur Ablaufsteuerung und Behandlung von Variablen.
4 5
Doch eine wirklich systemnahe Programmierung für Treiber oder Anpassungsarbeiten am Quellcode der (meisten) UNIX-Programme ist mit einer Skriptsprache nicht möglich. Für diese Aufgaben führt unter UNIX kein Weg an C/C++ vorbei. Wer diese Sprache erlernt, kann dann sogar den Kernel des Betriebssystems um eigene Codezeilen oder elementare Systemprogramme wie den Mailserver oder Apache um eigene Ideen erweitern.
4.7.1
6 7 8
Einführung in die Shell-Programmierung
9
Das Schöne an der Shell-Programmierung ist, dass Sie bereits mit dem Terminal arbeiten können und alle bereits erlernten Funktionen zur Ausgabeumleitung, Dateibearbeitung und sämtliche Systemprogramme wie date, cat, cut, cp, rm ... sofort einsetzen können.
10
Sie können also bereits einfache Shell-Programme schreiben: Öffnen Sie einen beliebigen Texteditor und fügen Sie die automatisiert auszuführenden Befehle ein. Um beispielsweise sämtliche Dateien, die älter als sechs Wochen sind, aus dem Verzeichnis /home/test zu löschen, genügt die Zeile:
12
11
13
rm 'find /home/test/* -mtime +1008'
14
Sie können dieses Shell-Programm über bash Programmname aufrufen. Um das Skript wie ein »richtiges« Programm einfach über die Eingabe des Namens auszuführen, ist neben einem chmod 700 Programmname die Ergänzung des Quellcodes um die Startzeile #!/bin/bash notwendig. Liegt das Shell-Skript in einem Verzeichnis von echo $PATH, können Sie es bereits über die Eingabe des Namens aufrufen. Ansonsten ist das Skript in ein entsprechendes Verzeichnis zu verschieben oder die Variable $PATH, wie in Abschnitt 2.4.7, Setzen von Umgebungsvariablen, beschrieben, zu erweitern. Variablen Über Variablen können Dateien umbenannt oder ausgelesene Werte weiter verarbeitet werden. Sie können einem Shell-Skript Positionsvariablen nach dem Programmnamen übergeben:
sh ./programmname erste "zweite Variable"
Automation
307
Besteht eine Positionsvariable aus zwei Wörtern, müssen Sie Anführungszeichen verwenden, da Shell sonst jedes Wort als eine Variable auffasst. Das folgende Programm gibt die übergebenen Positionsvariablen aus:
#!/bin/bash echo erste Variable: $1 echo zweite Variable: $2 echo alle Variablen: $* Dieses simple Beispiel ist natürlich nicht sonderlich nützlich. Wenn Sie jedoch das Einführungsbeispiel unseres kleinen Löschskripts um eine Positionsvariable erweitern, erhalten Sie ein »mächtiges Programm«, mit dem gezielt sämtliche ältere Dateien eines Verzeichnisses gelöscht werden können. Dieses Beispiel zeigt, dass eine Fehlbedienung Ihr gesamtes Dateisystem zerstören könnte. Der mögliche Wirkungsbereich von Shell-Skripten muss deshalb gezielt eingeschränkt werden. Pfade sind grundsätzlich so weit wie möglich anzugeben. Beispielsweise könnten Sie ein Löschskript auf /pfad/$1/ftp/log/* einschränken, um ältere Webalizer-Statistiken aus den Logdirs eines Kundenverzeichnisses zu entfernen. Nun wird der find-Befehl lediglich dann Dateien zum Löschen entdecken, wenn $1 ein existierender Verzeichnisname ist.
#!/bin/bash rm 'find /usr/local/httpd/$1/ftp/log/*gz -mtime +9000' Glücklicherweise sind Sie nicht auf die Übergabe von Positionsvariablen angewiesen. Sie können über set selbst Positionsvariablen erstellen:
#!/bin/bash set -- 'date' echo Heute ist der $3.$2 $6. echo Es ist genau $4 Uhr! Bei der Erstellung einzelner Positionsvariablen nutzt Shell den »Leerraum« als Trennzeichen. Sie können auch andere Trennzeichen definieren und so beispielsweise Zeilen wie: »user:x:507:65534::/home/user:/bin/bash« bequem in Nutzernamen, UserID, Home-Verzeichnis und so weiter zerlegen:
#!/bin/bash IFS=: set -- 'grep "$1" /etc/passwd' echo Der User $1 hat die UID $3 und die GID $4 Mit IFS= können Sie ein Trennzeichen (im Beispiel den Doppelpunkt:) definieren. Danach wird über grep nach der dem Skript zu übergebenden Positionsva-
308
Verwaltung und Administration
1 2 riablen gesucht. Sie müssen nicht unbedingt den Nutzernamen übergeben, sondern können auch gezielt nach einer bestimmten ID suchen.
3
IFS ist also sehr praktisch. Allerdings sollte es nur dann verwendet werden, wenn der Ausgabewert tatsächlich vollständig benötigt wird. Um lediglich alle Nutzernamen auszugeben, sollten Sie lieber cut verwenden: cut -d : -f 1
4 5
/etc/passwd Positionsvariablen besitzen den großen Nachteil, dass sie nur einmal definiert werden können beziehungsweise alte Positionsvariablen bei Übergabe neuer verloren gehen. Außerdem ist der Aufruf vieler Positionsvariablen über »ihre Nummern« wenig intuitiv und eine häufige Fehlerquelle. Sie können in Shell jedoch beliebige Namen für die Variablen vergeben:
6 7 8
#!/bin/bash Jahr='date +%Y' echo Wir schreiben das Jahr $Jahr!
9 10
Falls Sie bereits eine andere Sprache beherrschen, wird Ihnen aufgefallen sein, dass Positionsvariablen wie Arrays sind. Glücklicherweise sind Sie nicht auf Positionsvariablen angewiesen. Sie können »echte Arrays« definieren:
11
#!/bin/bash c=1 test[0]="Hallo" test[$c]="Guten Tag" test[2]="und Tschüß" echo Der erste Array Wert von test: ${test[0]} echo Der zweite Array Wert von test: ${test[$c]} echo Der dritte Array Wert von test: ${test[2]} echo Alle Werte des Arrays test: ${test[*]}
12 13 14
Das Beispiel mit $c für das zweite Array (Ziffer 1) zeigt, dass Sie auf eine Variable zur Definition sowie zum Auslesen von Array-Werten zurückgreifen können. Dies ist nützlich, um ein Array aus Positionsvariablen zu bilden oder sämtliche Array-Werte in einer Schleife auszulesen. Komplexere Shell-Skripte erfordern häufig mehrere Benutzereingaben. Um nicht sämtliche Informationen als Positionsvariable übergeben zu müssen, können Sie read nutzen:
echo -n "Name: " read name echo "Ihr Name ist $name!"
Automation
309
Ablaufsteuerung Es wäre sehr aufwändig, Abläufe, die auf mehrere unterschiedliche Ordner anzuwenden sind, entsprechend häufig wiederholen zu müssen. Flexibler und schneller geht es mit einer Schleife. Um beispielsweise den Ordner /home/beispieldaten in jedes Webverzeichnis zu kopieren und den Eigentümer entsprechend umzusetzen, genügen folgende Programmzeilen:
#!/bin/bash copy="beispieldaten" to_copy="/home/$copy" cd /usr/local/httpd/htdocs set -- 'find * -type d -maxdepth 0' while test -n "$1" do cp –rp $to_copy /usr/local/httpd/htdocs/$1/ chown -R $1 /usr/local/httpd/htdocs/$1/$copy shift done Interessant ist der Befehl shift. Er dient dazu, die Positionsvariablen zu durchlaufen. Sobald eine Variable leer ist, wird die Programmschleife beendet. Die Prüfung der Variablen wird mit test erledigt (siehe auch man test). Die eigentliche Schleife besteht aus
while [Bedingung] do ... done Sämtliche Befehle, die zwischen do und done stehen, werden so häufig ausgeführt, bis die Bedingung nicht mehr erfüllt ist. Neben einer Prüfung auf die Existenz einer Variablen können Sie zudem mit mathematischen Funktionen arbeiten und so eine Schleife x-mal ausführen oder bis zum Erreichen eines bestimmten Wertes durchlaufen lassen. Die von anderen Programmiersprachen bekannte For-Schleife unterstützt die Bash seit Version 2.04:
for (( x=1; x<11; x++)) do echo Wert = $x done
310
Verwaltung und Administration
1 2 Diese Schleife zählt von 1 bis 10. Selbstverständlich stehen Ihnen die mathematischen Grundfunktionen über let (man let) auch zur Verfügung:
3
a=5 b=3 let plus=a+b let minus=a-b let mul=a*b let dev=a/b echo $a + $b = $plus echo $a - $b = $minus echo $a \* $b = $mul echo $a / $b = $dev
4 5 6 7 8
Wenn Sie das Beispiel ausprobieren, werden Sie über die Ausgabe von a$/$b erstaunt sein: 1 ist nicht wirklich korrekt. Wer bereits eine andere Sprache erlernt hat, ahnt es: Shell nutzt lediglich ganze Zahlen. Wenn es unbedingt notwendig ist, können Sie mit Dezimalwerten rechnen. Hierzu sind die Variablen zunächst über typeset –F name_der_Variable als Fließkommazahlen zu initialisieren. Leider kann die Bash2 noch nicht mit Fließkommazahlen arbeiten. Sie müssen auf Z- oder Korn-Shell (wenn Perl für die Aufgabe nicht ohnehin besser geeignet ist) ausweichen.
9 10 11 12
if-then-else sind wohl die bekanntesten Kürzel zur Ablaufsteuerung. Auch in Shell können Sie darauf zurückgreifen. Die Syntax lautet:
13
if [Bedingung] then ... elif [Bedingung] then ... else ... fi
14
Shell-Skripte sind häufig kurz und übersichtlich. Meist werden nur ein oder zwei Befehle mit Bedingungen verknüpft. Neben der herkömmlichen if-thenelse-Methodik stehen Ihnen in Shell auch die case-Bedingungen zur Verfügung, die üblicherweise bei den Startskripten Verwendung finden. Interessant ist, dass Sie in case-Abfragen die Wildcard einsetzen können, um eine Variable zu prüfen. Darüber hinaus können Sie eine Wildcard auch als eine else-Bedingung setzen:
Automation
311
case "$1" in start) echo "Positions-Variable eins = start" sto*) echo "Positions-Variable eins beginnt mit \"sto\"" *) echo "Positions-Variable ist weder start noch beginnt" echo "sie mit \"sto\". Der Wert ist: $1" ;; esac Wenn $1 weder »start« lautet noch mit »sto« beginnt, dann wird der letzte echo-Befehl ausgeführt. Allerdings eignen sich case-Abfragen lediglich für Textprüfungen. Passt der auszuführende Befehl in eine Zeile, werden die abschließenden doppelten Semikolons der »Sternchen-Bedingung« nicht benötigt. Wenn Sie einen Wert auf größer, kleiner oder ist prüfen möchten, führt an test in einem if-then-else-Abschnitt kein Weg vorbei.
case $1 in [1–9]) if test $1 -gt 5 then echo $1 ist größer als fünf. elif test $1 -eq 3 then echo $1 ist ganz genau drei. elif test $1 -lt 5 then echo $1 ist kleiner als fünf. else echo $1 = fünf fi ;; *) Geben Sie eine Zahl von 1 bis 9 ein! esac Sehr gewöhnungsbedürftig sind die Vergleichsoperatoren. Glücklicherweise sind diese für Zeichenketten in der Shell- und Perl-Programmierung identisch, so dass Sie sie nur einmal erlernen müssen. Tabelle 4.5 bietet eine Übersicht über alle Operatoren. Achten Sie darauf, in der Shell-Programmierung vor den Vergleichsoperator zusätzlich ein Minuszeichen zu stellen. Die Kürzel stehen übrigens für greater than (gt) beziehungsweise greater equal (ge) sowie less equal (le) und less than (lt).
312
Verwaltung und Administration
1 2 Operator
Zahl (nur bei Perl)
Zeichen (und Zahl bei Shell)
x gleich y
==
eq
x ungleich y
!=
ne
x kleiner als y
<
lt
x kleiner gleich y
<=
le
x größer als y
>
gt
x größer gleich y
>=
ge
3 4 5 6 7
Tabelle 4.5 Übersicht über alle Vergleichsoperatoren für Zeichenketten in der Shell- und PerlProgrammierung
8 Text mit sed ersetzen Der Stream Editor (sed) zählt zu den ältesten UNIX-Tools. Mit ihm wurden bereits Texte bearbeitet, als es Editoren wie vi oder emacs noch nicht gab. Aufgrund seiner Unhandlichkeit wird sed nicht mehr zur manuellen Bearbeitung von Texten verwendet, aber Shell-Skripte können über sed mit mächtigen Editierbefehlen erweitert werden.
9 10 11
Ähnlich wie die Suchen-und-Ersetzen-Funktion von vi sieht auch die Syntax von Sed aus. Mit s/Suchbegriff/neuer Begriff/g werden sämtliche Vorkommen von »Suchbegriff« durch »neuer Begriff« ersetzt. Um sed in einem Shell-Skript nutzen zu können, müssen Sie zudem die Option -e beim Aufruf angeben.
12 13 14
Weiterhin gilt zu beachten, dass sed Dateien zeilenweise ausliest und in STDOUT schreibt. Ein einfaches Umleiten in die Zieldatei ist somit nur dann möglich, wenn die zu ersetzenden Textstellen in eine andere Datei geschrieben werden als die, aus der sie gelesen werden. Meist ist die Ausgabe deshalb in einer temporäre Datei zu sichern. Nachdem sed sämtliche Zeilen bearbeitet hat, können Sie die Änderungen über cat tmp > zieldatei && rm tmp in die eigentliche Datei übernehmen und die temporäre Datei löschen. Ein gutes Beispiel für sed ist die automatisierte Erstellung von Domain-Zonendateien für bind. Hierzu wird ein Muster mit sämtlichen Werten für MX, NS und so weiter angelegt. Gleichzeitig sind in das Muster Platzhalterbegriffe aufzunehmen, die dann mit sed durch die richtigen Angaben – wie beispielsweise den Domain-Namen – ersetzt werden müssen. Da die Ausgabe in eine neue Datei erfolgt, können Sie sich das Erzeugen einer temporären Datei auch sparen.
Automation
313
sed -e "s/muster.domain/$1/g" \ /etc/bind/db.muster.domain > /etc/bind/db.$1 Sämtliche Vorkommen von muster.domain und der Datei db.muster.domain werden durch die Variable $1 ersetzt und als db.$1 gesichert. Wird g am Ende der Substitutionsanweisung weggelassen (s/suchen/ersetzen/), wird lediglich das erste Vorkommen ersetzt.
4.7.2
Einführung in die Perl-Programmierung
Ähnlich unkompliziert wie in der Shell-Programmierung sind die ersten Schritte mit Perl. Speichern Sie mit Ihrem bevorzugten Editor die Zeile:
print "Hallo Welt!\n" und rufen Sie das Programm über perl Programmname auf. Wie in der ShellProgrammierung können Sie das Programm über chmod 700 programmname ausführbar machen. Damit Perl beim Programmaufruf gestartet wird, ist das Skript um die Startzeile:
#!/usr/bin/perl zu ergänzen. Möchten Sie das Programm über Programmname anstatt durch die Eingabe /pfad/programmname aufrufen, ist PATH, wie in Abschnitt 2.4.7, Setzen von Umgebungsvariablen, beschrieben, zu erweitern oder das Programm in einen bereits aufgenommenen Pfad zu verschieben. Variablen In Perl wird zwischen undefinierten Variablen, leeren oder solchen mit Werten unterschieden. Undefinierte Variablen entpuppen sich in der Praxis meist als Tippfehler. Lediglich bei »interaktiven Benutzereingaben« kann durch einen Abbruch ebenfalls eine undefinierte Variable entstehen. Um detailliertere Hinweise zur Skriptausführung zu erhalten, sollte Perl mit der Option -w aufgerufen werden:
#!/usr/bin/perl –w my $defvar="Wert"; my $name="mein Name"; print "defvar: $defvar \n"; print "Name: $nam \n"; Ein Aufruf dieser Skriptzeilen führt zu den Meldungen:
Name "main::nam" used only once: possible typo at ./hallowelt line 6.
314
Verwaltung und Administration
1 2 Use of uninitialized value in concatenation (.) or string at ./hallowelt line 6.
3
Das Programm wurde trotz der Warnmeldungen erwartungsgemäß ausgeführt. Kommt die undefinierte Variable $unknown an weiteren Stellen vor, entfällt die erste Warnmeldung, und es werden lediglich für alle Zeilen, in denen die Variable verwendet wurde, »uninitialized value ...«-Meldungen ausgegeben.
4 5
Wenden wir uns dem eingangs erwähnten Unterschied zwischen einer leeren und einer undefinierten Variablen zu:
6
#!/usr/bin/perl –w print "Eingabe: "; $a = <STDIN>; print "\nSie haben eingegeben: $a";
7
Geben Sie nach der Eingabeaufforderung einen Wert ein, drücken Sie in einem zweiten Lauf direkt Return und brechen Sie die Eingabe über (Strg) + (D) in einem dritten Versuch ab. Letzteres führt zu der Ausgabe:
9 10
Use of uninitialized value in concatenation (.) or string at ./hallowelt line 4..
11
Die Nutzung einer undefinierten Variable gilt als »unsauber«. Sie können Benutzereingaben deshalb mit einer if-Bedingung versehen:
12
if (defined $a) { print "\nSie haben eingegeben: $a"; }
13
8
14
Nun erscheint die Warnmeldung bei einem Abbruch der Benutzereingabe nicht mehr. Wenn Sie das Wort »defined« entfernen, prüft Perl, ob die Variable einen Wert enthält, anstatt sie nach definiert beziehungsweise undefiniert zu überprüfen. Selbstverständlich sind Variablen, die keinen Wert enthalten, ebenfalls undefiniert. Der Zusatz defined wird somit nur dann benötigt, wenn auch leere Variablen berücksichtigt werden sollen. Da die Benutzereingabe über STDIN mit der Return-Taste abgeschlossen wird, übernimmt Perl ebenfalls das Newline-Zeichen. Deshalb können Variablen lediglich dann leer sein, wenn das durch die Return-Taste erzeugte NewlineZeichen entfernt wird. Dies geschieht komplikationslos bei der Eingabe über chomp ($var_name = <STDIN>);. Allerdings entfällt hier die Prüfung, ob der Benutzer die Eingabe unterbrochen hat. Die korrekte Form unseres kleinen Ein- und Ausgabebeispiels lautet somit:
Automation
315
#!/usr/bin/perl -w print "Eingabe: "; if (defined ($a = <STDIN>)) { chomp $a; if ($a) { print "Sie haben eingegeben: $a \n"; } else { print "Sie haben lediglich Return gedrückt.\n"; } } else { print "\nEingabe wurde über Strg+D abgebrochen!\n"; } Durch die zweite if-Bedingung wird die Zeile »Sie haben eingegeben ...« lediglich bei einer tatsächlichen Eingabe ausgegeben. Gerade in Automations-Skripten, die mit Root-Rechten ausgeführt werden, ist es wichtig, diese Feinheiten zu beachten. Ein exec-Befehl wie rm -fr /home/$name würde bei einer defined-Prüfung auch einen leeren String »akzeptieren« und deshalb das gesamte Home-Verzeichnis löschen. Arrays und Hashs
#!/usr/bin/perl -w @array = ("bla", "blub", "blob"); print "Array: $array[0], $array[1], $array[2]\n"; print "Alle Elemente: @array\n"; Mit split können Arrays anhand eines Trennmusters aus einer Variablen komplikationslos erzeugt werden. Über join ist es möglich, ein Array »zu einer einzelnen Variablen« zusammenzusetzen.
#!/usr/bin/perl -w $a="bla,blub,blob"; @array=split(/,/,$a); $join=join(":", @array); print "Array: $array[0], $array[1], $array[2]\n"; print "Join: $join\n"; Die split-Funktion verwendet für die Erstellung der einzelnen Arrayelemente reguläre Ausdrücke. Sie finden in diesem Kapitel im Abschnitt Reguläre Suchmuster und Substitution hierzu nähere Erläuterungen.
316
Verwaltung und Administration
1 2 Hashs sind Arrays sehr ähnlich. Allerdings werden die Werte hier nicht einfach über ihre Positionsnummer angesprochen, sondern über ihren Namen:
3
#!/usr/bin/perl -w %preise = ("Monitor", "300.34", "Tastatur", "19.95", \ "Computer", "1999.99"); print "Der Monitor kostet: $preise{Monitor}, die Tastatur\ ist für $preise{Tastatur} zu haben und der Computer \ wechselt für $preise{Computer} den Besitzer\n"; @konvert=%preise; print "Gesamter Hash: @konvert\n";
4 5 6 7
Die Ausgabe des gesamten Hashs ist über den Umweg einer Konvertierung in ein Array möglich. Sehr interessant ist, dass Sie aus einem Array einen Hash bilden oder Hashs über %kopie = %original duplizieren können.
8 9
Mathematische Funktionen
10
In Perl müssen Variablen für Zahlen nicht gesondert deklariert werden. Zudem unterscheidet Perl nicht zwischen ganzen oder Fließkommazahlen. Somit gestaltet sich die Handhabung arithmetischer Funktionen sehr einfach, wenn Sie beachten, dass Perl mit dem Dezimalpunkt anstelle des in unseren Breitengraden üblichen Kommas arbeitet.
11 12
#!/usr/bin/perl –w print "erste Zahl: "; chomp ($a = <STDIN>); print "zweite Zahl: "; chomp ($b = <STDIN>); $addition = $a + $b; print "\n$a + $b = $addition\n"; print ("$a - $b = ",$a - $b, "\n"); print ("$a * $b = ",$a * $b, "\n"); printf ("$a / $b = %.4f\n", $a / $b);
13 14
Sehr interessant ist die letzte Programmzeile: Mit printf lassen sich Buchstabenund Zahlenausgaben effektiv formatieren. In unserem Beispiel wird der Divisionswert vierstellig ausgegeben und gegebenenfalls gerundet. Weitere Informationen finden Sie über man perlfunc (Textsuche nach printf und sprintf). Ablaufsteuerung Wie in der Shell-Programmierung finden Sie auch in Perl die bekannten while-, for- und if-Schleifen. Allerdings weicht die Syntax von der Shell-Sprache ab. Den-
Automation
317
noch werden Sie die folgenden Beispiele sicher auf Anhieb nachvollziehen können.
#!/usr/bin/perl -w print "Bitte geben Sie eine Zahl kleiner als zehn ein: "; chomp ($a = <STDIN>); while ($a < 10) { print "$a ist kleiner als zehn\n"; $a++; } Dieses einfache Programm addiert so lange den Wert 1 zu der vom Benutzer eingegebenen Zahl hinzu, bis der Wert 10 erreicht ist. Interessant ist die Zeile $a++, die eine Kurzform von $a = $a + 1 ist. Sie können sogar $a+=2 schreiben, um zum Wert $a 2 zu addieren.
#!/usr/bin/perl -w for ($i=10; $i>=0; $i--) { print "$i\n"; } Das einfache Countdown-Skript bedarf keiner weiteren Erklärung. Dies trifft auch für das abschließende Beispiel einer if-, else-if- oder else-Schleife zu.
#!/usr/bin/perl –w print "Eingabe: "; chomp ($a = <STDIN>); if ($a eq "Gutenberg") { print "Der gute Mann erfand den Buchdruck!"; } elsif ($a) { print "Sie haben eingegeben: $a"; } else { print "Sie haben nichts eingegeben!"; } print "\n"; Funktionen Schleifen werden leicht sehr unübersichtlich und verschachtelt. Ab und zu stoßen Sie zudem auf Elemente, die an mehreren Stellen gleichzeitig verwendet werden müssen. Code einfach per Copy-and-Paste zu kopieren, ist zwar schnell erledigt, bei Änderungen muss jedoch daran gedacht werden, auch die übrigen
318
Verwaltung und Administration
1 2 Stellen entsprechend zu erweitern. Dies wird nicht nur leicht vergessen, sondern ist zudem sehr fehleranfällig.
3
Die Lösung aus diesem Dilemma sind Funktionen. Sie können beliebig oft und an beliebiger Stelle aufgerufen und dürfen gesammelt ans Ende oder den Anfang des Perl-Programms geschrieben werden.
4 5
#!/usr/bin/perl -w do { print "Eingabe: "; chomp ($a = <STDIN>); if ($a) { funktion(); } } while ($a); print "Programmende, Eingabe vergessen!\n\n"; sub funktion { print "Sie haben eingegeben: $a\n"; print "------------------------\n"; }
6 7 8 9 10 11
Die do-while-Schleife wird so lange ausgeführt, solange ein Wert vom Nutzer eingegeben wird. Die Funktion funktion wird am Programmende über sub funktionsname definiert. Der Aufruf der Funktion erfolgt dann einfach über
12
funktionsname ();.
13
Häufig ist es unsinnig, Werte direkt in Funktionen auszugeben oder abschließend zu bearbeiten. Über return können Sie einen Rückgabewert verwenden:
14
#!/usr/bin/perl -w $ausgabe = funktion("Karl", "Mustermann"); sub funktion { return "Ihr Vorname: $_[0], Ihr Nachname: $_[1]"; } print "Ausgabe = $ausgabe!\n"; Beachten Sie, dass in der Klammer des Funktionsaufrufs Werte in einem temporären Array übergeben werden können, ohne zunächst Variablen festlegen zu müssen. Reguläre Suchmuster und Substitution Die Geschwindigkeit und Flexibilität von regulären Suchausdrücken gilt als eine der großen Stärken von Perl. Allerdings wird die hohe Flexibilität durch
Automation
319
einen mindestens ebenso großen Lernaufwand für die kryptisch anmutenden regulären Ausdrücke erkauft.
#!/usr/bin/perl -w $bla = "Hallo World!"; $bla =~ s/World/Welt/; print $bla."\n"; Dieses einfache Beispiel ersetzt World durch Welt. Interessanter wird es, wenn Zeichenketten zu ersetzen sind, die in der Länge, aber nicht in den verwendeten Zeichen variieren:
$bla = "big xyx, big badaxxyxyxx"; $bla =~ s/[xy]+/boom/g; $bla wird nach der Substitution zu big boom, big badaboom. Das Pluszeichen steht für beliebig viele Zeichen des angegebenen Musters. Damit mehr als ein Vorkommen ersetzt wird, ist die Substitution mit der zusätzlichen Option -g abzuschließen. Über die spitze Klammer können Sie das Muster auf mehrere Zeichen beschränken. Um sämtliche Ziffern zu berücksichtigen, können Sie sogar [0– 9] verwenden oder für alle Kleinbuchstaben [a-zöäü]. Darüber hinaus sind diese gruppierenden Muster mit Oder-Anweisungen nutz- und kombinierbar. [a-c|0–4][yz|O] würde beispielsweise auf az oder 2O zutreffen, nicht jedoch auf a3, abz oder z0. In der Voreinstellung arbeitet Perl »case sensitive«. Somit wird zwischen Großund Kleinschreibung unterschieden. Weiterhin möchten Sie vielleicht nur wissen, ob ein Suchmuster passt, ohne Ersetzungen durchführen zu wollen. In den nächsten Beispielen möchte ich Ihnen die so genannten Ankermuster vorstellen.
if ($a =~ /\baha\b/) Das Wort »aha« muss in $a vorkommen. Die Prüfung, ob es tatsächlich ein eigenes Wort (allein stehend) ist, wird über das Ankermuster \b erledigt (davor und danach darf außer dem Leerzeichen oder einer Newline kein anderes Zeichen stehen.).
if ($a =~ /ba?c/) $a enthält bc oder bac. Das Fragezeichen steht für keines oder genau ein Zeichen des angegebenen Musters. Verwenden Sie ein Sternchen für keines oder beliebig viele Zeichen des angegebenen Musters. Beachten Sie den Unterschied zum Pluszeichen: Hier muss das Muster mindestens einmal vorkommen.
320
Verwaltung und Administration
1 2 if ($a =~ /oi\b/)
3
In $a endet ein Wort mit »oi«
if ($a =~ /\bHa\B/)
4
Eines der Wörter beginnt mit »Ha«. Beachten Sie, dass der Anker \B prüft, ob das Wort an dieser Stelle nicht über eine Newline oder ein Leerzeichen beendet wird.
5 6
if ($a =~ /^a b c$/)
7
$a ist identisch mit »a b c«. Das Hütchen (^) dient als Muster für den Zeilenanfang; über das $-Zeichen wird das Zeilenende überprüft.
8
if ($a =~ /lust/i) $a enthält »lust«. Groß- und Kleinschreibung wird bei der Prüfung über die Option i ignoriert. Es könnte also auch »lUsT« in $a enthalten sein.
9
if ($a =~ /\b[a-z]{3}\b/)
10
$a enthält mindestens eine Buchstabenfolge, die aus genau drei aufeinander folgenden Buchstaben von a–z besteht.
11
if ($a =~ /\b[a-z]{4,}\b/)
12
$a enthält eine Buchstabenfolge aus mindestens vier aufeinander folgenden Buchstaben von a-z.
13
if ($a =~ /\b[A-Z]{1,4}\b/)
14
prüft, ob $a eine Buchstabenfolge mit mindestens einem, aber höchstens vier aufeinander folgenden Großbuchstaben enthält. Zum Abschluss unserer kleinen Suchmuster-Einführung will ich Ihnen die äußerst nützliche Möglichkeit zur Zwischenspeicherung einzelner Teile eines Suchmusters vorstellen, mit der es beispielsweise möglich ist, IP-Adressen oder Domain-Namen aus einem Logfile herauszufiltern.
($bla) = $a =~ /^([0–9]+\.[0–9]+\.[0–9]+\.[0–9]+)/; Dieses Beispiel würde eine IP-Adresse, die am Zeilenanfang steht (wie zum Beispiel im Apache Log), in den String $bla speichern. Beachten Sie, dass die Speicherung über die runde Klammer initialisiert wird. Sie können auch mit mehreren Zwischenspeichern (jeweils eigene Klammer) arbeiten und die gewünschten Namen der zu erzeugenden Variablen über Kommata getrennt definieren. Wenn auf ($bla) = verzichtet wird, sichert Perl die Werte automatisch als $1, $2, $3 ...
Automation
321
Weitere Beispiele und Informationen zu den komplexen Möglichkeiten der regulären Ausdrucksformen in Perl erhalten Sie über man perlre. Dateien lesen und erstellen Obwohl der Umgang mit Dateien in Perl nicht so einfach und intuitiv wie in der Shell-Programmierung ist, führt häufig kein Weg am Einsatz der Perl-DateiHandels vorbei. Das Auslesen über Systembefehle wäre meist aufwändiger und nicht gerade performant. Falls Sie bereits eine andere Programmiersprache erlernt haben, werden Sie mit der notwendigen Syntax ohnehin vertraut sein:
#!/usr/bin/perl -w open (datei, "< /etc/passwd"); while ($zeile =
#!/usr/bin/perl –w open (datei2, ">> testfile"); flock (datei2, 2); print datei2 "testeintrag\n"; close datei2; Falls Sie nur eine geschlossene spitze Klammer in der open-Zeile verwenden, würde der Inhalt einer bestehenden Datei durch die neuen Zeilen ersetzt. Beachten Sie die Zeile flock (datei2, 2);, über die unsere testfile-Datei für andere Nutzer gesperrt und so ein theoretischer Datenverlust bei gleichzeitiger Bearbeitung verhindert wird. Systembefehle absetzen Mit system ("[BEFEHL]"); können Sie Systembefehle (wie in Shell) mit den Rechten des eingeloggten Nutzers direkt ausführen. Um Tippfehlern bei der
322
Verwaltung und Administration
1 2 Nutzereingabe vorzubeugen und Shell-Escaping zu verhindern, ist es möglich, Befehle und Optionen voneinander zu trennen:
3
#!/usr/bin/perl -w print "Wie viele Sekunden möchten Sie pausieren? "; chomp ($sekunden = <STDIN>); system ("sleep", "$sekunden"); print "Wartezeit vorüber (Systembefehl: \ \"sleep $sekunden"."s\" ausgeführt)!\n";
4 5 6
Die Arbeitsweise wird besser durch ein – absichtlich fehlerhaftes – Skript verdeutlicht:
7 8
#!/usr/bin/perl -w system ("echo das; echo funktioniert"); system ("echo aber das", "echo nicht");
9
Wie Sie sehen, wäre im ersten Fall bei Übergabe einer Variablen das Risiko des Shell-Escapings gegeben. Im zweiten Fall wird jedoch lediglich ein Befehl (der erste) ausgeführt. Danach können ausschließlich Argumente, nicht aber ein weiterer Shell-Befehl übergeben werden.
10 11
Falls Sie den Ausgabewert weiter behandeln möchten, anstatt diesen auf STDOUT direkt auszugeben, können Sie Systembefehle wie in der Shell-Programmierung einfach mit einer Variablen kombinieren:
12 13
$heute= 'date';
14
Kommunikation mit MySQL Mit dem DBI-Modul können Sie die MySQL-Datenbank direkt und recht bequem aus Perl heraus ansprechen. So wird es möglich, sämtliche SQL-Befehle automatisiert abzusenden oder Ausgabeseiten anhand von Datenbankabfragen dynamisch zu erstellen. Das folgende Perl-Skript benötigt neben dem DBI- das DBD::mysql-Modul. Häufig wird dies in der Voreinstellung Ihres Perl-Pakets bereits mit installiert. Falls Sie bei der Programmausführung jedoch die Fehlermeldung »Can't locate DBI.pm in @INC« erhalten, müssen Sie die Pakete DBI und DBD nachträglich installieren. Die aktuellen Debian-, OpenBSD- und SUSE-Versionen bestehen jedoch bereits in den Paketabhängigkeiten bei Installation der MySQL-Clientund Server-Pakete auf die notwendigen Bibliotheken, so dass Sie im Normalfall keine weiteren Installationsarbeiten erledigen müssen. Notfalls finden Sie die benötigten Originalpakete unter http://search.cpan.org/ search?dist=DBDmysql zum Download.
Automation
323
Hinweis zur Kompilierung der Quellen Make test ist ziemlich wackelig, da der Gastzugang und die Tabelle test vorausgesetzt werden. Sie können make test jedoch auch überspringen. Im Normalfall treten dadurch keinerlei Probleme auf.
#!/usr/bin/perl –w use DBI; # Datenbank Zugangsinformationen $USER = "root"; $PASSWORD = "dummy"; $DBASE = "mysql"; #Verbindungsaufbau $dbh = DBI->connect("DBI:mysql:database=$DBASE", \ "$USER", "$PASSWORD", {'RaiseError' => 1}); # Gib Datenfelder User und Host der Tabelle user aus $query = $dbh->prepare("select User, Host \ from user") or die $dbh->errstr(); $query->execute() or die $dbh->errstr; while ($res = $query->fetchrow_hashref()) { print "$res->{'User'} ($res->{'Host'})\n"; } $query->finish(); # Beende Datenbankverbindung. $dbh->disconnect(); Mit dem DBI-Modul wird über Klassen eine Verbindung zur MySQL-Datenbank aufgebaut. Eine vollständige Einführung in die objektorientierte Programmierung würde an dieser Stelle zu weit führen. Dennoch sollten Sie auch ohne Kenntnisse der objektorientierten Programmierung in der Lage sein, das DBIModul erfolgreich zu nutzen.
$dbh = DBI->connect("DBI:mysql:database=$DBASE", \ "$USER", "$PASSWORD", {'RaiseError' => 1}); Der Name $dbh ist beliebig austauschbar und wird bei späteren Abfragen verwendet, um die richtige User-, Passwort- und Datenbank-Kombination zu nutzen. Sie können gleichzeitig mehrere Verbindungen öffnen. Das ist jedoch nur dann sinnvoll, wenn Sie verschiedene Datenbanken bearbeiten müssen.
$query = $dbh->prepare("select User, Host \ from user") or die $dbh->errstr(); $query->execute() or die $dbh->errstr;
324
Verwaltung und Administration
1 2 Um Daten auszulesen, müssen Sie zu ->prepare greifen. In die Klammer ist dann der gewohnte MySQL-Befehl einzutragen; lediglich auf das Semikolon ist zu verzichten. Nach Ausführung von ->execute() wird die MySQL-Ausgabe zeilenweise in $query gespeichert. Um das Ergebnis mit Perl auszugeben, müssen Sie $query zeilenweise in einer Schleife auslesen:
3 4 5
while ($res = $query->fetchrow_hashref()) { print "Name: $res->{'User'} Zugang: $res->{'Host'}\n"; }
6
Selbstverständlich könnten Sie die Ausgabe ansehnlich formatieren und über ein CGI-Skript als HTML-Tabelle darstellen. Viel interessanter ist an dieser Stelle jedoch die Funktionsweise. Die abgefragten Felder stehen über ihren Namen bereit und können über einen Hash bequem ausgelesen werden.
7 8
Wesentlich einfacher als das Auslesen ist das Löschen, Aktualisieren oder Neuerstellen von Datenbankeinträgen. Die folgende Zeile setzt sämtliche Host-Felder der Tabelle user auf localhost.
9 10
$dbh->do("update user set Host='localhost'") \ or die $dbh->errstr();
11
Weitere Informationen zur Kommunikation von MySQL mit dem DBI-Modul von Perl erhalten Sie über man DBD::mysql.
12
CGI-Skripte fürs Web
13
Perl ist neben PHP eine der beliebtesten Skriptsprachen zur Erzeugung dynamischer Websites. Darüber hinaus steht es Ihnen frei, komfortable Administrationsoberflächen zur Erledigung von Routineaufgaben oder eine Sammelstelle für Statistiken zu entwerfen. Prinzipiell sind bei Perl/CGI-Skripten zwei Dinge zu beachten: Die Skripte müssen für den Webserver les- und ausführbar im cgibin-Verzeichnis abgelegt werden, und sie müssen den Header vor der eigentlichen HTML-Ausgabe übertragen:
14
#!/usr/bin/perl -w print "Content-type: text/html\n\n"; print "Hallo Welt!"; Beachten Sie die doppelte Zeilenschaltung nach Content-type. Bevor mit der eigentlichen Ausgabe begonnen werden kann, ist eine Leerzeile zwingend erforderlich. Wird diese vergessen, ist ein »500 Internal Server Error« das einzige Ergebnis auf Seitenanfragen. Ein weiterer wichtiger Punkt besteht in der Möglichkeiten zur Übermittlung von Variablen. Hierzu sollten Sie am besten das param-Element des Perl-Moduls CGI einbinden:
Automation
325
#!/usr/bin/perl -w use CGI qw(param); $name=param(name); print "Content-type: text/html\n\n"; print "Hallo, $name!"; Rufen Sie das Perl-Skript über http://ip-adresse/cgi-bin/scriptname.pl?name=Ihr_Name auf, um die Variable name über den ULR zu übergeben. Man spricht hier von der Get-Methode, die auch in HTML-Formularen neben der Post-Methode genutzt werden kann. Die get-Methode ist allerdings auf »wenige Datenseiten« beschränkt, und die übertragenen Daten stehen in einer hässlichen Form in der Browser-Zeile. Nutzen Sie daher zur Übergabe von Variablen über ein Formular stets die Post-Methode:
Beachten Sie, dass das Formular als HTML-Datei im normalen Webverzeichnis gespeichert werden muss. Alternativ können Sie selbstverständlich auch sämtliche Formulardaten in einem Perl-Programm ausgeben. Falls Sie Administrationsskripte mit Perl über ein Webinterface anbieten wollen, müssen Sie sich unbedingt mit Zugriffsschutz beschäftigen. Als rudimentäre Lösung bietet sich ein Verzeichnisschutz mit .htaccess an. Flexibler und sicherer ist jedoch ein über SSL gesichertes Formular zur Passwortübertragung. Dann können Sie sogar mit verschiedenen Rechtemodellen arbeiten und einzelne Accounts über eine Session-ID identifizieren. Wer mit relativen Pfadangaben arbeitet, könnte als bequeme Lösung die Session-Kennung über einen langen und kryptischen Softlink realisieren, der über at nach x Minuten gelöscht wird.
#!/usr/bin/perl –w use DBI; use CGI qw(param); $passwd=param($passwd); print "Content-type: text/html\n\n"; # Datenbank Zugangsinformationen open (datei1, "< /.perlpass/mysql"); chomp($USER =
326
Verwaltung und Administration
1 2 chomp($PASSWORD =
3 4 5 6 7 8 9 10 11 12 13
Die Passwortüberprüfung wurde hier über die MySQL-Datenbank realisiert. Durch die Systembefehle zum Erzeugen und Löschen eines Softlinks ersparen wir uns die spätere Prüfung der Session-ID, die für einen Administrationsbereich, der lediglich Root zur Verfügung stehen soll, ohnehin wenig sinnvoll ist (entweder es ist alles oder gar nichts erlaubt).
14
Der Softlink wird über pwgen zufällig erstellt und sollte mit seiner Länge von 40 Zeichen (darunter Ziffern und Groß- sowie Kleinbuchstaben) die notwendige Sicherheit bieten, zumal der Softlink bereits nach 15 Minuten wieder gelöscht wird. Interessant dürfte für Sie die Zeile if (defined($res)) sein. Lediglich wenn das Passwort richtig ist, wird auch die Zeile mit dem gewünschten Account gefunden und die Variable res definiert. Eine weitere Besonderheit ist das Einlesen der Zugangsdaten von einer externen Datei. Theoretisch könnte bei einem Fehler in Apache, mod_perl oder in einer versehentlich fehlerhaften Konfiguration das Perl-Skript von Dritten eingesehen werden. Damit dann nicht auch noch das Datenbankpasswort bekannt wird, sollten Sie sich angewöhnen, diese Informationen in einer zusätzlichen Datei abzulegen, die außerhalb der Apache-Verzeichnisse liegt.
Automation
327
4.7.3
Abschließende Anmerkungen und Skriptübersicht
Sichern Sie eigene Perl- und Shell-Skripte unbedingt ab, indem lediglich dem Eigentümer Lese-, Schreib- und Ausführrechte erteilt werden. Group und »jedermann« benötigen keinen Zugriff auf Ihre Skripte. Beachten Sie bei CGI-Skripten die Problematik, dass alle Skripte mit den Rechten des Webservers ausgeführt werden, und denken Sie gegebenenfalls über den Einsatz von suExec nach. Insbesondere bei CGI-Skripten (ob mit oder ohne suExec) gilt es, unbefugte Nutzung über Passwortschutz zu erschweren und einem möglichen Shell-Escaping unbedingt vorzubeugen. Name
Beschreibung
Sprache
Ort
Auto-webalizer.sh
Erstellt Webalizer-Statistiken automatisiert und anonymisiert.
Shell-Skript 3.3.9
Daily-backup.sh
Nutzdaten-Backup.
Shell-Skript 4.8.5
Digestpwd.sh
Generiert Password für Apache-Authentifizierung mit mod_digest.
Shell-Skript 3.3.6
FTPeinmalPwd.pl
Generiert über pwgen ein FTP-Einmalpasswort für ProFTPD- Loginprüfung via MySQL.
Perl-Skript
3.7.7
FTPtraffic.pl
Für monatliche Archivierung der von ProFTPD abgelegten Traffic-Informationen nützlich.
Perl-Skript
3.7.8
Sicherheitstests.jsp
Testet, ob Tomcat missbraucht werden kann.
JSP
3.4.3
Sicherheitstests.php
Prüft Server auf Sicherheitslükken in PHP-Konfiguration.
PHP-Skript
3.3.10
OptimizeSQL.pl
Wendet den MySQL-Befehl optimize table auf sämtliche Tabellen aller Datenbanken an.
Perl-Skript
3.5.2
Tabelle 4.6 Übersicht praxisbezogener Beispiele für Perl- und Shell-Programme. Sie finden die Skripte im Verzeichnis Beispielskripte auf der CD zum Buch.
4.8
Backup
Lediglich ein vollständiges Backup der Server- und Nutzdaten bietet Sicherheit vor einem Festplatten-Crash, ermöglicht das Zurückspielen versehentlich gelöschter Dateien und hilft beim schnellen Aufsetzen eines neuen Servers. Die Frage ist nicht, ob Sie Backups Ihrer Server-Daten anfertigen, sondern wie Sie diese anfertigen. Das richtige Backup-Konzept und die geeignete BackupSoftware ist hingegen nicht ganz so einfach zu finden.
328
Verwaltung und Administration
1 2 Einige Hoster stellen einen Backup-Server zur Verfügung. Hier ist darauf zu achten, ob die Nutzdaten in mehreren kleineren, täglichen Backups abgelegt werden können – neben einem »Voll-Backup« der gesamten Server-Daten. Eine Sicherung der gesamten Server-Daten mit gleichzeitiger Überspielung der Altdaten ist nicht empfehlenswert.
3 4
Häufig können Sie einen Backup-Server nicht flexibel genug ansprechen. Sprechen Sie mit einem Techniker des Dienstleisters über die gewünschten Möglichkeiten, bevor Sie Ihren Vertrag erweitern.
5
4.8.1
7
6
Welche Daten sind zu sichern?
Die Frage nach dem Backup der Nutzdaten ist schnell beantwortet: Sämtliche FTP- und Home-Verzeichnisse sind – neben MySQL-Datenbanktabellen und Konfigurationsdateien – vollständig zu sichern.
8 9
Bei der Einrichtung von Kunden-Accounts sind die entsprechenden Daten entweder vom Backup auszuschließen oder es muss in den AGB auf die Sicherung und Archivierung der jeweiligen Dateien hingewiesen werden.
10
Solange POP3 anstelle von IMAP verwendet wird, ergibt eine Sicherung der Postfächer wenig Sinn. Auch bei IMAP ist eine Sicherung aus datenschutzrechtlichen Gründen problematisch. Dies gilt nicht nur bei Kundendaten, sondern auch bei Mitarbeiter-Accounts. Beachten Sie hierzu Abschnitt 8.2.4, Datenschutzfragen beim Betrieb eines Webservers.
11 12 13
Die Logdateien sollten nach ihren Rotationszyklen archiviert und beim Erstellen eines Archivs direkt per E-Mail versandt werden. Nun müssen Sie beim Backup der Nutzdaten lediglich die laufenden (von Syslogd zur Protokollierung genutzten) Logdaten integrieren. Die komprimierten Archive wurden bereits per E-Mail versandt.
14
Selbst für ein Voll-Backup sind nicht die gesamten Daten zu sichern, da die Nutzdaten bereits in einem getrennten und aktuelleren Backup vorliegen. Außerdem enthalten die Verzeichnisse /tmp und /proc lediglich temporäre Systemdaten und sind über mkdir /tmp; chmod oga+rwxt /tmp && mkdir /proc; chmod 555 /proc nach dem Einspielen des Backups jederzeit verlustfrei zu erzeugen. Im Normalfall können die lost-and-found-Verzeichnisse ignoriert werden.
4.8.2 Wie häufig ist zu sichern? Je nach Nutzung der Accounts bietet sich eine tägliche oder wöchentliche Sicherung der Nutzdaten an. Sie sollten die einzelnen Backups nicht einfach
Backup
329
überspielen, sondern archivieren. Bei täglicher Sicherung könnte der Tag als Archivname genutzt werden. Für den Notfall stünden dann insgesamt sieben Archive bereit, und kleinere Fehler (die Datei XY wurde vor vier Tagen versehentlich gelöscht) sind dadurch im Handumdrehen zu beseitigen. Bei wöchentlicher Datensicherung genügt meist ein zusätzliches Archiv. Je nach Kapazitätsgröße können Sie die Archivzahl erweitern. Das Voll-Backup sollte nach der Einrichtung des Servers angefertigt und bei umfangreichen Änderungsarbeiten an der Software oder nach einer angemessenen Zeitspanne (von einem halben Jahr oder länger) erneuert werden, um beim Einspielen des alten Backups nicht unnötig viel Zeit mit dem erneuten Patchen oder den Downloads wichtiger Sicherheits-Updates zu vergeuden.
4.8.3 Wohin ist zu sichern? Das Voll-Backup sollte keinesfalls auf einem einzelnen Datenträger abgelegt werden, sondern auf mindestens zwei Read-only-Medien (zum Beispiel CDROM oder DVD), die an getrennten Orten aufbewahrt werden. Die Nutzdaten sollten bei lokaler Sicherung auf mindestens zwei Festplatten abgelegt und für zusätzliche Sicherheit monatlich auf ein Read-only-Medium übertragen werden. Die einzelnen Read-only-Medien sollten an getrennten Orten jeweils ein halbes Jahr aufbewahrt werden. Wenn Sie einen Backup-Server nutzen können, sollten Sie auch hier zusätzlich das Voll-Backup auf CD-ROM oder DVD sichern und in einem angemessenen Zeitraum die Nutzdaten zusätzlich auf eine lokale Sicherungsfestplatte übertragen. So haben Sie für einen – unwahrscheinlichen, aber dennoch möglichen – Ausfall des Backup-Servers Notfalldaten bei der Hand. Bänder sind lediglich dann empfehlenswert, wenn mehrere Server-Systeme zu sichern sind und die Server vor Ort zur Verfügung stehen. Häufig bietet sich als Übergangslösung ein entsprechendes Backup durch den Dienstleister selbst an. Die lokale Server-Anbindung lohnt sich nicht (siehe auch Kapitel 7, Der eigene Server). Bedenken Sie, dass selbst Firmen wie Strato kein eigenes Rechenzentrum betreiben.
4.8.4 Womit ist zu sichern? Kommerzielle Backup-Software wie Arkeia (ältere Versionen stehen kostenlos bereit) oder BRU ist nur dann empfehlenswert, wenn gleich eine größere Server-Farm über voluminöse Backup-Bänder zu sichern ist.
330
Verwaltung und Administration
1 2 Ein sehr interessantes Projekt ist das unter GPL stehende Mondo, das afio (eine Alternative zu tar) nutzt und sogar in der Lage ist, eine Boot-CD zu erstellen. Auch AMANDA (Advanced Maryland Automatic Network Disk Archiver), das in der Lage ist, ein Backup automatisiert für mehrere Server anzufertigen, ist einen Blick wert.
3 4 5
Selbst gestrickte Lösungen sind nicht nur kostenlos, sondern wesentlich flexibler als vorbereitete Produkte. Zur Erfüllung ausgefallener oder individueller Backup-Lösungen sind Shell-Skripte unschlagbar. Als hochwertige BackupTools bieten sich für den Eigenbau insbesondere rsync und tar an.
6 7
Tar erzeugt eine Archivdatei, die auf Wunsch komprimiert werden kann, und ist somit für ein Voll-Backup prädestiniert. Allerdings kann es theoretisch vorkommen, dass bei der Komprimierung ein Fehler auftritt und das Archiv dadurch insgesamt »verloren geht«. In der Praxis ist zumindest bei mir dieser Fall noch nie aufgetreten. Dennoch empfiehlt sich ein lokaler Testlauf, nachdem das Archiv auf das Read-only-Medium gespeichert und von diesem Datenträger zurückkopiert wurde.
8 9 10
rsync ist ein äußerst mächtiges Programm, das Dateien und Verzeichnisse über SSH spiegeln kann. Gleichzeitig ist es möglich, die Daten komprimiert zu übertragen, um Kosten und Zeit einzusparen. Rsync ist auch in der Lage, Änderungsdaten zu vergleichen und lediglich relevante Daten abzugleichen.
11 12 13
4.8.5 Backup der Nutzdaten mit rsync Am einfachsten ist diese Aufgabe mit einem Shell-Skript realisierbar. Um den Vorgang nicht unnötig in die Länge zu ziehen, bietet es sich an, jeweils das älteste Archiv zu aktualisieren und nur neue oder geänderte Daten zu sichern.
14
Sollen Dateien, die gelöscht wurden, auch im bestehenden Archiv entfernt werden, ist rsync mit der Option --delete aufzurufen. Dies ist grundsätzlich bei Nutzerverzeichnissen sinnvoll. Konfigurationsdateien oder andere wichtige Systemdaten sollten Sie ruhig langfristig gegen ein eventuelles Löschen absichern. Weiterhin gilt es, für ein späteres Rückspielen sämtliche Dateiinformationen wie Owner, Group und Zugriffsrechte sowie das Erstellungsdatum für schnelleren Datenabgleich zu übernehmen. Sehr wichtig ist die Angabe der Option -r, ohne die Verzeichnisse lediglich in der ersten Ebene gesichert werden. Unterordner werden dann nicht mehr berücksichtigt.
Backup
331
Um Softlinks zu übernehmen, ist die Option -l notwendig. Sämtliche rsyncOptionen finden Sie in Tabelle 4.7. Das folgende Shell-Skript erledigt die tägliche Sicherung einiger wichtiger Nutzdaten mit rsync.
tag='date' mkdir -p /home/.backup/$tag rsync -rlpgot --delete /var/www/httpd /home/.backup/$tag/ rsync –rlpgot --delete /var/lib/mysql /home/.backup/$tag/ rsync -rlpgot /etc /home/.backup/$tag/ rsync -rlpgot /var/log /home/.backup/$tag/ --exclude "*gz" Beachten Sie, dass bei Systemdaten die Option --delete nicht verwendet wurde. In der Regel werden Sie keine Konfigurationsdateien oder aktuelle Logdateien löschen. Falls Sie dies doch einmal möchten, können Sie die BackupDaten über einen mit find gekoppelten Löschbefehl ebenfalls entfernen. Da eine lokale Sicherung zwar vor dem versehentlichem Löschen einer Datei und anderen Flüchtigkeitsfehlern schützt, nicht aber vor einem FestplattenCrash, kommen Sie um eine zusätzliche externe Sicherung nicht herum. Da die Nutzdaten bereits in einem Backup-Verzeichnis anhand des Wochentages abgelegt wurden, genügt auf dem Backup-Server ein rsync-Befehl zum Datenabgleich des aktuellen Backup-Verzeichnisses:
rsync -e ssh -rlpgotvz –-delete \ root@ihr_server.de:/home/.backup/heute/* \ /home/.serverbackup/heute/ Beachten Sie die Option -e ssh für sichere Datenübertragung sowie die Option -z zur komprimierten Übertragung der relevanten Dateien. Selbstverständlich könnten Sie den Befehl auch auf dem Webserver absetzen, um das Backup-Verzeichnis mit den Daten des Backup-Servers zu aktualisieren:
rsync -e ssh -rlpgotvz -–delete \ /home/.backup/heute/* \ [email protected]:/home/.serverbackup/heute/ Das Ergebnis ist dasselbe. Allerdings ist es ein großer Unterschied, ob das Passwort (oder der SSH-Key) auf dem Backup-Server oder auf dem Webserver benötigt wird.
332
Verwaltung und Administration
1 2 Option
Beschreibung
-e ssh
Datenabgleich über eine sichere ssh-Verbindung.
--delete
Löscht Dateien aus dem Archiv, die im bestehenden Archiv vorhanden, aber im zu sichernden Verzeichnis gelöscht wurden.
4
-t
Übernimmt Erstellungs- beziehungsweise Änderungsdatum.
5
-r
Rekursive Datensicherung (berücksichtigt Unterordner).
-R
Verzeichnisstruktur bleibt erhalten. rsync -R /dir/datei /backup/ erzeugt /backup/dir/datei – anstelle von /backup/datei.
6
-b
Geänderte und im Archiv bestehende Dateien werden nicht ersetzt, sondern mit einem vorangestellten ~ vor Übertragung der aktuellen Datei umbenannt.
7
-l
Übernimmt Softlinks.
8
-L
Sichert Daten, die über einen Softlink verknüpft wurden (der Softlink wird sozusagen aufgelöst und durch die verknüpfte Datei ersetzt).
9
3
-H
Hardlinks werden ohne diese Option als eigenständige Datei gesichert. Verwenden Sie die Option, wenn lediglich ein Hardlink erzeugt werden soll.
-pog
Durch -p werden die Dateirechte, über -o die UID (Eigentümer) und durch -g die GID (Gruppe) übernommen.
-u
Lediglich neuere Dateien werden gesichert. Sind im Archiv Dateien neueren Datums vorhanden, werden diese übersprungen.
-exclude
Schließt ein Suchmuster vom Abgleich aus. Um sämtliche lost+found-Verzeichnisse zu ignorieren, dient exclude=”*lost+found*”.
-include
Die Option include ist sinnvoll, wenn ein bestimmtes Unterverzeichnis oder eine einzelne Datei eines über exclude ausgeklammerten Bereichs dennoch berücksichtigt werden soll: --exclude=”/root” --include=”/root/mydata”.
-v
Der Verbose-Modus ist bei manuellen rsync-Aufrufen immer empfehlenswert. So können Sie den teils langwierigen Vorgang beobachten und beurteilen, wie viel Arbeit noch vor rsync liegt.
-n
Gibt lediglich detaillierte Informationen über die abzugleichenden Dateien aus, ohne tatsächlich Daten zu übertragen. Sehr nützlich, um in einem Testlauf sicher zu gehen, dass Verzeichnisangaben keine Tippfehler enthalten.
10 11 12 13 14
Tabelle 4.7 Die wichtigsten rsync-Optionen in der Übersicht
4.8.6 Voll-Backup mit tar Tar wurde ursprünglich entwickelt, um Backups auf Bändern zu erstellen. Da UNIX-Systeme – technisch gesehen – nicht zwischen einer Datei, einem Ordner oder einem Laufwerk unterscheiden, wird tar schon seit langer Zeit für CDROM, DVD oder Backups über eine externe Festplatte »missbraucht«.
Backup
333
Aus den vielen tar-Optionen (man tar) sind für uns lediglich die in Tabelle 4.8 genannten Funktionen interessant. Normalerweise kommen Sie bereits mit tar -pczf archiv.tgz /zu/sichernder/pfad aus, um ein Archiv zu erzeugen beziehungsweise mit tar –xzf archiv.tgz, um das Archiv zu entpacken. Die Option -j (anstelle von -z) verwendet zur Kompression den bzip2-Algorithmus. Insbesondere bei größeren Sicherungsarchiven (bei mehr als 50 MB) sollten Sie diesen effektiven Algorithmus aufgrund seines Ressourcenhungers jedoch nur über Nacht verwenden und den Nice-Wert erhöhen, wie in diesem Kapitel beschrieben. Sind lediglich einzelne Dateien aus einem Archiv zu extrahieren, ist auf die Option --files-from (oder -I unter OpenBSD) zurückzugreifen. Tar entpackt dann lediglich die in der zusätzlich anzulegenden Datei aufgeführten Files. Zur Kontrolle können Sie die Option -t mit --files-from kombinieren und so vor einem Entpacken die berücksichtigten und eventuell überschriebenen Dateien überprüfen. Beispiel für ein Linux-Voll-Backup ohne Nutzdaten und andere Überflüssigkeiten:
tar -pczPf /Vollbackup.tgz / --exclude "*lost+found*" \ -–exclude "/tmp" --exclude "/proc" \ --exclude "/Vollbackup.tgz" Beachten Sie, dass die zu erzeugende Archivdatei ebenfalls über exclude ausgeschlossen wurde. Dies ist notwendig, damit tar bei der Sicherung des RootVerzeichnisses die Archivdatei überspringt. Leider geschieht dies nicht automatisch. Diese Tatsache wird gerne übersehen, weshalb sich eine Sicherung in eines der übersprungenen Verzeichnisse (beispielsweise home) empfiehlt. Weiterhin müssen Sie eventuell gemountete CD-ROMs oder DVDs ebenfalls vom Voll-Backup über exclude ausschließen. Die Hinweismeldungen »socket ignored« können Sie übrigens selbst ignorieren. Die OpenBSD-Variante des tar-Befehls kennt die Option --exclude nicht. Deshalb müssen Sie auf grep zurückgreifen, um /backup und /tmp von der Archivierung auszuschließen. Die Verzeichnisse proc und lost+found sind spezifisch für Linux und nicht unter OpenBSD vorhanden.
tar -vpczPf /backup/openbsd.tgz 'ls / | grep -v \ backup | grep –v tmp'
334
Verwaltung und Administration
1 2 Option
Beschreibung
-c
Weist tar an, ein Archiv zu erzeugen (siehe Option -f).
-x
Entpackt ein bestehendes Archiv (siehe Option -f).
-u
Aktualisiert ein bestehendes Archiv (siehe Option -f); leider nicht in Verbindung mit komprimierten Archiven nutzbar. Gegebenenfalls sind gzip oder bzip2 mit der Option -d auf die Archivdatei anzusetzen.
3 4 5
-r
Hängt ein angegebenes Verzeichnis oder eine angegebene Datei an ein bestehendes tar-Archiv an (siehe Option -f). Wie die Option -u ist auch -r nicht auf komprimierte Archive anwendbar.
6
-t
Listet den Archivinhalt einer tar-Datei auf (siehe Option -f).
7
-p
Übernimmt UID, GID und Zugriffsrechte von Dateien.
-z
Wendet gzip zur Dateikompression an.
-j
Nutzt das starke, aber ressourcenhungrige bzip2 zur Kompression.
-f
Diese Option muss zuletzt aufgeführt werden und wird mit Eingabe des zu erstellenden beziehungsweise zu extrahierenden Archivnamens abgeschlossen.
10
Speichert die über einen Soft- oder Hardlink verknüpften Dateien, anstatt einen sym-Link anzulegen.
11
-h
8
--files-from -I (in BSD)
In einer zusätzlichen Liste können Sie zu berücksichtigende Dateien gezielt angeben und so bei einer Extraktion lediglich tatsächlich benötigte Daten auspacken.
--exclude
Nur Linux: Grenzt einzelne Dateien oder Ordner aus.
-P
In der Voreinstellung entfernt tar vorangestellte /-Pfadangaben, um so bei einem Rückspielen ungewolltes Überschreiben aktuellerer Daten durch alte Informationen zu verhindern. Mit der Option -P weisen Sie tar an, die leading-Slashes nicht zu entfernen.
-C
9
12 13 14
Falls die Option -P beim Erstellen von tar-Archiven genutzt wurde, werden beim Rückspielen eventuell neuere Dateien unbeabsichtigt ersetzt. Stellen Sie bei einem Blick ins tar-Archiv (siehe -t) fest, dass vollständige Pfadangaben vorhanden sind (beispielsweise /pfadname/datei anstelle von dirname/datei), sollten Sie über die Option -C ein anderes Zielverzeichnis angeben!
Tabelle 4.8 Die wichtigsten tar-Optionen
4.9
Stresstests
Der Aufbau und Test eines Servers im lokalen Betrieb hat den Schönheitsfehler, dass Sie nur schwer einschätzen können, wie zuverlässig und performant der Server im harten Einsatz reagieren wird. Mit Stresstests können Sie Ihren Webserver mit Anfragen bombardieren oder die CPU- und Load-Auslastung nach oben treiben.
Stresstests
335
Allerdings ist zu beachten, dass die Server-Hardware Ihres Testsystems (in der Regel) nicht mit der Server-Hardware bei Ihrem Hoster identisch ist und Tests auf dem Probesystem so lediglich dabei helfen, die Server-Konfiguration auf generelles Verhalten im Belastungsfall zu prüfen. Deshalb sollten Sie vor Inbetriebnahme des Webservers die Belastungsgrenzen des Webservers zumindest mit stress und siege abklopfen. Nur so werden Sie MRTG-Statistiken praxisbezogen auswerten und beurteilen können, welche Load- und CPU-Werte kritisch sind. Unter http://ltp.sourceforge.net/tooltable.php finden Sie eine Übersicht über weitere Testprogramme, darunter auch Tools für ausgefallenere Aufgaben wie einen Java-Chatroom-Belastungstest (VolanoMark) oder diverse Filesystem-Test-Software.
4.9.1
Mit Stress Arbeitsspeicher entziehen und CPU/LoadBelastung erhöhen
Die Installation von Stress gestaltet sich nach dem Download der Quellen von http://weather.ou.edu/~apw/projects/stress/ dank des gewohnten »Dreisatzes« unproblematisch. Um die CPU- und Load-Belastung in die Höhe zu schrauben, genügt stress -m 0 -c 6 -i 6 &. Rufen Sie danach top auf, um die Systembelastung zu überwachen. Sollte die gewünschte Auslastung noch nicht erreicht sein, können Sie Stress ruhig weiter mit diesen Optionen aufrufen. Um ein Gefühl für das Systemverhalten bei knappem Arbeitsspeicher oder bei starker SWAP-Nutzung zu bekommen, verwenden Sie stress -m 0 --vm-bytes 400M &. Stress verschlingt nun 400 MB Arbeitsspeicher und gibt diesen danach wieder frei. Beachten Sie, dass Stress so lange weiterläuft, bis Sie den Prozess beenden. Um eine durchgehend hohe Speicherauslastung zu erzielen, können Sie den Befehl ein zweites Mal aufrufen, kurz bevor Stress beginnt, den Arbeitsspeicher freizugeben (top hilft, den richtigen Zeitpunkt zu finden). Falls Sie sich zu diesem »gefährlichen Systemtest« entschließen sollten, gilt es, beide Stress-Aufrufe mit einem Timeout zwischen fünf und zehn Minuten zu versehen (-t 300 für fünf Minuten). Falls Sie dies vergessen und der Rechner »plötzlich« nicht mehr ansprechbar ist, werden Sie an einem manuellen Reboot durch den Dienstleister nicht vorbeikommen.
336
Verwaltung und Administration
1 2 Option
Beschreibung
-m
Steuert die Dauer eines Prozesses. Verwenden Sie 0 für eine unendliche oder -4 für eine viermalige Wiederholung des Belastungstests.
--vm-bytes
Verschlingt Arbeitsspeicher. Nutzen Sie 200M, um dem Server 200 MB zu entziehen und wieder freizugeben.
-i
Erhöht die Load-Belastung (I/O) des Systems. Als Wert ist die Anzahl der von Stress zu verwendenden Prozesse (Forks) anzugeben. Beginnen Sie zunächst mit einem Wert zwischen 4 und 8.
-c
3 4 5 6
Erhöht die CPU-Auslastung des Systems. Als Wert ist die Anzahl der von Stress zu verwendenden Prozesse (Forks) anzugeben. Beginnen Sie zunächst mit einem Wert zwischen 4 und 8.
7
--hdd-bytes Dient zum Testen des Server-Verhaltens bei hoher Festplattenbelastung. Verwenden Sie 10M, um eine 10 MB große Datei zu schreiben und sofort zu löschen. -t
8 9
Beendet den Stress-Prozess spätestens nach Ablauf der anzugebenden Sekundenzahl. Vor allem bei kritischen (sehr hohen) Belastungstests sinnvoll.
10
Tabelle 4.9 Die wichtigsten Stress-Optionen in der Übersicht. Nutzen Sie man stress, um sämtliche Optionen kennen zu lernen.
11 4.9.2 Apache under Siege
12
Realistische Tests des Webservers sind aus mehreren Gründen schwierig zu realisieren. Zum einen gilt es, die Datenübertragung über langsame oder schnelle Verbindungen zu berücksichtigen. Zum anderen ist das User-Verhalten schwer simulierbar. Neben Zeitunterschieden, bis die nächste Site angefordert wird, ist unklar, welche Sites gezogen werden.
13 14
Ein realistischer Test ist somit eigentlich nicht möglich. Allerdings können Sie über die Auswahl vieler »Standardseiten« und einer Handvoll der umfangreichsten Webseiten, Download-Links oder aufwendiger PHP- oder Perl-Skripte ein gutes Gefühl für die tatsächliche Belastbarkeit gewinnen. Nach der Installation von Siege beginnt somit erst die eigentliche Arbeit. Für Debian gibt es ein vorbereitetes Siege-Paket. Unter den anderen Systemen kann Siege über den unter http://www.joedog.org/siege/index.shtml erhältlichen Quelltext kompiliert werden. Über siege –C erhalten Sie eine Übersicht über die Standard-Files Ihrer Installation. Die »Link-Liste« ist in die Datei urls.txt zu übernehmen. Die Zufallsliste sollte mindestens 50 Links enthalten. Sites wie die Startseite, die öfter aufgerufen werden, sollten ebenfalls mehrmals eingetragen werden. Eine der Stärken von Siege ist ein Zufallsgenerator zur Auswahl der anzufordernden Adressen
Stresstests
337
sowie für den Zeitrahmen, bis der User eine erneute Seitenanfrage startet. Zudem ist die Anzahl gleichzeitig anfragender User einstellbar:
siege -i -t 180s -d 30s -c 500 Siege »attackiert« den Server nun drei Minuten (-t 180s) mit bis zu 500 gleichzeitigen Abfragen (eigenständigen Besuchern), die zwischen den einzelnen Anfragen eine zufällige Auszeit zwischen null und 30 Sekunden vor der nächsten Anfrage nehmen. Bedenken Sie, dass 500 gleichzeitige Anfragen immens viel sind. Eine derart hohe Auslastung ist selbst bei mehr als 30 GB Traffic monatlich eher unüblich. Falls Sie der Empfehlung zur Nutzung eines Download-Links gefolgt sind und nur wenige »normale« URLs ausgesucht haben, kann sich das Ergebnis drastisch verschlechtern. Doch selbst bei vielen Failed Transactions sollte die durchschnittliche Verfügbarkeit auf keinen Fall unter 99 Prozent fallen. Probleme bei der Datenübertragung führen nicht automatisch zum Abbruch der Anforderung, sondern zu einem erneuten Nachfragen des Browsers. Deshalb ist es nicht ungewöhnlich, wenn Siege trotz einer Erreichbarkeit von 100 Prozent verlorene Datenpakete registriert. Ein weiteres Problem ist der realistische Server-Test. Eine Prüfung über das lokale Netzwerk gibt selbst bei relativ gleicher Hardware des Test-Servers keinen verlässlichen Überblick, sondern lediglich einen ersten Eindruck über die Belastbarkeit des Webservers. Die Ablieferung der Pakete an »echte Clients« über das Internet ist natürlich nicht so schnell möglich wie im lokalen Netzwerk. Für einen realistischen Test müssten Sie Siege auf mindestens zehn verschiedenen Rechnern mit jeweils eigener DSL-Anbindung auf den Webserver loslassen. Die User-Anzahl ist dann entsprechend »aufzuteilen«. Hinweis Sie können Siege über (Strg)-(C) noch vor dem Ablauf der über -t definierten Zeit anhalten und die Statistik ausgeben lassen. Beachten Sie nicht nur das von Siege ermittelte Endergebnis, sondern lassen Sie auf dem Webserver gleichzeitig top zur Beobachtung der httpd-Instanzen und des angeforderten CPU- und Arbeitsspeicher-Volumens laufen!
4.10 Ressourcen beschränken Einzelne Systemprozesse wie Daten-Backup oder Statistikfunktionen können durchaus die freien Prozessor-Ressourcen auf ein Minimum reduzieren. Deshalb sollten Prozesse, die Zeit- und CPU-Leistung fressen, in den Morgenstunden via Cron automatisiert aufgerufen werden. Zusätzlich bietet es sich an, die-
338
Verwaltung und Administration
1 2 sen Prozessen einen hohen Nice-Wert zuzuweisen. Der Prozess steht dann anderen Aufgaben nicht im Weg und wartet gegebenenfalls auf freie Ressourcen.
3 4
Setzen Sie vor dem Programmaufruf nice –n 19 [Befehl], um die niedrigste Priorität zu verwenden. Üblicherweise werden Prozesse mit dem Wert 0 ausgeführt. Wichtige und schnellstmöglich abzuschließende Aufgaben können Sie als Root mit nice –n –20 [Befehl] die höchste Priorität zuweisen.
5 6
In der top-Abfrage finden Sie in der Spalte NI übrigens den Nice-Wert wieder, mit dem der Prozess ausgeführt wird. Interessant ist, dass Nutzer eine niedrigere Priorität (einen höheren Nice-Wert) vergeben dürfen, jedoch keine höhere Priorität als den ihnen zugewiesenen Standardwert verwenden können.
7 8
Falls Sie den Nice-Wert bereits laufender Prozesse ändern möchten, können Sie auf renice zurückgreifen. Mit diesem Befehl ist es als Root sogar möglich, den Nutzer und die Gruppe, unter denen der Prozess läuft, zu ändern. Details erfahren Sie über man renice. Um den Nice-Wert zu ändern, benötigen Sie die Prozess-PID. Renice +5 110 steigert den Nice-Wert des laufenden Prozesses (110) um 5 (und senkt somit seine Priorität um fünf Zähler).
9 10 11
4.10.1 Ressourcen unter Linux über PAM nutzerbezogen beschränken
12
Neben dem Nice-Wert können Sie Anwendern (natürlich auch ProgrammAccounts) über die PAM-(Pluggable Authentication Modules-)Konfigurationsdatei /etc/security/limits.conf weitere Limitierungen auferlegen und so den maximal nutzbaren Speicher oder die maximale Login- oder Prozesszahl einschränken.
13 14
Generell ist eine Einschränkung immer sinnvoll, da so verhindert wird, dass ein gekaperter Daemon oder ein geknackter Nutzer-Account das gesamte System lahm legt. So bietet es sich an, den maximal nutzbaren Arbeitsspeicher auf 60 Prozent des physikalischen RAMs zu beschränken:
*
hard
memlock
254000
Das Sternchen sorgt dafür, dass das harte Speicherlimit von 254 000 Byte für jeden Account gilt. Über priority können Sie den Nice-Wert in einer niedrigeren Priorität vorgeben:
@user
-
priority
10
Ressourcen beschränken
339
Über das vorangestellte at-Zeichen wird eine Gruppe definiert. Sämtliche Accounts, die zur Gruppe User gehören, können fortan Befehle oder Programme lediglich mit einem Nice-Wert von 10 ausführen.
@user
-
maxlogins2
Über Maxlogins wird die Anzahl der zulässigen Logins auf zwei beschränkt. Selbst wenn eine Session im Normalfall reicht, müssen Sie an die Möglichkeit einer Beendigung einer Verbindung durch Übertragungsfehler oder Ähnliches denken. Bis die auf dem Server noch offene Session durch Timeout beendet wird, ist ein weiterer Login nicht möglich. Deshalb sollten Sie als Beschränkung lieber zwei Logins erlauben. Nach dem erneuten Login ist der User über kill in der Lage, die offene Session vor einem Timeout zu beenden, um so selbst bei einem erneuten Verbindungsabbruch einen weiteren Login »frei zu haben«.
@user @user
hard hard
nproc cpu
50 4
Über nproc wird die maximale Prozessanzahl festgelegt. Weiterhin stehen der Gruppe Nutzer für Befehle oder Programmaufrufe lediglich vier Minuten CPUZeit zur Verfügung. Beide Werte sollten nur vorsichtig eingesetzt werden. Tomcat und andere Software reagieren sehr empfindlich auf Beschränkungen der Prozessanzahl. Die CPU-Zeit sollte bei Daemons generell nicht eingeschränkt werden. Somit eignen sich nproc und cpu in erster Linie für Nutzer-Accounts. Eine vollständige Einführung in die komplexe Thematik der Pluggable Authentication Modules bietet »The Linux-PAM System Administrators' Guide« unter http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html.
4.10.2 Ressourcen unter OpenBSD nutzerbezogen einschränken Unter OpenBSD können Sie die von einzelnen Accounts maximal nutzbare Prozessanzahl, CPU-Zeit sowie den Arbeitsspeicher festlegen. Im Gegensatz zu PAM für Linux ist es jedoch leider nicht möglich, die maximale Login-Anzahl zu beschränken. Werfen Sie einen Blick auf die Datei /etc/login.conf Ihres Systems. Für die Gruppen staff und daemon sind bereits sinnvolle Voreinstellungen getroffen, die die Werte von default überschreiben. Um Mitarbeiter- oder Kundenzugänge mit spezifischeren Restriktionen zu versehen, bieten sich eine spezielle Gruppe nutzer und folgende zusätzlichen Zeilen in /etc/login.conf an:
340
Verwaltung und Administration
1 2 nutzer:
3
:maxproc=20: :memorylocked=50M: :cputime=4: :priority=12:
4 5
User der Gruppe Nutzer können fortan lediglich 20 Prozesse (maxproc) gleichzeitig starten und dürfen insgesamt maximal 50 MB Systemspeicher (memorylocked) verwenden. Prozesse werden mit einer erhöhten Priority ausgeführt (als unwichtiger als andere Prozesse eingestuft) und werden spätestens bei Erreichen von vier Minuten CPU-Laufzeit (cputime) beendet.
6 7
Weitere Hinweise zu den Einstellungen von login.conf sind in der gleichnamigen Manpage verfügbar.
8
4.11 Loadbalancing
9
Loadbalancing (Lastverteilung) ermöglicht höhere Ausfallsicherheit und entlastet CPUs. Allerdings sind mindestens drei Rechner erforderlich, die mit 100 Mbit kommunizieren können (im selben Gebäude stehen).
10 11
Theoretisch genügen bereits zwei Rechner. Allerdings sollte der Server für das Loadbalancing selbst auf keinen Fall größeren Belastungen ausgesetzt werden. Eine gute Lösung wäre es, den Nameserver auf dem Lastverteilungs-Server laufen zu lassen und lediglich maximal fünf oder zehn gleichzeitige Anfragen an den Apache direkt entgegenzunehmen.
12 13
Vorsicht ist bei unterschiedlichen Subnetzen geboten, da dann nicht gewährleistet ist, dass die Rechner über das Hausnetz direkt kommunizieren können. Beachten Sie weiterhin, dass der (zu berechnende) Traffic lediglich vom Loadbalancer ausgeht. Üblicherweise wird jedoch jeder Server einzeln abgerechnet, so dass Sie die Freigrenze beim Loadbalancer möglicherweise überschreiten werden und hohe zusätzliche Traffic-Gebühren zu entrichten haben. Dies, obwohl der gesamte entstandene Traffic, wenn er durch die genutzten Server geteilt wird, deutlich unter der Freigrenze liegen könnte. Bevor Sie Server zum Loadbalancing bestellen, sollten Sie sich deshalb in jedem Fall mit Ihrem Dienstleister in Verbindung setzen, um etwaige Vertragsdetails abzusprechen.
14
Mit Pen steht ein Open-Source-Programm zur Lastverteilung des TCP über eine simple Weiterleitung anhand der Port-Nummer zur Verfügung. Auch wenn somit neben Apache auch eine Lastverteilung des Mailservers realisierbar ist, sollten Sie in der Regel Lastverteilung nur für den Apache- und eventuell den Datenbank-Server verwenden (wenn Zugriff von außerhalb erwünscht ist). Ein
Loadbalancing
341
Loadbalancing des Mailservers würde zu einer dezentralen Sicherung der Nachrichten führen und somit das Abholen der zugestellten E-Mails (über POP3 oder IMAP) erschweren. Pen ist seiner niedrigen Versionsnummer zum Trotz (auf der CD-ROM finden Sie die Version 0.10.0) sehr ausgereift. Besucheranfragen werden immer an denselben (erstmalig zugewiesenen) Server weitergeleitet, so dass auch ShopSysteme, die mit Sessions und temporären Daten (Warenkorb) arbeiten, für eine Lastverteilung in Frage kommen. Die Installation der Quellen von http://siag.nu/pen/ ist unproblematisch. Der wohlbekannte Dreisatz genügt. Die Handhabung ist erstaunlicherweise sogar noch einfacher und schneller als die Installation: Der Befehl pen -df 81 home.test:80 leitet alle Anfragen an Port 81 des Pen-Servers an den Apache von home.test weiter (unter home.test muss Pen nicht installiert sein). Nachdem der erste Test erfolgreich absolviert worden ist, sollten Sie für Pen einen eigenen User-Account anlegen sowie /usr/local/bin/pen in das entsprechende User-Verzeichnis kopieren. Diese beiden kurzen Handgriffe schützen Ihren Pen-Server zuverlässig vor Angreifern, wenn Sie Pen beim Start chrooten und unter dem neuen Account starten:
pen 80 ws1:80 ws2:80 localhost:8080:5 -u pen -j /home/pen/ & Beachten Sie, dass Anfragen an Port 80 des Pen-Servers an den Port 8080 von Localhost für maximal fünf gleichzeitige Verbindungen umgeleitet werden. Es ist zwingend notwendig, dass der Apache-Server des Pen-Servers unter einer anderen Port-Nummer lauscht, da Pen sonst nicht startet (über die zusätzliche Debug-Option -df erhalten Sie in diesem Fall die Meldung:
local address=[0.0.0.0:80] can't bind local address. Hinweis Wird auf die Angabe einer maximalen Anzahl der gleichzeitigen Verbindungen verzichtet, geht Pen nicht etwa von unendlich vielen, sondern lediglich von derzeit maximal 256 gleichzeitigen Anfragen aus.
4.12 Hochverfügbarkeit Loadbalancing ist nicht mit Hochverfügbarkeit gleichzusetzen. Obwohl der Ausfall einzelner Webserver der Erreichbarkeit nicht schadet, gilt dies nicht für einen Ausfall des Loadbalancers. Wer es mit Hochverfügbarkeit ernst meint, kommt deshalb nicht an einem Ausfall-Server vorbei, der für den Haupt-Server einspringt, falls dieser ausfällt.
342
Verwaltung und Administration
1 2 Bevor Sie einen Ausfall-Server einrichten, sollten zunächst ÜberwachungsSkripte erstellt werden, die die angebotenen Dienste auf dem Haupt-Server regelmäßig überprüfen und bei nicht Erreichbarkeit einen simplen Neustart durchführen. Nicht ansprechbare Dienste sollten am besten über kill –9 beendet werden, um denkbaren Problemen beim Stoppen des Dienstes durch einen Restart über das Startskript entgegenzuwirken. Eventuell vom Dienst angelegte Pidfiles sind ebenfalls als Vorsichtsmaßnahme vor dem erneuten Starten des ausgefallenen Dienstes zu löschen.
3 4 5 6
Falls alle diese Maßnahmen nicht weiterhelfen oder der Server feststellen muss, dass etwas mit der Netzwerkkarte nicht stimmt (weder Ausfall-Server noch zwei weitere Referenzadressen sind pingbar), greift ein Automatismus, der die IP-Adresse des Haupt-Servers auf die des Ausfall-Servers stellt und den Rechner danach ausschaltet (shutdown –h now).
7 8 9
Sobald der Ausfall-Server feststellt, dass der Haupt-Server nicht mehr pingbar ist, obwohl die Netzwerkkarte korrekt arbeitet, da mindestens eine weitere Referenzadresse pingbar ist, könnte ein Automatismus die IP-Adresse auf die des Haupt-Servers ändern, damit der Ausfall-Server zukünftige Verbindungsanfragen entgegennimmt. Gleichzeitig bietet es sich an, eine E-Mail an den Administrator zu senden, in der auf den Server-Ausfall hingewiesen wird.
10 11 12
So können Sie in aller Ruhe den ausgefallenen Haupt-Server über die IPAdresse des eingesprungenen Notfall-Servers näher inspizieren und die entstandenen Probleme bereinigen.
13
Aus Sicherheitsgründen sollten Sie übrigens auf dem Notfall-Server erst bei Bedarf sämtliche Dienste wie FTP-, Mail- und Webserver aktivieren, um so Angreifern lediglich den SSH-Server als »einzige von außen erreichbare Angriffsfläche« zu bieten.
14
Wenn das geschilderte Szenario nicht Ihren Anforderungen an ein Hochverfügbarkeitssystem entspricht, sollten Sie einen Blick auf das »Virtual Router Redundancy Protocol« (vrrp – http://www.ietf.org/rfc/rfc2338.txt) werfen. Eine Umsetzung des VRPP ist für Linux unter http://w3.arobas.net/ ~jetienne/vrrpd/index.html und für FreeBSD über http://www.bsdshell. net/hut_vrrpimpl.html erhältlich. Dennoch möchte ich an dieser Stelle nicht näher darauf eingehen, da Cisco leider ein Patent auf die grundlegende Technik der virtuellen, wandernden IP-Adresse für Haupt- und Notfall-Server (siehe auch: http://www.foo.be/vrrp/) angemeldet hat. Anmerkung: Obwohl im Web Zitate von E-Mails aus dem Hause Cisco kursieren, in denen versichert wird, dass eine Umsetzung des in rfc2338 beschriebe-
Hochverfügbarkeit
343
nen Protokolls von Cisco nicht als Patentverstoß behandelt wird (http://archives.neohapsis.com/archives/openbsd/2002–08/0203.html), sind Sie vor einem Meinungswechsel im Hause Cisco nicht sicher. Außerdem sollten Sie neben den hohen Kosten und zusätzlichen Wartungsaufwand für einen Backup-Server bedenken, dass die häufigsten Gründe für einen Server-Ausfall in der Netzwerktechnik des Rechenzentrums (Ausfall eines Routers oder Switchs) zu suchen sind. Derlei Ausfälle können Sie auch nicht über einen Notfall-Server kompensieren, da dieser im selben Subnetz stehen muss und somit im Normalfall am selben Switch beziehungsweise Router hängt. Wer wirklich die maximale Verfügbarkeit erreichen möchte und weder Kosten noch Mühen scheut, für den ist die Einrichtung eines Backup-Servers durchaus eine Überlegung wert. Allen anderen sei ein Raid-Level-5-System empfohlen, da eine »einfache« IDE- oder SCSI-Festplatte wohl den größten Schwachpunkt in der Server-Hardware darstellt. Eine zweite Netzwerkkarte, die an dieselbe IPAdresse gebunden wird, ist ebenfalls sinnvoll. Dies nicht nur, um die Bandbreite Ihres Servers zu erhöhen, sondern auch, um durch einen Ausfall der Netzwerkkarte nicht gleich den ganzen Server »zu verlieren«.
4.13 Festplatte prüfen Die Festplatte zählt zu den kritischsten Hardware-Merkmalen eines Servers. Lediglich ein teures Raid-System (siehe Abschnitt 4.15, Raid-Systeme) kann eine hohe Ausfallsicherheit garantieren. Im Regelfall werden Sie jedoch vor dieser Investition zurückschrecken und lediglich auf eine günstige IDE-Festplatte zurückgreifen. Fsck wird versuchen, fehlerhafte Dateisystem-Informationen zu korrigieren, die je nach Anzahl der Reboots oder automatisiert nach einem Absturz ausgeführt werden. In der Regel verläuft der Prozess ohne ernste Schwierigkeiten und kommt gänzlich ohne die Hilfe des Administrators aus. Schwerer wiegende Fehler veranlassen fsck jedoch zu einer Rückfrage, ob das Problem behoben werden soll oder nicht. Bis die Antwort erfolgt, wird der Prozess unterbrochen. Da die Prüfung jedoch noch vor dem Starten von Netzwerkdiensten und anderen wichtigen Diensten abläuft, haben Sie im Regelfall gar keine Möglichkeit, auf Rückfragen zu antworten. Deshalb sollten Sie unbedingt prüfen, ob die Option -y in den Startskripten Ihres Systems (Linux: grep -sli "fsck" /etc/init.d/*, BSD: grep"fsck" /etc/rc) bei jedem fsck-Aufruf genutzt wird. Im Normalfall führt an einer manuellen Nachbearbeitung kein Weg vorbei. -p beziehungsweise -a sollten
344
Verwaltung und Administration
1 2 durch -y ersetzt und die nachfolgenden Zeilen entsprechend angepasst werden, damit fsck ebenfalls schwer wiegende Probleme ohne Rückfrage zu beheben versucht. Unter Debian wären beispielsweise checkfs.sh und checkroot.sh anzupassen:
# # # # #
3 4
if [ "$FSCKFIX" = yes ] then fix="-y" else fix="-a" fi
5 6 7
Beachten Sie, dass die Variable fix durch Auskommentieren immer die Option -y enthält. Allerdings birgt dieses Vorgehen das Risiko, bestehende Probleme zu verschlimmern. Dummerweise kann fsck ausschließlich Read-only- oder ungemountete Partitionen reparieren. Dies hat zur Folge, dass Sie von Programmen genutzte Partitionen, die nicht im laufenden Betrieb read-only gemountet werden können, lediglich über einen Reboot (shutdown –Fr now) reparieren können.
8 9 10 11
Um dem Blindflug die Ungewissheit zu nehmen, können Sie unter Linux fsck –nvA aufrufen, um so alle in /etc/fstab eingetragenen Partitionen auf Probleme zu prüfen, ohne Änderungsarbeiten (die im laufenden Betrieb mehr zerstören als reparieren würden) durchzuführen. Unter OpenBSD führt der Befehl fsck 'cut -d" " -f1 /etc/fstab' zum selben Ergebnis.
12 13
Immerhin sind so ernsthafte Probleme bereits im laufenden Betrieb feststellbar. Eine Reparatur kann dann über ein Rettungssystem erfolgen. Nachdem Sie lilo beziehungsweise bootable flag mit fdisk entsprechend angepasst haben, sollten Sie, um eine automatische fsck-Prüfung auf jeden Fall zu überspringen, shutdown –fr now zum Systemneustart nutzen.
14
Wenn fsck lediglich kleinere Probleme wie fehlerhafte Datei-Counter oder unsaubere Inodes entdeckt, können Sie die Reparatur beruhigt über shutdown -Fr now automatisiert beim Neustart durchführen lassen. Falls Sie mit ernsteren Problemen rechnen und mangels Rettungssystem zu einem »Blindflug« gezwungen sind, sollten Sie zumindest den Dienstleister informieren, dass der Server eventuell Handarbeit benötigt und den Zeitpunkt des Reboots absprechen.
Festplatte prüfen
345
4.13.1 Debian und SUSE zur Reparatur read-only starten Wenn Ihnen kein Rettungssystem zur Verfügung steht und Sie fsck dennoch nicht im Blindflug nutzen möchten, steht es Ihnen frei, das System zur Reparatur read-only zu starten. Dies ist möglich, da der SSH-Server für seinen Start keine Schreibberechtigung benötigt. Dennoch ist große Vorsicht geboten: Programme, die über die Startskripte aufgerufen werden, aber nicht starten können, ohne Schreibzugriff zu erlangen, sind in der Lage, den Startvorgang zu unterbrechen. Ihr System könnte durchaus stehen bleiben, ohne über ssh remote ansprechbar zu sein. Testen Sie einen Read-only-Start deshalb unbedingt vorher auf einem lokalen Testsystem. Unter Debian 3.0 ist es im Gegensatz zu SUSE 9.2 notwendig, sysklogd vom Startprozess auszuschließen. Damit dies nicht vergessen wird, sollten Sie sich die Zeit nehmen, ein Shell-Skript zu schreiben, das die Startlinks der problematischen Programme aus den Runleveln entfernt, die entsprechenden /etc/fstab-Einträge auf ro setzt und shutdown -Fr now ausführt. In SUSE 9.2 sorgen remount-Befehle in /etc/init.d/boot.localfs dafür, dass Sie trotz Anpassungen der /etc/fstab-Einträge nach dem Systemstart noch immer keine Möglichkeit haben, die Festplatte mit fsck ordnungsgemäß zu reparieren. Glücklicherweise lassen sich die verantwortlichen Zeilen auskommentieren ... Sobald Ihre Distribution read-only gestartet wurde, können Sie nach den (hoffentlich problemlosen) fsck-Reparaturen die Partitionen über die mount-Optionen -o remount -rw erneut für Schreibzugriff einbinden und neben der Datei /etc/fstab eventuell abgeänderte Startlinks und Boot-Skripte auf den ursprünglichen Stand zurücksetzen. Schließen Sie die aufwendigen Reparaturarbeiten mit einem Neustart des Servers ab.
4.13.2 Read-only-Start von OpenBSD? OpenBSD kann zwar einwandfrei von einem read-only gemounteten System gestartet werden, allerdings lässt sich die Festplatte bei Nutzung des StandardDateisystems nicht wie unter Linux über -o remount –rw erneut schreibbar mounten. Sie kommen daher nicht darum herum, den Dienstleister zu bitten, über ein Rettungssystem vor Ort /etc/fstab wieder in den Urzustand zu versetzen.
4.13.3 S.M.A.R.T. S.M.A.R.T steht für »Self-Monitoring Analysis and Reporting Technology System« und wurde entwickelt, um Festplatten zu überwachen und Hardware-Fehler zu entdecken. Da S.M.A.R.T. keine reine Software-Lösung ist, muss die Festplatte das Überwachungs- und Analyse-System ebenfalls unterstützen.
346
Verwaltung und Administration
1 2 linux
3
Rufen Sie zunächst hdparm -I /dev/hda | grep SMART auf, um zu überprüfen, ob S.M.A.R.T. von Ihrer Festplatte unterstützt wird (ein Sternchen am Zeilenanfang steht für aktiv). Falls S.M.A.R.T. unterstützt wird, steht einer Installation der Pakete smartsuite und ide-smart Ihrer Distribution nichts mehr im Weg. Notfalls können Sie die Quellen über http://www.linuxide.org/smart.html beziehen.
4 5 6
Nach dem Start von smartd genügt der Aufruf smartctl -t /dev/hda, um die angegebene Festplatte alle vier Stunden automatisiert zu überprüfen. Gefundene Probleme werden über Syslogd protokolliert. Weiterhin haben Sie die Möglichkeit, einen kurzen Test direkt über smartctl -S /dev/hda durchzuführen. Die längere Variante (smartctl -X /dev/hda) bietet sich erst bei ernsthaft vermuteten Festplattenproblemen und ergebnislosem Kurztest bei zusätzlich fehlenden Logeinträgen an.
7 8 9
Sehr interessant ist zudem die Option -a, mit der smartctl eine Logstatistik ausgibt und die bisherige Gesamtlaufzeit der Festplatte in Stunden anführt. Spätestens nach vier Betriebsjahren (bei ca. 35 000 Betriebsstunden) sollten Sie den vorbeugenden Austausch einer IDE-Festplatte in Erwägung ziehen.
10 11 12
atactl für ATA/DIE-Festplatten unter OpenBSD Der Befehl atactl /dev/wd0 identify gibt die Festplatteninformationen zur ATA-Festplatte /dev/wd0 aus. Wenn hier die Zeile: »SMART feature set« unter »Device has enabled the following command sets/features« aufgeführt ist, können Sie den Befehl atactl /dev/wd0 smartenable ausführen, um das SelfMonitoring Analysis and Reporting Technology System zu aktivieren.
13 14
Der Befehl atactl /dev/wd0 smartstatus sollte täglich per Cron-Job aufgerufen werden und zur Antwortzeile »No SMART threshold exceeded« führen. Bei einem anderen Ergebnis besteht Grund zur Besorgnis, und Sie sollten mit Ihrem Dienstleister über einen frühzeitigen – aber dafür kontrollierbaren – Austausch der Festplatte sprechen. Ein weiteres Feature von atactl, das leider von vielen Festplatten nicht unterstützt wird, ist das Geräuschmanagement. Da es keine Rolle spielt, wie laut die Festplatte Ihres Servers arbeitet, können Sie manchmal einen PerformanceGewinn (bei gesteigerter Betriebslautstärke) erzielen. Rufen Sie hierzu den Befehl atactl /dev/wd0 acousticset 0 auf.
Festplatte prüfen
347
4.14 Das Rettungssystem Über ein Rettungssystem können Sie die Hauptpartitionen Ihres Systems remote mit fsck überprüfen und haben die Möglichkeit, eine AIDE- oder Tripwire-Datenbank zuverlässig gegen ein möglicherweise kompromittiertes System laufen zu lassen. Insbesondere für letztere Aufgabe sollten Sie zu einem Read-only-Medium wie einer CD-ROM greifen. Leider ist es unter OpenBSD notwendig, eine bootbare CD-ROM (beispielsweise wie in http://www.shockley.net/obsd-bootcd.asp beschrieben) zu erzeugen. Diese kann natürlich nicht im Laufwerk verbleiben, da bei jedem Systemstart von CD-ROM gebootet werden würde. Falls Ihr Dienstleister nicht zu fairen Konditionen den Disk-Jockey-Auftrag übernehmen möchte, sind Sie unter OpenBSD leider auf eine zusätzliche Rettungspartition angewiesen, die natürlich von einem Angreifer manipuliert werden könnte. Die Root-Partition des Notfallsystems zur OpenBSD-Boot-Partition ist hierzu in /etc/boot.conf einzutragen und ein Neustart auszuführen. Weitere Informationen finden Sie in Abschnitt 2.5.2, Boot (OpenBSD) und Bootable-Flag (fdisk).
4.14.1 Ein Linux-Rettungssystem auf CD-ROM Unter Debian und SUSE genügt es prinzipiell, ein Image aus einer für den Readonly-Start vorbereiteten Partition über mkisofs -o /pfad/cd.iso -R /notfallpartition zu erstellen und dieses zu brennen. Das Programm mkisofs zählt nicht zum Grundsystem, ist aber als vorbereitetes Paket für Ihre Distribution vorhanden. Die CD-ROM kann wie gewohnt in /etc/lilo.conf eingetragen werden:
image=/cdrom/usr/src/linux-2.4.29/arch/i386/boot/bzImageroot=/dev/cdromlabel=Rettungssystem Werden Sie beim Aufruf von lilo mit einer Fehlermeldung wie »Fatal: geo_ query_dev HDIO_GETGEO (dev 0x1600): Invalid argument« konfrontiert, dann liegt dies daran, dass der Kernel nicht korrekt über die gemountete CDR/DVD-R eingebunden werden konnte. Zum Glück genügt es in diesem Fall, das Image auf die Festplatte zu kopieren:
cp -rp /cdrom/usr/src/linux-2.4.29/arch/i386/boot/bzImage /usr/src/read_only_kernel Nach
dem Anpassen der image-Direktive in /etc/lilo.conf zu image=/usr/src/read_only_kernel wird lilo erfolgreich ausgeführt werden. Falls Sie die Integrität des Systems überprüfen möchten, empfiehlt es sich
348
Verwaltung und Administration
1 2 jedoch, den Kernel erneut von CD-R zu kopieren, um sicher zu gehen, dass ein Angreifer den Kernel des Ausfallsystems nicht kompromittiert hat.
3
Häufig ist es hilfreich, wenn die Konfigurationsdateien der CD-ROM im laufenden Betrieb angepasst werden können, oder – um bei längerfristigen Arbeiten dafür zu sorgen, dass die Webseiten dennoch erreichbar sind – einen Apache auf dem Notfallsystem zu starten.
4 5
Sicherlich fragen Sie sich, wie Daten auf eine CD-ROM überhaupt geschrieben werden sollen. Natürlich sind die Files auf dem Datenträger selbst nicht veränderbar. Allerdings können Sie zu ändernde Daten in eine RAM-Disk spielen und diese dann entsprechend mounten. Voraussetzung dafür ist, dass der Kernel mit »Ram Disk Support« (unter Block Devices zu finden) kompiliert wurde und »Default RAM disk size« groß genug ist. Die Voreinstellung von 4 096 Byte dürfte kaum genügen, ist jedoch fast beliebig erweiterbar. Allerdings sollten Sie dem System mindestens 100 MB echten Arbeitsspeicher überlassen.
6 7 8 9
Die AIDE- oder Tripwire-Datenbank sowie das aktuellste Backup der Websites muss übrigens nicht unbedingt auf eine RAM-Disk gespielt werden. Sie können die Daten auch in der /tmp-Partition oder einem anderen Verzeichnis des Hauptsystems ablegen.
10 11
Erstellen eines Images für /dev/ram und /initrd
12
Für einen ersten Test, ob Ihr Kernel fehlerfrei kompiliert wurde und der RAMDisk-Support korrekt arbeitet, sollten Sie folgende Befehle ausführen:
13
mkdir /mntram dd if=/dev/zero of=/dev/ram0 bs=1M count=2 mkfs -t ext2 /dev/ram0 mount /dev/ram0 /mntram df –h
14
Nun müssten Sie die zusätzliche Partition /mntram mit 2 MB Dateigröße in Ihrem System wiederfinden. Die Größe der RAM-Disk wurde über dd festgelegt (bs x count; 1 MB x 2 = 2 MB). Da unsere »neue Partition« noch kein Filesystem besitzt, wurde über mkfs das ext2-Filesystem zugewiesen. Es wäre unsinnig, die benötigten Daten nach dem Anlegen einer RAM-Disk über cp einzuspielen, da dieser Schritt bereits beim Erzeugen der RAM-Disk durchgeführt werden kann. Hierzu muss zunächst ein leeres Image in der benötigten Dateigröße angelegt werden und der Kernel mit »Loopback device support« (auch unter Block Devices zu finden) kompiliert worden sein.
Das Rettungssystem
349
dd if=/dev/zero of=/ramdisk bs=1M count=20 losetup /dev/loop0 /ramdisk mkfs –t ext2 /dev/loop0 mount /dev/loop0 /mntram Beachten Sie, dass die 20 MB große /ramdisk-Datei auf Festplatte geschrieben wird, bevor Sie als Loopback-Device initialisiert wurde. Da unser neues »Image« noch kein Filesystem besitzt, wurde erneut über mkfs das ext2-Filesystem zugewiesen. Bei nachträglichen Änderungen an /ramdisk ist dieser Schritt natürlich weder notwendig noch sinnvoll. Mit dem Anlegen eines Filesystems (Formatierung) werden bereits bestehende Informationen vollständig gelöscht. Der Aufruf von mkfs ist somit lediglich nach dem erstmaligen Erzeugen der »leeren ImageDatei« über dd notwendig. Dieser Schritt entfällt beim Erzeugen einer RAMDisk aus dem Image. Bevor Sie das Image über die RAM-Disk mounten, sollten Sie einige Testdateien in /mntram abspeichern und das Loopback Device deaktivieren:
umount /mntram losetup –d /dev/loop0 dd if=/RAM disk of=/dev/ram0 mount /dev/ram0 /mntram Die ersten beiden Befehle dienen zum Deaktivieren des Loopback-Devices. Beim Anlegen der RAM-Disk benötigen Sie diesmal keine Größenangaben, da wir die gewünschte Größe bereits festgelegt haben. Eine nachträgliche Vergrößerung des Speicherplatzes von /dev/ram0 wäre übrigens mit bs=1M count=40 durchaus möglich. Die /initrd Das Mounten einzelner Verzeichnisse über eine RAM-Disk ist recht praktisch. Allerdings kann mit der vorgestellten Methode das Konfigurationsverzeichnis /etc nicht ausgelagert werden, da es unmittelbar beim Bootvorgang und somit noch vor dem möglichen Mounten einer RAM-Disk benötigt wird. Die Lösung liegt in der »Initial RAM-Disk«. Der große Unterschied besteht darin, dass initrd direkt über lilo geladen und unter /initrd gemountet wird. Üblicherweise ist das benötigte Verzeichnis in Ihrem System bereits angelegt, anderenfalls können Sie dies jederzeit nachholen. Allerdings ist beim Einsatz von /initrd neben der Limitierung auf die Speicherplatzgröße einer RAM-Disk zusätzlich zu beachten, dass der Kernel mit »Initial
350
Verwaltung und Administration
1 2 RAM-Disk (initrd) support« (diese Option ist erst bei aktiviertem RAM-Disksupport verfügbar) kompiliert sein muss.
3
Die Vorgehensweise zum Erzeugen eines initrd-Images ist mit den bereits beschriebenen Schritten zum Erzeugen eines RAM-Disk-Images identisch: Legen Sie zunächst eine leere Datei über dd in der gewünschten Größe an, und mounten sowie formatieren Sie diese Datei über das Loopback-Device. Sobald die gewünschten Files kopiert und das Loopback-Device deaktiviert wurde, können Sie in lilo.conf die zusätzliche Zeile initrd=/dateiname aufnehmen. Beim nächsten Reboot des Systems wird initrd automatisch eingebunden.
4 5 6 7
Damit die Verzeichnisse innerhalb von /initrd gefunden werden, sind – wie bei Nutzung von /dev/ram – einfache Softlinks zu verwenden, beispielsweise ln -s /initrd/etc etc. Bevor Sie das Verzeichnis /etc löschen, um den Softlink anlegen zu können, sollten Sie jedoch sicherheitshalber ein tar.gz-Archiv anlegen.
8 9
Hinweise zu SUSE und Debian
10
Prinzipiell könnten Sie nach den bereits beschriebenen Schritten zu einem Read-only-System SUSE und Debian auf CD-ROM brennen. Allerdings dürfte der Speicherplatz einer CD-ROM ohne Deinstallation der für ein Rettungssystem unnötigen Programme und das Entfernen von /var/log/* und /var/lib/rpm/* (SUSE) beziehungsweise /var/lib/apt/* sowie /var/lib/dpkg/* (Debian) nicht ausreichen. Glücklicherweise wird der Inhalt von /proc ebenfalls nicht benötigt.
11 12 13
Falls Sie /var auf wenige Megabytes verkleinern konnten, bietet sich ein Einsatz von /initrd neben /tmp und /etc an. So wird Ihr Rettungssystem bedienungsfreundlicher, und Sie können manpages direkt aufrufen.
14
4.15 Raid-Systeme Es gibt gleich mehrere Raid-Varianten für teure SCSII- sowie günstige IDE-Festplatten. Sind Kosten eher zweitrangig, drängt sich für einen Webserver ein hochwertiges SCSII-Hardware-Raid-Level-7-System mit mindestens drei einzelnen Festplatten auf. Wer Geld sparen muss und in erster Linie einen Festplattenausfall kompensieren möchte, für den ist ein günstiges IDE-Software-Raid-Level-1-System mit lediglich zwei Festplatten eine Überlegung wert. Falls Sie sich die Hardware selbst zusammenstellen, ist bei Software-Raid-Systemen Vorsicht geboten: Nicht alle Software-Raid-Adapter arbeiten mit Linux und OpenBSD zusammen. Werfen Sie deshalb einen kritischen Blick auf die Hardware-Datenbank Ihrer Distribution.
Raid-Systeme
351
In Tabelle 4.10 sind sämtliche Raid-Systeme aufgeführt. Wie das Beispiel für die Kombination von 0 und 1 zeigt, können Raid-Level nach den eigenen Bedürfnissen kombiniert werden. So ist auch eine Kombination von 5 und 0 denkbar. Die Vernunftlösung, bei der Sie von den echten Vorteilen eines Raid-Systems profitieren, ist zweifelsohne Raid-Level 5. RL
Beschreibung
0
Verbindet mehrere Festplatten zu einer. Vorteile: Geschwindigkeitsgewinn durch Zusammenschaltung. Effektive Skalierbarkeit der Festplattenkapazität. Nachteil: ausfallkritisch. Fällt eine Festplatte des Verbundes aus, wird das gesamte Raid-System unbrauchbar.
1
Spiegelung zweier Festplatten. Vorteile: Datensicherheit. Fällt eine Festplatte aus, arbeitet der Server ohne Datenverlust oder Ausfall mit der verbliebenen Festplatte weiter. Durch die Datensicherung auf zwei identischen Datenträgern entsteht ein Geschwindigkeitsgewinn beim lesenden Zugriff (es kann die Festplatte verwendet werden, die weniger ausgelastet ist). Nachteil: Trotz doppelt vorhandener Festplatten steht effektiv lediglich der Speicherplatz »einer« Platte zur Verfügung.
0+1
Kombination der Raid-Level 0 und 1. Auch bekannt als Raid-Level 10. Vorteile: Performance-Gewinn und Ausfallsicherheit. Nachteile: Mindestens vier Festplatten sind notwendig. Effektiv steht lediglich die Hälfte der tatsächlich verfügbaren Festplattenkapazität zur Verfügung.
4
Lagert eine Festplatte als Backup-Medium aus und sichert dort sämtliche Daten, die lediglich auf einer Festplatte vorhanden sind. Vorteile: Datensicherheit. Fällt eine Festplatte aus, werden die Daten aus den Backup-Informationen wieder hergestellt. Große Dateien können durch die Sicherung in größere Blöcke schneller gelesen werden. Nachteile: Skalierbarkeit an Kapazität des Backup-Mediums beschränkt. Die Daten werden in größeren Blöcken gesichert, was die Lesegeschwindigkeit von kleinen Files (wie HTML-Seiten) beeinträchtigt.
5
Ab drei Festplatten möglich. Schreibt Backup-Daten, die lediglich auf einer Festplatte vorhanden sind, in eine andere. Vorteile: Datensicherheit. Fällt eine Festplatte aus, werden die Daten aus den Backup-Informationen wieder hergestellt. Geschwindigkeitsgewinn und gute Skalierbarkeit der Festplattenkapazität. Effektive Datensicherheit, ohne unnötige Festplattenkapazitäten zu verschwenden.
6
Ähnelt Raid-Level 5, legt Backup-Informationen jedoch doppelt an. Vorteile: Sehr hohe Datensicherheit durch doppeltes Backup. Gute Skalierbarkeit. Nachteile: Verlust von Speicherplatz für doppeltes Backup und Performance-Einbußen beim Schreibzugriff.
7
Lediglich in guten Hardware-Raid-Systemen verfügbar. Kann ähnlich dem Raid-Level 5 oder 6 arbeiten, verwendet jedoch zusätzliche Pufferspeicher und ein integriertes Echtzeit-Betriebssystem. Vorteile: Sehr gute Skalierbarkeit und Geschwindigkeit bei gleichzeitig hoher Ausfallsicherheit. Nachteile: Hardware-Raid-Level-7-Systeme sind teuer.
Tabelle 4.10 Vor- und Nachteile verschiedener Raid-Level (RL) in der Übersicht
352
Verwaltung und Administration
1 2
4.16 Vorstellung verschiedener Admintools
3
Nach Möglichkeit sollten Sie sämtliche Konfigurationsarbeiten manuell durchführen. Für regelmäßige Arbeiten bietet sich die Erstellung eines entsprechenden Shell- beziehungsweise Perl-Skripts an.
4
Wenn für jeden Account allerdings voneinander abweichende, individuelle Konfigurationen eine Automatisierung nur mit großem Aufwand ermöglichen und die Anpassungsarbeiten von einem Kollegen oder Partner zu erledigen sind, der mit einem SSH-Zugang nicht zurechtkommt, führt an einem aufwändigen Webinterface kein Weg vorbei.
5 6 7 8 9 10 11 12 13 14
Abbildung 4.2 Webmin ist wie ein Schweizer Taschenmesser. Von System-Accounts über Quotas bis hin zu Mail- und Webserver lässt sich so ziemlich jeder Dienst über ein Webinterface administrieren.
Häufig werden Tools wie Confixx oder Webmin (http://www.webmin.com/) bereits mit der Einrichtung Ihres Webservers vom Dienstleister vorinstalliert. Webmin können Sie gegebenenfalls nachträglich installieren. Dies gilt selbstverständlich auch für Confixx. Allerdings fällt hier eine zusätzliche Lizenzgebühr für die Software an und Anpassungsarbeiten am Quellcode sind natürlich auch nicht möglich. Immerhin dürfen Sie sich unter http://www.confixx.de durch ein rudimentäres Beispielsystem klicken. Für das Alternativprodukt WEBppliance, das derzeit allerdings nur mit Red Hat Enterprise Linux ES 03 und Fedora arbeitet, stehen über http://www.ensim.de Video-Touren bereit.
Vorstellung verschiedener Admintools
353
Allen Tools ist jedoch gemeinsam, dass nicht sämtliche Möglichkeiten einer manuellen Konfiguration von Apache oder Postfix bereitstehen. WebspaceReseller, die ohne ausgefallene Wünsche auskommen und lediglich Hauptfunktionen wie PHP, Perl oder SSI über ein simples Ja/Nein-Feld auswählen möchten, werden mit den auf diese Aufgabe abgestimmten Confixx Professional oder Ensims WEBppliance jedoch zufriedener sein als mit Webmin, das sogar Funktionen für Samba und einen Print-Server enthält. Wer individuellere Einstellungsmöglichkeiten benötigt oder Automatismen einbauen möchte, kommt nicht an einer manuellen Erweiterung des Perl-Programms Webmin vorbei. Dies gilt auch für die Administration von OpenBSD. Im Gegensatz zum Open-Source-Projekt können weder WEBppliance noch Confixx auf irgendeinem BSD-System installiert werden. Hinweis Falls Sie sich für eines der genannten Programme entscheiden, sollten Sie unbedingt auf eine sichere Authentifizierung über SSL achten.
354
Verwaltung und Administration
1 2
5 Server absichern
3 4
5.1
Vorbemerkung.......................................................... 357
5.2
Einspielen von Security-Updates.............................. 358
5.3
Paketfilter................................................................. 362
5.4
Systrace .................................................................... 382
7
5.5
Chroot ...................................................................... 388
8
5.6
Feinabstimmung....................................................... 389
5.7
Nessus...................................................................... 394
5.8
nmap ........................................................................ 397
5.9
Portscans erkennen .................................................. 398
5.10 Integritätsprüfung mit AIDE..................................... 399 5.11 Das Intrusion-Detection-System Snort .................... 403 5.12 Absichern von Logfiles ............................................. 406 5.13 Logfile-Analyse......................................................... 407 5.14 Sicherheitsinformationen beziehen .......................... 416 5.15 Verhalten beim Super-GAU ...................................... 417
5 6
1
Einführung
2
Erste Schritte
3
Wichtige Serverdienste
4
Verwaltung und Administration
5
Server absichern
6
Linux-Vserver
7
Der eigene Server
8
Bürokratisches
1 2
5
Server absichern
3
If security is no concern, why not just delete the data and turn the PC off, saving electricity – after all the data doesn't really need to be copied over, it's of no concern if it's there or not … (Dom De Vitto – www.devitto.com)
4 5 6
5.1
Vorbemerkung 7
Sicherheit spielte bereits in den vorangegangenen Kapiteln eine wichtige Rolle. Dennoch wurden einige bedeutende Aspekte noch nicht beleuchtet. Dies hängt nicht zuletzt damit zusammen, dass es nicht sinnvoll ist, beispielsweise die Integritätsdatenbank von AIDE zu erzeugen, bevor das Server-System abschließend eingerichtet ist. Paketfilterung wurde ebenfalls noch nicht angesprochen, da sonst Regeln zu SSH oder FTP quer durch das ganze Buch verstreut wären.
8 9 10
Leider werden Sie selbst mit allen im Buch beschriebenen Maßnahmen keinen absolut sicheren Webserver aufbauen können. Totale Sicherheit gibt es nicht. Wer einen Webserver betreibt, muss damit rechnen, dass irgendwann eine Lücke gefunden wird. Sogar Systrace und ein Paketfilter sind gegen einen Bug im Kernel machtlos. Obendrein kann auch Security-Software Lücken enthalten, die ein Angreifer für sich ausnutzen kann.
11 12 13
Wer vollständige Sicherheit wünscht, muss den Rechner abschalten. Das ist jedoch Unsinn, da der Server dann natürlich nicht mehr nutzbar ist. Dennoch ist übertriebene Panik fehl am Platz:
14
왘 Spielen Sie Sicherheits-Patches unmittelbar ein. 왘 Entfernen Sie unnötige Software vom Server. 왘 Regelmäßige Backups verhindern möglichen Datenverlust. 왘 Setzen Sie einen Paketfilter mit restriktiven Regeln ein. 왘 Gestatten Sie durch Systrace den von außen erreichbaren Programmen ledig-
lich Zugriff auf tatsächlich benötigte Dateien und System-Befehle. 왘 Prüfen Sie mit AIDE regelmäßig die Integrität Ihres Systems. 왘 Lassen Sie empfangene Pakete von Snort auf Angriffsmuster prüfen. 왘 Überwachen und sichern Sie Ihre Logfiles.
Diese Maßnahmen sind in einem vertretbaren Zeitrahmen realisierbar und schützen zuverlässig vor Script Kiddies und Hobby-Crackern. Wer auf seinem Server keine besonders bekannten Webseiten hostet und Cracker nicht mit
Vorbemerkung
357
Sprüchen wie beispielsweise »wir sind der Secure-Hoster Nr. 1 – kein einziger Hack in den letzten 20 Jahren« provoziert, ist durchaus auf der sicheren Seite. Es gibt unzählige schlecht gesicherte Webserver. Warum sollte sich ein Script Kiddie an Ihrem Server die Zähne ausbeißen wollen? Die wirklichen Könner der BlackHat-Szene beschäftigen sich zudem bevorzugt mit Weltkonzernen, Sicherheitsfirmen, Staatsorganen oder ungeliebten Software-Häusern.
5.2
Einspielen von Security-Updates
Spielen Sie Sicherheits-Updates so schnell wie möglich ein. Dieser Satz mag sich trivial anhören, wird jedoch oftmals nicht beherzigt. Ein bekannt gewordenes Sicherheitsloch ist wie eine Zeitbombe. Script Kiddies stürzen sich mit Begeisterung auf Exploits und lassen ganze IP-Adressräume automatisiert nach kürzlich bekannt gewordenen Sicherheitslücken abklappern, um automatisiert in offene Systeme einzudringen. Betrachten Sie das Einspielen von sicherheitsrelevanten Updates also eher als ein Wettrennen, für das Sie auch am Wochenende stets bereit sein müssen. Lieber 20 Minuten vom Sonntag »geopfert«, als am Montag einen geknackten Server neu aufsetzen zu müssen. Trotz aller Eile ist Hektik fehl am Platz. Bevor Sie Updates auf Ihrem Server einspielen, sollten Sie die Pakete auf dem lokalen Testrechner überprüfen. Obwohl Probleme äußerst selten auftreten, ist es besser, auf Nummer sicher zu gehen. Nichts ist ärgerlicher als ein fehlerhaftes Update-Paket, das einen wichtigen Server-Dienst unerwartet lahm legt. Falls zu einem Sicherheitsloch noch kein Update verfügbar ist, sollten Sie über den Einsatz einer Alternativlösung oder das Deaktivieren des Dienstes nachdenken. Manchmal hinken die Distributionen mit der Veröffentlichung eines Updates selbst den Entwicklern hinterher. Werfen Sie einen Blick auf die jeweilige Projekt-Homepage und kompilieren Sie gegebenenfalls eine aktuelle Version aus dem CVS-Repository.
5.2.1
Debian
Die Debian-Distribution macht es Admins besonders leicht. Aktualisieren Sie die Paketdatenbank als Root mit dem Befehl apt-get update, bevor Sie die Sicherheits-Updates über apt-get upgrade einspielen. Damit apt-get korrekt arbeitet, sind die zu nutzenden Security-Server in /etc/apt/sources.list unbedingt einzutragen:
deb http://security.debian.org/ stable/updates \ main contrib non-free
358
Server absichern
1 2 deb http://security.debian.org/ woody/updates \ main contrib non-free deb http://security.debian.org/debian-non-US \ stable/non-US main contrib non-free deb http://security.debian.org/debian-non-US \ woody/non-US main contrib non-free
3 4 5
Paketspezifische Informationen zu Sicherheitsfragen können Sie ebenfalls unter http://www.debian.org/security/ einsehen. Wenn Sie nicht sicher sind, ob ein Paket aktualisiert wurde, dann sollten Sie einen Blick in changelog werfen: zcat /usr/share/doc/php4/changelog.gz | less.
6 7
Abonnieren Sie die Mailingliste debian-security-announce, um auf dem Laufenden zu bleiben, ohne ständig die Website überprüfen zu müssen. Diskussionen zu Sicherheitsfragen können in debian-security geführt werden. Beide Mailinglisten sind über http://www.debian.org/MailingLists/subscribe zu beziehen.
8 9 10
5.2.2
SUSE
11
Unter http://www.suse.de/de/private/download/updates/ finden Sie Sicherheits-Updates zu aktuellen und gepflegten SUSE-Distributionsversionen. Seit Version 8.1 stehen neben dem vollständigen RPM-Programm-Paket zudem Patches zur Verfügung. Diese enthalten lediglich die Dateien, die sich geändert haben. Nur wenn Sie ein Programmpaket neu installieren möchten, sind die vollständigen RPM-Pakete interessant, da Sie so das nachträgliche Updaten beziehungsweise Patchen des ursprünglichen Pakets sparen.
12 13 14
Um zu prüfen, ob das Paket auf Ihrem System überhaupt installiert ist, sollten Sie vor einem Download den Befehl rpm –qa | grep Paketname ausführen. Wenn Sie sich nicht sicher sind, welche Sicherheitslücken in dem bestehenden Paket behoben sind, rufen Sie rpm -q --changelog Paketname auf. Nach dem Download der Patch-Variante genügt die Eingabe von rpm –U paketname.patch.rpm als Root, um das Sicherheits-Update einzuspielen. Neuinstallationen werden wie gewohnt mit rpm –i paketname.rpm durchgeführt. Falls Ihnen die Bedienung von YaST unter der Konsole zusagt und Sie SUSEconfig vertrauen, können Sie alle relevanten Pakete als Root auch mit you (Yast Online Update) automatisiert einspielen. Hinweis: Der Informationsabgleich zwischen installierten Paketen und zu aktualisierenden Versionen nimmt einige Zeit in Anspruch.
Einspielen von Security-Updates
359
Um auf dem Laufenden zu bleiben, sollten Sie die Mailingliste »suse-securityannounce« und für Diskussionen zu Sicherheitsfragen die Liste »suse-security« unter: http://www.suse.de/de/private/support/online_help/mailinglists/ abonnieren.
Abbildung 5.1 Gewöhnungsbedürftig und hässlich: you kann via Putty ebenfalls remote zum Einspielen von Sicherheits-Updates genutzt werden.
5.2.3
OpenBSD
Neue Programmpakete, die Sicherheits-Updates enthalten, finden Sie unter http://www.openbsd.org/pkg-stable.html. Es handelt sich hierbei um eigenständige Pakete. Bei einer Neuinstallation sollten Sie also zunächst prüfen, ob das gewünschte Paket bereits ein Sicherheits-Update erhalten hat, und in diesem Fall gleich das korrigierte Paket installieren. Damit Sie das neue Paket mit pkg_add Paketname.tgz installieren können, müssen Sie das alte mit pkg_ delete Paketname entfernen. So weit, so einfach. Leider war das noch nicht alles, denn unter http://www.openbsd.org/de/errata.html finden Sie Patches zu elementaren
360
Server absichern
1 2 Systembestandteilen. Am Einspielen dieser Patches führt lediglich dann ein Weg vorbei, wenn das betroffene Programmpaket durch alternative Software ersetzt werden kann (zum Beispiel statt named alias Bind4 zu aktualisieren lieber Bind9 installieren). Einige Patches werden Sie jedoch manuell einspielen müssen. Neben der Patch-Datei müssen Sie den jeweiligen Quellcode via CVS beziehen (siehe man cvs). Der Befehl grep »cvs« 005_named.patch liefert als Ergebnis den Pfad zu named: »RCS file: /cvs/src/gnu/usr.sbin/named/«. Wechseln Sie in das Verzeichnis /usr, bevor Sie die benötigten Quellen beziehen:
3 4 5 6
cvs -d [email protected]:/cvs \ co -rOPENBSD_3_6_BASE src/usr.sbin/named/
7
Der »Trick« besteht darin, von »[email protected]« im Verzeichnis /cvs den Quellcode von Bind über die Angabe von co -rOPENBSD_X_Y_ BASE (wobei X und Y für Ihre OpenBSD-Version stehen) zu beziehen. Mit dem Quellverzeichnis src/usr.sbin/named/ wird die Eingabe abgeschlossen. Eine Liste aller CVS-Server finden Sie unter http://www.openbsd.org/anoncvs.html.
10
Lassen Sie sich die Patchdatei mit less anzeigen. Hier finden Sie Informationen, wie Sie den Patch einspielen und die Quellen danach kompilieren können.
11
8 9
Um nicht täglich nach neuen Sicherheits-Updates oder Patches sehen zu müssen, bietet sich ein Abonnement der Mailingliste security-announce unter http://www.openbsd.org/de/mail.html an. Spezifische Sicherheitsfragen können in der allgemeinen Mailingliste misc gestellt werden.
12 13 14
Automatisiertes und vereinfachtes Patchen mit Tepatch Tepatch ist kein offizieller Bestandteil der OpenBSD-Distribution, kann jedoch über http://www.gwolf.cx/soft/tepatche/ bezogen werden und ist auf der CD-ROM enthalten. Das Perl-Programm benötigt neben dem Paket p5-libnet sämtliche Quellen für das System und den Kernel. Zu beziehen sind diese über
cd /usr cvs -q -d [email protected]:/cvs \ get -rOPENBSD_3_6 -P src Nach make install müssen Sie in der Konfigurationsdatei /etc/tepatche.conf die von Ihnen genutzte OpenBSD-Version eintragen. Weiterhin ist über touch /var/db/tepatche/statusfile eine leere Datei anzulegen, in der Tepatch eingespielte Patches verzeichnet. Obwohl tepatch als Cron-Job gestartet werden kann, sollten Sie davon Abstand nehmen. Falls bei einem Update etwas schief läuft, müssen Sie gegebenenfalls zeitnah »das System manuell korrigieren«. Zudem sollten Sie über-
Einspielen von Security-Updates
361
prüfen, welche Patches veröffentlicht und von Tepatch tatsächlich eingespielt wurden. Werden Patches nachträglich korrigiert, könnte es passieren, dass tepatch der Meinung ist, den Patch nicht einspielen zu müssen. Dies ist in der Vergangenheit bei einem Patch zu OpenSSH vorgekommen. Falls Sie nicht sicher sind, ob ein Patch eingespielt wurde, sollten Sie den entsprechenden Eintrag in der statusfile-Datenbank entfernen und tepatch erneut starten.
5.3
Paketfilter
Ein Paketfilter beschränkt ein- und ausgehende Datenpakete auf einzelne Ports und Protokolle. Unerwünschte Pakete können entweder verworfen oder zurückgewiesen werden. Da auf einem Internetserver jedoch nur Programme laufen (sollten), die tatsächlich benötigt werden, mögen Sie sich fragen, ob sich der Aufwand für einen Paketfilter lohnt. Die Antwort ist: Ja. Mit einem Paketfilter können Sie Dienste wie MySQL oder SNMP, die zwar auf dem Server laufen sollen, aber nicht von außen erreichbar sein müssen, zusätzlich schützen. Weiterhin können Sie mit einem Paketfilter das Scannen Ihres Servers erschweren sowie unerwünschte ICMP-Pakete unterbinden oder nur bestimmten IP-Adressen erlauben. Im UNIX-Umfeld gibt es vielfältige Paketfilterlösungen. Die bekanntesten sind iptables (Linux Kernel 2.4), ipchains (Linux Kernel 2.2) und ipfw (ältere BSDSysteme, Darwin und Mac OS X) sowie ipf (von NetBSD und FreeBSD genutzt). OpenBSD geht seit Version 3.0 mit dem pf eigene Wege. Die Syntax von pf ist an ipf angelehnt, jedoch erfolgt das Logging über tcpdump, und die Performance konnte deutlich gesteigert werden. Obwohl sich die einzelnen Paketfilter in Syntax, Features und Konfiguration meist deutlich unterscheiden, ist das Prinzip sehr ähnlich, so dass Sie die folgenden Beispiele für iptables und pf ebenfalls auf andere Paketfilter übertragen können.
5.3.1
TCP
Das Transport-Control-Protocol ist das meistgenutzte Protokoll, um Daten zu transportieren. Damit einzelne Dienste gezielt angesprochen werden können, müssen Sie neben dem Port-Bereich von 1 bis 1023 den so genannten Highport-Bereich von 1024 bis –65535, der jedem Nutzer und jedem Programm offen steht, und deshalb auch als der unprivilegierte Portbereich bezeichnet wird, freischalten. Trojaner und Backdoors greifen gerne auf diesen HighportBereich zurück. Leider wird für »Passives FTP« oder die Kommunikation mit Nameservern der Highport-Bereich benötigt.
362
Server absichern
1 2 Über die Stateful-Inspection-Funktion von iptables (siehe Option -m in man iptables) sowie OpenBSD (siehe flags in man pf.conf) können Sie den Verbindungszustand zwar abfragen und so ausschließlich bestehende Verbindungen eingehend zu Highports erlauben, jedoch lassen sich diese Zustandsmeldungen fälschen, und schon stehen Ihre Regeln auf wackeligen Beinen. Auch die Einschränkung des Quellports hilft nur bei flüchtigen Angriffen. So können Sie keinesfalls sicher sein, dass unter Port 21 von Server XY tatsächlich ein fremder FTP-Server läuft.
3 4 5 6
Daher sollten Sie sich die Mühe machen, belegte Highports, die nach außen nicht erreichbar sein sollen, auszugrenzen und beispielsweise eine Regel für den Portbereich 1024–3005 sowie eine für 3007–65535 festlegen, um sicherzugehen, dass der MySQL-Port 3006 trotz korrekt arbeitendem Paketfilter nicht dennoch über einen Trick von außerhalb angesprochen wird. Damit Sie nicht jede Regel doppelt schreiben müssen, bietet es sich an, die betroffenen Ports (wie in Abschnitt 5.3.17 beschrieben) am Anfang der Filterregeln zu sperren.
5.3.2
7 8 9 10
UDP
Auf einem Webserver werden nur wenige UDP-Ports benötigt. Das so genannte User-Datagramm-Protocol ist kleiner und schneller als TCP, da es beispielsweise keine Empfangsbestätigung erwartet.
11 12
UDP wird unter anderem zur DNS-Kommunikation, von ntpdate und von FileServern für SMB oder AppleTalk verwendet. Der Portbereich reicht wie bei TCP von 1 bis 65535.
13 14
5.3.3
ICMP
Das Internet-Control-Message-Protocol dient in erster Linie dazu, Fehler- und Zustandsmeldungen zu übertragen. Bekanntestes Beispiel ist ping, mit dem sich die grundsätzliche Erreichbarkeit und Antwortzeit eines Hosts überprüfen lässt. Die »destination unreachable«-Meldung ist nützlich, um Applikationen bei Nichterreichbarkeit eines Dienstes zu einem vorzeitigen Abbruch zu verleiten, anstatt den Timeout abzuwarten. Leider lassen sich ICMP-Pakete sowie Pings, beispielsweise für DOS-Attacken oder zum Scannen eines Hosts, missbrauchen. Deshalb gilt auch hier die Regel: Zunächst alles verbieten und danach freigeben, was tatsächlich benötigt wird. Global können Sie bis auf Fragmentation Needed und Parameter Problem prinzipiell alles verbieten.
Paketfilter
363
Im Gegensatz zu TCP und UDP ist ICMP nicht portbasiert. Es übermittelt Meldungen oder Anfragen anhand einer Type/Code-Wertekombination. In Tabelle 5.1 finden Sie eine Übersicht über die wichtigsten Parameter. Wer einen Blick auf sämtliche Parameter werfen möchte, sollte der Site http://www.iana.org/ assignments/icmp-parameters einen Besuch abstatten. Typ/Code
Name
type 0
Echo Reply
type 3
Destination Unreachable
type 3 code 3
Port Unreachable
type 3 code 4
Fragmentation Needed and Don't Fragment was Set
type 4
Source Quench
type 5
Redirect (ignorieren und statische Routen verwenden)
type 8
Echo Request
type 11
Time Exceeded
type 11 code 0
Time to Live Exceeded
type 11 code 1
Reassembly Time Exceeded
type 12
Parameter Problem (signalisiert Probleme mit IP-Headern)
type 13
Timestamp Request
type 14
Timestamp Reply
type 17
Address Mask Request
type 18
Address Mask Reply
Tabelle 5.1 Übersicht über die wichtigsten ICMP-Pakete
5.3.4
Vorgehensweise
Bei OpenBSD ist in /etc/rc.conf die Zeile pf=NO in pf=YES zu ändern. Nach einem Neustart steht der Paketfilter mitsamt dem Logging-Daemon pflogd zur Verfügung. Aktuelle Linux-Distributionen werden bereits mit 2.4er Kernels ausgeliefert. Dennoch sollten Sie einen eigenen Kernel mit SYNcookie-Unterstützung kompilieren (siehe Abschnitt 2.9.1, Linux). Das ältere ipchains ist wegen fehlender »Stateful Inspection« nicht empfehlenswert. Grundsätzlich gibt es zwei Methoden, um Filterregeln zu definieren: Nach Scans des Servers (siehe Abschnitt 5.8, nmap) ungewünschte Ports und Proto-
364
Server absichern
1 2 kolle schließen oder alles verbieten und ausschließlich tatsächlich benötigte Dienste gezielt freigeben.
3
Sie sollten sich für die zeitaufwändigere, aber effektivste Variante entscheiden und zunächst sämtliche ein- und ausgehenden Pakete verbieten. Hierbei ist das Ignorieren (drop oder block) eines Paketes dem Zurückweisen (reject oder block return-rst) im Normalfall vorzuziehen, da diese Methode beispielsweise Portscans erschwert.
4 5 6
5.3.5
Syntax und Definition von Regeln
7
Warnung: Mit einem Paketfilter können Sie sich selbst aussperren. Erstellen und testen Sie die Regeln deshalb unbedingt mit Ihrem lokalen Spiegelserver, bevor Sie Regeln auf dem Internetserver setzen. Um Tippfehler zu vermeiden, sollten Sie zur Aktivierung oder Änderung bestehender Filterregeln unter Linux unbedingt Shell-Skripte oder iptables-save beziehungsweise iptables-restore verwenden.
8 9 10
Hinweis Auf der CD-ROM finden Sie im Verzeichnis linux/config die Datei ipfilter für ipchains sowie unter openbsd/config das File pfilter für den OpenBSD-Paketfilter. Hier sind alle besprochenen Regeln enthalten und können so ohne mühseliges Abtippen übernommen und an die eigenen Wünsche angepasst werden.
11 12 13
iptables
14
In der Manpage zu iptables ist die umfangreiche Syntax kurz erläutert. Wer sich näher für Masquerading und die Konzeption von Firewall-Systemen interessiert, dem sei »Das Firewall-Buch« von Wolfgang Barth (SUSE PRESS) ans Herz gelegt. Für einen Webserver ist folgende Syntax von Bedeutung:
iptables –A|D INPUT|OUTPUT [--protocol] [--destination] [--source] [-i/o] [-m] –j ACCEPT|DROP|REJECT|LOG 왘
iptables –A|D: Erstellt neue (-A) beziehungsweise löscht bestehende (-D) Regel. Beim Löschen ist die Regelnummer oder die gesamte Filterdefinition anzugeben.
왘
INPUT|OUTPUT: Wendet die Regel für eingehende INPUT- oder ausgehende OUTPUT-Verbindungen an.
왘
--protocol: Sie können das Protokoll auf TCP, UDP oder ICMP festlegen (Abkürzung ist -p).
Paketfilter
365
왘
--destination: Optional kann die Zieladresse über -d IP-Adresse definiert werden. Zusätzlich können Sie zudem den Port-Bereich mit --dport festlegen. Ein Port-Bereich ist über einen Doppelpunkt zu definieren. Der Highport-Bereich ist beispielsweise über --dport 1024:65535 ansprechbar. ICMP-Protokolle sind mit --icmp-type NAME festzulegen. Der richtige »NAME« kann über das Kommando iptables -p icmp -h in Erfahrung gebracht werden.
왘
--source: Die Definition der Absenderadresse ist mit --destination identisch. Anstelle von -d oder --dport ist jedoch -s und --sport anzugeben.
왘
-i|o: Optional können Sie das Interface beschränken. Das Interface ist bei eingehenden Verbindungen INPUT mit der Option -i zu definieren. Analog dazu führt iptables -A OUTPUT -p ICMP -i eth0 zu einer Fehlermeldung, da bei ausgehenden Verbindungen das Interface mit -o eth0 festzulegen ist.
왘
-m: Mit -m state --state leiten Sie die »Stateful Inspection«-Funktion von iptables ein. NEW erlaubt lediglich den Verbindungsaufbau und RELATED, ESTABLISHED lässt nur Pakete passieren, die zu bestehenden Verbindungen gehören.
왘
-j: Legt die Aktion fest. ACCEPT dient dazu, ein Paket zu akzeptieren. Mit DROP wird das Paket ignoriert, REJECT weist es zurück. Nutzen Sie LOG, um Logfile-Einträge zu erzeugen.
In Linux können die Regeln direkt auf der Kommandozeile eingegeben werden. Eine Liste der gesetzten Regeln kann mit iptables -vL [INPUT|OUTPUT] abgefragt werden. Interessant ist der Befehl iptables -F [INPUT|OUTPUT], der sämtliche Regeln oder (wenn angegeben) nur die Input- beziehungsweise Output-Regeln löscht. Als Besonderheit ist die Default Policy lediglich über iptables -P INPUT|OUTPUT auf DROP|ACCEPT|REJECT zu setzen, zum Beispiel: iptables –P INPUT ACCEPT. Weitere Optionen dürfen nicht verwendet werden. Bevor Sie iptables -F aufrufen, sollten Sie die Default Policy für Input sowie Output unbedingt auf Accept ändern. Sitzt die Default Policy auf Drop oder Reject, ist der Rechner von außen nicht mehr zu erreichen und eventuell offene SSH-Verbindungen werden gekappt. Wenn Sie Filterregeln manuell angepasst haben, können diese mit dem Kommando iptables-save > Dateiname gesichert werden. Um die Regeln auf dem Webserver anzuwenden, ist iptables-restore < Dateiname zu nutzen. Alternativ können Sie auch sämtliche Befehle in einem »Shell-Skript« ablegen.
366
Server absichern
1 2 Hinweis: Lokale Prozesse kommunizieren über das Loopback Device (lo). Wenn Sie als Default-Policy alles verbieten, sollte als erste Regel das LoopbackDevice freigeschaltet werden:
3 4
iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT
5
OpenBSD
6
Einen umfassenden Einblick in pf erhalten Sie in der Manpage zu pf.conf. Für einen Webserver ist folgende Syntax von Bedeutung:
7
Rule Direction [log] [quick] [Device] [proto] [Address [port] [icmp-type [code]]] [flags] [keep state] 왘
8
Rule: Erlaubt pass oder ignoriert block, weist block return-rst beziehungsweise block return-icmp zurück.
왘
Direction: Eingehend in oder ausgehend out.
왘
log: Ist die Regel auf ein Paket zutreffend, erzeugt pflogd einen Logeintrag.
왘
quick: Nutzen Sie diese Option, um das Paket sofort zu akzeptieren oder abzulehnen. Der Paketfilter sieht zutreffende quick-Regeln als letzte zu prüfende Zeile an. Wenden Sie diese Option möglichst häufig an, um die Performance zu steigern und die Belastung des Systems zu verringern. Kombinieren Sie quick mit keep state, wenn weitere Verbindungsanfragen (wie zum Beispiel bei ftp oder ssh) absehbar sind.
왘
Device: Erlaubt die Definition eines Interfaces. Der Interface-Name Ihrer Netzwerkkarte hängt mit dem Treiber zusammen. So steht on sis0 für das gleichnamige Netzwerk-Interface (siehe Abschnitt 2.6.3, Konfiguration eines Netzwerk-Interfaces unter OpenBSD).
왘
proto: Optional kann ein Protokoll festgelegt werden, zum Beispiel mit der Eingabe proto icmp. Sollen zwei Protokolle gleichzeitig angesprochen werden, ist eine geschweifte Klammer zu verwenden: proto { tcp, udp }.
왘
Address: Mit dem Kürzel inet werden sämtliche IP-Adressen und Port-Bereiche beziehungsweise ICMP-Protokolle abgedeckt. Alternativ können Sie die IP-Adresse des Absenders from und des Empfängers to eingeben. Zusätzlich kann der jeweilige Port-Bereich angegeben werden. So steht port >1023 für sämtliche Highports, port 1023 >< 3006 erlaubt jedoch ausschließlich die Highports von 1024 bis 3005. Bei ICMP-Protokollen kann icmp-type angegeben werden. Gegebenenfalls ist der Code mit zu übergeben (icmp-type 11 code 0 hat eine andere Bedeutung als icmp-type 11).
Paketfilter
9 10 11 12 13 14
367
왘
Flags: Bei der Übertragung von Paketen spielen die so genannten Flags, die den Verbindungszustand eines Pakets beschreiben, eine wichtige Rolle. Sie können die Flags ebenfalls im Paketfilter abfragen und so über flags /S nur bestehende Verbindungen erlauben beziehungsweise lediglich einen Verbindungsaufbau mit flags S zulassen.
왘
keep state: Erzeugt einen State für die aktive Verbindung und beschleunigt dadurch weiteren Datenverkehr, da pf die Filterregeln für diese Verbindung nicht noch einmal prüfen muss. Empfehlenswert ist dies unter anderem für ftp-, ssh- oder http-Verbindungen. Bei einmaligen Anfragen oder kurzen Verbindungen wie ntpdate oder ping ist keep state unsinnig. Kombinieren Sie dann quick mit keep state.
Das Regelwerk ist in einer Filterkonfigurationsdatei zu definieren und mit pfctl -f Filterdatei einzulesen. Nutzen Sie in der Testphase zusätzlich die Option -x misc, um bei Syntaxfehlern die Zeilennummer der fehlerhaften Regel zu erfahren. Da OpenBSD mit der Übergabe neuer Filterkonfigurationen stets die bestehenden Regeln löscht, kann echo "Filterregel" | pfctl -f nur zu Testzwecken sinnvoll eingesetzt werden. Eine Übersicht der gesetzten Filterregeln erhalten Sie durch pfctl -s rules. In der Testphase ist es häufig praktisch, dass der Paketfilter sich durch Eingabe von pfctl -d kurzerhand deaktivieren und über pfctl -e ebenso schnell reaktivieren lässt. Gesetzte Filterregeln bleiben hierbei erhalten.
5.3.6
Logging zur Regelerstellung nutzen
Das Loggen von Filterregeln ist nicht nur zum Protokollieren von Angriffsversuchen nützlich. Insbesondere wenn Sie nicht sicher sind, welche Ports und Protokolle für einen Dienst freizugeben sind, ist Loggen hilfreich, da Sie anhand der Meldungen die benötigten Protokolle und Port-Bereiche gezielt freigeben können. Am besten erlauben und loggen Sie in der Testphase sämtliche ein- und ausgehenden Pakete. Dies beschleunigt die Regelerstellung erheblich, da Sie nicht erst mühselig die notwendigen Protokolle und Ports eingehend erlauben müssen, um zu erkennen, welche Ports und Protokolle ausgehend benötigt werden (da keine Pakete »den Rechner erreichen«, wird er keine Antwortpakete versenden). Bauen Sie dann gezielt die verschiedenen Verbindungen auf und werfen Sie nach jedem genutzten Dienst einen Blick in das Logfile, um die entsprechende Regel erstellen zu können.
368
Server absichern
1 2 iptables Loganweisungen müssen in einer zusätzlichen Regel definiert werden:
3
iptables –A INPUT –i eth0 –j LOG iptables -A OUTPUT -o eth0 -j LOG
4
Nun werden sämtliche Pakete, die über das Netzwerk-Interface eth0 laufen, Syslogd übergeben. Als Loglevel wird info verwendet, und die Facility lautet kern. Üblicherweise finden Sie eine Zeile wie:
5
kern.*
6
-/var/log/syslogd
7
bereits in der Datei /etc/syslog.conf Ihrer Distribution. Notfalls können Sie die Konfigurationsdatei selbst erweitern und den Syslogd neu starten, um das Logging von iptables-Paketen zu aktivieren. Siehe Abschnitt 4.2, Syslogd. Das Logfile können Sie mit dem Befehl tail -f /var/log/firewall beobachten:
8 9
Dec 11 16:50:10 IN=eth0 OUT= SRC=192.168.0.99 DST=192.168.0.32 PROTO=TCP SPT=3010 DPT=22 Dec 11 16:50:10 IN= OUT=eth0 SRC=192.168.0.32 DST=192.168.0.99 PROTO=TCP SPT=22 DPT=3010
10 11
Der gekürzte Logfile-Eintrag enthält alle wichtigen Informationen. Am 11. Dezember, 16:50:10 Uhr, sandte der Rechner 192.168.0.99 unter Port 3010 ein TCP-Paket an den Port 22 von 192.168.0.32. Das Netzwerk-Interface eth0 IN=eth0 hat die Daten empfangen. Unmittelbar darauf antwortete der Rechner 192.168.0.32 OUT=eth0 ebenfalls über das Netzwerk-Interface eth0 mit einem TCP-Paket von Port 22 an 3010. Folgende Regeln erlauben die Kommunikation auf dem Rechner 192.168.0.32:
iptables -A -d iptables -A -s
12 13 14
INPUT -p TCP -s 0/0 --sport 1024:65535 \ 0/0 --dport 22 –i eth0 -j ACCEPT OUTPUT -p TCP -d 0/0 --dport 1024:65535 \ 0/0 --sport 22 –o eth0 -j ACCEPT
Auf dem Server 192.168.0.32 ist nun der SSH-Daemon für die Außenwelt freigegeben. Vielleicht wundern Sie sich über die Angabe 1024:65535. Stellen Sie sich anstelle des Doppelpunktes einen Bindestrich vor: Es sind sämtliche Highports von 1024 bis 65535 freigegeben. Hintergrund ist die Nutzung eines »zufälligen« und freien Ports ab 1024 aufwärts. OpenBSD Loganweisungen können in einer Extraregel stehen oder an bestehende Anweisungen geknüpft werden:
Paketfilter
369
block in log on sis0 inet all block out log on sis0 inet all Sämtliche ein- und ausgehenden Pakete des Netzwerk-Interfaces sis0 werden geblockt und geloggt. Alternativ können Sie in der ersten Zeile Ihrer PaketfilterKonfigurationsdatei detailliert festlegen, welche Pakete geloggt werden sollen. Ist kein Blocken erwünscht, können Sie pass verwenden. Nachträgliche Blockanweisungen führen zum Verwerfen des Pakets; der Logeintrag wird trotzdem erzeugt:
pass in log on sis0 inet proto { tcp, udp } all pass out log on sis0 inet proto icmp all Diese Regeln loggen alle eingehenden TCP- und UDP-Pakete sowie alle ausgehenden ICMP-Pakete des Netzwerk-Interfaces sis0. Über das Kommando tcpdump -n -e -ttt –q -r /var/log/pflog | tail -10 werden die letzten 20 Logeinträge ausgegeben. Ein gekürztes Beispiel:
17:01:28.615622 192.168.0.99.3012 > 192.168.0.32.22: tcp 17:01:28.615654 192.168.0.32.22 > 192.168.0.99.3012: tcp Lesart: Um 17:01:28 Uhr sandte der Rechner 192.168.0.99 unter Port 3012 ein TCP-Paket an den Port 22 von 192.168.0.32. Unmittelbar darauf antwortete Rechner 192.168.0.32 ebenfalls mit einem TCP-Paket von Port 22 an 3012. Um den Vorgang auf 192.168.0.32 zu erlauben, sind folgende Regeln notwendig:
pass in on sis0 proto tcp from 0/0 port >1023 to 0/0 port 22 pass out on sis0 proto tcp from 0/0 port 22 \ to 0/0 port >1023 Nun ist auf dem Rechner 192.168.0.32 der SSH-Daemon für die Außenwelt freigegeben. Vielleicht wundern Sie sich über die Angabe port >1023. Dieses Kürzel steht für sämtliche Highports von 1024 bis 65535. Hintergrund ist die Nutzung eines »zufälligen« und freien Ports ab 1024 aufwärts.
5.3.7
SSH
Der Secure-Shell-Server wurde bereits in den Beispielen zu Linux und OpenBSD angesprochen. Allerdings fehlt eine Regel, um vom Webserver auf andere SSH-Server zugreifen zu können. An dieser Stelle wird es interessant, da sämtliche Highports eingehend freigeschaltet werden. Allerdings erfolgt der Verbindungsaufbau von unserer Seite aus, so dass über Stateful Inspection ausschließlich bestehende Verbindungen eingehend zu Highports erlaubt werden müssen.
370
Server absichern
1 2 iptables
3
# Ausgehende Verbindung zu fremdem SSH-Server iptables -A OUTPUT -p TCP -d 0/0 --dport 22 \ -s 0/0 --sport 1024:65535 –o eth0 -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 22 \ -d 0/0 -–dport 1024:65535 -i eth0 -j ACCEPT # Eingehende Verbindung zum SSH-Server des Webservers iptables -A INPUT -p TCP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 22 -i eth0 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 1024:65535 \ -s 0/0 --sport 22 -o eth0 -j ACCEPT
4 5 6 7 8
OpenBSD
9
# Ausgehende Verbindung zu fremdem SSH-Server pass out quick proto tcp from any to any port 22 \ keep state pass in quick proto tcp from 0/0 port 22 to 0/0 \ port >1023 flags /S keep state # Eingehende Verbindung zum SSH-Server des Webservers pass out quick proto tcp from 0/0 port 22 to any \ flags /S keep state pass in quick proto tcp from 0/0 port >1023 to \ 0/0 port 22 keep state 5.3.8
10 11 12 13 14
http(s)
Das HTTP kommt ohne unangenehme Überraschungen aus. Die Beispiele gehen lediglich auf den http-Port 80 ein. Analog können Sie anstelle von port 80 auch port 443 für SSL/TLS alias https verwenden. Möchten Sie auf fremde Webinhalte auf dem Server zugreifen können, sollten Sie die Highport-Problematik berücksichtigen. iptables
# Zugriff auf den Webserver iptables -A INPUT -p TCP -d 0/0 --dport 80 -s 0/0 \ --sport 1024:65535 -j ACCEPT iptables -A OUTPUT -p TCP -s 0/0 --sport 80 -d 0/0 \ --dport 1024:65535 -j ACCEPT # Ausgehender Zugriff auf fremde http-Inhalte
Paketfilter
371
iptables -A OUTPUT -p TCP -d 0/0 --dport 80 \ -s 0/0 --sport 1024:65535 –o eth0 -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 80 -d 0/0 -–dport \ 1024:65535 –m state –-state RELATED,ESTABLISHED \ –i eth0 -j ACCEPT OpenBSD
# Zugriff auf den Webserver pass in quick proto tcp from 0/0 port >1023 \ to 0/0 port 80 keep state pass out quick proto tcp from 0/0 port 80 \ to 0/0 port >1023 keep state # Ausgehender Zugriff auf fremde http-Inhalte pass out quick proto tcp from 0/0 port >1023 \ to 0/0 port 80 keep state pass in quick proto tcp from 0/0 port 80 \ to 0/0 port >1023 flags /S keep state 5.3.9
FTP
Das FTP arbeitet gleich in zwei verschiedenen Modi. Beim ursprünglichen und so genannten »aktiven Modus« baut der Client eine Control Connection zum Server (Port 21) auf. Die eigentlichen Daten werden in der danach initialisierten Data Connection übertragen. Hierzu wird der Port 20 genutzt. Als weitere Besonderheit erfolgt der Verbindungsaufbau der Data Connection nicht vom Client zum Server, sondern vom Server zum Client. Das bedeutet, dass eine Stateful Inspection auf Seiten des Clients nicht möglich ist und sämtliche Highports freigeschaltet werden müssen. Somit kann eine Verbindung zu eventuell vorhandenen Trojanern und Backdoors trotz Paketfilter ausgehend über Port 20 problemlos aufgebaut werden. Um diese Sicherheitsproblematik auszuhebeln, wurde der »Passive Modus« entwickelt. Ärgerlicherweise löst der »Passive Modus« das Problem auf der Client-Seite, indem die Data Connection vom Client zu einem Server-Highport(!) hergestellt wird. Das führt zu einer kuriosen Regel: Sie müssen auf dem FTP-Server sämtliche ein- und ausgehenden Verbindungen von Highport zu Highport zulassen. Sicherheitsbewusste Administratoren lassen daher einen FTP-Verbindungsaufbau im »aktiven Modus« nur zu vertrauenswürdigen FTP-Servern zu. Gleichzeitig wird beim eigenen FTP-Server jedoch auf dem »aktiven Modus« bestanden.
372
Server absichern
1 2 Auf der Firewall eines Firmennetzwerks lässt sich recht einfach der »aktive Modus« für den FTP-Server des Webservers freischalten.
3
Was bedeutet das nun für Sie? Wenn Sie einen FTP-Server für Anonymous Login anbieten möchten, werden Sie im »aktiven Modus« einige Anwender aussperren. Weiterhin ist fragwürdig, ob bei Einrichtung von unternehmensfremden Kundenzugängen jeder die Möglichkeit besitzt und bereit ist, eine eventuell vorhandene Firewall um Sonderregeln für Ihren Webserver zu erweitern.
4 5 6
Falls Sie gezwungen sind, den »aktiven Modus« zu verwenden, sollten Sie unbedingt darauf achten, sämtliche bereits belegten Highports auszugrenzen. In ProFTPD können Sie die zu nutzenden Highports, wie in Abschnitt 3.12.2, Konfiguration von ProFTPD, beschrieben, einschränken. Weiterhin sollten Sie den Rechner in regelmäßigen Abständen scannen, um sicher zu sein, keinen unerwünschten Highport übersehen oder nachträglich geöffnet zu haben.
8 9
Passives-FTP
Aktives-FTP Client
Server
10
Client
Server
11
>1023
>1023
Control Conn
ection; SYN
21
>1023 ection; ACK Control Conn
21
Control Conn
ection; SYN
21
>1023 ection; ACK Control Conn
21
12 13
>1023
>1023
sendet Zufalls
port: 8956
>1023
igt Zufallsport
erbittet pass
21 21
ives FTP
>1023
tion; Data Connec
SYN
20
tion
14
21
>1023
Data Connec
tion; SYN
8956
Data Connec
fallsport: 6821
21
sendet Zu
bestät
8956
7
20
>1023
n; ACK
6821 6821
tio Data Connec
Abbildung 5.2 Das FTP hat es in sich. Es besteht aus zwei verschiedenen Verbindungen und benötigt entweder auf dem Client oder dem Server die Freigabe eingehender Verbindungen auf Highports.
iptables
# Eingehender Zugriff auf FTP-Server (aktiver Modus) iptables -A INPUT -p TCP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 20:21 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 1024:65535 \
Paketfilter
373
-s 0/0 --sport 20:21 -j ACCEPT # Passiver Modus; für eingehende Verbindung (auskommentiert) # iptables -A INPUT -p 6 -d 0/0 --dport 1024:65535 \ # -s 0/0 --sport 1024:65535 -j ACCEPT # Ausgehender Zugriff auf fremde FTP-Server – passiver Modus iptables -A OUTPUT -p TCP -d 0/0 --dport 21 \ -s 0/0--sport 1024:65535 -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 21 -d 0/0 \ --dport 1024:65535 –m state --state \ RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 1024:65535 \ -s 0/0 --sport 1024:65535 -j ACCEPT iptables -A INPUT -p TCP -d 0/0 --dport 1024:65535 -s 0/0 \ --sport 1024:65535 –m state --state \ RELATED,ESTABLISHED -j ACCEPT # Ausgehender Zugriff, aktiver Modus (auskommentiert) # Vertrauenswürdige(n) Server mit IP-Adresse identifizieren! #iptables -A OUTPUT -p TCP -d 12.34.56.78 --dport 20:21 \ # -s 0/0--sport 1024:65535 -j ACCEPT #iptables -A INPUT -p TCP -s 12.34.56.78 --sport 20:21 \ # -d 0/0 --dport 1024:65535 -j ACCEPT OpenBSD
# Eingehender Zugriff auf FTP-Server (aktiver Modus) pass in quick proto tcp from 0/0 port >1023 \ to 0/0 port 19><22 pass out quick proto tcp from 0/0 port 19><22 \ to 0/0 port >1023 # Passiver Modus; für eingehende Verbindung (auskommentiert) # pass in quick proto tcp from 0/0 port >1023 \ to 0/0 port > 1023 # Ausgehender Zugriff auf fremde FTP-Server –(passiver Modus) pass out proto tcp from 0/0 port >1023 \ to 0/0 port 21 keep state pass in proto tcp from 0/0 port 21 \ to 0/0 port >1023 flags /S keep state pass out proto tcp from 0/0 port >1023 \ to 0/0 port >1023 keep state pass in proto tcp from 0/0 port >1023 \ to 0/0 port >1023 flags /S keep state
374
Server absichern
1 2 # Ausgehender FTP-Zugriff, aktiver Modus (auskommentiert) # pass out proto tcp from 0/0 port >1023 to 0/0 port 19><22 # pass in proto tcp from 0/0 port 19><22 to 0/0 port >1023
3 4
5.3.10 Mailserver Üblicherweise lauschen Mailserver (MTA) auf Port 25. POP3-Dienste nutzen Port 110 und POP3(s) läuft über Port 995. IMAP(2) ist über Port 143 und IMAP(s) auf Port 993 erreichbar. Für alle genannten Dienste ist die Erstellung sauberer Regeln unproblematisch. Die Kommunikation mit der Gegenstelle erfolgt wie gewohnt über die Highports. Als kleine Besonderheit gilt es zu beachten, dass der MTA nicht nur Mails empfangen, sondern auch versenden muss. Hierzu wird der Highport-Bereich ausgehend zum und eingehend vom fremden Mailserver benötigt.
5
Im folgenden Beispiel wird lediglich der MTA neben POP3(s) freigeschaltet. Tauschen Sie gegebenenfalls die Portnummer 995 gegen jene des von Ihnen genutzten Dienstes aus.
9 10
iptables
11
6 7 8
# Einlieferung von Mails an Mailserver iptables -A INPUT -p TCP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 25 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 1024:65535 \ -s 0/0 --sport 25 -j ACCEPT # Versand von Mails des lokalen smtp-Servers iptables -A OUTPUT -p TCP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 25:25 -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 25:25 -d 0/0 \ --dport 1024:65535 –m state -–state \ RELATED,ESTABLISHED -j ACCEPT # Zugriff auf POP3(s) iptables -A INPUT -p TCP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 995 -i eth0 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 1024:65535 \ -s 0/0 --sport 995 -o eth0 -j ACCEPT
12 13 14
OpenBSD
# Einlieferung von Mails an Mailserver pass in proto tcp from 0/0 port >1023 \
Paketfilter
375
to 0/0 port 25 keep state pass out proto tcp from 0/0 port 25 \ to 0/0 port >1023 keep state # Versand von Mails des lokalen smtp-Servers pass out proto tcp from 0/0 port >1023 \ to 0/0 port 25 keep state pass in proto tcp from 0/0 port 25 \ to 0/0 port >1023 flags /S keep state # Zugriff auf POP3(s) pass in proto tcp from 0/0 port >1023 to 0/0 port 995 pass out proto tcp from 0/0 port 995 to 0/0 port >1023 5.3.11 auth/ident In Einzelfällen versuchen Dienste wie FTP- oder Mailserver bei einem Verbindungsaufbau die Identität des Users der Gegenstelle herauszufinden. Auf UNIX-Systemen steht dafür der Daemon auth/ident bereit. Sie sollten Verbindungsanfragen an diesen Dienst nicht einfach ignorieren, sondern zurückweisen, da die Gegenstelle sonst weitere Anfrageversuche startet und der Aufbau der eigentlichen Verbindung unnötig in die Länge gezogen wird. Weitere Informationen zu diesem merkwürdigen Dienst gewährt RFC 1413. Ein Blick auf http://www.faqs.org/rfcs/rfc1413.html ist für Interessierte empfehlenswert. iptables
iptables -A INPUT -p TCP -d 0/0 --dport 113 -j REJECT OpenBSD
block return-rst in quick proto tcp from 0/0 to 0/0 port 113 5.3.12 DNS Für unseren Server ist die Kommunikation mit Nameservern eine Notwendigkeit. Nur so können beispielsweise Domains von E-Mail-Adressen auf grundsätzliche Gültigkeit geprüft werden. Interessant ist, dass zur Kommunikation jeweils der TCP- und UDP-Port 53 ausgehend freigegeben werden muss. Betreiben Sie einen eigenen Nameserver, ist es wichtig zu wissen, dass erst Bind9 auf den Highport-Bereich für Anfragen zurückgreift. Ältere Versionen nutzen in der Voreinstellung für Anfragen ebenfalls Port 53. Soll der eigene Nameserver nicht nur Adressen auflösen, sondern auch Anfragen beantworten, müssen Sie
376
Server absichern
1 2 deshalb neben dem Highport-Bereich ebenfalls auf Port 53 Pakete entgegennehmen und beantworten.
3
iptables
4
# Anfragen an externe Nameserver von Resolver/Bind9 iptables -A OUTPUT -p UDP -d 0/0 --dport 53 \ -s 0/0 --sport 1024:65535 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 53 \ -s 0/0 --sport 1024:65535 -j ACCEPT iptables -A INPUT -p UDP -s 0/0 --sport 53 -d 0/0 \ --dport 1024:65535 -m state --state \ RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 53 -d 0/0 \ --dport 1024:65535 -m state --state \ RELATED,ESTABLISHED -j ACCEPT # Eingehende Anfragen an lokalen Nameserver iptables -A OUTPUT -p UDP -d 0/0 --dport 53 \ -s 0/0 --sport 53 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 53 \ -s 0/0 --sport 53 -j ACCEPT iptables -A INPUT -p UDP -s 0/0 --sport 53 \ -d 0/0 --dport 53 -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 53 \ -d 0/0 --dport 53 -j ACCEPT iptables -A OUTPUT -p UDP -d 0/0 --dport 1024:65535 \ -s 0/0 --sport 53 -j ACCEPT iptables -A OUTPUT -p TCP -d 0/0 --dport 1024:65535 \ -s 0/0 --sport 53 -j ACCEPT iptables -A INPUT -p UDP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 53 -j ACCEPT iptables -A INPUT -p TCP -s 0/0 --sport 1024:65535 \ -d 0/0 --dport 53 -j ACCEPT
5 6 7 8 9 10 11 12 13 14
OpenBSD
# Anfragen an externe Nameserver von Resolver/Bind9 pass out proto udp from 0/0 port >1023 to 0/0 port 53 pass in proto udp from 0/0 port 53 to 0/0 port > 1023 pass out proto tcp from 0/0 port >1023 to 0/0 port 53 pass in proto tcp from 0/0 port 53 to 0/0 port > 1023
Paketfilter
377
# Eingehende Anfragen an lokalen Nameserver pass in proto udp from 0/0 port 53 to 0/0 port 53 pass out proto udp from 0/0 port 53 to 0/0 port 53 pass in proto tcp from 0/0 port 53 to 0/0 port 53 pass out proto tcp from 0/0 port 53 to 0/0 port 53 pass in proto udp from 0/0 port >1023 to 0/0 port 53 pass out proto udp from 0/0 port 53 to 0/0 port >1023 pass in proto tcp from 0/0 port >1023 to 0/0 port 53 pass out proto tcp from 0/0 port 53 to 0/0 port >1023 5.3.13 Timeserver Auf die Nutzung eines Timeservers sollten Sie nicht verzichten. Wie in Abschnitt 4.4, Systemzeit, beschrieben, ist es von zentraler Bedeutung, dass Logeinträge mit korrekten Zeitangaben erzeugt werden. Beim Erstellen der Filterregeln sollten Sie die IP-Adresse des genutzten Timeservers angeben. Iptables
iptables -A -d iptables -A -s
OUTPUT -p UDP -s 0/0 --sport 123 \ 213.22.12.69 --dport 123 -j ACCEPT INPUT -p UDP -d 0/0 --dport 123 \ 213.22.12.69 --sport 123 -j ACCEPT
OpenBSD
pass out proto udp from 0/0 port 123 \ to 130.133.1.10 port 123 pass in proto udp from 130.133.1.10 port 123 to 0/0 port 123 5.3.14 Fragmentation Needed and Don't Fragment was Set Sind die von oder zu Ihrem Webserver übertragenen Datenpakete zu groß, um verarbeitet werden zu können, wird das ICMP-Paket »Fragmentation Needed and Don't Fragment was Set« übermittelt. Hierdurch wird Ihrem Webserver beziehungsweise der Gegenstelle mitgeteilt, dass kleinere Pakete notwendig sind, um die angeforderten Daten erfolgreich übertragen zu können. Sie sollten dieses ICMP-Paket in beide Richtungen erlauben, da es sonst passieren kann, dass größere Daten wie Programm-Downloads oder hochauflösende Bilder nicht übertragen werden können. Tritt dieses Problem auf, ist ein interessantes Phänomen zu beobachten: Die Datenübertragung startet und arbeitet zunächst wie erwartet, doch plötzlich
378
Server absichern
1 2 geht die übertragene Datenmenge rapide gen null, bis überhaupt keine Übertragung mehr erfolgt.
3
iptables
4
iptables -A INPUT –p icmp \ -–icmp-type fragmentation-needed –j ACCEPT iptables -A OUTPUT –p icmp \ -–icmp-type fragmentation-needed –j ACCEPT
5 6
OpenBSD
7
pass in quick inet proto icmp all icmp-type 3 code 4 pass out quick inet proto icmp all icmp-type 3 code 4
8
5.3.15 Ping
9
Eingehende Ping-Anfragen (echo request) und ausgehende Ping-Antworten (echo reply) sollten nur von beziehungsweise zu den Rechnern erlaubt sein, die Ihren Server mit Ping auf grundsätzliche Erreichbarkeit prüfen. Um Attacken wie »Ping-of-Death« zu verhindern, sollten Sie diese Pakete ansonsten herausfiltern. Ausgehende Ping-Anfragen vom Server zu anderen Hosts sind jedoch nützlich und können neben eingehenden Ping-Antworten bedenkenlos erlaubt werden.
10 11 12 13
iptables
iptables -A INPUT -p icmp -s 123.45.67.89 \ --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p icmp -d 123.45.67.89 \ --icmp-type echo-reply -j ACCEPT iptables -A OUTPUT -p icmp \ --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp \ --icmp-type echo-reply -j ACCEPT
14
OpenBSD
# Ping pass in quick inet proto icmp from 192.168.0.25 \ to any icmp-type 8 pass out quick inet proto icmp from any \ to 192.168.0.25 icmp-type 0
Paketfilter
379
pass out quick inet proto icmp all icmp-type 8 pass in quick inet proto icmp all icmp-type 0 5.3.16 Parameter-Problem Dieses ICMP-Paket wird versandt, wenn ein Problem im IP-Header von Paketen aufgetreten ist und sollte in beide Richtungen freigegeben werden. iptables
iptables -A INPUT –p icmp \ -–icmp-type parameter-problem –j ACCEPT iptables -A OUTPUT –p icmp \ -–icmp-type parameter-problem –j ACCEPT OpenBSD
pass in quick inet proto icmp all icmp-type 12 pass out quick inet proto icmp all icmp-type 12 5.3.17 Unsinnige Pakete verwerfen Bei der Definition unserer Filterregeln wurde bisher nicht bedacht, dass die IPAdresse des Absenders gefälscht sein kann. Es gibt Spoofing-Attacken, in denen Angreifer sogar die IP-Adresse des Webservers als Absenderadresse oder den Adressraum des Loopback Devices (127.0.0.0/255.0.0.0) einsetzen. Derartige Pakete sind natürlich Unsinn und sollten deshalb am Anfang der Paketfilterregeln verworfen werden. Dasselbe gilt für TCP-Pakete, die keinen gültigen Zustand besitzen und mit iptables gefiltert werden können. Weiterhin bietet es sich an, eingehende Pakete auf unerwünschte Highports wie beispielsweise den MySQL-Port 3306 zu Beginn auszugrenzen. Andernfalls müssten Sie für jede Paketfilterregel einen Port-Bereich von 1024 bis 3305 und einen weiteren von 3307 bis 65535 für eingehende Pakete festlegen, um sicherstellen zu können, dass ein Angreifer noch nicht einmal durch »einen Trick« eine unerwünschte Verbindung aufbauen kann. Iptables
iptables -A INPUT -i eth0 -s 192.168.0.25 -j DROP iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP iptables -A INPUT -m state --state INVALID -j DROP
380
Server absichern
1 2 iptables -A INPUT -p TCP -d 0/0 --dport 3306 -j DROP iptables -A INPUT -p UDP -d 0/0 --dport 3306 -j DROP
3
OpenBSD
4
block block block block
in in in in
quick quick quick quick
on on on on
sis0 sis0 sis0 sis0
from 192.168.0.25 to any from 127.0.0.0/8 to any proto tcp from 0/0 to 0/0 port 3306 proto udp from 0/0 to 0/0 port 3306
5 6 7
Hinweis Pf filtert ungültige Pakete automatisch heraus. Deshalb wird die zusätzliche Regel zum Verwerfen ungültiger Datenpakete von iptables unter OpenBSD nicht benötigt.
8 9
5.3.18 Welche Pakete sollten geloggt werden? Es ergibt wenig Sinn, sämtliche Pakete aufzuzeichnen. Das Logfile würde in kürzester Zeit eine erhebliche Dateigröße erreichen und auf lange Sicht die Festplatte des Servers zum Überlaufen bringen. Auch wenn Sie dies natürlich über Logrotate zu verhindern wissen, fördert eine Protokollierung sämtlicher Daten nicht gerade die Übersichtlichkeit des Logfiles. Dagegen nimmt die Wahrscheinlichkeit zu, dass wichtige Informationen übersehen werden.
10
Wenn Sie feststellen, dass von einer statischen IP-Adresse verstärkt Scans Ihres Rechners oder ähnlich fragwürdige Aktionen durchgeführt werden, ist es eine Überlegung wert, sämtliche Pakete von und zu dieser IP-Adresse zu loggen.
13
11 12
14
Abgesehen davon sollten Sie Verbindungsversuche loggen, bei denen alle Flags (Christmas Scan) sowie lediglich FIN, URG und PSH gleichzeitig gesetzt sind. Selbst Pakete, die ohne Flags übertragen werden, verdienen eine Aufzeichnung. Neben ungültigen Paketen bieten sich die eingehenden ICMP-Pakete »destination unreachable«, »source quench«, »redirect« und »address mask request«, aufgrund ihrer Eignung für Attacken ebenfalls zum Loggen an. iptables
iptables -A INPUT -m state --state INVALID -j LOG iptables -A INPUT –p ICMP -–icmp-type \ destination-unreachable -j LOG iptables -A INPUT -p tcp --tcp-flags ALL, FIN,URG,PSH -j LOG iptables -A INPUT -p tcp --tcp-flags ALL, NONE -j LOG iptables -A INPUT -p tcp --tcp-flags NONE, ALL -j LOG
Paketfilter
381
iptables -A INPUT –p ICMP -–icmp-type source-quench -j LOG iptables -A INPUT –p ICMP -–icmp-type redirect -j LOG iptables -A INPUT –p ICMP -–icmp-type \ address-mask-request -j LOG OpenBSD
block block block block block block block block
in log on sis0 from 0/0 in log on sis0 from 0/0 in log on sis0 from 0/0 in log on sis0 from 0/0 flags FSRPAUEW/FSRPAUEW in quick log inet proto in quick log inet proto in quick log inet proto in quick log inet proto
to to to to
0/0 0/0 0/0 0/0
icmp icmp icmp icmp
flags /FUP flags FUP/FUP flags /FSRPAUEW \
all all all all
icmp-type icmp-type icmp-type icmp-type
3 4 5 17
5.3.19 Paketfilter-Regeln nach dem Booten automatisiert laden Unter OpenBSD genügt es, die Paketfilterregeln in der Datei /etc/pf.conf zu speichern. Bei einem Neustart werden die Regeln dann automatisch eingelesen. Für iptables bietet sich ein kleines Shell-Skript mit dem Aufruf iptables-restore < Regeldatei oder den Filterregeln im »Klartext« an. Weitere Hinweise hierzu finden Sie in Abschnitt 2.8, Startskripte.
5.4
Systrace
Das Konzept der Benutzerrechte von UNIX-Systemen ermöglicht einen grundsätzlichen Schutz vor unprivilegierten Nutzern. Dem Apache-Webserver ist es auf einem sinnvoll konfigurierten System zum Beispiel nicht möglich, die Konfigurationsdateien des Nameservers zu lesen oder zu verändern. Allerdings gibt es manche Prozesse, die leider als Root laufen müssen und somit Root-Rechte besitzen. Gelingt es einem Angreifer, Kontrolle über einen Prozess zu erlangen, kann er sämtliche Befehle mit den Rechten des Benutzers, unter dem der Prozess läuft, ausführen. Wird ein Root-Prozess gekapert, steht somit der gesamte Server offen. Leider gibt es einige Prozesse, die unter Root-Rechten laufen müssen und – wie beispielsweise der SSH- oder FTP-Server – obendrein von außen direkt erreichbar sind. Dennoch ist es möglich, den Schaden, den ein Angreifer mit dem Kapern eines Prozesses erzielen kann, deutlich einzuschränken.
382
Server absichern
1 2 Die Lösung liegt im Überwachen der Systembefehle, die ein Prozess ausführt. So ist es möglich, einen Prozess trotz Root-Rechten lediglich auf das Lesen und Ausführen der Befehle zu beschränken, die das Programm zum ordnungsgemäßen Betrieb benötigt. Für gewöhnlich genügen minimale Dateizugriffsrechte. Eine Shell muss der Prozess schon gar nicht erzeugen können.
3 4 5
Somit ist der Schaden meist auf ein Minimum reduzierbar. Direkt von außen erreichbare Dienste wie DNS, Apache, Mail- und FTP-Server sollten auf jeden Fall mit Systrace abgesichert werden. Wenn Sie Zeit finden, ist es ratsam, die anderen Systemprozesse ebenfalls abzusichern, die mit Root-Rechten laufen.
6 7
5.4.1
Installation
8
Open- und NetBSD-Nutzer können diesen Abschnitt überspringen. Systrace gehört zur Grundausstattung dieser Systeme. In den Linux-Kernel hat das leistungsstarke Security-Tool leider noch keinen Einzug gefunden.
9
Dummerweise waren für Systrace zum Zeitpunkt der Drucklegung lediglich Kernel-Patches für 2.4.24 und 2.6.1 verfügbar. Dies ist schlecht, da in diesen Kernel-Versionen gravierende Mängel bekannt geworden sind und die Kernel nicht für den harten Betrieb geeignet sind.
10 11
Falls über http://www.citi.umich.edu/u/provos/systrace/index.html noch kein Kernel-Patch zu einer aktuellen Version verfügbar ist, sollten Sie Systrace unter Linux lediglich zu experimentellen Zwecken einsetzen. Falls Sie Systrace unter diesen Voraussetzungen dennoch in einem Produktivsystem einsetzen möchten oder müssen, sollten Sie unbedingt zu einer gepatchten Kernel-Variante wie beispielsweise der von Debian greifen.
12 13 14
Installation aus den Quellen (für Linux) Um den Systrace-Patch einspielen zu können, ist das Verzeichnis, das die Kernel-Quellen enthält, umzubenennen:
cd /usr/src mv linux-2.4.24 linux-2.4.24-marius Nun kann der Patch eingespielt
patch -p0 < systrace-linux-2.4.24-v1.5.diff und der Kernel wie in Abschnitt 2.9 beschrieben kompilieren werden. Tragen Sie den Kernel in /etc/lilo ein und rufen Sie lilo auf, siehe Abschnitt 2.5.1, LILO – Generic Bootloader for Linux.
Systrace
383
Rebooten Sie Ihr System mit dem selbst erstellten Kernel. Bevor Systrace genutzt werden kann, ist noch das »Userland« zu kompilieren. Je nach LinuxDistribution kann dies recht umständlich sein. Unter SUSE ist hierzu die systrace.h-Datei aus den Kernel-Quellen zu kopieren:
cp -p \ /usr/src/linux-2.4.24 marius/include/linux/systrace.h \ /usr/include/linux/ Bleibt make bei »Performing simple regression tests« stehen, können Sie die Tests über (ctrl)-(c) abbrechen. Unabhängig davon wird sich die Installation von Systrace mit make install abschließen lassen. Im letzten Schritt müssen Sie für Systrace ein eigenes Device anlegen. Dies geschieht mit mknod /dev/systrace c 10 226
5.4.2
Regelerstellung und Betrieb
Das Erlernen der Systrace-Regelsprache ist dank der interaktiven Regelerstellungsfunktionen keine Hexerei. So erzeugt der Aufruf systrace -A /bin/cat /etc/passwd sämtliche Regeln, die notwendig sind, um mit cat die Datei passwd auszulesen. Andere Dateien können vom Programm – wenn es über systrace gestartet wird – nicht mehr gelesen werden:
mirrorian:~/.systrace# systrace -a /bin/cat /etc/shadow /bin/cat: /etc/shadow: Operation not permitted mirrorian:~/.systrace# systrace -a /bin/cat /etc/passwd root:x:0:0:root:/root:/bin/bash (...) Verwenden Sie vollständige Pfadangaben beim Aufruf des Programms. Beachten Sie, dass Systrace den Prozess lediglich dann schützt, wenn der Programmaufruf über Systrace erfolgte. Anders gesagt: /bin/cat/etc/shadow ist trotz Ihrer Systrace-Regeln weiterhin möglich. Hinweis Wenn Sie bei der Regelerstellung zusätzlich die Option -t verwenden, fragt Systrace bei jedem einzelnen Systembefehl nach, ob Sie diesen erlauben (permit) oder verbieten (deny) möchten. Die automatisiert erzeugten Regeln finden Sie im .systrace-Ordner des HomeVerzeichnisses. Sie werden nach Pfad und Befehlsnamen benannt und sind an die eigenen Vorstellungen anpassbar.
384
Server absichern
1 2 mirrorian:~/.systrace# cat bin_cat Policy: /bin/cat, Emulation: linux linux-newuname: permit linux-brk: permit linux-fsread: filename eq "/etc/ld.so.preload" then permit linux-fsread: filename eq "/etc/ld.so.cache" then permit linux-fstat64: permit linux-old_mmap: permit linux-close: permit linux-fsread: filename eq "/lib/libc.so.6" then permit linux-read: permit linux-mprotect: permit linux-munmap: permit linux-fsread: filename eq "/etc/passwd" then permit linux-write: permit linux-ni_syscallexit: permit
3 4 5 6 7 8 9 10
Sämtliche dieser Systembefehle werden von /bin/cat benötigt. Lediglich das Auslesen der Datei /etc/passwd
11
linux-fsread: filename eq "/etc/passwd" then permit
12
gehört nicht zu den Grundbefehlen und wurde von uns über den Aufruf /bin/cat /etc/passwd veranlasst. Wer sich die einzelnen Befehle näher ansieht, wird sich an linux-write stören. Doch der Systembefehl steht lediglich für die Ausgabe des Textes an den Benutzer. Häufig finden Sie in den Manpages Informationen zu den einzelnen Systembefehlen. Geben Sie man write ein, um die Beschreibung zum Systemcall linux-wirte aufzurufen. Außerdem bietet sich ein Studium der relevanten Manpages (über man -k syscall) neben der SystraceManpage an.
13 14
Für uns sind insbesondere die Policy-Filtermöglichkeiten von Systrace von Bedeutung. Durch eq wird die Regel auf die angegebene Datei beschränkt. Um beispielsweise sämtliche Dateien des /etc-Verzeichnisses zum Lesen freizuschalten, steht match zur Verfügung:
linux-fsread: filename match "/etc/*" then permit In Systrace ist grundsätzlich alles verboten, was nicht erlaubt ist. Dennoch stellt das Programm Ihnen ebenfalls Deny-Regeln zur Verfügung. Wenn Sie, wie in unserem obigen Beispiel, das gesamte /etc-Verzeichnis bis auf die Datei /etc/geheim freigeben möchten, ist die Deny-Regel sinnvoll:
Systrace
385
linux-fsread: filename eq "/etc/geheim" then deny linux-fsread: filename match "/etc/*" then permit Beachten Sie, dass für Systrace die erste gefundene Regel maßgebend ist. Würden Sie die pauschale Freigabe des /etc-Verzeichnisses vor die Deny-Regel der Datei /etc/geheim setzen, wäre die Verbotsregel wirkungslos und die Datei /etc/geheim lesbar. Ausführliches Beispiel: Regeln für ProFTPD Grundsätzlich ist die Vorgehensweise zur Definiton von Systrace-Programmregeln immer gleich: Beenden Sie den Daemon und starten Sie ihn über Systrace im automatischen Lernmodus neu:
/etc/init.d/proftpd stop systrace -A /usr/sbin/proftpd Stellen Sie eine FTP-Verbindung her und führen Sie sämtliche Operationen aus: Datei umbenennen, hoch- und herunterladen sowie das Ändern von Zugriffsrechten (falls gewünscht). 왘 Beenden Sie danach den ProFTPD-Daemon und bearbeiten Sie die von Sys-
trace erzeugten Regeln: 왘 Ändern Sie die Chroot-Befehle in eine match-Regel, die zum Hauptpfad der
FTP-Login-Verzeichnisse
führt:
linux-chroot: filename "/usr/local/httpd/htdocs/kundenserver/*/ftp" then permit
match
왘 Für aktives FTP sind sämtliche linux-connect: sockaddr eq »inet ...-Zeilen
durch linux-connect: sockaddr match »inet-*« then permit zu ersetzen. 왘 Jede Instanz von ProFTPD benötigt Zugriff auf temporäre Daten, die mit der
jeweiligen PID-Nummer (im Beispiel wurde 2036 verwendet) gesichert werden. Anstelle von
linux-fswrite: filename eq \ "/var/run/proftpd/proftpd-2036" then permit linux-fsread: filename eq \ "/var/run/proftpd/proftpd-2036" then permit sind die folgenden Zeilen zu verwenden:
linux-fswrite: filename match \ "/var/run/proftpd/proftpd-*" then permit linux-fsread: filename match \ "/var/run/proftpd/proftpd-*" then permit
386
Server absichern
1 2 왘 Die Befehle fsread, fswrite, chdir, chmod und rename bereiten Ärger, da sie
3
eigentlich generell erlaubt werden müssten, wenn wir FTP-Nutzer per Chroot in ihren Bereich einsperren wollen. Leider erkennt Systrace (aufgrund der neuen Verzeichnisstruktur und der entsprechend anderen Systemaufrufe) nicht, dass der FTP-Pfad /bilder eigentlich für den Pfad /usr/local/httpd/htdocs/kundenserver/kundeXY/bilder steht.
4 5
왘 Die Lösung liegt in einem Kunstgriff: Damit Nutzer Daten ebenfalls auf dem
Webserver sichern können, ohne dass diese über einen URL abrufbar sind (zum Beispiel zur Ablage von Klartextpasswörtern, die über ein Skript ausgelesen werden), bietet es sich an, den Zugriff auf die Unterordner des FTPHauptverzeichnis (/www, /log, /private) zu beschränken. Die Namen sind selbstverständlich symbolisch gemeint und sollten keinesfalls als Verzeichnisse »im eigentlichen Root-Pfad« des Servers vorhanden sein, sondern im Verzeichnis /home/accountname/ftp/ liegen. Beispiel für /www:
6 7 8 9
linux-chdir: filename eq "/www" then permit linux-chdir: filename match "/www/*" then permit linux-fsread: filename match "/www/*" then permit linux-fsread: filename eq "/www" then permit linux-fswrite: filename match "/www/*" then permit linux-rename: filename match "/www/*" then permit linux-chmod: filename match "/www/*" then permit
10 11 12
FTP-User können nun keine Dateien innerhalb des Startverzeichnisses anlegen oder die Standardverzeichnisse löschen, da der Zugriff über /www (eigentlich /home/accountname/ftp/www) beschränkt wurde. Nutzer sollten dies durch den großen Sicherheitsgewinn verschmerzen können. Es bedeutet ohnehin keinen Nachteil, Dateien anstatt im Startverzeichnis in /private abzulegen. Damit dies möglich ist, müssen Sie für /private natürlich die gleichen Regeln definieren wie für /www.
5.4.3
13 14
Stolperfallen
Systrace kann Prozesse nicht über die Startskripte Ihrer Distribution aktivieren. Sie müssen den Aufruf »direkt« vornehmen. ps aux -o pid,user,command | grep Prozessname verrät, mit welchen Optionen der Dienst üblicherweise gestartet wird. Das Beenden eines über Systrace gestarteten Daemons können Sie jedoch wie gewohnt erledigen. Einige Dienste wie beispielsweise der MySQL-Server können lediglich über ein nachgestelltes & von Systrace vernünftig gestartet werden. Ohne das Zeichen & starten manche Dienste nicht wie gewohnt als Hintergrundprozess und blo-
Systrace
387
ckieren in der Folge Ihre Shell. Dies ist beim Erstellen eigener Startskripte und Cron-Einträge unbedingt zu beachten.
5.4.4 Logging Verstößt ein mit Systrace gestartetes Programm gegen seine Regeln, wird der jeweilige Befehl von Systrace verweigert und über den Syslog protokolliert. Wurde das Systrace-Regelwerk entsprechend sorgsam erstellt, liegt somit ein erfolgreicher Missbrauch (und damit eine ausgenutzte Sicherheitslücke) vor.
Dec 27 13:47:46 mirrorian systrace: deny user: root, prog: \ policy: /usr/sbin/proftpd, filters: 234, \ syscall: linux-chdir(12), filename: /www Diese Zeilen im Syslog-Logfile verraten nicht nur Programm und Zeitpunkt, sondern auch den abgelehnten Befehl (Verzeichniswechsel nach /www). In unserem Beispiel wurde das Regelwerk für ProFTPD nicht korrekt erstellt. Ein Verzeichniswechsel innerhalb der Chroot-FTP-Umgebung ins Webverzeichnis des FTP-Nutzers muss selbstverständlich möglich sein. Falls tatsächlich ein Missbrauch vorliegt, profitieren Sie gleich doppelt: Ein Angreifer hat sich verraten, ohne Schaden anzurichten, und Sie können anhand des Zeitpunkts die Logfiles nach weiteren Hinweisen gezielt durchsuchen. Als Zeitraum empfiehlt sich ein Fenster von 30 Minuten vor sowie nach dem Missbrauchsversuch. Selbstverständlich sollten Sie ebenfalls nach Sicherheits-Updates des »geknackten« Programms suchen beziehungsweise über den Einsatz alternativer Software nachdenken.
5.5
Chroot
Ursprünglich wurde Chroot als Sandbox konzipiert, in der neue Programme sicher ausgetestet werden können, ohne auf das eigentliche System Zugriff zu erlangen. Chroot wird deshalb gerne als zusätzliche Absicherung kritischer Prozesse wie beispielsweise Bind oder Apache verwendet. Tatsächlich ist dies nur dann effektiv, wenn die jeweiligen Daemons nicht mit Root-Rechten laufen. Erhält ein Angreifer Kontrolle über einen Prozess, der in einer Chroot-Umgebung mit Root-Rechten arbeitet, kann er aus dem Chroot-Käfig ausbrechen. Dies gilt ebenfalls für das flexiblere und ausgereiftere Jail von Free- und NetBSD-Systemen. Prinzipiell können Sie jeden Prozess chrooten. Damit das eingesperrte Programm korrekt arbeiten kann, gilt es, sämtliche von diesem Programm genutz-
388
Server absichern
1 2 ten Befehle, Bibliotheken und Konfigurationsdateien ebenfalls in den ChrootKäfig zu kopieren. Welche Dateien im Detail zu kopieren sind verrät ldd:
3
linbook:~ # ldd /bin/bash libreadline.so.4 => /lib/libreadline.so.4 (...)
4 5
Selbstverständlich müssen Sie bei Änderungen an diesen Dateien ebenfalls die Duplikate im Chroot-Käfig anpassen. Dies wird gerne vergessen. Bei Fehlverhalten von eingesperrten Programmen liegt das Problem meist in nicht aktualisierten Systemdateien. Wenn Sie lediglich einen Chroot-Käfig einsetzen, ist es deshalb empfehlenswert, mit Softlinks (die auf die jeweiligen Dateien im Chroot-Käfig verweisen) zu arbeiten. Hardlinks bieten sich dagegen beim Einsatz mehrer Chroot-Käfige an, allerdings sollten Sie in beiden Fällen darauf achten, lediglich »ungefährlichere« Dateien zu verlinken. Sensible Informationen sollten lieber doppelt im System vorhanden sein, um mögliche böswillige Manipulierungen effektiv auf den Chroot-Käfig zu beschränken.
6 7 8 9 10
Effektiver als Chroot oder Jail ist die Absicherung der von außen erreichbaren Prozesse mit Systrace. Wenn Sie ein Linux-System nutzen und eine virtuelle Root-Umgebung zur Absicherung verwenden möchten, sollten Sie einen Blick auf das Vserver-Projekt (siehe Kapitel 6, Linux VServer) werfen. Hier ist ein Ausbrechen nahezu unmöglich. Allerdings benötigen Sie für jeden Vserver eine eigene IP-Adresse, und der zusätzliche Speicherplatz- sowie RAM-Bedarf einer Vserver-Umgebung sollte ebenfalls bedacht werden.
5.5.1
11 12 13 14
Chroot als Admintool
Chroot hilft bei administrativen Aufgaben ungemein. So ist es möglich, via Chroot von einem Rettungssystem direkt ins eigentliche System zu wechseln und dort nativ den Paketmanager oder andere Verwaltungs-Tools zu nutzen sowie einzelne Dienste für Testzwecke zu starten. Sogar der Wechsel von einer Debian- zu einer SUSE-Installation ist per Chroot möglich. Dies ist beispielsweise nützlich, um den lilo-MBR einer vorangegangenen Installation wieder herzustellen (Aufruf von chroot/ ursprungsinstallation sowie lilo und abschließendes exit genügen).
5.6
Feinabstimmung
Das Entfernen unnötiger Programme ist ein sehr sinnvoller Schritt. Software, die nicht vorhanden ist, kann auch nicht missbraucht werden. Wie Sie ein sauberes Linux- oder OpenBSD-System aufsetzen können, wurde bereits in Abschnitt 2.1, Vorbereitungen und Hinweise zur Installation, beschrieben.
Feinabstimmung
389
5.6.1
Inetd abschalten
Der »Internet Superserver« alias Inetd stellt eigentlich kein Sicherheitsrisiko dar. Allerdings werden über ihn Dienste aktiviert, die Sie im Normalfall nicht benötigen. Ein Aspekt, der für Inetd spricht, ist die Möglichkeit, Programme über den TCP-Wrapper zu starten, um externen Zugriff auf einzelne IP-Adressen zu beschränken oder ganz zu verbieten. Indes können Sie den Zugriff auf Dienste wie den SSH- oder FTP-Server neben dem Paketfilter üblicherweise in der jeweiligen Konfigurationsdatei beschränken. Eine dritte Absicherung über den TCP-Wrapper erscheint aufgrund der zusätzlich benötigten System-Ressourcen wenig sinnvoll. Sie können Inetd problemlos deaktivieren. Unter Linux werden mit rm 'find /etc/* -name "S*inetd"' sämtliche Start-Links aus allen Runleveln entfernt. Unter OpenBSD ist der Eintrag inetd=YES in rc.conf auf inetd=NO zu setzen. Den bereits gestarteten Inetd können Sie über kill 'pidoff inetd' beenden.
5.6.2
Der TCP-Wrapper
Wahrscheinlich haben Sie die Dateien /etc/hosts.allow und /etc/hosts.deny bereits auf Ihrem System entdeckt. Diese Konfigurationsdateien gehören zum TCPD, der üblicherweise in jedem UNIX-System als Grundpaket installiert wird. Der TCPD-Wrapper ist in der Lage, eingehende Netzwerkanfragen gemäß der Dienst- und IP-Adresse zu verbieten oder zu gestatten. Der TCP-Wrapper ist schnell und leicht konfigurierbar und kann als »zusätzliche Firewall« betrachtet werden. Zunächst sollten Sie in der Datei /etc/hosts.deny die Zeile ALL: ALL eintragen. Dies lehnt alle Verbindungsanfragen zu überwachten Diensten ab, die in /etc/hots.allow nicht ausdrücklich gestattet sind. Nun gilt es, die einzelnen Dienste in /etc/hosts.allow global oder nach IPAdresse zu erlauben. Die Zeile sshd: ALL gestattet jedem Rechner, auf den SSHD-Server zuzugreifen. Falls Sie die Administration über einen Rechner mit statischer IP-Adresse vornehmen können, ist es möglich, den Zugriff über sshd: IP-Adresse zu beschränken. Allerdings schützt TCPD lediglich Dienste, die von ihm überwacht werden. Der SSH-Server stellt hier eine Ausnahme dar. Über Inetd können Sie einzelne Dienste durch den TCPD-Wrapper starten und überwachen lassen. Generell ist dies jedoch nur dann sinnvoll, wenn Sie externen Zugriff auf einzelne IP-Adressen beschränken oder ganz verbieten möchten.
390
Server absichern
1 2 In der Datei inetd.conf finden Sie zu vielen Diensten bereits vorbereitete Einträge, die über das Entfernen des Kommentarzeichens aktiviert werden können. Erklärungen und Beispiele sind über die Manpages zu tcpd, inetd und inetd.conf abrufbar.
5.6.3
3 4
Zugriffsrechte
5
In den vorangegangenen Kapiteln wurde häufig auf korrektes Setzen der Zugriffsrechte hingewiesen. Abgesehen von den angesprochenen Konfigurationsdateien und Systemprogrammen finden Sie im /etc-Verzeichnis sowie den in $PATH gespeicherten Ordnern sicher weitere Dateien, denen Sie das World readable oder/und World executable entziehen können. Beispielsweise eignen sich Programme wie ifconfig, finger oder top neben den meisten Konfigurationsdateien und Logfiles für restriktivere Zugriffsrechte.
6 7 8 9
Besonders kritisch ist das SUID- und SGID-Bit (erkennbar am Eintrag »s« in ls – l-Abfragen) zu bewerten. Das jeweilige Programm wird mit den Rechten des Besitzers (SUID-Bit User: -rwsr-xr-x) oder den Rechten der Gruppe (SGID-Bit Group: -rwxr-sr-x) ausgeführt. Entfernen Sie nach Möglichkeit das SUID-Bit mit chmod u-s Dateiname und das SGID-Bit über chmod g-s Dateiname.
10 11
Der Befehl find /* -perm -4000 zeigt alle Dateien mit gesetztem SUID-Bit, und find /* -perm -2000 alle Dateien mit gesetztem SGID-Bit an. Tatsächlich benötigen einige Programmdateien das SUID-Bit, um korrekt arbeiten zu können. In Debian Woody finden Sie zum Beispiel folgende SUID-Bits:
12 13
/bin/login, /bin/su, /sbin/unix_chkpwd, /usr/bin/chsh /usr/bin/gpasswd, /usr/bin/gpg, /usr/bin/newgrp, /usr/bin/passwd, /usr/lib/pt_chown, /usr/lib/apache/suexec, /usr/lib/apache-ssl/suexec, /usr/lib/ssh-keysign
14
Eine Änderung der Account-Informationen (man chfn) über /usr/bin/chfn wird auf einem Webserver-System in den meisten Fällen ebenfalls nicht notwendig sein. Deshalb kann das SUID-Bit im Normalfall entfernt werden. SGID-Bits sind nicht ganz so problematisch, da über sie im Normalfall keine privilegierten Gruppenrechte »erschlichen« werden können. Setzen Sie find neben der Suche nach SGID-Bits ebenfalls auf die Root-Gruppen-ID an: find /* -perm -2000 -group 0. Bis auf zwischengespeicherte Manpages sollten eigentlich keine SGID-Bits für die Root-Gruppe entdeckt werden. Unter OpenBSD 3.2 stellt das Verzeichnis /var/audit eine Ausnahme dar, das Sie im Normalfall von SGID-Bit befreien können.
Feinabstimmung
391
5.6.4 Bastille und harden-suse Unter Linux ist die Installation von Bastille empfehlenswert. Über den Aufruf BastilleInteractive können Sie dann einzelne System-Dienste gezielt deaktivieren sowie SUID- und SGID-Bits im Multiple-Choice-Verfahren entfernen. Für Nutzer von SUSE-Linux steht ebenfalls das Paket harden-suse bereit. Doch Vorsicht: Das Perl-Programm ist in der Lage, Ihr gesamtes System – inklusive Apache und SSHD – abzuriegeln, so dass der Rechner beim nächsten Neustart der betreffenden Dienste nicht mehr erreichbar sein könnte. Beantworten Sie die einzelnen Fragen deshalb mit Bedacht, und sehen Sie sich das Logfile /etc/harden_suse.log näher an. Um sicherzugehen, dass der Rechner über SSH weiterhin erreichbar ist, sollten Sie vor dem Beenden der bestehenden SSH-Verbindung versuchen, eine zweite SSH-Verbindung herzustellen. Falls dies nicht möglich ist, müssen Sie wahrscheinlich in /etc/hosts.allow die Zeile sshd: ALL hinzufügen. Siehe Abschnitt 5.6.2, Der TCP-Wrapper.
5.6.5
Informationen zu /proc, insmod und dem Ptrace-Bug
Unter Linux wird das virtuelle /proc-Filesystem beim Systemstart automatisch initialisiert und mit sämtlichen Systeminformationen gefüttert. Zudem sind hier aktuelle Änderungen wie Routing-Tabelle (cat /proc/net/route) und ausführliche Informationen zur System-Hardware (zum Beispiel cat /proc/cpuinfo) wie selbstverständlich zu finden und von jedermann einzusehen. Die hohe Informationsfreiheit mag beim Betrieb von Systemüberwachungsskripten – die somit ebenfalls als unprivilegierte Nutzer laufen können (wie beispielsweise mrtg) sehr sinnvoll sein. Dass dieser vermeintliche Sicherheitsvorteil sich durchaus ins Gegenteil umkehren lässt, hat erst vor kurzem ein findiger Programmierer entdeckt. Der berüchtigte Ptrace-Bug ermöglicht es im Zusammenspiel mit modprobe (alias insmod) und /proc jedem unprivilegierten Account, Root-Rechte zu erlangen. Unabhängig von einer Anfälligkeit Ihres Systems gegenüber dem Ptrace-Bug sollten Sie /proc auf die Rechte 550 umsetzen und einer gesonderten Gruppe wie beispielsweise sysinfo übertragen. Nun können Sie allen Programmen, denen der Bezug von Systeminformationen gestattet sein soll (wie beispielsweise mrtg), sysinfo als Untergruppe zuweisen (usermod -g sysinfo mrtg).
392
Server absichern
1 2 Kernel-Versionen 2.2 bis 2.4.20 auf ptrace-bug testen
3
Die Möglichkeit, dass Angreifer Root-Rechte über ein einfaches Exploit erlangen können, ist der Alptraum gewissenhafter Systemadministratoren. Der Fall Ptrace ist umso tragischer, als die Original-Kernel-Versionen von 2.2 bis 2.4.20 mit diesem Fehler belastet sind und Sie sich nicht sicher sein können, ob der Standard-Kernel Ihrer Distribution nun gegen ptrace immun ist oder nicht.
4 5
Die einzige Methode, dies mit Sicherheit festzustellen, ist es, selbst zu prüfen. Kopieren Sie – als unprivilegierter User – die Datei isec-ptrace-kmodexploit.c von der CD zum Buch, rufen Sie gcc -i isec-ptrace-kmodexploit.c -o ptrace-exec auf und setzen Sie ptrace-exec auf 700. Nun wird es ernst:
6 7 8
user@debian:~$ ./ptrace-exec [+] Attached to 242 [+] Waiting for signal [+] Signal caught [+] Shellcode placed at 0x4000da2d [+] Now wait for suid shell... sh-2.05a# whoami root
9 10 11 12
Wie Sie sehen, kann es ein Kinderspiel sein, Root-Rechte zu erlangen. Die Argumentation, dass ptrace nur über einen System-Account ausgenutzt und nicht remote ausgeführt werden kann, ist leider Wunschdenken – sobald jemand ein Sicherheitsloch in einem von außen erreichbaren Server-Dienst (ob FTP-, Weboder Mailserver ist irrelevant) entdeckt und den Daemon kapert, könnte die Datei über diesen Daemon auf den Server übertragen und ausführt werden.
13 14
So fatal sich der ptrace-Bug auswirkt und so einfach sich Exploit ausführen lässt – genauso einfach ist er zu unterbinden: setzen Sie einfach ein chmod 500 /proc ab, und schon läuft ptrace ins Leere. Da sich der Exploit nach Ausführung selbst den owner Root zuweist und ein SUID-Bit setzt, wird jeder Aufruf von /ptrace-exec – unabhängig von der Anfälligkeit des Systems gegenüber dem ptrace-Bug – zu einer Root-Shell führen. Bevor Sie die Wirkung der Änderung der Zugriffsrechte von /proc auf den Exploit testen können, müssen Sie somit su root -c "chown user ./ptrace-exec && chmod 700 ./ptrace-exec" aufrufen oder den Exploit neu übersetzen.
user@debian:~$ ./ptrace-exec [+] Attached to 262 [+] Waiting for signal [+] Signal caught
Feinabstimmung
393
[+] Shellcode placed at 0x4000da2d [-] Unable to read /proc/self/exe: Permission denied Killed Wie eingangs erwähnt, macht der Exploit sich einen Fehler von insmod zunutze, um unter Zuhilfenahme von /proc/self/exe Root-Rechte zu erlangen. Die Möglichkeit, nachträglich Kernel-Module hinzuzuladen, bringt einen deutlichen Flexibilitätsgewinn bei einem erhöhten Sicherheitsrisiko. Da Sie modprobe auf einem Webserver nie mehr benötigen werden, sobald alle Treiber und Kernel-Erweiterungen eingebunden und konfiguriert sind, sollten Sie die Option »Loadable module support« (wie in Abschnitt 2.9, Der eigene Kernel, beschrieben) deaktivieren und alle benötigten Treiber sowie Kernel-Erweiterungen statisch einbinden.
5.7
Nessus
Netzwerk-Scanner tasten Rechner nach bekannten Sicherheitslücken ab. Deshalb sind Satan, Saint und ISS neben Nessus nicht nur für sicherheitsbewusste Admins, sondern auch für Cracker interessant. Nessus besitzt eine umfangreiche Angriffsdatenbank in Form vieler einzelner Plugins, die gezielt aktiviert oder deaktiviert werden können. Weiterhin sind die übersichtlichen und ausführlichen Sicherheitshinweise hilfreich bei der Absicherung des eigenen Servers. Da Nessus liebevoll gepflegt und leicht zu aktualisieren ist, sollten Sie auf diesen Scanner nicht verzichten.
5.7.1
Vorbereitungen
Der Nessus-Client benötigt einen Windows-Manager wie beispielsweise KDE oder Gnome. Damit der »Angriff« realistisch ist, gilt es zudem, einen Zweitrechner für den Nessus-Server zu nutzen. Natürlich kann auf dem Nessus-Server ebenfalls der Nessus-Client installiert werden. Gängige Linux- und BSDSysteme enthalten meist ein vorbereitetes Nessus-Client/Server-Paket. Sie sollten auf http://www.nessus.org nachsehen, ob für diese Version aktuelle Plugins verfügbar sind. Die Nessus-Plugins müssen unbedingt auf dem aktuellen Stand gehalten werden. Falls Ihre Version zu alt ist, um die neuesten Plugins zu beziehen, sind die Quellen einer aktuellen Version zu kompilieren. Übrigens ist der Nessus-Client ebenfalls in einer Windows-Version erhältlich. Auf http://www.nessus.org werden regelmäßig Plugins zu neuen Sicherheitslöchern und Exploits veröffentlicht. Sie sollten Nessus als Root über den Befehl nessus-update-plugins -v regelmäßig aktualisieren und gegen Ihren lokalen Spiegelserver laufen lassen.
394
Server absichern
1 2 Nach der Installation muss ein User-Account angelegt werden, über den später der Nessus-Server genutzt wird. Dies geschieht als Root über den Befehl nessus-adduser. Als Authentication-Methode können Sie die Voreinstellung (pass) übernehmen und das Ruleset über (Ctrl) + (D) überspringen.
5.7.2
3 4
Nutzung
5
Bevor Sie Nessus nutzen können, müssen Sie den Nessus-Daemon starten. Geben Sie dazu als Root den Befehl nessusd & ein. Nun kann der Nessus-Client unter einem User-Account durch Eingabe von nessus in einem X-term gestartet werden.
6 7
Geben Sie unter Login den Namen des Nessus-User-Accounts an. Nachdem Sie das Passwort eingegeben haben, können Sie die Verbindung zum Nessus-Server mit dem Button Login aufbauen.
8
Unter dem Reiter Plugins finden Sie eine Übersicht aller Plugins. Drücken Sie auf den Button Enable all, um sämtliche Plugins zu aktivieren. Mit »Enable all but dangerous plugins« wird auf »gefährliche« Plugins verzichtet, die den untersuchten Server lahm legen könnten.
10
9
11 12 13 14
Abbildung 5.3 Weitere Hinweise zu den Sicherheitshinweisen finden Sie über die CVE-Kennung unter http://icat.nist.gov und http://www.cve.mitre.org.
Nessus
395
Da Ihr Spiegelserver nicht im harten Betrieb arbeitet und Abstürze keinen Ausfall des eigentlichen Webservers bedeuten, sollten Sie unbedingt sämtliche Plugins aktivieren. Damit »gefährliche« Angriffe tatsächlich durchgeführt werden, ist die Option Safe checks im Reiterabschnitt Scan options gegebenenfalls zu deaktivieren. Nun müssen Sie noch die IP-Adresse des zu überprüfenden Servers unter Target(s) über den Reiter Target selection eintragen und den Scan mit dem Button »Start the scan« starten. Der Vorgang sollte zunächst mit offenem Paketfilter ausgeführt werden, um den Server so auf alle theoretisch von außerhalb erreichbaren Sicherheitslücken zu untersuchen. Erst im zweiten Durchlauf ist der Paketfilter zu aktivieren. Hinweis Der Überprüfungsvorgang wird einige Zeit in Anspruch nehmen. Am besten lassen Sie Nessus beispielsweise in der Mittagspause laufen.
5.7.3
Fehlalarm ist keine Seltenheit
Selbst wenn Nessus zur Auffassung gelangt, eine Sicherheitslücke gefunden zu haben, heißt dies nicht, dass Ihr Server tatsächlich über diesen Weg zu knacken ist. Sehen Sie sich zunächst die Beschreibung näher an. Weitere Informationen können über die CVE-Kennung unter http://icat.nist.gov und http:// www.cve.mitre.org abgefragt werden. Bedenken Sie, dass Nessus die Prüfung nach Sicherheitslücken in vielen Fällen lediglich anhand der Versionsnummer des Dienstes und seiner Exploit-Datenbank »aufdeckt«. Manuell oder via you, up2date beziehungsweise apt automatisch eingespielte Sicherheits-Patches werden von Nessus nicht erkannt, und somit wird ein falscher Alarm ausgelöst. Falls changelog zum angemahnten Programm keinen Hinweis zu einem Patch für das angemahnte Sicherheitsproblem enthält, sollten Sie im nächsten Schritt einen Blick auf die Projektseite des entsprechenden Programms werfen. Sind weder auf der Homepage noch in den einschlägigen Mailinglisten und Websites (siehe Abschnitt 5.14, Sicherheitsinformationen beziehen) entsprechende Meldungen zu finden, können Sie von einem Fehlalarm ausgehen. Falls zu einem kritischen Sicherheitsproblem kein aktueller Patch oder keine neue Programmversion existiert, sollten Sie die Software nach Möglichkeit deinstallieren und auf eine entsprechend korrigierte Version warten oder die Software durch ein alternatives Programm vollständig ersetzen.
396
Server absichern
1 2
5.8
nmap
3
Script Kiddies greifen auf gekaperte Server gerne über Backdoors zu. Einige Exploits liefern einen passenden Trojaner gleich mit. In diesen Fällen wird üblicherweise ein ungewöhnlicher Highport zur Datenkommunikation genutzt. Falls Sie schnell überprüfen möchten, ob Ihr Server kompromittiert wurde, bietet sich ein Portscanner wie nmap an. Um beispielsweise nach dem bekannten Back Orifice – das häufig unter dem UDP-Port 31337 gastiert – zu fahnden, nutzen Sie den Befehl nmap -sU Server.de -p 31337.
4 5 6
Zusätzlich sollten Sie in regelmäßigen Abständen einen vollständigen Portscan durchführen, um zu überprüfen, welche Ports oder Dienste von außen erreichbar sind. Auf die Standard-Trojaner-Ports ist leider kein Verlass, da Angreifer die Ports durchaus ändern können. Bei Abweichungen vom erwarteten Ergebnis sollten alle Alarmglocken läuten, und Sie sollten sich Abschnitt 5.15, Verhalten beim Super-GAU, zuwenden.
5.8.1
7 8 9 10
Die wichtigsten Funktionen
Wie bei Nessus, werden Sie auch für nmap ein auf Ihr System angepasstes Paket vorfinden. Somit können Sie sich mühevolles Kompilieren sparen. In der Manpage finden Sie sämtliche Funktionen von nmap ausführlich beschrieben. Für unsere Zwecke genügen die in Tabelle 5.2 aufgeführten Optionen.
11 12 13
Option
Bedeutung
-sT
TCP connect scan: Versucht eine Verbindung zu jedem relevanten Port aufzubauen und listet die erreichbaren Ports auf.
-sU
UDP-Scan: Vorsicht – arbeitet nur erwartungsgemäß, wenn auf dem gescannten Rechner »ICMP-port-unreachable«-Antwortpakete erlaubt sind und alle eingehenden UDP-Pakete akzeptiert werden. Sonst werden alle(!) Ports als offen betrachtet.
14
-p <port ranges> Überprüft, ob unter bestimmten Ports ein Dienst erreichbar ist. Sie können einzelne Ports durch Kommata trennen oder das Zeichen »-« verwenden (-p 80, 995, 20–23). -vv
Sorgt für ausführliche Meldungen zum Scan-Vorgang.
Tabelle 5.2 Sinnvolle nmap-Optionen zum Scannen des eigenen Servers
Die in Abschnitt 5.3, Paketfilter, vorgeschlagenen restriktiven Paketfilter-Regeln verhindern »leider« einen erfolgreichen -sU-Scan. Nutzen Sie ein Shell-Skript, um eingehende UDP-Pakete von Ihrem nmap-Rechner sowie die ICMP-Meldung port-unreachable zu Ihrem nmap-Rechner zu erlauben. Da insbesondere UDP-
nmap
397
Scans sehr zeitraubend sind, sollten Sie sich die Mühe machen, lediglich die vom Dial-up-ISP zugewiesene IP-Adresse Ihres lokalen Rechners freizugeben. In einem zweiten Scan sollten zudem sämtliche Ports des TCP vom und zum scannenden Rechner freigegeben werden. Nur so sehen Sie, welche Ports tatsächlich von außen erreichbar sind und auf welchen Ports (ohne Paketfilter) Dienste nach außen angeboten werden. iptables
# Für vollständigen UDP-Scan iptables -A INPUT -p UDP -s 123.45.67.89 -j ACCEPT iptables -A OUTPUT -p icmp –d 123.45.67.89 \ --icmp-type port-unreachable -j ACCEPT # Für vollständigen TCP-Scan iptables -A INPUT -p TCP -s 123.45.67.89 -j ACCEPT iptables -A OUTPUT -p TCP -d 123.45.67.89 -j ACCEPT OpenBSD
# Für vollständigen UDP-Scan pass in quick proto udp from 123.45.67.89 to any pass out quick inet proto icmp all icmp-type 3 code 3 # Für vollständigen TCP-Scan pass in quick proto tcp from 123.45.67.89 to any pass out quick proto tcp from any to 123.45.67.89 Danach kann ein vollständiger Scan über nmap –vvsTU server.de > output.nmap durchgeführt werden. Sobald der Scan abgeschlossen ist, finden Sie sämtliche auf http://server.de erreichbaren TCP- und UDP-Ports in der Datei output.nmap. Wer seine Logfiles aufmerksam beobachtet und Port-Anfragen auf bekannte Backdoors loggt, dem wird sicher nicht gefallen, dass Portscanner durch restriktive Paketfilter in die Irre geführt werden und dritten Personen eine vermeintliche »Schwachstelle« angezeigt wird. Dennoch ist dies weit besser, als sämtliche UPD-Ports für eingehende Pakete zu öffnen.
5.9
Portscans erkennen
Üblicherweise wird ein Angreifer Ihr System scannen, bevor er versucht, bekannte Sicherheitslücken mit Exploits auszunutzen. Es gibt einige Scan-Verfahren, die sehr subtil sind und sogar die Version des von Ihnen genutzten
398
Server absichern
1 2 Betriebssystems ermitteln können. Rein rechtlich gesehen ist ein »einfacher« Portscan nicht illegal, aber häufig leitet er Angriffsversuche ein. Deshalb sollten Sie die IP-Adressen, von denen Portscans vorgenommen wurden, genau beobachten.
3 4
Das Erkennen von Portscans ist nicht kompliziert. Installieren Sie Scanlogd, der für jede Linux- und BSD-Distribution erhältlich ist. Nach dem Start meldet das Programm dem Syslog-Daemon die erkannten Portscans:
5 6
Dec 28 11:57:45 mirrorian scanlogd: 192.168.0.25 to \ 192.168.0.2 ports 1532, 1472, (...) , fSrpauxy, TOS 00 (...)
7
Allerdings wird Ihr Paketfilter bereits einige Scans verhindern und vor dem Scanlogd verbergen. Deshalb ist es wichtig, zusätzlich die in Abschnitt 5.3.18, Welche Pakete sollten geloggt werden?, beschriebenen Filterregeln zum Loggen von Portscans in iptables zu aktivieren.
8 9
Es ist eine gute Idee, den Paketfilter auf einem Testrechner zu deaktivieren und mit nmap (siehe Abschnitt 5.8, nmap) die verschiedenen Scan-Methoden durchzuspielen, um die jeweiligen Signaturen im Logfile erkennen zu lernen. Aktivieren Sie danach den Paketfilter, um zu überprüfen, wie sich die Änderungen sowohl auf den Portscanner als auch auf Scanlogd auswirken. Sie werden feststellen, dass es subtile (und langwierige) Portscans gibt, die weder über Scanlogd noch über ausgefeilte iptables-Logrules leicht zu erkennen sind.
10 11 12 13
5.10 Integritätsprüfung mit AIDE
14
Angreifer ersetzen Systemprogramme gerne durch Backdoors oder Rootkits. So ist es möglich, Programme oder Logdateien von Passwort-Sniffern und ähnlich fragwürdiger Software vor Ihnen zu verstecken, indem beispielsweise die Befehle ls, find und locate manipuliert werden. Auf der anderen Seite verraten sich geänderte Systemprogramme durch eine abweichende Checksumme. Damit ist die Prüfsumme gemeint, die sich aus dem Binärcode der Programmdateien ermitteln lässt. Es gibt dazu verschiedene Verfahren wie md5 oder sha1. Im Gegensatz zum Datum oder der Dateigröße ist es (nahezu) unmöglich, eine Prüfsumme zu fälschen. Tripwire ist der wohl bekannteste Integritätsprüfer. Leider ist das Programm kommerziell ausgerichtet. Nur eine ältere Version steht als Open Source zur Verfügung. Das AIDE-Projekt ist ähnlich leistungsstark, steht unter der GPL und wird gut gepflegt. Da es zudem leicht konfigurierbar ist und übersichtliche Berichte erzeugt, will ich Ihnen das »Advanced Intrusion Detection Environment« näher vorstellen.
Integritätsprüfung mit AIDE
399
5.10.1 Vorbereitungen – Initialisieren und Erstellen der AIDEDatenbank Die Installation gestaltet sich unproblematisch, da für gängige Linux- und BSDSysteme bereits entsprechend vorbereitete AIDE-Pakete existieren. Nach dem Einspielen der Paketdatei gilt es dennoch einiges zu beachten. In der Datei /etc/aide/aide.conf sind alle wichtigen Einstellungen vorzunehmen. Hier können Sie zudem Ort und Namen der AIDE-Datenbank ändern. Es ist empfehlenswert, beim Erstellen einer neuen Datenbank die ursprüngliche beizubehalten, damit Sie nicht versehentlich die Datenbank neu initialisieren. Um Dateien zu überprüfen, kann AIDE sämtliche in Tabelle 5.3 aufgeführten Verfahren gleichzeitig anwenden. Kürzel
Bedeutung
P
Permissions (Zugriffsrechte)
I
Inode (siehe Glossar zur Erläuterung)
N
Number of Links (Anzahl der auf eine Datei weisenden Soft- und Hardlinks)
U
User (Eigentümer)
G
Group
s
Size (Dateigröße)
b
Block Count (Anzahl der verwendeten Speicherblöcke)
m
mtime (Zeitpunkt der letzten Änderung am Inhalt der Datei)
a
atime (Zeitpunkt des letzten Aufrufs)
c
ctime (Zeitpunkt der letzten Statusänderung)
S
Check for growing Size (Datei darf lediglich größer werden; sinnvoll für Logfiles)
md5
Md5 Checksumm
sha1
Sha1 Checksumm
rmd160
rmd160 Checksumm
tiger
tiger Checksumm
Tabelle 5.3 Übersicht über alle von AIDE unterstützten Methoden zur Integritätsprüfung
Es ist durchaus sinnvoll, möglichst viele Optionen gleichzeitig zu nutzen. Allerdings ergibt es wenig Sinn, Logfiles nach ihrer Checksumme zu überprüfen. Damit die Konfiguration übersichtlich bleibt, empfiehlt es sich, die einzelnen
400
Server absichern
1 2 Optionen in Variabeln zu sichern und so Konfigurationsabschnitte mit Prüfungen nach Logfiles oder Systemprogrammen zu trennen.
3
Aide.conf ist bereits gut vorbereitet, so dass Ihnen der Einstieg nicht schwer fallen sollte. Prüfen Sie, ob Pfade zu sämtlichen Binaries enthalten sind. Falls Sie Courier-IMAP nutzen, ist der Abschnitt # Binaries beispielsweise um die Zeile /usr/lib/courier-imap Binlib zu ergänzen. Prüfen Sie auch, ob sämtliche Standard-Programmpfade Ihres Systems (Ausgabe von echo $PATH) enthalten sind.
4 5 6
Da auf einem Webserver eher selten Konfigurationsdateien geändert werden, sollten Sie AIDE über die Zeile /etc ConfFiles auf das Verzeichnis mit den Konfigurationsdateien ansetzen. Daneben bietet es sich an, in »versteckten« Verzeichnissen ausgelagerte, eigene Shell- oder Perl-Skripte ebenfalls einer Integritätsprüfung (mit Binlib oder ConfFiles) zu unterziehen.
7 8 9
Wer auf den Server »vor Ort« zugreifen kann und die Möglichkeit hat, bei einem Einbruch sämtliche Daten über ein Rettungssystem read-only zu mounten und auf CD-ROM zu brennen, sollte beachten, dass von tar oder rsync kopierte Dateien neue Inodes erhalten. Verzichten Sie in diesem Fall auf die Option -i, um die Integritätsprüfung in Ruhe auf dem gesicherten Datenträger vornehmen zu können.
10 11 12
5.10.2 Überprüfung der Systemintegrität
13
Zur Überprüfung der Systemintegrität vergleicht AIDE die Systemdaten mit den Informationen der programmeigenen Datenbank. Letztere gilt es zuvor mit dem Befehl aide -i als Root zu erstellen. Generell muss AIDE von Root benutzt werden, da es Zugriff auf sämtliche Verzeichnisse und Programme des Systems benötigt. Kopieren Sie die erzeugte Datenbank in das als Variable database_out festgelegte Verzeichnis und benennen Sie die Datenbank entsprechend um: cp -p /var/lib/aide/aide.db.new /var/lib/aide/aide.db.
14
Zur Überprüfung der Funktionstüchtigkeit legen wir die Dummydatei test mit touch /sbin/test im Verzeichnis /sbin an. Nach dem Aufruf von aide -C sollte AIDE Änderungen am Verzeichnis /sbin bemängeln und die neu erzeugte Datei test aufführen:
mirrorian:/etc/aide# aide -C AIDE found differences between database and filesystem!! Start timestamp: 2002–12–26 14:19:45 Summary: Total number of files=52359,added files=1,removed files=0,chan-
Integritätsprüfung mit AIDE
401
ged files=1 Added files: added:/sbin/test Changed files: changed:/sbin Detailed information about changes: Directory: /sbin Mtime : 2002–12–26 09:54:22, 2002–12–26 14:19:39 Ctime : 2002–12–26 09:54:22, 2002–12–26 14:19:39 In der ersten Zeit empfiehlt es sich, AIDE täglich manuell aufzurufen, um so im harten Server-Betrieb die AIDE-Datenbank weiter anzupassen, bis kein Fehlalarm mehr angezeigt wird. Um häufig zu ändernde Dateien oder Verzeichnisse von der AIDE-Prüfung auszuschließen, genügt der Eintrag !/pfad/begriff. Das vorangestellte Ausrufezeichen signalisiert AIDE, dass dieses Suchmuster ignoriert werden soll. Unser Beispiel bewirkt die Ausklammerung sämtlicher Dateien und Verzeichnisse (inklusive der in ihnen enthaltenen Unterverzeichnisse und Dateien), die über ls /pfad/begriff* angezeigt würden. Beachten Sie, dass die Ausklammerung eines Verzeichnis- oder Dateinamens vor der Prüfung des entsprechenden Abschnitts erfolgen muss. Sie sollte daher generell vor den zu prüfenden Abschnitten notiert werden. Aktualisieren Sie die Datenbank nach einem Fehlalarm über den Befehl aide -u und ersetzen Sie danach die ursprüngliche Datenbank durch die neue Datei. Wenn so gut wie kein Fehlalarm mehr auftritt, sollten Sie darüber nachdenken, den Aufruf aide -C regelmäßig über cron auszuführen. Wenn Ihr Server wenig belastet wird, sollten Sie durchaus alle 20 Minuten die Systemintegrität überprüfen. Auf Systemen, die mit hoher Load- oder CPU-Belastung zu kämpfen haben, ist dies wenig sinnvoll. Dennoch sollten Sie AIDE auch hier zwei- bis viermal täglich ausführen. Denken Sie vor dem Einspielen von Sicherheits-Updates oder vor dem Installieren neuer Software ebenfalls an AIDE. Untersuchen Sie Ihr System, bevor Sie das Sicherheits-Update einspielen beziehungsweise das neue Software-Paket installieren. Rufen Sie direkt nach den vorgenommenen Änderungen aide -u auf und ersetzen Sie danach die ursprüngliche Datenbank durch die neue Datei.
5.10.3 Sicherheitshinweise Systemprogramme zur Überprüfung der md5-Checksumme können selbstverständlich ebenfalls manipuliert werden. Dennoch sind Tools zur Überprüfung
402
Server absichern
1 2 der Systemintegrität sinnvoll. Grundsätzlich sollten Sie AIDE auf dem ServerSystem regelmäßig neu installieren und die Datenbank auf Ihren lokalen Rechner auslagern. Selbstverständlich können Sie vor einer AIDE-Prüfung die AIDEDatenbank auf den Server übertragen und nach den Änderungen die neue Datenbank erneut auf dem lokalen Rechner speichern.
3 4 5
Installieren Sie AIDE einfach regelmäßig neu, um sicherzustellen, dass die Ausgaben korrekt sind. Natürlich sollten Sie die Datenbank, mit der das System überprüft wird, bei dieser Gelegenheit ebenfalls durch eine (externe) Sicherheitskopie ersetzen.
6 7
Wer wirklich hundertprozentig sicher gehen möchte, dass die Ausgabe von AIDE nicht manipuliert wird, der stellt auf der Festplatte (oder noch besser auf einer CD-ROM) ein Notfallsystem mit installiertem AIDE bereit. Mounten Sie nach dem Start des Notfallsystems die eigentliche Server-Partition und wenden Sie eine entsprechend angepasste Variante von aide.conf (anstelle von / ist /mountpoint/ zu verwenden) an. Überspielen Sie aide.conf zusammen mit einer Sicherungskopie der entsprechenden AIDE-Datenbank nach /tmp, bevor Sie mit der Prüfung beginnen. Weitere Hinweise hierzu finden Sie in Abschnitt 4.14, Das Rettungssystem.
5.11
8 9 10 11
Das Intrusion-Detection-System Snort
12
IDS werden zum Erkennen von Angriffen verwendet. Snort kann sozusagen als das Gegenstück zu Nessus betrachtet werden. Anstatt Angriffe auszuführen, werden Einbruchsversuche und andere unliebsame Aktionen protokolliert.
13 14
In Netzwerken, die höchsten Sicherheitsansprüchen gerecht werden müssen, werden häufig gleich mehrere IDS auf gesonderten Rechnern eingesetzt. Lediglich ein IDS, das vor dem Paketfilter platziert wird, ist in der Lage, sämtliche Angriffsversuche zu protokollieren. Obwohl Sie vor Ihren Webserver kaum ein IDS stellen können, ist Snort selbst auf dem Server nützlich. So können Angriffsversuche, die den Paketfilter passieren konnten, erkannt und geloggt werden. Neben einem Sniffer und einem eigenen Paket-Logger bringt Snort zudem einen Portscan-Detektor mit. Erfahrene Nutzer schätzen die flexiblen Möglichkeiten zur Erstellung weiterer Angriffsfilter. http://www.snort.org/docs/ writing_rules/ hält eine sehr gute englischsprachige Dokumentation zu dieser Thematik bereit. Allerdings wird Snort von vielen Experten regelmäßig mit den neuesten Angriffsignaturen erweitert. Im Normalfall werden Sie Snort ohne großartigen Zeitaufwand als zuverlässiges IDS verwenden können.
Das Intrusion-Detection-System Snort
403
5.11.1 Installation und Aktualisierungen Snort lebt von der Aktualität seiner Angriffsignaturen. Ähnlich einem VirenScanner arbeitet das IDS lediglich dann wirklich zuverlässig, wenn Sie regelmäßig Aktualisierungen der Angriffsignaturen einspielen. Da Snort intensiv weiterentwickelt wird, sind die neuesten Angriffsignaturen von http:// www.snort.org/dl/rules/ häufig nicht für die etwas betagteren Standardpakete Ihres Linux- oder BSD-Systems verfügbar. Ärgerlicherweise ist die Installation der neuesten Snort-Version ebenfalls an aktuelle Systembibliotheken gebunden, die obendrein meist von allen wichtigen Diensten benötigt werden. Eine Aktualisierung kann sich allerdings negativ auf die Stabilität des Systems und auf das Einspielen von SicherheitsUpdates auswirken. Falls Sie beim Kompilieren des Quellcodes (http://www.snort.org/dl/) oder beim Einspielen der RPM-Pakete (http:// www.snort.org/dl/binaries/) wegen »betagteren« Systembibliotheken auf Probleme stoßen, ist es meist besser, zugunsten eines möglichst stabilen Webservers auf aktuelle Angriffsignaturen zu verzichten. Diese Regel gilt natürlich nicht für einen gesonderten Rechner, der lediglich als Snort-System arbeitet.
5.11.2 Betrieb Snort kann mit vielfältigen Optionen gestartet werden. Einen vollständigen Einblick erhalten Sie über die Manpage. Auf einem Webserver empfiehlt sich der Befehl /usr/sbin/snort -m 027 -D -c /etc/snort/snort.conf -b -d -u snort -g snort -i eth0 -p. Erläuterungen zu den wichtigsten Startoptionen finden Sie in Tabelle 5.4. Kürzel
Beschreibung
-D
Startet Snort als Daemon.
-A
Alert mode, fast oder full. Wird -A nicht angegeben, formatiert Snort seine Meldungen in mehreren Zeilen. Mit Full wird zusätzlich der Header ins Logfile geschrieben. Mit fast erzeugt Snort seine Logmeldungen im Syslog-Modus (in einer Zeile).
-c
Nutzt die angegebene Konfigurationsdatei für IDS-Funktionen.
-l
Bestimmt das Verzeichnis, in dem Snort seine Logfiles ablegt.
-i
Optional kann Snort angewiesen werden, lediglich das angegebene NetzwerkInterface zu beachten.
Tabelle 5.4 Die wichtigsten Snort-Befehlsoptionen. Eine Übersicht sämtlicher Befehle bietet man snort.
404
Server absichern
1 2 Kürzel
Beschreibung
-p
Deaktiviert den Promiscuous-Modus. Unbedingt angeben, wenn lediglich der Server, auf dem der Snort-Daemon läuft, zu überwachen ist.
-I
Nützlich, wenn auf mehr als einem Netzwerk-Interface »gelauscht« wird. Snort gibt dann im Logfile das Device an, an das die Daten gerichtet wurden.
-u -g
Legt den Benutzer (-u) sowie die Gruppe (-g) fest, unter der Snort gestartet wird.
-b -d
Da Snort sämtliche Pakete aufzeichnet, ist es ratsam, das eigentliche Logfile im Binärformat zu erzeugen. Dies geschiet mit der Option -b. Damit die Binärdatei von tcpdump gelesen werden kann, sollten Sie als Ergänzung -d verwenden.
3
-m
Bestimmt die Umask, mit der die Logdaten gesichert werden.
-s
Sendet Warnmeldungen (gefundene Angriffsignaturen) an Syslog.
-t
Chrooted Snort ins angegebene Verzeichnis.
-r
Liest die angegebene Binärlog-Datei aus (alternative zu tcpdump).
4 5 6 7 8 9 10
Tabelle 5.4 Die wichtigsten Snort-Befehlsoptionen. Eine Übersicht sämtlicher Befehle bietet man snort. (Forts.)
11
Im Snort-Logverzeichnis finden Sie neben der Binärdatei und portscan*.log für aufgezeichnete Portscans ebenfalls das besonders interessante Logfile alert. Hier sind sämtliche erkannten Angriffsversuche gesichert. Ein Beispiel:
12
[1:1704:3] WEB-CGI cal_make.pl directory traversal attempt [Classification: Web Application Attack] [Priority: 1] 12/28–19:36:26.600183 192.168.0.44:34112 -> 192.168.0.2:80 TCP TTL:64 TOS:0x0 ID:9699 IpLen:20 DgmLen:371 DF ***AP*** Seq: 0x1AFFFAFE Ack: 0x1D8A9892 Win: 0x16D0 TcpLen: 32 TCP Options (3) => NOP NOP TS: 319261 59955 [Xref => bugtraq 2663][Xref => cve CVE-2001–0463]
13 14
Snort versorgt Sie mit allen lebenswichtigen Informationen. Neben Zeitpunkt und Namen der Attacke finden Sie ebenfalls die IP- und Port-Adresse des angegriffenen Servers (192.168.0.2; Port 80 = Apache) sowie die Daten des Angreifers (192.168.0.44; Highport). Um zu überprüfen, ob Ihr Server anfällig für diese Attacke ist, finden Sie detaillierte Informationen über die Advisory-Kennung CVE-2001–0463 im Internet. Empfehlenswerte Anlaufstellen sind http://icat.nist.gov und http://www.cve.mitre.org. Es bietet sich an, diese Datei mit Logsurfer automatisiert zu überwachen und bei schwerer wiegenden beziehungsweise ungewöhnlichen Angriffsmustern sofort per E-Mail eine Benachrichtigung abzusenden. Interessant ist ebenfalls
Das Intrusion-Detection-System Snort
405
die Möglichkeit, eine Statistik über angreifende IP-Adressen, Anzahl und Art des Angriffs über cat /var/log/snort/alert | snort-stat ausgeben zu lassen. So können Sie schnell überprüfen, ob von einem Rechner mit fester IPAdresse regelmäßig Angriffe gestartet werden.
5.12
Absichern von Logfiles
Das Absichern von Logfiles ist neben der rechtzeitigen Auswertung eine wichtige Aufgabe. Falls es einem Angreifer gelingt, sämtliche Logdaten, die Hinweise auf seine Identität geben, zu verändern oder zu löschen, dann werden Sie, abgesehen von einer Anzeige gegen unbekannt, keine Möglichkeit finden, rechtliche Schritte einzuleiten. Der Syslog-Daemon kann neben der Sicherung in Logfiles die Logeinträge zusätzlich an einen Loghost senden. Falls Sie einen zweiten Server oder eine Vserver-Umgebung nutzen, ist dies eine bequeme und schnell zu realisierende Methode. Allerdings können Angreifer die Nutzung eines Loghosts schnell aufspüren und greifen häufig zu einer recht unschönen Gegenmaßnahme: Mit einem Tool wie logger werden automatisiert haufenweise unsinnige Loginformationen produziert, um die Suche nach wichtigen Einträgen deutlich zu erschweren. Obendrein werden relevante Daten früher oder später nicht mehr geloggt, da irgendwann keine Festplattenkapazität mehr für weitere Logeinträge vorhanden ist. Selbstverständlich werden aufmerksame Administratoren ein derart hohes Aufkommen an Logeinträgen schnell bemerken und sofort Gegenmaßnahmen ergreifen. Falls der Angriff jedoch über Nacht passiert, oder die zuständigen Administratoren in einer Besprechung oder anderweitig »abgelenkt sind«, kann der Cracker »seelenruhig« die gesetzten Ziele verfolgen.
5.12.1 Automatisierte Sicherung über ssh Ein automatisiertes Backup durch einen zweiten Rechner ist eine relativ unauffällige Sicherungsmethode. Damit ein Einbruch auf dem Backup-System nicht gleichzeitig zu Root-Rechten auf dem Webserver führt, ist ein zusätzlicher UserAccount zu erstellen. Weisen Sie diesem eine unauffällige und unprivilegierte Gruppe zu, die Berechtigung zum Lesen der Logfiles hat. Auf dem zweiten System können Sie ein Shell-Skript erstellen, das über eine SSH-Verbindung die neuen Logeinträge alle zehn Minuten ausliest und in einer lokalen Datei sichert. Siehe dazu Abschnitt 4.1, Automatische Jobsteuerung, und Abschnitt 3.1, Open SSH.
406
Server absichern
1 2 Unter Linux ist die Sicherung der Logfiles einer Vserver-Umgebung noch einfacher und völlig unauffällig zu realisieren. Hier genügt bereits tail -f /vserver/foo/path/log >> /pfad/zum/backup &. In Kapitel 6, Linux-Vserver, ist die Installation und der Betrieb eines Vservers beschrieben.
3 4
5.12.2 Automatisierte Sicherung per E-Mail
5
Falls Ihnen kein zweiter Server zur Verfügung steht, und eine Vserver-Umgebung nicht in Betracht kommt, ist eine Sicherung per E-Mail denkbar. Selbstverständlich sollten Sie die E-Mail keinesfalls in einem Postfach auf dem Server ablegen, sondern lieber das Postfach Ihres Zugangs-Providers oder notfalls das eines Free-Mailers nutzen.
6 7 8
Halten Sie den entstehenden Datenverkehr durch vorherige Komprimierung der relevanten Logdaten klein. Insbesondere wenn der Angreifer Ihre Taktik bemerkt und zu logger greift, kann das Versenden per E-Mail trotz Komprimierung problematisch bis unmöglich werden. Deshalb bietet es sich an, lediglich bei fragwürdigen Logeinträgen oder Warnungen von AIDE oder Snort automatisiert den relevanten Zeitraum der wichtigen Logfiles zu übermitteln. Nutzen Sie dazu Logsurfer, wie in Abschnitt 5.13.1, Automatisierte Warnmeldungen via Logsurfer, erläutert.
5.13
9 10 11 12
Logfile-Analyse
13
Die Auswertung von Logdateien wird durch Programme wie Logcheck erheblich vereinfacht. Mit dem menschlichen Spürsinn können aktuelle Analyser jedoch nur bedingt mithalten. Verstehen Sie die Tools als eine Hilfe, um in den oftmals mehrere Megabyte großen Logfiles wichtige Elemente herauszufiltern. Überfliegen Sie Ihre Logfiles regelmäßig selbst, um mögliche Unstimmigkeiten und ungewöhnliche Logmuster zu erkennen.
14
Eine rein manuelle Prüfung ist ebenso ungeeignet wie eine vollständig automatisierte Analyse. Das Problem liegt nicht nur in der Datenmenge, sondern auch im Zeitraum. Selbst der gewissenhafteste Administrator wird nach einiger Zeit aufhören, sämtliche relevanten Logfiles mehrmals täglich zu überprüfen. Andererseits schlägt Snort mit schöner Regelmäßigkeit Alarm, und auch Logcheck macht fleißig Meldung. Tatsächlich werden Sie erstaunt sein, wie häufig Ihr Server drittklassigen Angriffen und Portscans ausgesetzt ist. Es ergibt wenig Sinn, mit Panik-Mails auf Bombardements von MS-IIS-Exploits zu reagieren. Dies würde dazu führen, dass Sie diese Nachrichten nicht mehr beachten und früher oder später eine wichtige E-Mail übersehen.
Logfile-Analyse
407
Erfahrene Systemadministratoren nutzen zur Logfile-Analyse deshalb mehrere Konzepte parallel: 1. sofortige automatisierte Meldung über elementare Verstöße, 2. regelmäßig ausführliche, automatisiert aufbereitete Analyseberichte, 3. manuelle Überprüfung und Vergleich (diff) mit Backup-Daten.
5.13.1 Automatisierte Warnmeldungen via Logsurfer Logsurfer ist ein sehr mächtiges Analyse-Tool. Es ist in der Lage, reguläre Suchmuster nicht nur auf einzelne Logzeilen, sondern auch in einem Kontext zu betrachten. Auf Wunsch startet Logsurfer als Hintergrundprozess und versendet problematische Logzeilen unmittelbar als Warnmeldung per E-Mail. Wem Logsurfer zu umfangreich oder zu umständlich erscheint, dem steht mit Swatch eine interessante Alternative offen. Weitere Informationen finden Sie unter http://www.oit.ucsb.edu/~eta/swatch. Ein zuverlässiger Indikator für ernst zu nehmende Angriffe ist Systrace. Sobald sich ein entsprechender Eintrag in der Logdatei zu Syslog findet, sollte eine E-Mail versandt werden. Falls Sie Nutzern keinen Shell-Zugang gewähren, bietet es sich ebenfalls an, Logins neben su- und sudo-Aktivitäten direkt zu melden. Wie eingangs erwähnt, sind die Ansatzmöglichkeiten sehr vielfältig und hängen stark von Ihrem System ab. Sie können Logcheck (siehe Abschnitt 5.13.2, Analyseberichte mit Logcheck erstellen) als weiterführende Regelbasis nutzen: Listen Sie die »harmlosen und eher uninteressanten« Meldungen in einer separaten Datei auf. Nach ein bis zwei Monaten können Sie die verbliebenen – und für Ihren Server relevanten – Suchmuster als Logsurfer-Regeln definieren. So werden Sie über ungewöhnliche und bedenkenswerte Vorgänge unmittelbar informiert. Installation Auf der CD zum Buch finden Sie das Archiv logsurfer-1.5b.tar.gz. Sie können das Paket gemäß der üblichen Vorgehensweise entpacken und kompilieren. Unter ftp://ftp.cert.dfn.de/pub/tools/audit/logsurfer/ steht neben Beispielen zur Konfiguration ebenfalls die aktuellste Logsurfer-Version bereit. Da Logsurfer von Ihnen als Hintergrundprozess gestartet werden sollte, ist es ratsam, einen zusätzlichen User anzulegen, um das Programm nicht mit RootRechten längere Zeit laufen lassen zu müssen.
408
Server absichern
1 2 Einführung
3
Die Nutzung von Logsurfer ist gewöhnungsbedürftig. In der Konfigurationsdatei können Zeilen mit # wie gewohnt auskommentiert werden. Leerzeichen oder Tabs dürfen am Zeilenanfang nur in Folgezeilen zu einer Regel verwendet werden, da Logsurfer diese Zeilen sonst als weitere Befehle zur vorhergehenden Regel betrachtet.
4 5
Als Filter für reguläre Ausdrücke verwendet Logcheck die Syntax von egrep (man egrep). Weiterhin sieht eine Regel folgende Optionen vor:
6
1. Match Regex (sucht nach Logzeilen, die das angegebene Muster enthalten)
7
2. Not Match Regex (wenn in der gefundenen Logzeile das zweite Suchmuster gefunden wird, ignoriert Logsurfer den Logeintrag)
8
3. Stop Regex (trifft das Suchmuster zu, wird diese Regel gelöscht. Über die Rule-Aktion können dynamisch Zusatzregeln erzeugt werden. Für diese kann ein Stop-Regex-Muster durchaus sinnvoll sein. Eine kurze Einführung in die Erstellung dynamischer Regeln finden Sie auf folgender Website: www.cert.org/security-improvement/implementations/i042.02.html)
9 10
4. Not Stop Regex (analog zu Not Match Regex wird bei zutreffendem Suchmuster die Stop-Regex-Anweisung ignoriert)
11
5. Timeout (komplexere Kontextregeln können mit einem Zeitlimit versehen werden. Bei einzelnen Logzeilen ist diese Option ohne Belang, und Sie können 0 verwenden.)
12 13
6. Action (legt fest, ob bei zutreffender Match-Regex-Regel ein Kontext geöffnet beziehungsweise die Logzeile ignoriert werden soll oder ein Kommando auszuführen ist)
14
Die Reihenfolge ist zwingend einzuhalten. Werden einzelne Optionen wie NotMatch sowie die Stopp-Regeln nicht benötigt, ist ein Minuszeichen als Platzhalter zu verwenden.
'failure.* -> .*' - - - 0 pipe "/usr/bin/mailx -s \"SU Missbrauch\" root" Dieses einfache Beispiel sendet bei jedem fehlgeschlagenen User-Wechsel über su (Passwortfehler) eine E-Mail an Root. Die eigentliche Logzeile wird dem EMail-Body über die Funktion pipe übergeben. Um fehlerhafte Passworteingaben der User-ID 1000 zu ignorieren, können Sie die Regel um einen NotMatch-Regex-Filter erweitern:
'failure.* -> .*' '(uid=1000)' - - 0 pipe "/usr/bin/mailx -s \"SU Missbrauch\" root"
Logfile-Analyse
409
Logsurfer erwartet für jede zu überwachende Logdatei eine Regeldatei und muss ebenfalls jeweils gesondert gestartet werden. Für einen Testlauf der oben genannten Regel genügt der Aufruf logsurfer -c /pfad/meineregeln.conf /var/log/auth.log. Damit Logsurfer nach dem Prüfen der letzten Zeile nicht beendet wird, sondern auf weitere Logeinträge wartet, ist die Option -f zu verwenden. Schließen Sie den Befehlsaufruf mit einem & ab, um Logsurfer als Hintergrundprozess zu starten: logsurfer -f -c /pfad/meineregeln.conf /var/log/auth.log &. Damit Logsurfer bereits überprüfte Zeilen nicht nochmals durchläuft, können Sie über -l eine Startzeile angeben, ab der das Programm mit seiner Arbeit beginnt. Siehe auch man logsurfer. Der Exec-Programmaufruf Alternativ zu pipe steht Ihnen exec als Aktion zur Verfügung. Mit exec ist es möglich, ein beliebiges Programm auszuführen und diesem die Logzeile über $0 zu übergeben.
'failure.* -> .*' '(uid=1000)' - - 0 exec "/home/logsurfer/exec.sh \"SU Missbrauch\" \"$0\"" Dies stellt dem aufgerufenen Shell-Skript die Missbrauchsbeschreibung über $1 und die entdeckte Logzeile über $2 zur Verfügung. In diesem Zusammenhang ist interessant, dass Logsurfer selbst keine beliebigen Befehle veranlassen oder ausführen kann.
'failure.* -> .*' '(uid=1000)' - - 0 exec "/usr/bin/touch /testdatei" führt schlicht zur Fehlermeldung:
unknown action in rule: failure.* -> .*' - - - 0 exec "/bin/touch /testdatei" config error arround line 3: failure.* -> .*' - - - 0 exec "/bin/touch /testdatei" Pipe kann neben dem Semikolon oder den Ausgabe-Umleitungen nicht verwendet werden. Dies ist keine merkwürdige Schikane von Seiten des LogsurfEntwicklers, sondern eine zwingend erforderliche Sicherheitsfunktion. Stellen Sie sich nur vor, was passieren würde, wenn ein Angreifer eine Logzeile mit Zusatzbefehlen erweitern würde, die bei korrekter Formulierung durch Logsurfer ausgeführt würden. Eine manipulierte Zeile wie (...) -> root for su service \\"; rm –rf /* könnte Ihr Server-System ohne weiteres vollständig
410
Server absichern
1 2 zerstören – wenn Sie Logsurfer mit Root-Rechten starten. Trotz der Sicherheitsfunktionen von Logsurfer sollten Sie das Programm selbstverständlich nicht als Root oder mit Root-Rechten starten.
3 4
Die Kontextfunktionen Eine herausragende Stärke von Logsurfer liegt in seinen Kontextfunktionen. Dies ermöglicht es Ihnen, nicht nur Regeln im Zusammenhang zu bewerten, sondern ebenfalls die Übermittlung aller relevanten Logeinträge anstatt lediglich einer einzigen Zeile.
5
Allerdings sind die Kontextfunktionen nicht gerade einfach erlernbar und setzen fundierte egrep-Kenntnisse voraus. Um Kontexte zu nutzen, sind die folgenden Aktionen von Belang:
7
왘
open: Leitet einen Kontext ein
왘
ignore: Ignoriert Logzeilen innerhalb eines Kontextes
왘
report: Sendet die gesammelten Kontextzeilen
왘
delete: Löscht und beendet einen Kontext
6
8 9 10 11
Zur Definition der einzelnen Kontextregeln sind spezielle Optionen zu beachten. Lediglich die Match-Regex-Angaben sind gleich geblieben:
12
1. Match Regex (sucht nach Logzeilen, die das angegebene Muster enthalten) 2. Not Match Regex (wenn in der gefundenen Logzeile das zweite Suchmuster gefunden wird, ignoriert Logsurfer den Logeintrag)
13
3. Line_limit (beschränkt die maximale Anzahl an zwischengespeicherten Logeinträgen. Da Logsurfer die Daten im Arbeitsspeicher ablegt, ist eine Limitierung unbedingt erforderlich. Obwohl man logsurfer.conf eine Limitierung auf 4 000 Zeichen empfiehlt, rate ich Ihnen, maximal 500 Zeichen zwischenzuspeichern. Falls tatsächlich ein längerer Kontext entstehen sollte, gilt es ohnehin, den Server näher zu überprüfen)
14
4. Timeout_abs (Zeitlimit in Sekunden, nach dessen Überschreitung der Kontext und die Default-Regel ausgeführt wird) 5. Timeout_rel (Anzahl der Sekunden, die bis zum nächsten kontextrelevanten Logeintrag vergehen dürfen. Bei Überschreitung wird die Default-Regel ausgeführt.) 6. Default Action (legt fest, ob bei zutreffender Match-Regex-Regel ein Kontext geöffnet oder gleich eine Programmaktion aufgerufen wird) An einem einfachen Beispiel möchte ich Ihnen den Umgang mit einem Kontext anhand einer SMTP-Verbindung demonstrieren:
Logfile-Analyse
411
(...) postfix/smtpd[19252]: connect from xxxx (...) (...) postfix/smtpd[19252]: (...): client=xxxx (...) (...) postfix/smtpd[19252]: reject: RCPT from xxxx: 554 <[email protected]>: Recipient address rejected: Relay access denied; from=
'smtpd\[([0–9]*)\]: connect from' - - - 0 open "smtpd\\[$2\\]:" - 500 1800 300 ignore Die Prozessnummer steht in $2. Die einleitende Kontextregel sorgt gleichzeitig dafür, dass nicht mehr als 500 Logzeilen in höchstens 30 Minuten bei maximal fünf Minuten »Sendepause« entstehen. Die danach folgende Zeile enthält als Filter die Prozessnummer. Obwohl als Default-Regel hier ignore verwendet wurde, bedeutet dies nicht, dass die Daten ignoriert werden. Lediglich wenn der Zeitrahmen überschritten wird, werden die gespeicherten Logzeilen gelöscht. Die eigentlich interessante Kontextregel ist die Suche nach der Zeile »Relay access denied«:
'smtpd\[([0–9]*)\]: .* Relay access denied' - - - 0 report "/usr/bin/mailx -s \"smtpd Relay\" root" "smtpd\\[$2\\]:" Wird eine Zeile, die den Text »Relay access denied« enthält, im untersuchten Logfile gefunden, sendet Logsurfer nicht nur die betreffende Zeile, sondern auch das gesamte Verbindungsprotokoll. Dies wird durch das Auslesen des Filters der einleitenden Kontextregel smtpd\\[$2\\]: bewirkt. Falls es einem Angreifer gelingen sollte, den Zeitrahmen zu sprengen, würden wegen der Default-Regel ignore sämtliche zwischengespeicherten Logzeilen gelöscht und es würde keine Warnung versandt. Werfen wir noch einmal einen Blick auf das Maillog. Disconnect from xxxx schreibt Postfix in sein Log, wenn eine Verbindung beendet wird. Die Lösung heißt deshalb:
'smtpd\[([0–9]*)\]: connect from' - - - 0 open "smtpd\\[$2\\]:" - 500 1800 300 report
412
Server absichern
1 2 "/usr/bin/mailx -s \"smtpd alert\" root" "smtpd\\[$2\\]:" 'smtpd\[([0–9]*)\]: .* Relay access denied' - - - 0 report "/usr/bin/mailx -s \"smtpd relay\" root" "smtpd\\[$2\\]:" 'smtpd\[([0–9]*)\]: disconnect from' - - - 0 delete "smtpd\\[$2\\]:"
3 4 5
Der Trick liegt in der Aktion delete. Wird eine Verbindung beendet, werden zwischengespeicherte Logzeilen, die neben der Prozessnummer ($2) ebenfalls den Text smtpd enthalten, gelöscht. Liegt ein versuchter Relay-Missbrauch vor, dann greift die zweite Report-Aktion, und Warnungen mit dem Betreff smtpd relay werden versandt, noch bevor es zu disconnect (und damit dem Löschen der Logzeilen aus dem Speicher) kommen kann.
6 7 8
Geht die Dauer der Verbindung über Timeout hinaus, greift Report als DefaultRegel, und die bisher gesicherten Logzeilen dieses Kontexts werden mit dem Betreff smtpd alert übermittelt.
9
An dieser Stelle wird ebenfalls die ignore-Aktion interessant: Unwichtige Logzeilen werden durch eine entsprechende Kontextregel nicht zwischengespeichert und halten so die übermittelten Logzeilen übersichtlicher.
10 11
5.13.2 Analyseberichte mit Logcheck erstellen
12
Logcheck ist im Vergleich zu Logsurfer angenehm einfach zu konfigurieren und enthält bereits recht gute Filterregeln für alle gängigen UNIX-Systeme. Die Filterbegriffe werden über ein Shell-Skript, das per Cron-Job aufgerufen wird, in wichtigen Logfiles gesucht.
13 14
Logcheck greift auf das Programm logtail zurück, um nicht bei jeder Überprüfung das gesamte Logfile, sondern lediglich den neu hinzugekommen Abschnitt untersuchen zu müssen. Installation Für Debian und OpenBSD sind entsprechend vorbereitete Pakete vorhanden, die aufgrund optimierter Regeln unbedingt verwendet werden sollten. Während der Installation von Logcheck stellt Ihnen Debian diverse MultipleChoice-Fragen. Wählen Sie als Security-Level den Eintrag Server und nutzen Sie Yes bei Configuring Logcheck, um die relevanten Logdateien aus der syslog.conf zu ermitteln. In der SUSE-Distribution wurde Logcheck nicht nur angepasst, sondern auch umbenannt. Hier trägt das Paket den Namen logdigest.
Logfile-Analyse
413
Eventuell firmiert das Logcheck-Paket Ihrer Distribution auch unter dem Namen Logsentry. Notfalls können Sie Logcheck unter dem Namen Logsentry von der Adresse http://www.psionic.com/products/logsentry.html beziehen. Die Software steht unter der GPL, die Registrierung kann optional übersprungen werden (Textlinks beachten). Über das Originalpaket werden die Quellen zu Logcheck und die Binärdateien zu logtail nebst den Filterregeln entpackt. Wechseln Sie in das neue LogcheckVerzeichnis und rufen Sie make linux auf, um das Paket mit Filterregeln für Linux-Systeme vorzubereiten. make install schließt den Prozess wie gewohnt ab. Einrichten des Originalpaketes unter OpenBSD Im Verzeichnis /etc/logcheck finden Sie die Filterbegriffe in drei Bewertungsgruppen unterteilt. Logcheck.hacking enthält Filter, die auf ein gehacktes System hinweisen können. Allerdings gehören auch Login-Failure-Meldungen zu dieser Gruppe. Die Gruppe logcheck.violations listet mögliche Sicherheitsverstöße auf. Falls gefundene Logzeilen auf den Filter der Datei logcheck.violations.ignore passen, werden diese Meldungen nicht als Verstoß gewertet und ignoriert. Jede weitere Logzeile, die auf keinen der Filter von logcheck.ignore passt, wird als ungewöhnliche Systemaktivität gemeldet. Active-System-Attack-Alerts-Meldungen, die auf Ihrem System harmlos sind, können durch Entfernen der entsprechenden Filterzeile in logcheck.hacking deaktiviert werden. So sollten Sie bei Security-Violations-Hinweisen ebenfalls vorgehen. Falls Logzeilen zu »Unusual System Events« auf Ihrem Server nicht ungewöhnlich sind, müssen Sie einen entsprechenden Suchfilter in logcheck.ignore aufnehmen, um diese Logmeldungen zukünftig zu ignorieren. Das Shell-Skript logcheck.sh finden Sie ebenfalls im Verzeichnis der Konfigurationsdateien. In der Voreinstellung werden die E-Mails bereits an den RootAccount versandt. Sie können ein anderes Postfach durch Änderung der Zeile SYSADMIN=root in logcheck.sh angeben. Einrichten des SUSE-Digest-Paketes Im Verzeichnis /etc/digest findet sich die Datei alarming, in der Filter für ernst zu nehmende Logmeldungen enthalten sind. Sämtliche weitere Logzeilen, auf
414
Server absichern
1 2 die kein Filter der ignore-Datei passt, werden als »All lines that are not in the »ignore« list« ausgegeben.
3
Um Alarmmeldungen zu deaktivieren, müssen Sie den Filter aus der Datei alarming entfernen. Falls die Meldung nun unter »All lines that are not in the »ignore« list« ausgegeben wird, gilt es, den Filterbegriff, der aus alarming gestrichen wurde, in ignore einzutragen.
4 5
Zu guter Letzt sollten Sie einen Blick auf die Datei logdigest.conf werfen. Hier können Sie über SYSADMIN anstelle von Root eine andere E-Mail-Adresse für den Logreport definieren und die zu durchsuchenden Logfiles in der Variablen LOGFILES festlegen. Die einzelnen Logverzeichnisse sind durch eine Leertaste zu trennen.
6 7 8
Einrichten des Debian-Logcheck-Paketes
9
Im Verzeichnis /etc/logcheck finden Sie das File logcheck.cracking, in dem Filter für ernst zu nehmende Attacken enthalten sind. Falls Sie mit Falschmeldungen im Abschnitt »Active System Attack Alerts« zu kämpfen haben, können Sie die entsprechende Zeile aus logcheck.cracking löschen.
10 11
Mögliche Sicherheitsverstöße werden als Possible Security Violations aufgelistet. Lediglich Logeinträge, zu denen ein Filter in der Datei logcheck.violations enthalten ist und auf die keines der Suchmuster von logcheck.violations.ignore passt, werden als Verstöße bewertet.
12 13
Sämtliche übrigen Meldungen, auf die kein Filter der generellen logcheck.ignore-Datei oder einer der spezifischen Programmfilter im Ordner logcheck.d passt, werden als ungewöhnliche Systemaktion Unusual System Events bewertet.
14
Um Falschmeldungen zu deaktivieren, müssen Sie einen entsprechenden Filter in logcheck.ignore hinzufügen. Eventuell finden Sie den verantwortlichen Suchbegriff auch in der jeweiligen Programmdatei im Verzeichnis logcheck.d. Der bei der Installation des Programmpaketes gewählte Loglevel wird über die beiden Softlinks logcheck.d und logcheck.ignore erledigt. Sie können somit recht einfach zwischen den Security-Leveln Server und Paranoid oder Workstation wechseln, indem Sie die Softlinks löschen und beispielsweise über »ln -s log-
check.ignore.paranoid logcheck.ignore; ln -s ignore.d.paranoid ignore.d« Paranoid als Level für ungewöhnliche Systemaktivitäten wählen. Das eigentliche Shell-Skript finden Sie im Verzeichnis /usr/sbin als logcheck. Die E-Mail-Adresse, an die Logcheck gefundene Logzeilen sendet, ist in log-
Logfile-Analyse
415
check.conf editierbar. Die Liste der zu untersuchenden Logfiles kann in logcheck.logfiles bearbeitet werden. Automatisierter Aufruf Um Logcheck zu aktivieren, genügt ein simpler Cron-Job, der das Shell-Skript regelmäßig ausführt. Wenn Sie Logsurf nutzen, um elementare Logzeilen sofort zu übermitteln, genügt es durchaus, Logcheck einmal täglich aufzurufen. Falls Sie lediglich Logcheck zur automatisierten Überwachung der Logdateien nutzen, sollten Sie einen zehnminütigen Rhythmus verwenden und die Nachrichten an ein »externes« Postfach (nicht an den Webserver selbst) übermitteln. Hinweis zu Debian Mit der Installation des .deb-Paketes wird ein stündlich ausgeführter Cron-Job im Verzeichnis /etc/cron.d/logcheck festgelegt. Passen Sie den vorhandenen Eintrag gegebenenfalls an Ihre Wünsche an.
Hinweis zu SUSE Das Shell-Skript logdigest finden Sie im Verzeichnis /etc/cron.daily. Logdigest wird somit bereits täglich ausgeführt. Um es häufiger aufzurufen, können Sie das Skript an einen beliebigen Ort verschieben und über einen Crontab-Eintrag, so oft wie gewünscht, automatisiert aufrufen.
5.14 Sicherheitsinformationen beziehen Nur wer über neu entdeckte Sicherheitslücken gut informiert ist, hat die Möglichkeit, einen Dienst abzusichern (oder notfalls zu deaktivieren), bevor die ersten Script Kiddies automatisiert mit Exploits nach Opfern suchen. Neben der Security-Announce-Mailingliste zu Ihrem System sollten Sie zusätzlich die in Tabelle 5.5 aufgeführten Sites regelmäßig besuchen oder die dort verfügbaren Newsletter abonnieren. Name, Bemerkung
URL
Insecurity (Bugtraq Mailinglistenarchiv)
http://lists.insecure.org
Cert
http://www.cert.org/advisories/
Nessus, Plugin-Verzeichnis
http://cgi.nessus.org/plugins/
Security Focus
http://online.securityfocus.com
Tabelle 5.5 Liste der wichtigsten Security-Sites im Web, mit denen Sie zusammen mit der Security-Announce-Mailingliste Ihrer Distribution auf dem Laufenden bleiben.
416
Server absichern
1 2 Name, Bemerkung
URL
Security Tracker
http://www.securitytracker.com
Snort
http://www.snort.org
Pro-Linux: Sicherheitsservice
http://www.pl-forum.de/security/
3 4 5
Tabelle 5.5 Liste der wichtigsten Security-Sites im Web, mit denen Sie zusammen mit der Security-Announce-Mailingliste Ihrer Distribution auf dem Laufenden bleiben. (Forts.)
6
5.15
Verhalten beim Super-GAU 7
Grundsätzlich gilt es, einen kühlen Kopf zu bewahren und ein vollständiges Backup (des geknackten Servers) anzufertigen. So können Sie später in aller Ruhe (auf einem read-only gemounteten Datenträger) Ursachenforschung und Beweissicherung betreiben. Insbesondere wenn der Einbrecher auf die beliebten, protzigen Erfolgsmeldungen durch Verunstalten Ihrer Startseite(n) verzichtet hat, gilt größte Vorsicht. In solchen Fällen wurde Ihr Rechner wahrscheinlich bereits für Attacken auf weitere Rechner, zum Versenden von Spam oder anderen unschönen Dingen missbraucht.
8 9 10 11
Cracker, die mit dem erfolgreichen »Hack einer Website« um Aufmerksamkeit buhlen, wollen neben der persönlichen Egostärkung manchmal lediglich auf ein Sicherheitsloch hinweisen. Für einen Black Hat wäre es in der Tat kontraproduktiv, mit einem erfolgreichen Hack zu protzen, wenn der Rechner für weitere fragwürdige Aktionen genutzt wurde oder werden soll.
12 13
Zunächst ist der Rechner vom Netz zu trennen und über ein Rettungssystem zu starten. Besonders paranoide Administratoren rufen weder halt noch shutdown -h now auf, sondern ziehen den Stecker des Servers, um etwaige Shutdown- oder andere Aktionsskripte der Black Hats auszubremsen. Bedenken Sie jedoch, dass durch eine plötzliche Stromunterbrechung im ungünstigsten Fall das Filesystem des Servers und damit auch die verräterischen Angriffsdaten beschädigt werden können.
14
Nach dem Start des Rettungssystems ist ein vollständiges Backup des kompromittierten Systems anzufertigen. Hierzu greifen Sie am besten zu dd, um die gesamte Festplatte Block für Block zu kopieren und so eventuell gelöschte Daten, die Spuren auf den Angriff enthalten, wieder herstellen zu können. Ein so erstelltes Image kann mit dem Sleuth Kit und Autopsy (http://www.sleuthkit.org) sowie TCT (The Coroners Toolkit: http://www.porcupine.org/forensics/tct.html) einer forensischen Analyse unterzogen werden.
Verhalten beim Super-GAU
417
Falls die Erstellung eines kompletten Images mit dd zu aufwändig ist, werden diese Tools nur bedingt nützlich sein und sind höchstens für Anwender, die keine Integritätsdatenbank mit AIDE gepflegt haben, einen Versuch wert. Deutlich geringere Erfolgschancen ergeben sich durch erneute Duplizierung Ihres Test-Servers und Aktualisierung mit rsync auf den Stand des gehackten Rechners. Zudem ist diese Methode nur dann verlässlich, wenn der Angreifer sshd oder andere relevante Pakete nicht bereits durch eine eigene Version ersetzt hat. Danach sollte der gehackte Rechner für den Überbrückungsbetrieb neu aufgesetzt und lediglich mit den allernotwendigsten Diensten (wie dem Webserver zur Anzeige der Homepages) online gestellt werden. Verzichten Sie auf sämtliche Shell- oder FTP-Zugänge und ändern Sie Ihre eigenen Zugangspasswörter, noch bevor Sie die »Nutzdaten« übertragen. Installieren Sie auf dem kompromittierten Server AIDE neu und starten Sie »Advanced Intrusion Detection Environment« mit Ihrer (hoffentlich als Backup vorhandenen) AIDE-Datenbank. Noch besser ist es natürlich, wenn zuvor über ein Rettungssystem bereits eine AIDE-Datenbank angelegt wurde – dann können Sie über das Rettungssystem das kompromittierte System zuverlässig auf Änderungen überprüfen (siehe Abschnitt 5.10, Integritätsprüfung mit AIDE). Weiterhin empfiehlt es sich, mit chkrootkit nach Rootkits zu suchen. Sie finden die neueste Version das Programms unter http://www.chkrootkit.org. Eine Installation ist nicht notwendig: direkt nach dem Entpacken des Archivs kann ./chkrootkit aufgerufen werden. Möchten Sie das befallene System über ein Rettungssystem prüfen, können Sie auf die Option -r /mountpoint zurückgreifen. Nun gilt es, die Logdateien zu durchforsten (insbesondere die vor dem Einbruch per Backup lokal gesicherten). Vergleichen Sie diese Logfiles mit denen des kompromittierten Systems. Der Befehl diff /backup/logfile1 /mnt/server/var/log/logfile1 spürt Abweichungen zuverlässig auf. Hat der Angreifer versucht, seine Spuren zu verwischen, nachdem Sie ein Backup mit den Originaleinträgen archivieren konnten, so haben Sie einen Hinweis auf den Verursacher gefunden. Sind keine Systemdateien verändert worden, ist in den Logfiles nichts Ungewöhnliches zu finden und wurde kein Sicherheitsloch übersehen (prüfen Sie dies nochmals mit Nessus und den Sites mit Security-Meldungen – siehe Abschnitt 5.14, Sicherheitsinformationen beziehen), dann gilt es, den betroffenen Bereich abzustecken. Falls lediglich eine Web-Präsenz verändert wurde, dann
418
Server absichern
1 2 könnte in dort verwendeten PHP-, Perl-, Java- oder Python-Programmen eine Sicherheitslücke enthalten sein, die das Ändern der Website gestattet hat.
3
Vielleicht ist es sogar noch banaler, und ein ehemaliger Mitarbeiter der Firma XY hat das FTP-Passwort verraten oder selbst missbraucht. Eventuell ist dem Angreifer das Hijacking einer bestehenden FTP-Verbindung gelungen. Wenn Sie auf Einmalpasswörter verzichten, könnte das Passwort abgehört oder durch eine Brute-Force-Attacke ermittelt worden sein. Letzteres sollten Sie über entsprechende Logeinträge jedoch längst bemerkt haben.
4 5 6 7
5.15.1 Rechtliche Maßnahmen? Konnten Sie Beweise über die Identität des Angreifers in den Logdateien oder durch ähnliche Spuren sichern, steht es Ihnen frei, einen Anwalt zu konsultieren. Die Identität des Angreifers werden Sie in den meisten Fällen nicht selbst überprüfen können. Zunächst bietet sich dig -x IP-Adresse neben einer whois-Abfrage nach der IP-Adresse an. So finden Sie zumindest heraus, wer für diese Adresse zuständig ist beziehungsweise den jeweiligen IP-Adressraum verwaltet.
8 9 10 11
Bedenken Sie jedoch, dass IP-Adressen ebenfalls gefälscht werden können oder der Rechner, der sich hinter der Adresse befindet, vielleicht nur zum Angriff eines Dritten missbraucht wurde. Eventuell hat der Administrator von der Kompromittierung seines Rechners noch gar nichts erfahren.
12 13 14
Verhalten beim Super-GAU
419
1 2
6 Linux-Vserver
3 4
6.1
Sinn und Zweck........................................................ 423
6.2
Installation ............................................................... 425
6.3
Einrichten einer virtuellen Vserver-Umgebung......... 425
6.4
Programme für parallelen Betrieb vorbereiten ......... 428
7
6.5
Betrieb von Vserver-Umgebungen ........................... 429
8
6.6
/proc gegen Missbrauch absichern........................... 433
5 6
1
Einführung
2
Erste Schritte
3
Wichtige Serverdienste
4
Verwaltung und Administration
5
Server absichern
6
Linux-Vserver
7
Der eigene Server
8
Bürokratisches
1 2
6
Linux-Vserver
3
Linux-Vserver zählt zu den interessantesten Projekten für Webserver unter Linux und eröffnet faszinierende Möglichkeiten. Den Entwicklern gebührt große Anerkennung!
4 5
6.1
Sinn und Zweck
6
Unter http://linux-vserver.org verbirgt sich das Projekt Linux-Vserver (ehemals bekannt als Vserver – Virtual private servers and security contexts), das mit der als Vserver vermarkteten virtuellen Server-Umgebung von Server4free jedoch nicht zu verwechseln ist. Auch wenn die Technik eine andere ist, wird von der Software das gleiche Ziel verfolgt: Die Bereitstellung einer unabhängigen und eigenständigen Root-Umgebung innerhalb eines Linux-Systems.
7 8 9
Verwechseln Sie ein Vserver-System nicht mit einer Rechner-Emulation, wie dies beispielsweise im VMware-Produkt geschieht. Ein Vserver benötigt im Gegensatz zu UML (User Mode Linux) noch nicht einmal einen eigenen Kernel und ist daher sehr ressourcenschonend. Lediglich die zusätzlich gestarteten Dienste benötigen selbstverständlich Arbeitsspeicher und CPU-Leistung.
10 11 12
Aus einer Vserver-Umgebung kann – im Gegensatz zu einem Chroot-Käfig – selbst mit Root-Rechten so gut wie nicht ausgebrochen werden. Dank der harten CAP_SET-Standardeinstellungen kann ebenfalls nicht auf Paketfilter-Einstellungen oder Netzwerk- und andere globale Systemfunktionen zugegriffen werden. Dies bedeutet natürlich auch, dass Sie mit Sonderwünschen hinsichtlich der Paketfilter-Regeln einzelner Admins rechnen müssen.
13 14
Vserver ist für das Hosting von anspruchsvollen Kunden, die einen eigenen Apache oder Tomcat-Server in einer virtuellen Root-Umgebung betreiben wollen, perfekt geeignet. Selbst wer seinen Webserver »nur für sich selbst« betreibt, sollte darüber nachdenken, Wackelkandidaten wie den Nameserver Bind nebst Apache, Mail- und FTP-Server in eine Vserver-Umgebung auszulagern. Bei einem erfolgreichen Angriff auf diese Dienste könnte lediglich innerhalb der Vserver-Umgebung Schindluder getrieben werden. Auch wenn aus einem Vserver nicht ausgebrochen werden kann, steht der umgekehrte Weg offen: unmittelbar über das Filesystem kann der Root des Basis-Servers auf die Dateien der Vserver zugreifen und sich in jeden Vserver einloggen. Der direkte Zugriff auf die Daten von Vservern ist besonders für Backups und die unbemerkte und zuverlässige Sicherung von Logfiles ungemein nützlich. Letzteres ist mit
Sinn und Zweck
423
tail –f /vservers/foo/var/log/logfilename \ > /backup/foo/log/logfilename & im Handumdrehen erledigt. Werden bei einem Vergleich der Logfiles (zum Beispiel mit diff) Unterschiede festgestellt, können Sie aufgrund der Originalzeilen schnell herausfinden, welche Informationen der Angreifer vor Ihnen verbergen wollte. Nicht weniger interessant ist es, verschiedene Distributionen als Vserver zu betreiben. Es ist problemlos möglich, auf einem Debian-Basissystem virtuelle SUSE- und oder Fedora-Server-Umgebungen nebeneinander zu betreiben. So verlockend dies auf den ersten Blick auch klingen mag, Sie sollten bedenken, dass der zusätzliche Administrationsaufwand für drei verschiedene Distributionen erheblich größer ist, als wenn Sie die gleichen Distributionen für alle Vserver sowie für das Basis-System verwenden. Sollen mehr als drei virtuelle Server-Umgebungen genutzt werden, kommt neben dem erhöhten RAM-Bedarf und größerer CPU-Belastung die Frage nach genügend freier Festplattenkapazität hinzu. Wer zu einer RPM-basierten Distribution wie SUSE greift, kann zumindest dieses Problem elegant umgehen: Mit vunify steht ein leistungsfähiges Shell-Skript bereit, das Dubletten durch Hardlinks ersetzt und es so ermöglicht, in allen Server-Umgebungen auf dieselben Programmdateien zuzugreifen, ohne die Sicherheit der virtuellen Root-Umgebungen aufzuweichen. Obendrein ist es dank vrpm sogar möglich, SicherheitsUpdates innerhalb aller Server-Umgebungen gleichzeitig einzuspielen. Das vunify- beziehungsweise vrpm-Pendant zur dpkg-Paketverwaltung von Debian befindet sich leider noch in der Entwicklung. Deshalb empfiehlt sich eine Vserver-Installation mit virtuellen Debian-Root-Umgebungen bedauerlicherweise nur für bis zu drei virtuelle Umgebungen. Weiterhin sollten Sie bedenken, dass für jede Vserver-Umgebung eine eigene IP-Adresse benötigt wird. Ein wirklicher Massenbetrieb wird deshalb selbst auf einem entsprechend leistungsstarken Dualprozessorsystem mit über 1 GB AM nicht ohne weiteres möglich sein. Unabhängig davon sind für den Eigenbedarf zwei Vserver-Umgebungen in der Regel ausreichend: 1. Das Basis-System, über dessen IP-Adresse lediglich der SSH-Server von außen erreichbar sein sollte und in dem AIDE, snort, snmp und mrtg das Gesamtsystem überwachen und Backups zentral angefertigt werden. 2. Der erste Vserver bildet die eigentliche virtuelle Server-Umgebung. Die könnte aus dem Block Apache, FTP-Server, MySQL, Postfix und Courier-
424
Linux-Vserver
1 2 IMAP bestehen. Ein SSH-Server ist nicht notwendig, da Sie sich über das Basissystem in Vserver-Umgebungen einklinken können.
3
3. In den zweiten Vserver könnten neben dem Nameserver Bind andere eigenständige Server-Dienste ausgelagert werden, die nicht innerhalb der eigentlichen Webserver-Umgebung (siehe Punkt 2) laufen, aber direkt von außen erreichbar sein müssen.
4 5
Programme, die nicht unbedingt im Basissystem laufen müssen, sollten in die zweite oder eventuell in eine dritte Umgebung ausgelagert werden.
6
6.2
7
Installation
Um Linux-Vserver installieren zu können, müssen Sie einen Kernel patchen. Unter dem Download-Link der Vserver-Projektseite sollten Sie einen KernelPatch für den aktuellen Kernel finden. Auf der CD zum Buch steht Ihnen neben dem Kernel 2.4.29 ein entsprechender Patch (in der Datei: linux-vserver1.2.10.tar.bz2 enthalten) zur Verfügung. Den Patch können Sie wie folgt einspielen:
8 9 10
debian:/usr/src# tar -xjf linux-2.4.29.tar.bz2 debian:/usr/src# tar -xjf linux-vserver-1.2.10.tar.bz2 debian:/usr/src# patch -p0 < patch-2.4.29-vs1.2.10.diff
11 12
Der Befehl patch -p0 < Dateiname zum Einspielen des Patchs wird lediglich dann im Verzeichnis /usr/src funktionieren, wenn der Kernel-Source zu 2.4.29 im selben Verzeichnis entpackt sowie der Vserver-Patch (patch-2.4.29vs1.2.10.diff) in diesem Ordner abgelegt wurde. Nach dem Patchen des Kernels müssen Sie ihn kompilieren. In Abschnitt 2.9.1, Linux, ist die Kompilierung von Kernel 2.4.29 beschrieben.
13 14
Nachdem das System mit dem neuen Kernel erfolgreich gebootet wurde, gilt es, das Archiv util-vserver-0.30.tar.bz2 nach dem Entpacken via make && make install zu installieren.
6.3
Einrichten einer virtuellen Vserver-Umgebung
Mit dem Kommando vserver foo build wird eine neue virtuelle Root-Umgebung anhand des installierten Basissystems im gegebenenfalls neu angelegten /vservers-Verzeichnis erstellt.
Einrichten einer virtuellen Vserver-Umgebung
425
Beachten Sie, dass vom build-Skript neben Diensten des Wirtssystems ebenfalls unerwünschte Nutzdaten übernommen werden! Verwenden Sie zur Erstellung einer Vserver-Umgebung deshalb eine saubere Basisinstallation, in der lediglich die von jedem Vserver benötigten Pakete wie Syslog oder Bash aufgenommen wurden! Dies erspart Ihnen ebenfals die nachträgliche Deinstallation von Diensten. Weiterhin laufen Sie nicht Gefahr, die Löschung sensibler Nutzdaten innerhalb einer Vserver-Umgebung zu übersehen. Lediglich neue Passwörter für User-Accounts wie root wären zu vergeben. Um eine andere Distribution als Vserver-Umgebung verwenden zu können, empfiehlt es sich, eine minimale Installation mit Vserver-Kernel aufzusetzen und die Build-Funktion aufzurufen. Das im Verzeichnis /vservers erzeugte Serverdirectory kann in ein tar.gz-Archiv gepackt und bequem im eigentlichen Vserver-Basissystem zur Installation beliebig oft entpackt und umbenannt werden. Natürlich müssen Sie daran denken, auch die Konfigurationsdatei /etc/vservers/foo.conf zu kopieren und entsprechend anzupassen. Falls Sie die virtuellen Server-Umgebungen in einer anderen Partition ablegen möchten, sollten Sie zuvor das /vservers-Verzeichnis manuell anlegen und mit den Rechten chmod 000 /vservers versehen sowie in /etc/fstab und /etc/mtab eintragen. Alternativ könnten Sie auch einen Softlink (ln –s /pfad/zu/vservers /vservers) setzen. Möchten Sie anstelle von ext2 bzw. ext3 zu ReiserFS greifen, müssen Sie die Partition, in der die Linux-Vserver Systeme abgelegt werden, mit der Option attrs mounten, da sonst der aus Sicherheitsgründen notwendige Befehl chattr +t vom build-Skript nicht auf das Verzeichnis /vservers angewendet werden kann! Ob das Flag korrekt gesetzt wurde, können Sie mit lsattr prüfen:
linux:~ # lsattr -d /vservers --------------t /vservers Ist dieses Flag nicht gesetzt, so kann aus dem Vserver ausgebrochen werden! Falls Sie sich nicht sicher sind, ob Ihr Vserver dem gewachsen ist, sollten Sie den Exploit http://seclists.org/lists/bugtraq/2004/Feb/0183.htm einfach selbst als Root des Vservers ausprobieren! Durch chattr +t wird auch die Löschung des Verzeichnisses /vservers verhindert. Wenn Sie alle Vserver entfernen möchten, müssen Sie chattr -t /vservers ausführen, bevor Sie rm –fr /vservers veranlassen können.
426
Linux-Vserver
1 2 Im nächsten Schritt gilt es, die IP-Adresse des Vservers unserer Netzwerkkarte zu übergeben: ifconfig eth0:1 192.168.0.101 up (siehe Abschnitt 2.6, Netzwerkeinstellungen und Konfiguration) und /etc/vservers/foo.conf anzupassen:
3 4
왘 IPROOT
IP-Adresse der Vserver-Umgebung (in unserem Beispiel 192.168.0.101)
5
왘 S_HOSTNAME
Erlaubt die Definition eines abweichenden Host-Namens für die virtuelle Root-Umgebung. Besonders interessant ist dies für eigenständige Vserver, die von einem »fremden« Admin über den SSH-Daemon des Vservers selbst verwaltet werden. Dadurch kann mit einer passenden Kundenbezeichnung (wie beispielsweise dem Projektnamen) als Host-Name gearbeitet werden.
6 7 8
왘 S_DOMAINNAME
9
Hier sollte der Domain-Name der Vserver-Umgebung eingetragen werden. Die Angabe ist optional. Wenn kein Domain-Name definiert wird, erhält die Vserver-Umgebung die Domain des Basis-Servers.
10
왘 S_NICE
11
Gestattet es, den Nice-Wert für die Vserver-Prozesse zu erhöhen. Sehr effektiv, da selbst der Root des Vservers den Nice-Wert nicht senken kann. Weitere Informationen finden Sie in Abschnitt 4.10, Ressourcen beschränken. Ein Nice-Wert zwischen 5 und 10 ist für eine fremde Vserver-Umgebung durchaus angemessen.
12 13
왘 ULIMIT=”-H -u 1000”
14
In der Voreinstellung sind maximal 1 000 gleichzeitige Vserver-Prozesse erlaubt. Dies ist sehr großzügig, da virtuelle Vserver-Systeme bei einer Minimalinstallation mit aktiviertem SSH-Server und Login des Admins gerade mal neun Prozesse benötigen (Ausgabe um PID, CPU et cetera gekürzt):
[root@myVserver root]# ps -x PID TTY STAT TIME COMMAND 1 ? S 0:04 init [3] 4371 ? S 0:00 syslogd -m 0 4510 ? S 0:00 /usr/sbin/sshd 4536 ? S 0:00 xinetd -stayalive -reuse \ -pidfile /var/run/xinetd.pid 4552 ? S 0:00 crond 4648 ? S 0:00 /usr/sbin/sshd 4650 pts/0 S 0:00 –bash 4694 pts/0 R 0:00 ps -x
Einrichten einer virtuellen Vserver-Umgebung
427
Je nach Einsatzzweck können Sie die Prozessanzahl somit durchaus auf 50 bis 200 herabsetzen. 왘 S_CAPS
Die Maintainer des Vserver-Projekts sind sehr sicherheitsbewusst. Alle Befehle, die sich auch nur im Entferntesten verfremden lassen könnten, sind in der Voreinstellung deaktiviert. So ist noch nicht einmal das Pingen von einer Vserver-Umgebung (unabhängig von den Paketfilterregeln) möglich, da die Erlaubnis zur Nutzung von RAW und Packet-Sockets ebenfalls missbraucht werden könnte (Stichwort Ping Of Death). Falls Sie dies nicht so eng sehen, können Sie über S_CAPS="CAP_NET_RAW" ausgehende Pings erlauben. Antworten auf eingehende Pings sind unabhängig von den CAP_NET_ RAW-Einstellungen generell möglich und müssen gegebenenfalls über einen Paketfilter geblockt werden (siehe Abschnitt 5.3.15, Ping). Weitere Informationen zu einzelnen CAPS und den damit verbundenen Privilegien bietet http://www.lids.org/lids-howto/node34.html. Sie sollten die hier aufgeführten CAPS jedoch erst dann aktivieren, wenn Sie genau wissen, welche Rechte und Möglichkeiten im Einzelfall hierdurch gewährt werden.
6.4
Programme für parallelen Betrieb vorbereiten
Programme, die innerhalb eines Vservers gestartet werden, sind automatisch an die IP-Adresse der virtuellen Server-Umgebung gebunden. Somit kommen sich zwei in voneinander unabhängigen Vserver-Umgebungen installierte Webserver nicht gegenseitig in die Quere. Programme, die im Basis-Server gestartet werden, lauschen jedoch üblicherweise auf Pakete sämtlicher IP-Adressen (0.0.0.0) und verhindern somit, dass in einem Vserver ein weiterer Dienst denselben Port verwenden kann. Dies hat zur Folge, dass der Daemon nicht gestartet werden kann. Eine Liste der vom Basissystem blockierten Ports lässt sich mit netstat abfragen (Ausgabe um die Spalten Foreign Address und State bereinigt):
linbook:~ # netstat -tulpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address tcp 0 0 0.0.0.0:mysql tcp 0 0 0.0.0.0:www-http tcp 0 0 0.0.0.0:https tcp 0 0 0.0.0.0:ssh
428
Linux-Vserver
PID/Program name 420/mysqld 10774/httpd 10774/httpd 283/sshd
1 2 In meinem Beispiel wäre es nicht möglich, in einen Vserver Web-, SSH- oder MySQL-Server zu betreiben, da diese Dienste an keine bestimmte IP-Adresse gebunden sind, sondern auf allen Devices (0.0.0.0) lauschen.
3 4
Leider gestatten nicht alle Daemons, wie der SSH- oder Webserver, die IPAdresse, an die der Dienst gebunden werden soll, via ListenAddress beziehungsweise Listen to festzulegen. Glücklicherweise gibt es das Vserver-Tool chbind, über das Dienste ebenfalls an eine feste IP-Adresse gebunden werden können.
5 6
chbind --ip 192.168.0.80 /etc/init.d/sshd restart
7
würde den SSH-Server auch ohne Anpassung von ListenAddress neu starten und an die IP-Adresse 192.168.0.80 binden.
8
netstat -tnlp | grep sshd tcp 0 0 192.168.0.80:22
9
6.5
510/sshd
10
Betrieb von Vserver-Umgebungen
Der Start einer virtuellen Server-Umgebung sollte denkbar einfach sein, da bereits der Befehl vserver foo start genügt, um unseren virtuellen Vserver foo hochzufahren. Allerdings arbeitet das build-Skript von util-vserver-0.30 unter einigen Distributionen fehlerhaft. Eventuell genügt es bereits die nicht erzeugte .profile als root via
11 12 13
echo PATH=\"'echo $PATH'\" > /vservers/foo/root/.profile
14
nachträglich zu erstellen. In hartnäckigen Fällen werden Sie ein eigenes Skript schreiben müssen, indem alle zu startenden Dienste über vserver foo exec gestartet werden – auf vserver foo können Sie dann auch getrost verzichten:
debian:~# vserver foo start Starting the virtual server foo Server foo is not running ipv4root is now 192.168.0.101 New security context is 49155 debian:~# vserver-stat CTX PROC VSZ RSS userTIME sysTIME UPTIME NAME 0 40 130MB 9kB m06.76 m07.94 34m21.22 root debian:~# vserver foo exec /etc/init.d/ssh start ipv4root is now 192.168.0.101 New security context is 49155 Starting OpenBSD Secure Shell server: sshd.
Betrieb von Vserver-Umgebungen
429
debian:~# vserver-stat CTX PROC VSZ RSS userTIME 0 40 130MB 9kB m06.93 49155 1 2MB 302B m00.00
sysTIME UPTIME NAME m08.00 34m42.68 root m00.00 m06.31 foo
Mit dieser Methode können Sie alle gewünschten Dienste in einem kleinen Shell-Skript zum Start zwingen. Wie bisher erläutert, wird dies natürlich nur möglich sein, wenn der Port unter der entsprechenden IP-Adresse des Vservers noch frei ist, also nicht von einem Dienst des Hauptservers bereits blockiert wird (siehe Abschnitt 6.4), und der zu startende Dienst keine Sonderwünsche an seine Umgebung stellt (siehe Abschnitt 6.5.2, Bind). Sie können vom Hauptserver direkt in eine Vserver-Umgebung wechseln, indem Sie vserver foo enter aufrufen. Auch ein Start der Server-Umgebung ist hierzu nicht einmal notwendig, aber in der Regel empfehlenswert, da Sie sonst alle benötigten Dienste manuell starten müssten. Wenn Sie vom Hauptserver aus in eine Vserver-Umgebung gewechselt haben, gelangen Sie nach einem simplen exit; wieder zurück in den Hauptserver. Sie können einen Vserver mit vserver foo stop beenden.
6.5.1
Feinheiten des Boot-Prozesses
Ein Blick in /var/log/boot.msg wird sicher noch weitere Startlinks und Prozeduren offenbaren, die aus einer Vserver-Umgebung gelöscht werden können oder müssen. Dienste wie klogd können mangels eigenem Kernel auf einem Vserver-System nicht betrieben werden. Auch das Partitionieren der Festplatte oder das Aufsetzen von Paketfilterregeln ist, wie bereits erwähnt, nicht möglich. Somit können Sie Pakete wie iptables, lilo, apmd, net-snmp-utils, mkbootdisk oder pciutils getrost aus der Vserver-Umgebung löschen. Um Änderungen am Startprozess des Vservers zu testen, ist ein Neustart via vserver foo restart notwendig. Zum Beenden unseres Vservers foo dient vserver foo stop. Damit beim Shutdown beziehungsweise Neustart des Basis-Servers die Vserver automatisch beendet und erneut gestartet werden, müssen Sie in den Konfigurationsdateien der zu berücksichtigenden Vserver das Kommentarzeichen der Zeile
#ONBOOT=yes entfernen und /etc/init.d/vservers in den gewünschten Runleveln mit S- und KSoftlinks versehen. Es empfiehlt sich, den Vserver als letzten Daemon zu star-
430
Linux-Vserver
1 2 ten beziehungsweise als ersten zu beenden (S99 / K99; weitere Informationen hierzu finden Sie in Abschnitt 2.8, Startskripte).
3
6.5.2
4
Bind
Eventuell lässt sich die Bind-Version Ihrer Distribution nicht innerhalb eines Vservers betreiben. In diesem Fall sollten Sie sich den Quellcode von http://www.bind.com/bind.html beschaffen und Bind via
5 6
./configure --disable-linux-caps && make && make install installieren.
7
6.5.3
8
Systemneustart innerhalb einer Vserver-Umgebung
Ein shutdown -r now führt in einem Vserver zu der lapidaren Meldung
9
init: timeout opening/writing control channel /dev/initctl
10
Damit Vserver-Admins ihre virtuelle Root-Umgebung neu starten können, müssen Sie für den Neustart des Systems zuvor via rebootmgr foo & einen Reboot-Dienst bereitstellen, der bei Aufruf der Befehle vreboot beziehungsweise vhalt des Vserver-Admins von foo tätig wird.
11 12
6.5.4 Die v-Befehlsversionen
13
Mit Installation von util-vserver-0.30 gelangen erweiterte Versionen der Befehle top, du, ps, pstree und kill in Ihr System. Die ursprünglichen Befehle bleiben voll erhalten. Um die erweiterten Varianten aufzurufen, die ebenfalls die VserverKontexte berücksichtigen, ist dem Befehlsnamen ein v voranzustellen:
debian:~# vps -x PID CONTEXT 1 0 MAIN ... 5345 8 foo2 5411 9 foo 5588 9 foo
TTY ?
STAT S
TIME COMMAND 0:05 init [3]
? ? ?
S S S
0:00 minilogd 0:00 syslogd -m 0 0:00 crond
14
In der Ausgabe ps –x sind lediglich Prozesse des Basis-Servers aufgeführt. Dies trifft auch bei top zu. Ausschließlich vtop führt ebenfalls Prozesse der Vserver auf. Gleichzeitig bedeutet dies, dass mit kill keine Vserver-Prozesse beendet werden können. Hierzu wird vkill benötigt. Nur vkill 5345 ist in der Lage, vom Hauptserver aus den Prozess 5245 des Vservers foo2 zu beenden.
Betrieb von Vserver-Umgebungen
431
6.5.5
Platz sparen mit vunify
Vunify gestattet es, die RPM-Pakete gleichartiger Distributionen durch Hardlinks auf die Dateien eines einzelnen Vservers zu beschränken. Falls Sie mehrere virtuelle Vserver anbieten möchten, ist es daher empfehlenswert, ein SUSE-System für sämtliche virtuelle Server-Umgebungen zu nutzen. Das Basissystem selbst braucht keine RPM-basierte Distribution zu sein. Gilt es, einen neuen Vserver einzurichten, ist das vorbereitete Vserver-System mitsamt Konfigurationsdatei zu duplizieren und entsprechend anzupassen. Selbst wenn Ihr Wirtssystem ebenfalls RPM basiert ist, könnte es sein, dass dies beim Kompilieren von util-vserver-0.30 nicht richtig erkannt wurde und vunify über das util-vserver-Verzeichnis aufzurufen ist:
./scripts/vunify.sh foo first second -- 'rpm -qa' Je nach Art und Umfang des »Quellservers« foo wird das Prozedere sehr viel Zeit beanspruchen. Wahrscheinlich werden Sie sogar mit Fehlermeldungen wie »ln: cannot remove '/vservers/first//usr/sbin/sshd': Operation not permitted« oder »chattr: No such file or directory while trying to stat /vservers/first//srv/www/icons/mrtg-l.png« konfrontiert. Unbeeindruckt dieser Tatsache wird das Skript erfolgreich ausgeführt werden, was Sie über du -hcs /vservers/* prüfen können:
392M 30M 30M 452M
foo first second total
Allerdings hat diese nahezu unglaubliche Ersparnis den beachtlichen Haken, dass sämtliche durch Hardlinks ersetzte Dateien in den eigentlichen Vservern nicht mehr geändert werden können! Um dies zu verhindern, müssen Sie sich etwas Arbeit machen und die Ausgabe von rpm -qa in eine Textdatei speichern, aus der Sie alle die Pakete entfernen, die vom root der jeweiligen Vserver geändert, gelöscht oder aktualisiert werden können soll. Den Inhalt dieser Datei übergeben sie vunify. Anstelle von 'rpm -qa' wäre also 'cat meine_ paketliste' zu verwenden.
6.5.6 RPM-Pakete gleichzeitig einspielen Das Einspielen von Sicherheits-Updates für RPM-Pakete ist dank vrpm auch in multiplen Vserver-Umgebungen schnell erledigt. Mit
/usr/sbin/vrpm --unify ALL -- -Uvh /security_updates/*.rpm
432
Linux-Vserver
1 2 werden sämtliche Updates des Verzeichnisses /security_updates in allen Vservern eingespielt. Zur Krönung setzt die Option --unify nach der Aktualisierung der einzelnen Systeme Hardlinks, um Dateidubletten zu verhindern und Platz zu sparen.
6.6
3 4
/proc gegen Missbrauch absichern
5
Soweit nicht über fehlende CAPS verboten, können Vserver lesend und gar auch schreibend auf das von Haupt- und Vservern gemeinsam genutzte procfs zugreifen! Das procfs stellt damit eine echte Angriffsfläche innerhalb einer Vserver-Umgebung dar.
6 7
Deshalb sollten Sie den auf der CD zum Buch enthaltenen und über http://www.13thfloor.at/vserver/s_release/v1.2.10/ beziehbaren Tarball vproc-0.01.tar.bz2 entpacken und mit einem simplen make kompilieren.
8 9
Nun können Sie mit ./vproc –d 'find /proc' so gut wie alle /proc Einträge für Vserver sperren. Fehlermeldungen dürfen ignoriert werden: vproc -d kann nicht auf alle Elemente angewendet werden.
10
Wer sich gut mit proc auskennt, hat die Möglichkeit, alle problematischen Einträge, zu denen unter anderem die Kernel- und Hardware-Schnittstellen zählen, via
11 12
./vproc -d /proc/path/element
13
gezielt zu deaktivieren. Falls Sie Einträge aus /proc für Vserver-Umgebungen nachträglich freischalten wollen, ist /vproc -e /proc/path/element aufzurufen. Beachten Sie, dass diese Befehle nach jedem Neustart oder dem Hinzufügen eines neuen Vserver-Systems auszuführen sind.
/proc gegen Missbrauch absichern
14
433
1 2
7 Der eigene Server
3 4
7.1
Die richtige Hardware .............................................. 437
7.2
Wahl des richtigen Vertragspartners ........................ 439
7.3
Vorgehensweise nach Bereitstellung eines Servers .. 443
5 6 7 8
1
Einführung
2
Erste Schritte
3
Wichtige Serverdienste
4
Verwaltung und Administration
5
Server absichern
6
Linux-Vserver
7
Der eigene Server
8
Bürokratisches
1 2
7
Der eigene Server
3
»Dedizieren« heißt »jemandem widmen« und wird speziell im EDVBereich in der Bedeutung »ausschließlich für eine bestimmte Aufgabe bestimmen« gebraucht: »ein dedizierter Datenbank-Server«. »Dezidiert« hingegen heißt »entschieden, bestimmt, energisch: einen Standpunkt dezidiert vertreten« (aus http://faql.de/desdfaql.txt).
4 5 6 7
Die Grundlagen zum Betrieb eines eigenen Servers wurden in den vorangegangen Kapiteln behandelt. Hier finden Sie nun alle Informationen, die bei der Wahl des richtigen Rechenzentrums und der Frage, ob der eigene Server gekauft oder lediglich gemietet werden soll, weiterhelfen.
8 9
Vorab weise ich darauf hin, dass es nicht sinnvoll ist, einen Server zu mieten und diesen über eine Standleitung selbst ans Internet anzubinden. Obwohl der Betrieb eines Servers »von zu Hause aus« sehr verlockend ist, steht sicherlich kein breitbandiger Backbone für den Anschluss zur Verfügung. Bereits »kleinere Standleitungen« mit einem Up- und Downstream von 1 bis 2 Mbit verursachen ein erhebliches Loch im Portemonnaie. Weiterhin gilt es bei dieser Lösung zu bedenken, dass bei Leitungsproblemen oder einem Ausfall des Carriers mangels einer zweiten Anbindung der Server nicht mehr erreichbar ist.
10 11 12 13
Selbst große Webhoster mieten in der Regel lediglich Platz und Traffic in einem Rechenzentrum an und stellen die Server nicht in den firmeneigenen Büroräumen ab. Die Frage ist also nicht, ob Sie einen Stell- oder Rackplatz für Ihren Server in einem Rechenzentrum mieten, sondern eher, mit welchem Sie den Mietvertrag schließen.
7.1
14
Die richtige Hardware
Eine wichtige Frage ist, ob Sie die Hardware ebenfalls mieten wollen und so die Gewissheit haben, dass der Dienstleister bei einem Defekt direkt selbst vor Ort Reparaturarbeiten vornehmen kann, oder ob Sie sich eigene Hardware anschaffen und die Reparaturarbeiten gegebenenfalls selbst erledigen oder dann den kostenpflichtigen Support des Dienstleisters in Anspruch nehmen. Wer mit den Standard-Servern des Dienstleisters (die häufig um RAM oder ein RAIDFestplattensystem erweiterbar sind) zurechtkommt, sollte daher lieber einen dedizierten Server anstelle von Höheneinheiten mieten.
Die richtige Hardware
437
Neben der Frage nach der Hardware-Sicherheit ist zu klären, ob sich jederzeit vor Ort ein Techniker um Störungen kümmern kann. Pflichtbewusste Dienstleister haben auch nachts Notfallpersonal zur Verfügung, das jederzeit bereit ist, eine defekte Netzwerkkarte auszutauschen und ein entsprechendes Monitoring durchzuführen. Fragen Sie den Dienstleister vor Vertragsabschluss, ob und wie er gegen einen Hardware-Ausfall am Samstag um 3 Uhr morgens gewappnet ist. Selbst preislich bietet die Miete von Höheneinheiten in der Regel keinen wirklichen Vorteil gegenüber Mietlösungen. Einerseits haben Vermieter von dedizierten Servern selbst ein Interesse an zuverlässiger Hardware, andererseits ermöglichen die höheren Stückzahlen Einkaufsrabatte, die aufgrund der starken Konkurrenz zu einem großen Teil an den Kunden weitergegeben werden. Das Mieten eines Servers ist demnach nicht wesentlich teurer als der Kauf von Hardware. Wer einen Montags-Server erwischt, hat in jedem Fall Pech und wird unter dem Strich durch Hardware-Reparaturen wahrscheinlich sogar mehr bezahlen als bei der Miete eines dedizierten Servers. Der Preis eines dedizierten Servers oder eigener Hardware richtet sich natürlich zu einem wesentlichen Teil nach den benötigten Komponenten. Für statische Webseiten und einen voraussichtlichen Traffic von weniger als 10 Gigabyte reichen ältere Celeron- oder Duron-Prozessoren mit lediglich 400 MHZ und 128 MB RAM völlig aus. Wer dagegen aufwendige Servlets unter Tomcat laufen lässt und mit hohem Traffic von mehr als 60 Gigabyte rechnet, der sollte schon einen zeitgemäßen Prozessor mit 2 GHZ sowie mindestens 512 MB RAM einsetzen. Wie viel RAM Ihr Rechner tatsächlich benötigt und ob Sie eventuell einen stärkeren Prozessor einsetzen müssen, offenbart sich jedoch immer erst in der Praxis durch die Überwachung mit snmp und mrtg (siehe Abschnitt 4.5, Systemüberwachung). Ich würde Ihnen empfehlen, einen Server mit 800-MHZ-Prozessor und 256 MB RAM für den Einstieg zu nutzen. Möchten Sie Tomcat einsetzen oder bis zu drei Vserver-Umgebungen aufsetzen, dann sollten Sie doppelt so viel RAM verwenden. Wer lediglich für private Testzwecke oder unkritische Einsätze einen Server mieten möchte, sollte sich die günstigen virtuellen Root-Server-Umgebungen von Surfplanet (gute Anbindung und kompetenter Support) oder Server4Free (der Aldi unter den Vermietern von dedizierten und virtuellen Root-Servern) näher ansehen. In einem virtuellen Root-Server stehen zwar nicht alle Optionen wie beispielsweise der Einsatz eines eigenen Kernels oder das Aufsetzen von Paketfilterregeln bereit, doch können Sie zu einem unschlagbar günstigen Preis Erfahrungen als Administrator eines Webservers sammeln. Für das ambitionierte, aber
438
Der eigene Server
1 2 nicht kommerzielle Homepage-Projekt ist ein virtueller Root-Server geradezu prädestiniert.
3
7.2
4
Wahl des richtigen Vertragspartners
Wer seine Hardware selbst kaufen möchte, ist logischerweise auf die Dienstleister vor Ort angewiesen. Wer jedoch einen dedizierten Server mieten möchte, ist weder auf die nähere Umgebung noch zwingend an deutsche Dienstleister gebunden. Beachten Sie jedoch, dass für deutsche Surfer ein im Inland angebundener Server in der Regel schneller erreichbar ist als ein Server in Übersee. Eine Homepage sollte deshalb grundsätzlich in dem Land gehostet werden, in dem die Mehrheit der anvisierten Zielgruppe zu Hause ist.
5 6 7 8
Viele Dienstleister treten als Reseller für ein Rechenzentrum auf. Dies muss nicht unbedingt ein Nachteil sein, da durch Wiederverkäuferrabatte häufig günstigere Preise für Traffic- und Rack-Einheiten erzielt werden können, als Ihnen bei direkter Vertragsabwicklung mit dem Rechenzentrum eingeräumt würden.
9 10
Der Support durch Techniker vor Ort muss ebenfalls nicht zwangläufig schlechter sein, wenn Sie den Vertrag über einen Reseller des Rechenzentrums und nicht mit dem Betreiber des Rechenzentrums selbst schließen. Insbesondere der Support ist für professionell ausgerichtete Aufgaben ein äußerst wichtiges Argument. Achten Sie darauf, dass die Reaktionszeiten auf keinen Fall über vier Stunden liegen und der Support rund um die Uhr erreichbar ist.
11 12 13
Ein telefonischer Support bietet gegenüber dem E-Mail-Support die Gewissheit, dass am anderen Ende jemand erreicht werden kann und das Problem nun in Angriff genommen wird. Dies ist insbesondere dann beruhigend, wenn Sie selbst als Reseller von Webspace auftreten und so die Möglichkeit erhalten, verzweifelte Kunden direkt über den Grund des Ausfalles informieren zu können. Beispiel: »Es ist lediglich ein Switch defekt; der Server und Ihre Daten sind noch voll intakt. Ein Techniker ist bereits dabei, den Switch zu ersetzen, so dass Ihre Homepage bereits in den nächsten Minuten wieder online sein wird.«
14
Sie sollten sich nicht nur auf eine telefonische Zusicherung des in den höchsten Tönen angepriesenen Supports verlassen, sondern dies einfach einmal selbst (natürlich vor Vertragsunterzeichnung) ausprobieren. Können Sie einen kompetenten Mitarbeiter des Supports auch am Samstag oder Sonntag zwischen 23 und 5 Uhr erreichen? Ein weiteres wichtiges Kriterium ist die Flexibilität des Dienstleisters. Sie sollten die Möglichkeit haben, Traffic-Tarife monatlich flexibel zu wechseln und zudem auch kurzfristig eine RAM-Erweiterung oder eine weitere IP-Adresse zu erhalten.
Wahl des richtigen Vertragspartners
439
Neben Support und Flexibilität sollten Sie ebenfalls großen Wert auf die verfügbare Bandbreite des Dienstleisters legen. Wenn eine bekannte Firma für das Hosting von mehr als zehntausend Präsenzen zuständig ist, aber auf der anderen Seite bei Zusammenschaltung aller Carrier lediglich eine Anbindung von 5 Gbit aufweisen kann, dann wird zur Rushhour keinesfalls die volle Bandbreite Ihrer Netzwerkkarte zur Verfügung stehen. Sie müssen dann anstelle der versprochenen 100 Mbit eher mit 30–40 Mbit rechnen, was sich durchaus in spürbaren Verzögerungen des Antwortverhaltens Ihres Servers bemerkbar machen kann. Als Faustregel sollten Sie darauf achten, dass der Anbieter mit insgesamt 9 Gbit angebunden ist. Für höhere Ausfallsicherheit sorgt die Aufteilung der Bandbreite in mindestens zwei unabhängige Carrier, die wiederum jeweils mit zwei unabhängigen Hausanschlüssen ans Rechenzentrum angebunden sein sollten. Wie ausfallsicher der Dienstleister seine Anbindung selbst einstuft, können Sie aus den AGB entnehmen. Die zugesicherte Verfügbarkeit sollte auf keinen Fall unter 98 Prozent liegen. Sprechen Sie den Dienstleister zudem auf eine unterbrechungsfreie Stromversorgung an und fragen Sie ihn, wie lange das USV bei einem Stromausfall die Server mit Energie beliefern kann. 30 Minuten sollte der absolute Mindestwert sein. In Tabelle 7.1 finden Sie eine Übersicht über mögliche Vertragspartner. Selbstverständlich erfüllen die unter Low-Budget aufgeführten Anbieter meine Empfehlungen nicht, sind aber für Hobbyprojekte oder andere unkommerzielle Sites, die nicht unbedingt mit Top-Performance und höchster Verfügbarkeit gehostet werden sollen, bestens geeignet. Für kommerzielle Angebote sind bereits die Anbieter im Mid-Range-Bereich häufig mehr als ausreichend. Insbesondere Net-Build und Surfplanet punkten mit kompetentem Support und guter Flexibilität. Wer nicht unbedingt auf ein gutes Preis-Leistungs-Verhältnis achten muss, könnte mit Plusserver, dank der zugesicherten Verfügbarkeit von sagenhaften 99,99 Prozent im Monatsmittel, selbst beim Hosten von kritischen Sites wie Online-Shops glücklich werden. Stehen trotz unserer harten Kriterien mehrere Dienstleister in Ihrer Kandidatenliste, mag neben dem Preis zudem die Flexibilität des Supports ein gutes Kriterium sein. Nur wer kompetenten und individuellen Support anbietet, wird bereit sein, nicht nur ein Betriebssystem Ihrer Wahl zu installieren, sondern ein von Ihnen entsprechend vorbereitetes Server-System auf einem frischen Rechner zu installieren und hinsichtlich Netzwerk- und Partitionseinstellungen so anzupassen, dass Ihre Server-Installation gebootet und sofort vollständig einsetzbar ist. So sparen Sie sich ein aufwendiges zweimaliges Voll-Backup des
440
Der eigene Server
1 2 dedizierten Servers (erste Sicherung vor den Anpassungsarbeiten, zweite Sicherung nach Abschluss aller Änderungen und einem erfolgreichen Neustart sowie Testlauf der Server-Programme).
3 4
7.2.1
Checkliste zur Prüfung des Wunschanbieters
5
1. Support rund um die Uhr erreichbar und kurze Reaktionszeiten (maximal vier Stunden vertraglich zugesichert).
6
2. Hohe Flexibilität (eine Änderungen von Hardware-Komponenten muss jederzeit möglich sein; ein Wechsel der Traffic-Tarife zum Monatsersten).
7
3. Die Internetanbindung wurde mit mindestens zwei Carriern und insgesamt 9 Gbit realisiert.
8
4. Eine USV mit mindestens 30 Minuten Notstromversorgung steht bereit. 5. Der Vertragspartner sichert eine Verfügbarkeit von mindestens 98 Prozent zu.
9
6. Voll-Backup sollte in kürzester Zeit vom Dienstleister selbst einspielbar sein und auf Wunsch angefertigt werden (siehe Abschnitt 4.8, Backup).
10
7. In kritischen Umgebungen sollte auf eine serielle Konsole, mit der der Rechner auch remote wie vor Ort administriert werden kann (so werden auch Arbeiten am Bios oder Filesystem-Checks beim Booten noch vor Initialisierung der Netzwerkkarte möglich), nicht verzichtet werden.
11
8. In besonders kritischen Umgebungen sollte der Dienstleister bereit sein, eine CD-ROM mit dem selbst angefertigten Notfallsystem in das Laufwerk zu schieben (siehe Abschnitt 4.14, Das Rettungssystem).
13
Low Budget
Homepage
Anmerkungen
1st Housing
www.1st-housing.de
– Anbindung
12
14
Systeme: SUSE und Debian Hard Reset über Webinterface Server4Free
www.server4free.de
+ günstige Hardware – Support, Anbindung Hard Reset über Webinterface und Notfallsystem System: SUSE
Mid Range
Homepage
Anmerkungen
Tabelle 7.1 Auswahl einiger Anbieter (Stand Januar 2005). Aktuelle Informationen und eine ausführliche Liste sind über http://www.webhostlist.de erhältlich.
Wahl des richtigen Vertragspartners
441
Low Budget
Homepage
Anmerkungen
1&1 AG
www.1und1.de
– Support + Serielle Konsole System: SUSE
Hetzner Online AG www.hetzner.de
+ Hardware – Support Systeme: SUSE und Debian
Surfplanet AG
www.surfplanet.de
+ Support, Flexibilität System: Fedora (eigenes übermittelbar)
Up Range
Homepage
Anmerkungen
Host Europe
www.host-europe.de
+ Traffic + Verfügbarkeit (99,9 %) Systeme: SUSE, Debian und FreeBSD
NeueMedien
www.neuemedien.net + Fexibilität, Support, BGP Failover realisierbar + Serielle Konsole (optional verfügbar) Systeme: SUSE und Debian
Plusserver
www.plusserver.de
+ Verfügbarkeit mtl.: 99,99 Prozent + Serielle Konsole, Hardware Reset Traffic System: auf Wunsch (Standard ist SUSE)
Webhostone
www.webhostone.de
+ Traffic, Anbindung System: Debian
Tabelle 7.1 Auswahl einiger Anbieter (Stand Januar 2005). Aktuelle Informationen und eine ausführliche Liste sind über http://www.webhostlist.de erhältlich. (Forts.)
Da meine kleine Anbieterübersicht keinesfalls den gesamten Markt widerspiegelt, sollten Sie http://www.webhostlist.de besuchen. Unter dem Menü Eigener Server steht eine umfangreiche Anbieterdatenbank für dedizierte Server und die Miete von Höheneinheiten (Colocation genannt) zur Abfrage bereit. Weiterhin stellt sich ein Großteil der Hoster den Geschwindigkeitstests, die über die Anbieterdetails eingesehen werden können. Hier sollte der Dienstleister Ihrer Wahl keine schlechtere Schulnote als eine 2 erhalten haben. Falls Sie sich entschließen sollten, selbst als Reseller von Webspace aufzutreten, können Sie Ihren Server übrigens ebenfalls mit dem Dienst von Webhostlist auf Geschwindigkeit und Verfügbarkeit abklopfen lassen. Neben der Performance und Erreichbarkeit bietet Webhostlist mit den UserMeinungen ein weiteres wichtiges Entscheidungskriterium. Insbesondere bei
442
Der eigene Server
1 2 größeren Anbietern lässt sich anhand der höheren Teilnehmerzahl leicht erkennen, ob die Mehrheit zufrieden ist. Aus den Beiträgen der einzelnen Kritiker können Sie außerdem auf die Art der aufgetretenen Probleme schließen. Fragen nach Konfiguration oder Abstürzen des Apache sollten dem Anbieter – zumindest bei der Miete eines dedizierten Servers oder von Rack-Einheiten – nicht angelastet werden.
7.3
3 4 5
Vorgehensweise nach Bereitstellung eines Servers
6
Ist Ihr Dienstleister bereit, das Server-System anhand eines von Ihnen übermittelten tar-Archivs aufzusetzen und IP-Adresse, Netzwerkkarte und Konfigurationsdateien entsprechend zu korrigieren, dann können Sie Ihr Server-System in Ruhe auf dem lokalen Testserver aufsetzen und alle benötigten Dienste entsprechend konfigurieren und absichern.
7 8 9
Die folgenden Schritte beschreiben die Absicherung eines vorinstallierten Systems und enden mit dem Überspielen und Aufsetzen eines Server-Backups auf dem lokalen Testserver. Selbstverständlich ist dies nicht notwendig, wenn Ihr Dienstleister ein von Ihnen übermitteltes tar-Archiv eingespielt hat, denn dann ist Ihr Testsystem bereits voll einsatzfähig.
10 11 12
In der Praxis sollte es für Sie zum Tagesgeschäft gehören, Updates oder Software-Installationen zunächst auf einem identischen Testsystem vorzunehmen, um so einen denkbaren Super-GAU auf dem eigentlichen Server zu vermeiden. Nur wer vorzunehmende Änderungen auf einem Testsystem durchspielt und überprüft, kann absehen, welche Schritte und Änderungen auf dem Server vorzunehmen sind, um die Software reibungslos zu aktualisieren oder neu zu installieren.
7.3.1
13 14
Absicherung eines vom Dienstleister vorinstallierten Systems
Es mag sich trivial anhören, will aber dennoch bedacht und gesagt sein: Sichern Sie Ihren Server als Erstes ab (Aktivierung einer im Vorfeld getesteten Firewall und Deinstallation unbenötigter Dienste), bevor Sie sich mit der Einrichtung und der Anpassung des Webservers an Ihre eigenen Wünsche beschäftigen. Sollte Ihnen das Root-Passwort per E-Mail übermittelt worden sein, muss dieses sicherheitshalber sofort geändert werden und dem Dienstleister sollte (falls erforderlich) das neue Passwort per Fax übermitteln werden.
Vorgehensweise nach Bereitstellung eines Servers
443
Wenn aus vertraglichen oder Support-Gründen ein Root-Zugang für den Dienstleister gestattet sein muss, sollten Sie den direkten Root-Zugriff lediglich auf den IP-Adressraum des Vermieters beschränken (siehe Abschnitt 3.1.1, Konfiguration) und für den Vertragspartner einen speziellen Root-Account anlegen (geben Sie dem neuen Nutzer-Account die UID 0). Nachdem der Server in den Grundzügen gesichert worden ist, sollten Sie sich eine Pause gönnen und in der Zwischenzeit ein Voll-Backup des Systems auf Ihren lokalen Testserver (siehe Abschnitt 4.8, Backup) übertragen. Am besten entpacken Sie das Voll-Backup in eine leere Partition. Es empfiehlt sich, das bereits installierte Linux- beziehungsweise BSD-System parallel zur gespiegelten Installation des Webservers zu betreiben. Damit das System beim nächsten Start das Server-Backup booten kann, müssen Sie allerdings einige Modifikationen vornehmen. Tipp Notieren Sie sich, welche Dateien geändert wurden, um bei einem späteren Rsync-Abgleich die auf dem Testserver modifizierten Files vor einer »Aktualisierung« schützen zu können. Zunächst gilt es, die /etc/fstab und /etc/mtab anzupassen (siehe Abschnitt 2.3.8, Partitionen richtig mounten (mount, umount)). Danach müssen Sie in den Bootloader, die Partition und den zu nutzenden Kernel des entpackten Server-Backups eintragen (siehe Abschnitt 2.5, Der Bootloader). Wenn Sie neugierig sind, ob das System bootet, können Sie bereits jetzt einen Neustart veranlassen und sich später den letzten Feinheiten widmen. Falls Ihr System nicht hochfahren sollte, gilt es, die Logmeldungen sorgsam zu studieren und Fehlermeldungen der Reihe nach auszumerzen. Da Sie in Ihrem Webserver kaum die gleiche Ethernetkarte betreiben werden wie im Testserver, sind Probleme mit der Netzwerkkarte vorprogrammiert. Häufig werden Sie einen neuen Kernel mit Support für die von Ihnen genutzte Netzwerkkarte kompilieren müssen (siehe Abschnitt 2.9, Der eigene Kernel). Weiterhin müssen Sie /etc/hosts und den in /etc/resolver.conf eingetragenen Nameserver anpassen. Wie die Netzwerkkarte beim Start eingebunden wird, hängt von Ihrem System ab und ist in Abschnitt 2.6, Netzwerkeinstellungen und Konfiguration, im Detail beschrieben.
444
Der eigene Server
1 2
8 Bürokratisches
3 4
8.1
Gesetzliche Regelungen für den Betrieb einer Website ........................................................... 449
5
8.2
Rechtliche Absicherungen gegenüber Kunden ......... 457
6
8.3
Rechtliche Hinweise und Verfahrensfragen zur Registrierung von Domain-Adressen........................ 469
7
8.4
E-Mail-Lauschangriff macht Betreuung von knapp über 1 000 Kunden zu kostspielig! ................ 471
8.5
Spam nur auf ausdrücklichen Wunsch blocken! ....... 471
8.6
Fällt das Datenschutzrecht für den Zwang zur personenbezogenen Vorratsdatenspeicherung? ....... 471
8
1
Einführung
2
Erste Schritte
3
Wichtige Serverdienste
4
Verwaltung und Administration
5
Server absichern
6
Linux-Vserver
7
Der eigene Server
8
Bürokratisches
1 2
8
Bürokratisches
3
Das Post- und Fernmeldegeheimnis von Art. 10 unseres Grundgesetzes gerät zusehends ins Wanken. Populäre Argumente wie der Kampf gegen kinderpornographische Inhalte des Webs lassen Stimmen nach einem Verbot von Anonymität im Internet immer lauter und zahlreicher werden.
4 5 6
Bereits die Nutzung eines Webservers zur Darstellung der eigenen Homepage ist heute an viele gesetzliche Bestimmungen verknüpft, die Sie beachten sollten, wenn Sie nicht unfreiwillig negative Erfahrungen mit unserem Staatsapparat sammeln wollen.
7
Bevor wir uns den verzwickten rechtlichen Details und Verfahrensfragen zuwenden, will ich Sie darauf aufmerksam machen, dass Betreiber eines Webservers in der Regel einige Behörden über ihre Tätigkeit informieren müssen.
9
8
10
1. Wird der Server im größeren Stil an Kunden oder auch nur an einige Bekannte vermietet, ist zu überprüfen, ob die Anmeldung eines Gewerbes erforderlich wird und welche Rechtsform zu wählen ist. Eine Gewerbeanmeldung (bei der Stadtverwaltung) ist immer dann notwendig, wenn die Tätigkeit nachhaltig sowie mit der Absicht einer Gewinnerzielung ausgeführt wird. Dies ist bei einem vermieteten Webserver der Fall. Ein Verlust in der Gründungszeit ist unerheblich.
11 12 13 14
2. Wer Mailaccounts zur Verfügung stellt, betreibt einen so genannten Teledienst, der bei der Regulierungsbehörde für Telekommunikation und Post (kurz RegTP; http://www.regtp.de) anzumelden ist. 3. Spätestens mit der Abgabe der Gewerbeanmeldung wird das Finanzamt auf Sie aufmerksam. Sie müssen sich nun entscheiden, ob Sie für die Umsatzsteuerpflicht optieren1 oder aufgrund hoher Einnahmen (ab einem Jahresumsatz von 16 620 Euro2) ohnehin Umsatzsteuer ausweisen müssen.
1 Häufig ist es für Gründer sinnvoll, freiwillig Umsatzsteuer in Rechnung zu stellen, da durch die hohen Ausgaben der Gründungsphase die gezahlte Umsatzsteuer oft höher als die vereinnahmte ist, und die Differenz vom Finanzamt erstattet wird beziehungsweise ans Finanzamt zu zahlen ist. 2 Die Ausgaben dürfen vom Umsatz nicht abgezogen werden! Wird der Jahresumsatz überstiegen, müssen Sie zum 1.1. des darauf folgenden Jahres (also unmittelbar) Umsatzsteuer ausweisen. Weiterhin darf der Umsatz im laufenden Geschäftsjahr 50 000 Euro jährlich nicht übersteigen, sonst wird das Finanzamt die Umsatzsteuer einfach nachträglich erheben (was zu einer hohen Nachzahlung führen wird)!
Bürokratisches
447
4. Ab einem Jahresgewinn von 24 500 Euro werden Sie neben der Umsatzsteuer zudem mit der Gewerbesteuer und der Buchführungspflicht konfrontiert. Kaufleute sind übrigens generell buchführungspflichtig, wenn sie im Handelsregister eingetragen sind. 5. Weiterhin verlangt die Industrie- und Handelskammer (IHK) ab 5 200 Euro Gewinn einen Pflichtobolus, der als Mitgliedsbeitrag getarnt ist. Diese Gewinngrenze gilt allerdings nur dann, wenn Sie im Handelsregister eingetragen sind (sei es durch freiwillige Eintragung oder weil Sie als Kaufmann dazu verpflichtet sind). Die IHK hat auf den Mitgliedsbeitrag übrigens einen Rechtsanspruch. Sie haben deshalb keine andere Möglichkeit, als dem »Verein« beizutreten. Wer trotz der angeführten Punkte den Mut noch nicht verloren hat, wird sich hoffentlich durch das übrige Rechtschaos und die undurchsichtigen Bestimmungen des Datenschutzes nicht davon abhalten lassen, die eigene Geschäftsidee weiter zu verfolgen. Die folgenden Abschnitte sind als grobe Übersicht und Einführung in die komplexe Materie des Internet-Rechts zu verstehen. Die juristische Auslegung hat sich in der Vergangenheit laufend geändert und wird weiterhin einem Wandel unterliegen. Beachten Sie hierzu Abschnitt 8.6, Fällt das Datenschutzrecht für den Zwang zur personenbezogenen Vorratsdatenspeicherung? Selbst wenn Sie sich über die aktuelle Lage mit den in Tabelle 8.1 aufgeführten Links informieren können, sollten Sie Ihr Wissen lediglich für eine vorbereitende Entwicklung von Impressum, AGB und der eigentlichen Homepage verwenden. An der abschließenden Überprüfung durch einen Anwalt führt kein Weg vorbei. Wer aus Kostengründen darauf verzichtet, geht das Risiko ein, mit ungleich teureren Schadensersatzforderungen, Bußgeldbescheiden und Abmahnungen konfrontiert zu werden. Hinweise zum Datenschutz
Beschreibung
http://www.bfd.bund.de
Bundesbeauftragter für Datenschutz.
http://www.datenschutz.de
Virtuelles Datenschutzbüro (umfangreiche Informationsseite des Landeszentrums für Datenschutz SchleswigHolstein. Enthält Kontaktadressen von Institutionen des Datenschutzes der einzelnen Bundesländer).
http://www.dud.de
DuD – Datenschutz und Datensicherheit, Verlag Vieweg, Wiesbaden.
Tabelle 8.1 Wichtige Links zu rechtlichen Fragen
448
Bürokratisches
1 2 Gesetzestexte und Infos
Beschreibung
http://bundesrecht.juris.de
Hält in einer »Gesamtliste« relevante Gesetzestexte unter anderem zu BDSG, TDG oder TDDSG zum Abruf bereit.
http://www.bmj.de
Bundesministerium der Justiz.
http://www.regtp.de
Regulierungsbehörde Telekommunikation (Menütipp: Gesetze und Verordnungen)
5
http://dip.bundestag.de
DIP – Dokumentations- und Informationssystem für Parlamentarische Vorgänge (Tipp: DIP-Suchmaschine).
6
http://www.jusline.de
Portal für Rechtsinformationen und Rechtsdienstleistungen.
7
http://www.marktplatz-recht.de
Ausführliche Informationen in Juristendeutsch.
Rund um Domain-Fragen
Beschreibung
http://www.dpma.de
Deutsches Patent- und Markenamt (Tipp: Nutzen Sie zumindest die kostenlosen Dienste zur Suche nach Patenten, Markennamen und Gebrauchsmustern vor der Domain-Registrierung).
10
Harmonisierungsamt für den Binnenmarkt (kostenlose Suche nach Gemeinschaftsmarken).
11
http://oami.eu.int/de/ http://www.abmahnwelle.de
Informationen und Hilfe für Abmahnungsopfer.
http://www.domainguard.de
Preisgünstige Namensrecherchen.
3 4
8 9
12
Tabelle 8.1 Wichtige Links zu rechtlichen Fragen (Forts.)
8.1
13
Gesetzliche Regelungen für den Betrieb einer Website
14
Selbst wer lediglich eine private Homepage betreibt, ist vor der Regelungswut unserer Regierung nicht sicher. Das Internet ist schon seit langer Zeit kein rechtsfreier Raum mehr, sondern derzeit eher eine Spielwiese für fragwürdige Abmahnvereine. Man könnte zu der Meinung gelangen, dass Anwälte durch das Web – auch ohne eigene Präsenz im Internet – am deutlichsten profitieren.
8.1.1
Pflichtangaben
Mit der eigenen Website können Sie mitnichten anstellen, was Sie wollen. Das Teledienstgesetz (TDG) kennt eine Fülle von Pflichtangaben, mit denen die eigene Website zu versehen ist. Am härtesten trifft es die Betreiber von Internet-Shops. Aber selbst private Hobbysites können Pflichtangaben unterliegen. Ein gutes Beispiel ist die Impressumspflicht für die sorgsam gepflegte Homepage des begeisterten Musikfans »Karl Mustermann«. Karls CD-Kritiken lassen
Gesetzliche Regelungen für den Betrieb einer Website
449
ihn durch seine Website zu einem »Dienstanbieter von journalistisch-redaktionell gestalteten Angeboten« werden. Als Folge davon muss die Homepage ein Impressum enthalten. Fehlt dieses, droht eine Abmahnung, die teuer werden kann. Hinweis Bereits eine Linkliste kann eine vermeintlich private Homepage zu einem impressumspflichtigen redaktionellen Angebot aufwerten. Selbst Betreiber von Homepages, die lediglich eine schlichte Visitenkarte mit kurzem Text zu Hobbys nebst einem Porträt enthalten, können bereits durch Bannereinblendungen eines Tauschprogramms juristisch zu Unternehmern wegen »Handelns im geschäftlichen Verkehr« werden. Lediglich wenn die Werbeeinblendung nicht durch den Betreiber der Homepage, sondern durch den Hoster erfolgt (dies ist bei werbefinanzierten Webspace-Angeboten der Fall), wird die Privatperson durch den Betrieb einer Homepage nicht zur Einzelfirma. Impressum Ist die Frage nach der Impressumspflicht beantwortet, dann gilt es, den Link als »Impressum« deutlich auf jeder Seite ins Rubrikmenü zu integrieren. Der Link muss zudem auch für diejenigen Besucher ohne Scrollen direkt zu erreichen sein, deren Bildschirm eine Auflösung von lediglich 640 × 480 Pixel hat. Das Impressum selbst muss natürlich ebenfalls die Überschrift »Impressum« tragen und Rechtsform, Name, Anschrift, E-Mail-Adresse, Telefon- sowie Faxnummer des Betreibers der Homepage aufführen. Juristische Personen sind darüber hinaus verpflichtet, alle Mitglieder der Geschäftsführung neben dem Vorstand aufzuführen. Zudem sind Umsatzsteueridentifikations- und Handelsregisternummer anzugeben. Natürlich hat sich der Gesetzgeber etwas einfallen lassen, um die Regelungen zum Impressum möglichst kompliziert zu machen. Erreicht wurde dies durch berufsspezifische Spezialregelungen. Sites mit redaktionellen Inhalten sind verpflichtet, die für den Inhalt verantwortlichen Redakteure aufzuführen. Hierbei ist zudem die Form zu beachten. Ein Satz wie beispielsweise »alle Texte entstammen der Feder von Karl Meyer« ist unzureichend. Es muss gemäß § 6 MDStV heißen: »Für den Inhalt verantwortlich: Karl Meyer«. Ist die Angabe einer inhaltlich verantwortlichen Person erforderlich, sollte zusätzlich die Anschrift der verantwortlichen Person aufgeführt werden. Falls die Anschrift nicht abweicht, genügt auch ein Passus wie »Anschrift oben«.
450
Bürokratisches
1 2 Ein weiteres Beispiel: Handwerksbetriebe müssen im Impressum die zuständige Kammer und die offizielle Berufsbezeichnung nennen sowie aufführen, von wem die Genehmigung zur Ausübung ihres Berufs erteilt wurde. Die Pflichtangaben sind weiterhin mit einem Verweis auf die für Sie bindenden berufsspezifischen Regelungen zu versehen.
3 4 5
Zum Glück steht bei der Erstellung des Impressums und der Beachtung aller Detailfragen der Impressums-Generator von Digi-Info: http://www.digiinfo.de/de/netlaw/webimpressum/index.php hilfreich zur Seite. Wer ganz sicher gehen will, kommt an einem Studium der §§ 6 und 7 des TDG (http://bundesrecht.juris.de/bundesrecht/tdg/) und der Prüfung des vorläufigen Impressums durch einen Anwalt nicht vorbei.
6 7 8
Für redaktionelle Anbieter gilt automatisch das Presserecht
9
Das Presserecht verbietet eine Mischung von redaktionellen Inhalten und Werbung. Banner müssen deshalb in einem vom redaktionellen Bereich getrennten Abschnitt eingeblendet oder über den Hinweis »Anzeige« deutlich als Werbung gekennzeichnet werden.
10 11
Weiterhin besteht ein Recht auf Gegendarstellungen zu Tatsachenbehauptungen. Lediglich bei deutlich gekennzeichneten Meinungsäußerungen (zum Beispiel satirischer Kommentar) hat der Betroffene kein Anrecht auf eine Gegendarstellung. Falls sich die Gegendarstellung auf eine Tatsachenbehauptung bezieht, müssen Sie den Text an gleicher Stelle unverändert veröffentlichen (anstelle der Tatsachenbehauptung) und gegebenenfalls auf der Startseite deutlich verlinken. Weiterhin muss die Gegendarstellung mindestens so lange wie die Tatsachenbehauptung online bleiben. Der Betroffene darf sogar eine Verlängerung von bis zu einem Monat verlangen.
12 13 14
Pflichten für Betreiber von Shop-Systemen Das Bürgerliche Gesetzbuch (siehe §§ 312 b–f BGB) hält für Shop-Betreiber einige besonders unerfreuliche Bestimmungen bereit. So ist der Kunde über das ihm bei Bestellungen über das Internet eingeräumte erweiterte Widerrufs- und Rückgaberecht und die genaue Anschrift des Vertragspartners (inklusive Angabe der Handelsregisternummer) noch vor Vertragsabschluss zu informieren. Zu jedem Artikel müssen vollständige Produktbeschreibungen erstellt und mit Bruttopreisen versehen werden. Weiterhin ist die Gültigkeitsdauer der Offerten anzugeben und es sind Zusatzkosten für Porto oder Verpackung aufzuführen. Selbstverständlich müssen die AGB, neben dem Impressum, für den Besucher leicht aufzufinden sein.
Gesetzliche Regelungen für den Betrieb einer Website
451
Shop-Betreiber kritisieren somit zu Recht, dass die Benutzerführung deutlich unter dem Umfang der Pflichthinweise leide. Es sei durchaus denkbar, dass potentielle Käufer aufgrund der »erschlagenden Fülle an Rechtshinweisen« den Bestellknopf nicht finden und den Vorgang entnervt abbrechen. Wer nun meint, er könne das Gesetz hinsichtlich »deutlicher Stelle« anders auslegen, der sei gewarnt! Neben Abmahnvereinen können auch Mitbewerber eine laxe Auslegung als Verletzung der Hinweispflicht betrachten und daraus einen Verstoß gegen das Gesetz zur Bekämpfung des unlauteren Wettbewerbs (UWG) ableiten. Datenschutzerklärung Das Gesetz über den Datenschutz bei Telediensten (TDDSG) schreibt das »Prinzip der Datensparsamkeit« vor. Dies heißt, dass Sie in interaktiven Formularen ausschließlich die unbedingt erforderlichen personenbezogenen Daten speichern sollten. Für einen Online-Shop bedeutet dies, dass alle kundenspezifischen Informationen spätestens nach der erfolgreichen Abwicklung der Bestellung (Ware hat Käufer erreicht und wurde bezahlt) und nach Ablauf der Rückgabe- beziehungsweise Widerspruchsfrist vom Server zu löschen sind. Selbstverständlich dürfen die Daten lediglich für die mit der Bestellung unmittelbar zusammenhängenden Zwecke verwendet werden. Die Postanschrift oder etwaige andere Daten des Kunden dürfen keinesfalls an eine dritte Person weitergegeben werden. Sollen in einer Community oder einem Online-Shop benutzerspezifische Daten auf unbestimmte Zeit gespeichert werden (damit der Kunde beispielsweise nicht für jede Bestellung seine Adressdaten nebst gewünschter Zahlungsmethode erneut eingeben muss), muss der Benutzer über Art und Umfang sowie Verwendungszweck seiner so genannten Bestandsdaten vor der Eingabe seiner Daten informiert werden und diesen Bestimmungen zustimmen. Am besten per zusätzlich auszuwählender Checkbox »Ich habe die Datenschutzbestimmungen gelesen und erkläre mich mit der Speicherung meiner Bestandsdaten für die genannten Zwecke einverstanden.« In der Datenschutzerklärung ist aufzuführen, wer welche Daten für welche Zwecke verwendet und wie lange die Daten gespeichert werden. Verstöße gegen den Datenschutz können mit harten Geldstrafen von bis zu 500 000 Euro belegt werden. Beachten Sie, dass der Besucher ein Recht auf Einsichtnahme in sämtliche über ihn gespeicherten personenbezogenen Daten besitzt. Gehen Sie daher ehrlich und detailliert auf die geplante Datennutzung ein! Falls Sie über Form und Inhalt der Datenschutzerklärung unsicher sind, finden Sie beim Online-Shop http://www.amazon.de ein schönes Beispiel.
452
Bürokratisches
1 2 8.1.2
Problematik externer Links
3
Linkseiten bergen neben der erstaunlichen Verwandlung in ein redaktionelles Angebot eine wahre Fülle an Gemeinheiten und potentiellen Stolperfallen. Auf der einen Seite besteht die Gefahr, dass Sie von einer dritten Partei für die Inhalte auf verlinkten Webseiten zur Verantwortung gezogen werden. Auf der anderen Seite ist es sogar schon vorgekommen, dass die Betreiber verlinkter Angebote mit der Einforderung einer Unterlassungsklage auf eine unerwünschte Verlinkung reagiert haben.
4 5 6
Das zweite Problem bezieht sich in der Regel auf Deep-Links. Das sind Links, die auf eine Unterseite und nicht auf die Startseite einer Homepage verweisen. Sie können durch eine kurze Bitte um Erlaubnis für den geplanten Link umgangen werden. Bei Dateien sollten Sie lieber auf die Startseite verweisen. Durch einen direkten Downloadlink entsteht bei unerfahrenen Internetnutzern der Eindruck, dass der Download über Ihren Server erfolgt. Tatsächlich wird jedoch der verlinkte Server belastet. Bei Anbietern, die ihre Traffic-Kosten über Werbeeinblendungen hereinholen, sind solche direkten Downloadlinks logischerweise nicht gern gesehen, da lediglich die Kosten für den Traffic entstehen, ohne dass auch nur ein einziges Banner eingeblendet wurde! Generell gilt: Wer sich fremde Inhalte durch geschicktes Einbinden in ein Frameset oder via direkten Downloadlinks zu Eigen macht, provoziert eine böse Reaktion.
7 8 9 10 11 12
Wenn Sie die Links deutlich als Verknüpfungen zu einer anderen Website gekennzeichnet haben, werden die Seitenbetreiber, zu denen Sie linken, in der Regel über die zusätzliche Aufmerksamkeit und die neu gewonnenen Besucher erfreut sein und kaum auf die Idee kommen, einen Anwalt auf Sie anzusetzen.
13 14
Allerdings droht bei Links auch durch Dritte Ungemach. Werden auf einer Homepage, zu der Sie gelinkt haben, unrechtmäßige Inhalte (zum Beispiel kinderpornographisches Material) entdeckt, können Sie selbst zur Verantwortung gezogen werden. Eine generelle Klausel, um die Haftung für externe Links (bekannt als Disclaimer) auszuschließen, ist nicht rechtmäßig. Auf der anderen Seite können Sie nur für Inhalte zur Verantwortung gezogen werden, die Ihnen selbst bekannt geworden sind. Das heißt, Sie müssen eine verlinkte Webseite prüfen, wenn Sie den Link setzen. Weiterhin sollte der Besucher darauf aufmerksam gemacht werden, dass die Linkliste zu eigenständigen Angeboten anderer Homepage-Betreiber verweist und Sie für die Inhalte der Seite nicht verantwortlich sind.
Gesetzliche Regelungen für den Betrieb einer Website
453
Die nachfolgenden Links verweisen auf externe Seiten, die beim Setzen geprüft wurden. Da wir nicht für diese Inhalte verantwortlich sind, können die Seiten im Nachhinein geändert werden. Falls Sie feststellen, dass ein Link nicht mehr existiert oder gar Inhalte enthält, die gegen geltendes Recht verstoßen, teilen Sie uns dies bitte mit (webmaster@ihre_domain.de). Für den Inhalt der externen Seiten übernehmen wir keine Haftung. Dort veröffentlichte Meinungen oder Tatsachenbehauptungen machen wir uns durch die Schaltung eines Links nicht zu Eigen, falls durch uns nicht ausdrücklich etwas anderes zu dem Link erklärt wird. Prüfen Sie Ihre Linkliste regelmäßig selbst und verweisen Sie lediglich auf vertrauenswürdige Websites. Falls Sie dennoch per E-Mail oder Briefpost von einer dritten Person auf einen Rechtsverstoß innerhalb einer verlinkten Website aufmerksam gemacht werden, ist der entsprechende Link selbstverständlich unmittelbar zu entfernen. Dies gilt auch dann, wenn der fragwürdige Inhalt lediglich in einer versteckten Unterseite entdeckt wurde.
8.1.3
Betrieb eines Gästebuchs oder Forums
Die Möglichkeit zur direkten und freien Meinungsäußerung birgt die Gefahr von unrichtigen Tatsachenbehauptungen oder persönlichen Beleidigungen. Betroffene Personen haben das Recht, die Löschung der entsprechenden Beiträge vom Administrator (des Forums oder Gästebuches) zu verlangen. Sehr schwierig ist zudem die Frage, ob sich der Betreiber die Inhalte des Forums oder Gästebuches zu Eigen macht und somit direkt haftbar für die dort veröffentlichten Beiträge ist. Auf der einen Seite heißt es in § 8 Abs. 2 des TDG: Diensteanbieter im Sinne der §§ 9 bis 11 sind nicht verpflichtet, die von ihnen übermittelten oder gespeicherten Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Auf der anderen Seite hat das Landgericht Trier eine Privatperson dazu verpflichtet, ihr Gästebuch mindestens einmal pro Woche zu überprüfen. Das Gericht war zu der Auffassung gelangt, dass sich der Betreiber die Inhalte zu Eigen gemacht habe. Eine ähnliche Erfahrung musste Microsoft machen: Das Landgericht Köln erachtete MSN für eine pornographische Fotomontage des Tennisstars Steffi Graf für haftbar. MSN habe sich die Inhalte des Forums zu Eigen gemacht, da MSN sich von den Foren-Benutzern weitere Nutzungsrechte an sämtlichen veröffentlichten Beiträgen einräumen ließ. Zusätzlich seien die von Besuchern und MSN-Mitarbeitern genutzten Pseudonyme nicht eindeutig gewesen. Nutzern des Forums
454
Bürokratisches
1 2 war es daher nicht möglich, zwischen offiziellen MSN-Beiträgen und Meinungsäußerungen anderer Forumsteilnehmer zu unterscheiden.
3
Um sicherzugehen, dass ein Gericht nicht zu der Auffassung gelangen kann, dass Sie sich Inhalte des Forums oder Gästebuches zu Eigen gemacht haben, sollten Sie eine Haftungsbeschränkung am besten auf der Startseite des Forums beziehungsweise Gästebuches an deutlicher Stelle aufnehmen:
4 5 6
Forenbeiträge werden in Echtzeit veröffentlicht. Eine redaktionelle Prüfung der Beiträge vor ihrer Veröffentlichung ist daher nicht möglich. Für den Inhalt der einzelnen Beiträge ist der jeweilige Verfasser verantwortlich. Beachten Sie, dass wir aus technischen Gründen nicht alle Beiträge auf unzulässige Inhalte überprüfen können. Falls ein Beitrag für Sie diffamierend ist oder gegen geltendes Recht verstößt, werden wir diesen sofort nach Kenntnisnahme löschen. Bitte informieren Sie den Administrator ([email protected]) über Autor, Zeitpunkt und Überschrift des zu löschenden Beitrages.
7 8 9 10
Der Einsatz eines derartigen Disclaimers lässt jedoch die juristisch spitzfindige Auffassung zu, dass Sie mit unzulässigen Inhalten rechnen. Falls das Gericht dieser Argumentation folgt, dann entsteht aus dem Haftungsausschluss die Pflicht zur sorgsamen Prüfung der Inhalte.
11 12
Lassen Sie es nicht darauf ankommen: Verwenden Sie eine Haftungsbeschränkung und prüfen Sie die Inhalte Ihres Forums oder Gästebuches regelmäßig und sorgsam auf unzulässige Inhalte.
8.1.4
13 14
Newsletter
Wer einen Newsletter anbietet, muss darauf achten, dass dieser ausschließlich auf ausdrücklichen Wunsch des Empfängers zugestellt werden darf. Sie dürfen also nicht einfach unverlangt »Kostproben« versenden. Weiterhin ist in jeder E-Mail ein Link beziehungsweise eine E-Mail-Adresse zum Abbestellen des Newsletters anzugeben. Bei einer Anmeldung sollten Sie eine Bestätigung an die angegebene E-Mail-Adresse senden, mit deutlichem Hinweis darauf, dass die E-Mail-Adresse von einem Besucher erfasst wurde. Falls sich jemand einen Streich erlaubt hat, muss der Empfänger die Möglichkeit haben, den Newsletter via Link oder kurzer E-Mail sofort abzubestellen.
Gesetzliche Regelungen für den Betrieb einer Website
455
8.1.5
Das Domain-Recht
Ein griffiger Domain-Name ist wegen des Internetbooms der vergangenen Jahre und der daraus entstandenen Registrierungswut nur schwer zu finden. Die eigentliche Arbeit beginnt jedoch erst nach der Namensfindung. Beachten Sie, dass Registrare die Prüfung, ob der gewünschte Name überhaupt von Ihnen gesichert werden darf, nicht übernehmen. Wer den bekannten Namen einer Firma, eines Produktes beziehungsweise den Namen eines Prominenten oder einer staatlichen Institution (zum Beispiel den Namen einer Behörde, einer Stadt oder Gemeinde) sichert, muss unweigerlich mit Problemen rechnen. Das Sichern von Kfz-Kennzeichen wird von der Denic ebenfalls als unzulässig betrachtet. Grundsätzlich sollten Sie prüfen, ob der gewünschte Domainname als Marke, Geschmacksmuster oder Patent eingetragen wurde, da die Registrierung einer entsprechenden Domain-Adresse juristisch als Verstoß gegen das Patentrecht betrachtet werden kann. Nicht nur der Versuch, sich allgemein bekannte Marken wie »Coca-Cola« oder »McDonalds« zu sichern, birgt das Risiko, eine Abmahnung zu erhalten und zur Herausgabe der Domain verpflichtet zu werden. Wenn Sie bei einer Recherche auf der Webseite des Deutschen Patent- und Markenamts (http://www.dpma.de/suche/suche.html) ebenso wenig wie bei der Suche nach Gemeinschaftsmustern (http://oami.eu.int/de/) sowie etwaigen Überschneidungen mit Produkt- und Firmennamen über eine Metasuchmaschine (wie http://www.google.de oder http://www.metacrawler.com) fündig werden, können Sie sich leider noch immer nicht in Sicherheit wiegen. Selbst bei kleinen Abweichungen in der Schreibweise können Domain-Namen das Namensrecht bestehender Marken verletzen. Als aktuelles und prominentes Beispiel sei der Fall »Asterix gegen Mobilix« genannt. Wer sicher sein möchte, dass der freie Domain-Name auch tatsächlich registriert und genutzt werden darf, muss einen Anwalt mit der Namensrecherche beauftragen. Er sollte darüber hinaus bei einer Domain-Registrierung den gefundenen Namen als Geschmacksmuster beim Patent- und Markenamt anmelden. Firmen müssen weiterhin beachten, dass es nicht erlaubt ist, einen Gattungsbegriff mehrfach zu registrieren. Damit ist gemeint, dass allgemein gültige Beschreibungen wie Immobilienmarkt lediglich einmal registriert werden dürfen und nicht zusätzlich als immobilien-markt und/oder für weitere ToplevelDomains registriert werden dürfen. Derartige Mehrfachregistrierungen können als Benachteiligung von Mitbewerbern ausgelegt werden, und Sie können zur Löschung der Domains verurteilt werden. Privatpersonen ist es jedoch
456
Bürokratisches
1 2 erlaubt, Gattungsbegriffe in verschiedenen Schreibweisen oder für weitere Toplevel-Domains zu registrieren.
3 4
Wer ohne aufwendige Recherche und Anmeldung einer Marke das Risiko einer Domain-Registrierung klein halten möchte, sollte seinen Namen in die Domain-Adresse mit aufnehmen (schreinermeister-karl-mustermann.de). Aufgrund des komplizierten Namens- und Patentrechts laufen Sie sonst Gefahr, mit einer Abmahnung konfrontiert zu werden und auf den Kosten, die vom Anwalt der Gegenpartei in Rechnung gestellt werden, sitzen zu bleiben.
5 6 7 8
Tatsächlich sollten Sie die Gefahr einer Abmahnung nicht unterschätzen. Die Seite http://www.abmahnwelle.de zeichnet ein erschreckendes Bild und verdeutlicht, dass kein Betreiber einer Homepage vor den umtriebigen Abmahnvereinen wirklich sicher ist. Viele Abmahnungen an Privatpersonen ergehen jedoch zu Unrecht, und die Abmahnvereine selbst bewegen sich auf rechtlich unsicherem Terrain. Foren wie in http://www.abmahnwelle.de helfen bei der ersten Bewertung des Anspruches. Falls sich Ihr Verdacht erhärtet, eine unrechtmäßige Abmahnung erhalten zu haben, ist sofort ein Anwalt zu konsultieren. Dieser kann dann unter anderem in Ihrem Auftrag eine Gegenabmahnung und/oder Androhung einer negativen Feststellungsklage in die Wege leiten, falls eine gütliche Einigung nicht möglich sein sollte.
8.2
9 10 11 12 13
Rechtliche Absicherungen gegenüber Kunden
14
Ein Hoster ist selbstverständlich nicht generell für die Inhalte der von ihm gehosteten Kunden-Sites oder etwaige Verstöße gegen das Namensrecht von Domain-Adressen verantwortlich. Sobald Sie jedoch Kenntnis von einem Rechtsverstoß erlangen, müssen Sie das entsprechende Angebot und den Kundenzugang sperren. Leider wird die Lage nur in den seltensten Fällen so eindeutig sein, dass Sie direkt zur Sperrung des Angebots schreiten können. Häufig ist die Rechtslage unklar und kann erst von einem Gericht abschließend beurteilt werden. Dies bedeutet jedoch auch, dass Sie bei Kenntnisnahme eines mutmaßlichen Rechtsverstoßes die Kosten einer anwaltlichen Beratung tragen müssen, um nicht selbst ins Kreuzfeuer der Justiz zu geraten. Insbesondere wenn es gegen den »kleinen Mann« geht, neigen Gegenparteien dazu, nicht nur mit der eigentlich verantwortlichen Person Kontakt aufzunehmen, sondern ebenfalls mit dem Hoster, um diesen zur Sperrung des entspre-
Rechtliche Absicherungen gegenüber Kunden
457
chenden Angebots aufzufordern. Bewahren Sie einen kühlen Kopf und sperren Sie Angebote ausschließlich dann, wenn ein Verstoß tatsächlich offenkundig ist. Eine generelle Sperrung, um Kosten und Zeit zu sparen, ist wenig sinnvoll. Wird die Anschuldigung zu Unrecht erhoben, dann hätten Sie das Angebot nicht sperren dürfen und der Kunde kann wiederum Sie belangen. In diesem Fall werden Sie schlüssig darlegen müssen, dass der Anspruch auf Sperrung des Angebots glaubhaft dargelegt wurde. In beiden Fällen können erhebliche Verfahrenskosten auf Sie zukommen. Das einzig probate Mittel, sich gegen solche Kosten abzusichern, ist die Aufnahme von Vertragsstrafen und eines Hinweises auf die Sorgfaltspflichten des Kunden sowie Ihrer Möglichkeit, bei glaubhaften Ansprüchen Dritter das Angebot sofort zu sperren. Weiterhin sollten Sie den Kunden darauf hinweisen, dass er nicht berechtigt ist, Spam oder ähnlich fragwürdige Inhalte über Ihren Mailserver zu versenden und Sie bei Zuwiderhandlung berechtigt sind, sein Postfach sofort zu sperren. Dies ist notwendig, da Sie sonst bei einer notwendigen Sperrung des Postfaches Gefahr laufen, vom Kunden selbst auf Schadensersatz verklagt zu werden, da ihm eine uneingeschränkte Nutzung des Mailservers gestattet wurde. Erlauben Sie die Speicherung von CGI-, PHP- oder JSP- beziehungsweise JavaServlets, dann sind durch fehlerhafte kundeneigene Programme nicht nur Sicherheitslöcher denkbar, die die Kundenpräsenz gefährden, sondern auch die Performance und die Stabilität des Webservers kann beeinträchtigt werden. Es muss Ihnen somit gestattet sein, fehlerhafte Programme jederzeit zu stoppen und vom Server zu löschen. In meinen AGB finden sich zur rechtlichen Absicherung gegenüber Missbrauch oder Rechtsverstößen des Kunden die folgenden Abschnitte. Bitte verstehen Sie die Texte nur als Beispiele, die natürlich individuell an Ihre Erfordernisse anzupassen und danach von einem Anwalt zu prüfen sind.
8.2.1
Inhalte von Internetseiten
1. Der Kunde ist verpflichtet, auf seine Internetseite eingestellte Inhalte als eigene Inhalte unter Angabe seines vollständigen Namens und seiner Anschrift zu kennzeichnen. Eine darüber hinausgehende gesetzliche Kennzeichnungspflicht kann zum Beispiel dann bestehen, wenn auf den Internetseiten Tele- oder Mediendienste angeboten werden. 2. Der Kunde darf durch die Internetpräsenz, dort eingeblendete Banner sowie die Angabe seiner E-Mail-Adresse nicht gegen gesetzliche Verbote, die guten Sitten und Rechte Dritter (Marken-, Namens-, Urheber-, Datenschutzrechte
458
Bürokratisches
1 2 und so weiter) verstoßen. Der Kunde ist verpflichtet, keine pornographischen Inhalte und keine auf Gewinnerzielung gerichteten Leistungen anzubieten oder anbieten zu lassen, die pornographische und/oder erotische Inhalte (zum Beispiel Nacktbilder) zum Gegenstand haben. Für jeden Fall der Zuwiderhandlung gegen eine der vorstehenden Verpflichtungen verspricht der Kunde dem Hoster – unter Ausschluss der Annahme eines Fortsetzungszusammenhangs – die Zahlung einer Vertragsstrafe in Höhe von EUR 5 000,00.
3 4 5 6
3. Der Kunde ist für alle von ihm über seine Zugangskennung oder von Dritten über seinen Internetservice des Hosters publizierten Inhalte selbst verantwortlich. Eine generelle Überwachung oder Überprüfung dieser Inhalte findet durch den Hoster nicht statt. Nach dem Erkennen von Rechtsverstößen oder von rechtswidrigen Inhalten ist der Hoster berechtigt, die Kundenseiten zu sperren.
7 8 9
4. Der Hoster überprüft die Inhalte des Kunden nicht dahingehend, ob Ansprüche Dritter berechtigt oder unberechtigt erhoben werden. Im Internet ist es üblich, dass bis zu einer gerichtlichen Klärung Daten auf glaubhaftes Verlangen jedes Dritten gesperrt werden (siehe auch die »Dispute Policy« des InterNic unter http://www.internic.net). Falls Dritte einen derartigen Anspruch glaubhaft erheben, erklärt sich der Kunde mit einer Sperrung seiner Inhalte einverstanden.
10 11 12
5. Sollte der Hoster aus den erwähnten Gründen eine Sperrung vornehmen, ist der Kunde dennoch ihm gegenüber leistungspflichtig. Weiterhin erklärt sich der Kunde mit sämtlichen Maßnahmen einverstanden, die zur Befolgung einer vollstreckbaren Entscheidung oder vollziehbaren Anordnung zu treffen sind. Der Kunde hält den Hoster diesbezüglich von Forderungen Dritter, sämtlichen entstehenden Kosten und nachteiligen Folgen frei.
8.2.2
13 14
Registrierung eines Domain-Namens
1. Bei der Verschaffung und/oder Pflege von Domains fungiert der Hoster zwischen dem Kunden und der jeweiligen Organisation zur Domain-Vergabe lediglich als Vermittler. Er hat auf die Domain-Vergabe keinen Einfluss und übernimmt keine Gewähr dafür, dass die für den Kunden beantragten Domains überhaupt zugeteilt werden und/oder zugeteilte Domains frei von Rechten Dritter sind oder auf Dauer Bestand haben. 2. Durch die Antragstellung versichert der Kunde, dass er seiner Verpflichtung zur Überprüfung der Verwendbarkeit des Domain-Namens nachgekommen ist und dass ihm keine Anhaltspunkte über die Verletzung von Rechten Dritter oder sonstiger Rechtsvorschriften bekannt sind. Von Ersatzansprüchen
Rechtliche Absicherungen gegenüber Kunden
459
Dritter sowie allen Aufwendungen, die auf der unzulässigen Verwendung einer Internet-Domain durch den Kunden oder mit Billigung des Kunden beruhen, stellt der Kunde den Hoster, dessen Angestellte und Erfüllungsgehilfen, die jeweilige Organisation zur Vergabe von Domains sowie sonstige für die Registrierung eingeschaltete Personen frei. 3. Durch die Registrierung einer Domain wird der Kunde nicht Eigentümer, sondern erhält lediglich ein Nutzungsrecht, solange die Domain auf ihn als Eigner (Admin-C) registriert ist. Ergänzend gelten die jeweils für den zu registrierenden Domain-Namen maßgeblichen Registrierungsbedingungen und Richtlinien. Diese sind fester Vertragsbestandteil und für die Registrierung und den Betrieb der Domain maßgebend. Die Bestimmungen können im Internet bei der jeweiligen Vergabestelle (zum Beispiel unter http://www.denic.de) abgerufen werden. 4. Aus technischen Gründen kann bei Domain-Namen mit der Endung .com, .net, .org und .info unter Admin-C nur die E-Mail-Adresse des Hosters eingetragen werden. Die Rechte des Vertragspartners werden davon nicht beeinträchtigt. Der Kunde stimmt dieser Verfahrensweise ausdrücklich zu. 5. Der Hoster ist berechtigt, die Domain nach Wirksamwerdung der Kündigung freizugeben. Damit erlöschen alle Rechte des Kunden aus der Registrierung der Domain. 6. Werden von Dritten gegenüber dem Hoster Ansprüche wegen tatsächlicher oder behaupteter Rechtsverletzung geltend gemacht, ist der Hoster berechtigt, die Domain des Kunden unverzüglich in die Pflege des Registrars zu stellen und die Präsenzen des Kunden zu sperren. 7. Bei einzelnen Services besteht die Möglichkeit, vorhandene Domains, die zurzeit von einem anderen Anbieter betreut werden, zukünftig als Bestandteil des Vertragsverhältnisses vom Hoster betreuen zu lassen. Dem Kunden ist bekannt, dass zur erfolgreichen Ummeldung eine Freigabe des bisher die Domain betreuenden Anbieters erforderlich ist. Eine Gewähr für den erfolgreichen Abschluss einer Ummeldung kann somit nicht übernommen werden. Eine erfolgreich umgemeldete Domain wird im Verhältnis zwischen dem Hoster und dem Kunden ansonsten wie eine neu registrierte Domain gemäß den hier getroffenen Regelungen behandelt. 8. Eine Haftung des Hosters ist ausgeschlossen, wenn eine Nichterreichbarkeit des Vertragsgegenstandes durch Dritte zu verantworten ist. Gleiches gilt, wenn bei einer Domain-Übertragung der alte Provider die Domain nicht herausgibt.
460
Bürokratisches
1 2 8.2.3
Pflichten des Kunden
3
1. Der Kunde ist verpflichtet, dem Hoster eine gültige Postanschrift (jedoch keine Postfach- oder sonstige anonyme Adresse) mitzuteilen und diese selbstständig über sein Kundenmenü oder durch Mitteilung per Post zu aktualisieren. Die Beweislast bezüglich der Absendung der Änderungsmitteilung liegt beim Kunden. Die Angabe einer ausländischen Anschrift oder einer Postfach-Adresse ist nicht ausreichend und berechtigt den Hoster zu einer Sperre sämtlicher Leistungen.
4 5 6
2. Der Kunde hat missbräuchliche Nutzungen und rechtswidrige Handlungen im Internet zu unterlassen und sicherzustellen, dass durch die eigene Präsenz (inklusive Skripte, Datenbanken, Programme et cetera) keine Präsenzen oder Angebote anderer Kunden beeinträchtigt werden und die Server-Stabilität, Server-Performance oder Server-Verfügbarkeit in irgendeiner Weise beeinträchtigt werden.
7 8 9
3. Der Kunde hat zudem die Entgelte zu zahlen, die im Rahmen der ihm zur Verfügung gestellten Nutzungsmöglichkeiten durch befugte oder unbefugte Nutzung der Dienste durch Dritte entstanden sind. Eine Überlassung von Login-, Zugriffs- und Verwaltungsdaten (User-Name, Passwort et cetera) ist ausdrücklich untersagt. Der Kunde ist verpflichtet, seine Zugangsdaten, Auftrags- und Kundennummer, Passwörter und so weiter geheim zu halten und sicherzustellen, dass kein Unberechtigter Zugriff auf diese Daten erhält.
10 11 12
4. Der Hoster ist berechtigt, Inhalte, die das Regelbetriebsverhalten oder die Sicherheit des Servers beeinträchtigen könnten, grundsätzlich und ohne Vorwarnung zu sperren oder deren Betrieb im Einzelfall zu unterbinden.
13 14
5. Der Kunde ist verpflichtet, dem Hoster Störungen, Mängel und Schäden unverzüglich anzuzeigen. Der Kunde hat die Kosten, die durch die Behebung von Störungen, Mängeln und Schäden entstehen – soweit er sie zu vertreten hat –, zu erstatten. 6. Der Kunde haftet für alle Folgen und Nachteile, die dem Hoster und Dritten durch die missbräuchliche Verwendung von Diensten des Hosters oder dadurch entstehen, dass der Kunde seinen sonstigen Obliegenheiten nicht nachkommt. Für die Nutzung durch Dritte ist allein der Kunde verantwortlich und in vollem Umfang haftbar. Es ist dem Kunden insbesondere untersagt, »Massen-E-Mails« (SPAM) über die Server des Hosters zu versenden. Ausgenommen davon sind Newsletter, die von den E-Mail-Empfängern selbst beantragt wurden. Bei einer missbräuchlichen oder rechtswidrigen Verwendung von durch Dritte oder durch den Kunden selbst genutzten Leistungen kann eine Sperre erfolgen. Die Leistungspflicht des Kunden wird bei einer Sperrung aus genannten Gründen jedoch nicht berührt.
Rechtliche Absicherungen gegenüber Kunden
461
8.2.4 Datenschutzfragen beim Betrieb eines Webservers Das Datenschutzgesetz besteht im Wesentlichen aus den Grundsätzen Datenvermeidung und Wahlfreiheit. Das Prinzip ist einfach zu verstehen: Es sind lediglich unbedingt notwendige Angaben zu erfassen. Im Idealfall kann der Besucher die erforderlichen Angaben ohne Nennung seines Namens und seiner Kontaktdaten wie E-Mail oder Telefonnummer anonym oder unter einem Pseudonym übermitteln. In diesem Fall kommen Sie mit dem Datenschutzgesetz nicht weiter in Berührung und können mit den Informationen nach Belieben verfahren. Der Grundsatz der Wahlfreiheit ist zu beachten, sobald Daten personenbezogen erfasst werden müssen. Der Besucher ist dann über Sinn und Zweck der abgefragten Informationen detailliert zu informieren, und es muss zudem angegeben werden, ob die Daten lediglich von Ihnen verarbeitet werden oder zusätzlich an Dritte (sowie in welchem Umfang) weitergeleitet werden. Im Idealfall würde das Eingabeformular Optionen vorsehen, wie beispielsweise »ich bin damit einverstanden, dass meine Anschriftdaten der Firma xyz zur Versendung eines Infoprospektes über abc übermittelt werden«, die in der Voreinstellung noch nicht ausgewählt sind. Falls, wie in einem Online-Shop, der Versand der Ware zwingend über eine externe Vertriebsfirma erfolgen muss, sind solche Optionen natürlich unsinnig. In diesem Fall ist der Besucher dennoch über die Weiterleitung seiner Adressdaten und der Produktliste an einen externen Vertrieb hinzuweisen. Falls Sie sich als Reseller von Webspace oder in großem Stil als Hoster betätigen möchten, ergeben sich aus den Grundsätzen des Datenschutzes häufig zustimmungsbedürftige Einzelheiten. Auswertung von Traffic-Daten und kundenspezifischen Logfiles In der Regel werden Sie nicht nur für den Kunden, sondern auch aus Gründen der Traffic-Berechnung und der zeitraumspezifischen Server-Belastung ein ausführliches Logfile über Zugriffe auf seine Homepage anfertigen wollen. Falls Sie den Webspace zu Pauschalbeträgen an den Kunden vermietet haben, benötigen Sie hierfür jedoch eine Genehmigung, da Sie diese Daten zur bloßen Abrechnung des Dienstes nicht benötigen. Zudem bedarf eine nähere Analyse über das Zugriffsverhalten der Besucher des Kunden einer Erlaubnis. Letzteres ist aber sehr hilfreich, um Kunden aufgrund der zu erwartenden Serverbelastung zeitraumabhängig effektiv auf einzelne Server zu verteilen. Manche Angebote werden eher abends, andere morgens oder überwiegend nachmittags genutzt.
462
Bürokratisches
1 2 Der Zeitraum, über den diese Statistiken gespeichert bleiben, ist dem Kunden ebenfalls mitzuteilen, wenn er über den für die Abrechnung erforderlichen Zeitraum hinausgeht. Nun ist es aber so, dass mit Webalizer erstellte statistische Informationsseiten im Kundeninteresse nicht gelöscht werden sollten. Eine Webstatistik, die neben dem laufenden Monat lediglich den vergangenen Monat enthält, ist nicht besonders ergiebig.
3 4 5
Umfang und Art von Backups sind informationspflichtig
6
Bieten Sie einen Backup-Service an, ist dem Kunden genau mitzuteilen, welche Daten in welchen Intervallen gesichert und wie lange die Backup-Medien aufbewahrt werden, bevor sie endgültig vernichtet werden.
7 8
Finger weg von E-Mails Elektronische Post ist grundsätzlich als nicht öffentlich zu verstehen und vertraulich zu behandeln. Selbstverständlich ist es Ihnen nicht gestattet, in Kundenpostfächern zu stöbern oder E-Mails zu kontrollieren. Von einer Sicherung der E-Mail-Postfächer innerhalb von Backups rate ich daher ausdrücklich ab. Technisch gesehen ist ein Backup des Postfaches ohnehin nur dann sinnvoll, wenn sämtliche Nachrichten in einem IMAP-Postfach auf dem Server verbleiben und nicht via POP3 abgeholt und danach auf dem Server gelöscht werden.
9 10 11 12
Gestatten Sie Kunden lediglich den Zugriff auf POP3, dann schlagen Sie gleich zwei Fliegen mit einer Klappe: Über den datenschutzrechtlichen Aspekt der Sicherung von E-Mails3 müssen Sie sich keine Gedanken machen. Neben der Einsparung von Datenträgern für ein Backup sparen Sie durch ein POP3-Postfach (im Gegensatz zur Archivspeicherung eines IMAP-Mail-Kontos) weiteren Festplattenplatz auf dem Server.
13 14
Formulierungsbeispiel für Hinweise zum Datenschutz 1. Der Kunde wird hiermit gemäß § 33 Abs. 1 Bundesdatenschutzgesetz (BDSG) und § 3 Abs. 5 Teledienstdatenschutzgesetz (TDDSG) darüber unterrichtet, dass der Hoster seine Adressdaten in maschinenlesbarer Form erfasst und für sich aus dem Vertrag ergebende Aufgaben maschinell verarbeitet. Zudem werden Login- und Zugriffsdaten für Beweis- und Abrechnungszwecke gespeichert. Der Hoster wird vom Kunden berechtigt, Apache-Logfiles auch hinsichtlich des Besucherverhaltens für interne Zwecke (beispielsweise für Informationen über Zugriffsspitzen zur Optimierung der Server-Perfor3 Möglicherweise hat sich die Gesetzeslage bereits verändert, und Sie sind sogar verpflichtet, sämtliche an und von Ihrem Webserver geschickten E-Mails im Wege einer Vorratsspeicherung bereitzuhalten.
Rechtliche Absicherungen gegenüber Kunden
463
mance) auszuwerten. Weiterhin werden im Kundeninteresse Backups der Daten des FTP-Bereichs und der MySQL-Datenbank angefertigt. Der Kunde stimmt dem ausdrücklich zu. 2. Im FTP-Bereich werden ebenfalls die kundenspezifischen Logfiles des Apache-Webservers abgelegt. Aus datenschutzrechtlichen Gründen werden vor der automatischen Generierung der Zugriffsstatistik die letzten drei Stellen der IP-Nummer der aktuellen Logfiles durch die Ziffern 000 anonymisiert. 3. Die »alten Logdateien« werden als old_access_JMT.gz und old_error_JMT.gz auf dem Server archiviert (J=Jahr, M=Monat, T=Tag). Am 20. Februar eines Jahres werden die Logfiles des Vorjahres gelöscht. Falls Sie an einer längeren Speicherung Ihrer Logfiles interessiert sind, müssen Sie diese Dateien vorher auf einen eigenen Datenträger übertragen. 4. Soweit sich der Hoster zur Erbringung der vertraglich geschuldeten Leistungen Dritter bedient, ist er berechtigt, die Teilnehmerdaten offen zu legen, wenn dies für die Leistungserbringung erforderlich ist. 5. Dem Kunden ist bekannt, dass für alle Teilnehmer im Übertragungsweg des Internets in der Regel die Möglichkeit besteht, von in Übermittlung befindlichen Daten ohne Berechtigung Kenntnis zu erlangen. Der Kunde weiß, dass der Hoster das auf dem Webserver gespeicherte Seitenangebot und unter Umständen zudem weitere dort abgelegte Daten des Kunden aus technischer Sicht jederzeit einsehen kann und dass diese Möglichkeit theoretisch ebenfalls anderen unbefugten Personen offen steht. Für die Sicherheit der von ihm ins Internet übermittelten und auf Webservern gespeicherten Daten trägt der Kunde im vollen Umfang selbst Sorge. Von der Speicherung sensibler Firmendaten auf Webservern ist generell abzuraten. 6. Um das Risiko zu minimieren, müssen beide Vertragsparteien sämtliche Passwörter geheim halten. Sobald die Vermutung besteht, dass unberechtigte Dritte Kenntnis von einem Passwort erhalten haben, ist dieses unmittelbar über das Kundenmenü zu ändern. 7. Die Bestandsdaten werden spätestens sechs Monate nach Beendigung des Vertragsverhältnisses gelöscht, sofern dem im Einzelfall nicht besondere Gründe entgegenstehen oder der Kunde ausdrücklich dazu auffordert. Soweit Kunden gegen die Höhe der in der Rechnung gestellten Entgelte fristgerecht Einwendungen erhoben haben, dürfen die Abrechnungsdaten gespeichert werden, bis die Einwendungen abschließend geklärt sind. Ferner können Bestandsdaten bis zum Ablauf von zwei Jahren gespeichert bleiben, sofern Beschwerdebearbeitungen sowie sonstige Gründe einer ordnungsgemäßen Abwicklung des Vertragsverhältnisses dies erfordern. Im Übrigen darf die Löschung von Bestands- und Abrechnungsdaten unterbleiben, soweit dies gesetzliche Regelungen vorsehen oder die Verfolgung von Ansprüchen dies erfordert.
464
Bürokratisches
1 2 8.2.5
Haftungsbeschränkung und technische Einschränkungen
3
Bei einem Server-Ausfall können Ihren Kunden Schäden entstehen. Einnahmeausfälle durch Offline-Zeiten des Online-Shops sind neben entgangenen Aufträgen durch einen kurzzeitigen Ausfall des Mailservers durchaus denkbar.
4
Selbst wenn Sie bei der Pflege und Wartung Ihres Servers größtmögliche Sorgfalt und Umsicht walten lassen, können Sie Ihren Kunden keine hundertprozentige Verfügbarkeit garantieren, da Hardware-Fehler an der Festplatte oder den Switches sowie an externen Netz-Routern ebenso denkbar sind wie ein Leitungsausfall durch einen defekten Telefon-Carrier.
5 6 7
Versuchen Sie, die Ausfallzeiten für Wartungs- und Sicherheits-Updates, den Austausch einer Festplatte, Server-Neustarts durch Kernel-Updates sowie theoretische System- oder Programmabstürze von Web- beziehungsweise Mailserver für ein gesamtes Jahr abzuschätzen. Addieren Sie zu dieser Zeit die vom Rechenzentrum veranschlagte Ausfallzeit und erhöhen Sie die Ausfallzeit für den Worst Case nochmals um vier Tage (zum Beispiel bei Ausfall und Suche eines neuen Rechenzentrums oder einem Hardware-Ausfall am Wochenende). Bei einer garantierten Verfügbarkeit von 96 Prozent stehen Ihnen im Jahresmittel großzügige 14 Tage Gesamtausfallzeit zur Verfügung (350 Tage / 100 * 4).
8 9 10 11
Abgesehen von der garantierten Verfügbarkeit, können Sie weitere Haftungsbeschränkungen sowie eine Haftungsgrenze aufnehmen. Allerdings verlieren entsprechende AGB-Regelungen bei grober Fahrlässigkeit ihre Wirkung. Wenn Sie einen Schaden durch grobe Fahrlässigkeit selbst zu verantworten haben, haften Sie mit Ihrem gesamten Firmen- beziehungsweise Privatvermögen.
12 13 14
Weisen Sie Ihren Kunden darauf hin, dass die verfügbare Bandbreite des Webs starken Schwankungen unterliegt und Sie selbstverständlich nicht vor höherer Gewalt gefeit sind. Weiterhin sollten Sie gegebenenfalls verdeutlichen, dass dem Kunden lediglich Webspace beziehungsweise ein eigener virtueller Server bereitgestellt wurde, der ebenfalls von anderen Kunden zur gleichzeitigen Nutzung verwendet wird. Der folgende AGB-Ausschnitt ist wieder nur als ein Beispiel anzusehen, das gerne an die eigenen Bedürfnisse angepasst werden darf, aber unbedingt erneut von einem Anwalt zu prüfen ist. Höhere Gewalt 1. Der Hoster ist von der Leistungspflicht in Fällen höherer Gewalt befreit. Als höhere Gewalt gelten alle unvorhergesehenen Ereignisse sowie solche Ereignisse, deren Auswirkungen auf die Vertragserfüllung von keiner Partei zu vertreten sind. Zu diesen Ereignissen zählen insbesondere rechtmäßige Arbeitskampfmaßnahmen, auch in Drittbetrieben, behördliche Maßnah-
Rechtliche Absicherungen gegenüber Kunden
465
men, Ausfall von Kommunikationsnetzen und Gateways anderer Betreiber, Störungen im Bereich von Leitungsgebern und sonstige technische Störungen, auch wenn diese Umstände im Bereich von Unterauftragnehmern, Unterlieferanten oder deren Subunternehmern oder bei vom Hoster autorisierten Betreibern von Subknotenrechnern auftreten. Der Kunde stellt den Hoster diesbezüglich von sämtlichen Ansprüchen Dritter frei. Es ergeben sich bei nicht durch den Hoster zu verantwortenden Ausfällen keine Schadensersatz- oder sonstige Ansprüche für den Kunden. 2. Der Hoster übernimmt keine Haftung für direkte oder indirekte Schäden aufgrund technischer Probleme, Server-Ausfall, Datenverlust, Übertragungsfehlern, Datenunsicherheit oder sonstiger Gründe, es sei denn, ihm kann Vorsatz oder grobe Fahrlässigkeit nachgewiesen werden. Alle Ansprüche des Kunden sind auf den Auftragswert beschränkt, sofern gesetzlich zulässig. Der Kunde ist für die Sicherung seiner E-Mails selbst verantwortlich. Der Hoster erstellt Sicherungskopien (Backup) ausschließlich über den FTP- und Datenbankbereich des Kunden. Hierbei erfolgt ein tägliches Bakkup, das wöchentlich überschrieben wird. Die Aufbewahrungszeit beträgt derzeit sechs Monate. Wenn der Datenverlust vom Kunden zu verantworten ist, ist der Hoster berechtigt, für die Rückspielung der Backupdaten eine Gebühr von EUR 30,00 zu berechnen. Haftung 1. Die Haftung des Hosters ist begrenzt auf das Dreifache einer Monatsgebühr. Für Schäden haftet der Hoster nur dann, wenn er eine wesentliche Vertragspflicht (Kardinalpflicht) in einer den Vertragszweck gefährdenden Weise verletzt hat oder der Schaden auf grobe Fahrlässigkeit oder Vorsatz zurückzuführen ist. Erfolgt die schuldhafte Verletzung einer wesentlichen Vertragspflicht (Kardinalpflicht) nicht grob fahrlässig oder vorsätzlich, so ist die Haftung auf solche typischen Schäden begrenzt, die zum Zeitpunkt des Vertragsschlusses für den Hoster vernünftigerweise voraussehbar waren. Weitergehende Haftungsansprüche sind ausgeschlossen. Die Haftung wegen zugesicherter Eigenschaften, bei Personenschäden sowie aufgrund zwingender gesetzlicher Vorschriften bleibt von dieser Vereinbarung unberührt. 2. Der Hoster übernimmt keine Haftung für die Folgen von Pflichtverletzungen des Kunden. Im Falle einer Pflichtverletzung des Kunden ist der Hoster zur sofortigen Sperrung der entsprechenden Seiten und des Domain-Namens sowie sämtlicher sonstigen Leistungen berechtigt. Jede Sperrung und Wiederaktivierung von Domains wird mit EUR 25,00 berechnet. Eine Sperre wird frühestens nach Zahlung der Sperr-/Entsperrgebühr aufgehoben. Durch eine Sperre wird der Kunde nicht von seiner Leistungspflicht entbunden.
466
Bürokratisches
1 2 Diese Rechte stehen dem Hoster insbesondere dann zu, wenn von Dritten auf Unterlassung geklagt und/oder Schadensersatz in Anspruch genommen wird und/oder durch eine Strafverfolgungsbehörde oder ein Gericht dazu aufgefordert wird. Für den Fall der Zuwiderhandlung des Kunden behält sich der Hoster die fristlose Kündigung vor. Schadensersatz- oder sonstige Ansprüche des Hosters bleiben davon unberührt. Soweit der Hoster durch Dritte wegen rechtswidriger Handlungen des Kunden (insbesondere im Bereich des Datenschutz-, Urheber- und Wettbewerbsrechts) in Anspruch genommen wird, verpflichtet sich der Kunde, den Hoster von allen denkbaren Ansprüchen freizustellen und die durch die Inanspruchnahme oder Beseitigung des rechtswidrigen Zustandes entstandenen Kosten zu tragen.
3 4 5 6 7
3. Die Server des Hosters werden überwiegend mit Fremd-Software, zu der unter anderem der Apache-Webserver oder die Programmiersprache PHP zählt, betrieben. Der Hoster trägt für Fremd-Software keinerlei Haftung, selbst wenn diese Software als zusätzliche Dienstleistung in sein Angebot integriert wurde.
8 9 10
8.2.6 Abschließende Hinweise und Tipps zu AGB
11
Abgesehen von den bereits aufgeführten Punkten, sollten Sie ebenfalls Geltung und Gegenstand des Vertrages sowie Details zur Rechnungsstellung und Detailfragen wie den Gerichtsstand aufnehmen. Falls Sie sich nicht sicher sind, welche Punkte Sie aufnehmen sollten, bietet ein Blick auf die AGB großer Hoster sicher Denkanstöße. Sobald Sie die Arbeit an Ihren AGB abgeschlossen haben, führt kein Weg an einem Beratungsgespräch mit einem Anwalt und dessen Prüfung der erstellten AGB vorbei.
8.2.7
12 13 14
Datenschutz und Logfiles
Bedenken Sie, dass es aus datenschutzrechtlichen Gründen vermieden werden muss, personenbezogene Daten wie eine IP-Adresse oder einen Host-Namen des Besuchers zu speichern. Auf der anderen Seite kann Ihnen nicht untersaget werden, IP-Adressen aus sicherheitsrelevanten Gründen in Logfiles zu sichern, da Sie nur so bei einem erfolgreichen Angriff rechtliche Schritte einleiten können. Dennoch haben Sie keinen Freibrief für die Nutzung und Auswertung personenbezogener Daten (Paketinformationen mit IP-Adressangaben) unter dem Deckmantel der Absicherung vor Angreifern. Dies bedeutet, dass Daten vor einer statistischen Auswertung gegebenenfalls zu anonymisieren sowie personenbezogene Informationen sobald als möglich zu löschen sind.
Rechtliche Absicherungen gegenüber Kunden
467
Spätestens nachdem die Traffic-Abrechnung von Web-, Mail-, Datenbank oder FTP-Traffic abgeschlossen ist, müssen Sie sämtliche Serverlogs löschen oder zumindest anonymisieren, die IP-Adressen von anderen Rechnern enthalten. In Abschnitt 3.3.9, Logfile-Erstellung und -Auswertung, finden Sie ein Beispiel für die Anonymisierung des Apache-Logfiles vor der Auswertung durch Webalizer.
8.2.8
Vorsicht bei Auskunftsersuchen und Durchsuchungen
Falls das Hosting einer Kunden-Site mit dem Namens- oder Markenrecht kollidiert oder Diffamierungen beziehungsweise Verleumdungen enthält, sind Sie verpflichtet, Daten zu dem Urheber der Site ebenfalls an die geschädigte Privatperson direkt weiterzugeben, wenn diese Daten nicht ohnehin auf der Website oder über eine whois-Abfrage vom Betroffenen selbst zu erfragen sind (weisen Sie gegebenenfalls auf die alternative Auskunftsmöglichkeit hin). In der Regel, dürfen Sie jedoch aus datenschutzrechtlichen Gründen keinerlei Informationen an Privatpersonen, Anwälte oder Behörden weitergeben. Bei einem Verstoß können Sie selbst vor Gericht landen und sich mit einem hohen Bußgeld konfrontiert sehen. Falls Sie nicht sicher sind, ob juristisch eine Verleumdung oder ein anderer Grund zur Herausgabe der Daten vorliegt, sollten Sie sich mit Ihrem Anwalt in Verbindung setzen. Die Datenschutzbestimmungen gelten ebenfalls gegenüber staatlichen Institutionen. So dürfen Sie noch nicht einmal der Polizei gegenüber Daten ohne weiteres preisgeben. Ausnahmen sind ein Durchsuchungsbefehl oder ein Gerichtsbeschluss sowie ein sofort vollziehbarer Verwaltungsakt. Im letzten Fall sollten Sie sofort Ihren Anwalt kontaktieren, um die Korrektheit der Frage nach »sofort vollziehbarem Verwaltungsakt« klären zu können. Selbst bei einer Durchsuchung haben Sie das Recht, auf das Hinzuziehen Ihres Anwalts zu bestehen. Grundsätzlich ist die Herausgabe sämtlicher relevanter Daten zur betreffenden Person auf einer CD-ROM völlig ausreichend. Ein Anwalt kann hier bei der Argumentation gegenüber der Polizei hilfreich sein und so eventuell die Beschlagnahme Ihrer gesamten Server- beziehungsweise Computer-Ausstattung verhindern.
8.2.9 Ernennung eines Datenschutzbeauftragten Da Ihre Firma personenbezogene Daten verarbeitet, sind Sie verpflichtet, einen Datenschutzbeauftragten zu ernennen, sobald mehr als fünf Mitarbeiter mit der Datenbearbeitung betraut werden oder insgesamt mehr als 20 Beschäftigte angestellt sind.
468
Bürokratisches
1 2 Der Datenschutzbeauftragte muss direkt der Geschäftsleitung unterstellt werden und Zugriff auf sämtliche Bereiche der Datenverarbeitung erhalten. Selbstverständlich muss der Datenschutzbeauftragte die Einhaltung der Datenschutzbestimmungen regelmäßig überprüfen und sämtliche Datenschutzregelungen kennen. Weiterhin ist dem Landesdatenschutzbeauftragten Ihres Bundeslandes der Datenschutzbeauftragte Ihrer Firma zu nennen.
8.3
3 4 5
Rechtliche Hinweise und Verfahrensfragen zur Registrierung von Domain-Adressen
6 7
Bei der Registrierung von Domains ist der Endkunde als Domain-Inhaber und Admin-C (administrativer Kontaktpartner) einzutragen. Der Domain-Inhaber kann alternativ eine andere Person beziehungsweise Firma als Admin-C benennen.
8
Sie sind lediglich der technische Verwalter (tech-c) sowie der Zonenverwalter der Nameserver (zone-c). Daraus folgt, dass Sie formgerechte KK-Anträge des Domain-Eigners unbedingt akzeptieren und der Domain-Übergabe zustimmen müssen. Dies gilt auch bei noch offen stehenden Forderungen oder ungeklärten Vertragsverhältnissen.
9 10 11
Selbstverständlich ist diese Regelung auch für die Gegenseite bindend. Allerdings sollten Sie überprüfen, ob der Endkunde tatsächlich als Domain-Eigner eingetragen ist. Es gibt einige schwarze Schafe, die Kunden-Domains wie eigene Firmen-Domains anmelden. In der Folge genügt ein Umzugswunsch des eigentlichen Domain-Kunden nicht. Falls sich die Gegenstelle weigert, wird Ihnen auch die Domain-Verwaltungsstelle nicht ohne weiteres helfen können (meist nur über einen Anwalt).
12 13 14
Beachten Sie weiterhin, dass im KK-Antrag neben der Domain zudem der Inhaber sowie der tech- und zone-c-Kontakt aufzuführen sind. Selbstverständlich ist der Antrag vom Domain-Inhaber oder dem Admin-C zu unterschreiben. Weiterhin ist der KK-Antrag nicht nur Ihnen, sondern auch dem bisherigen techund zone-c-Kontakt zuzustellen (Fax genügt). Es kommt vereinzelt vor, dass sich eine Firma weigert, trotz korrektem Eintrag des Endkunden als Admin-C und Domain-Eigner, der Übergabe zuzustimmen. In diesem Fall können Sie mit einem so genannten Late-Ack-Antrag vorgehen (verspätete Zustimmung), der zusammen mit dem KK-Antrag per Einschreiben mit Rückschein und mit einer angemessenen Frist (14 Tage reichen völlig aus) zuzustellen ist. Bei erneuter Übergabeverweigerung ist die Denic zu bitten, ohne Zustimmung des Mitglieds die Domain in Ihren Zugriffsbereich zu übertragen. Reichen Sie hierzu bei der Denic eine Kopie des Einschreibens mit Empfangsbestätigung sowie den KK-Antrag innerhalb von drei Monaten nach Stellung des KK-Antrages ein.
Rechtliche Hinweise und Verfahrensfragen zur Registrierung von Domain-Adressen
469
Abbildung 8.1 Ein formgerechter KK-Antrag
470
Bürokratisches
1 2
8.4
E-Mail-Lauschangriff macht Betreuung von knapp über 1 000 Kunden zu kostspielig!
3
Wer mit dem Gedanken spielt, in den Markt der Billig-Webspace-Anbieter einzusteigen, wird ab 1 000 Kunden mit der Verpflichtung konfrontiert, sämtliche E-Mails dieser Kunden inklusive der Header-Daten auf Anfrage dem Staatsapparat bereitzustellen. Eine derartige Abhörmaßnahme wird nach der Strafprozessordnung durch einen Richter oder den jeweils zuständigen Bundes- und Landesminister angeordnet und von Polizei-, Zoll- oder den VerfassungsschutzBehörden (berechtigte Stellen) durchgeführt.
4 5 6 7
Die Angelegenheit wäre technisch unproblematisch, wenn da nicht das kleine Detail wäre, dass die Übertragungstechnik dieser Daten von der RegTP zertifiziert und kontrolliert werden muss. Tatsächlich steht keine Open-SourceLösung bereit, sondern man muss mit mehreren tausend Euro für den Erwerb einer proprietären Hardware-Komponente rechnen. Hier empfiehlt es sich, mit dem Dienstleister oder dem Rechenzentrum Ihrer Wahl direkt über die Details zu sprechen: Eventuell können Sie bestehende Hardware »günstig« mitnutzen.
10
8.5
11
8 9
Spam nur auf ausdrücklichen Wunsch blocken!
E-Mails unterliegen dem Fernmeldegeheimnis, weshalb die Unterdrückung übermittelter Sendungen nicht zulässig ist. RBL-Listen dürfen somit nur auf ausdrücklichen Wunsch des Mailbox-Inhabers genutzt werden, um Spam bereits vor der Annahme zu verweigern. Wer dies nicht beachtet, macht sich nach §§ 206(2) und 303a StGB Strafbar, da man das Abweisen von Nachrichten ohne ausdrückliche Genehmigung des Empfängers als ein Unterdrücken auslegen muss. Wir sprechen hier nicht über ein Kavaliersdelikt, sondern über einen ernsten Gesetzesverstoß, der mit bis zu fünf Jahren Freiheitsstrafe oder einer empfindlichen Geldstrafe geahndet werden kann!
12 13 14
In der Praxis sollten Sie es dem Mailbox-Inhaber beispielsweise über ein Webinterface, das mit einem ausführlichen Infotext versehen ist, ermöglichen, die Nutzung von RBL-Listen optional zu aktivieren, aber auch zu deaktivieren. In der Voreinstellung müssen die RBL-Listen deaktiviert sein.
8.6
Fällt das Datenschutzrecht für den Zwang zur personenbezogenen Vorratsdatenspeicherung?
Der Bundesrat hat bereits im Mai 2002 den »Entwurf eines Gesetzes zur Verbesserung der Ermittlungsmaßnahmen wegen des Verdachts sexuellen Missbrauchs von Kindern und der Vollstreckung freiheitsentziehender Sanktionen« (Drucksache 275/02, siehe http://www.bundesrat.de/pr/pr118_02.html) im
Fällt das Datenschutzrecht für den Zwang zur personenbezogenen Vorratsdatenspeicherung?
471
Bundestag eingebracht. Darüber wurde bis heute noch nicht abschließend entschieden. Die bisher geltenden Regelungen des Datenschutzes werden von diesem Gesetzentwurf über den Haufen geworfen. Wenn es nach dem Bundesrat geht, dann müssen Zugangs-Provider und Hoster zukünftig sämtliche Kommunikationsdaten personenbezogen »für Zwecke der Strafverfolgung und der Gefahrenabwehr und für die Erfüllung der gesetzlichen Aufgaben der Verfassungsschutzbehörden des Bundes und der Länder, des Bundesnachrichtendienstes, des Militärischen Abschirmdienstes sowie des Zollkriminalamtes« in einer Vorratsspeicherung archivieren. Der wichtige Grundsatz der Datenvermeidung würde somit vollständig entfallen. Lediglich für die Nutzung der gesammelten personenbezogenen Daten gälten die bisherigen Einschränkungen und das zwingende Wahlrecht für den Besucher weiterhin. Allerdings bestünde gegenüber Strafverfolgungsbehörden kein Verweigerungsrecht. Sämtliche Daten müssten auf Wunsch selbst ohne Durchsuchungsbefehl, Gerichtsbeschluss oder sofort vollstreckbarem Verwaltungsakt der Behörde ausgehändigt werden. Es bleibt zu hoffen, dass Hoster nicht – ähnlich den aktuell herrschendem Bestimmungen zur E-Mail Überwachung – ebenfalls die gesamten Kosten für die Datensicherung selbst tragen müssen und dass die Übermittlung angeforderter Daten nicht derart umständlich und kostspielig wie beim Negativbeispiel des E-Mail-Lauschangriffs zu erfolgen hätte. Allerdings ist noch kein abschließender Entschluss gefasst worden, so dass Firmen, die eine Vorratsspeicherung betreffen würde, noch die Gelegenheit haben, sich gegen diese Pläne einzusetzen. Eine Möglichkeit wäre es, die Arbeit von Vereinen und Organisationen wie eco.de und Bitkom.org oder Initiativen wie die »Rote Karte« (http://www.datenschutzzentrum.de) tatkräftig zu unterstützen.
472
Bürokratisches
A Anhang Der schwerste Anfang ist der Anfang vom Ende. (Hans Helmut Dickow)
A.1
Wegweiser: Buch CD-Rom
Verzeichnis
Inhalt
Beispielskripte
Selfmade: Beispiel für Backup (Nutzdaten) ProFTPD Einmalpasswort und Traffic Verwaltung Optimierung der MySQL Datenbank Sicherheitstests für PHP und JSP Beispiel zur automatisierten Erstellung von Digest Passwörtern für .htaccess (htpasswd)
Debian
Lesenswerte Dokus – inklusive umfangreicher Referenz und Details zu Sicherheitsfragen.
Linux
Meine Paketfilter-Regeln (iptables_activate.sh) Kernel Quellen zu Linux 2.4.29 und 2.6.10
Linux/linux-vserver
Enthält mit dem Linux-Vserver Verzeichnis die Quellen zu Kapitel 6.
SUSE
CD-Rom mini Install ISO
OpenBSD/36_install
Enthält neben Images für Installations-Disketten ebenfalls die Basiskomponenten für 3.6
OpenBSD
Enthält meine Paketfilter-Regeln (PF.CPNF) sowie eine kleine Paketauswahl inkl. bash, MySQL, Postfix und Tepatche – dem Helfer für das Einspielen von Security Updates ins Basis System
Src
Betriebssystemunabhängige Quellen und Skripte. Zu den unbekannteren Perlen zählen: pg_backup.sh (ausgefeiltes Shell Script zur Erstellung von PostgreSQL Backups) oder sipcalc-1.1.2 (berechnet IP-Adressräume und Subnetmasks).
Windows
FileZilla, PuTTY und PuTTY Tools, WinSCP
Tabelle A.1 Wegweiser durch die CD-ROM zum Buch.
Wegweiser: Buch CD-Rom
473
A.2
Glossar
ARPA Advanced Research Projects Agency ist eine Abteilung zur Forschungsförderung im Department of Defense (dem amerikanischen Verteidigungsministerium).
flow zu erzeugen. Am Ende des Datenflusses stehen die gewünschten Befehle, die nach einem erfolgten Buffer Overflow vom angegriffenen Programm ausgeführt werden.
Backdoor Der Begriff Hintertür ist sehr treffend gewählt. Die Aufgabe einer Backdoor besteht darin, möglichst unbemerkt einen Port für die direkte Kommunikation mit dem Opfer-Host aufzubauen. Eine Backdoor kann in einem Trojaner eingeschleust oder nach einer erfolgreichen Attacke geöffnet werden.
Common Gateway Interface (CGI) Schnittstelle zwischen Webserver und einer Programmiersprache wie Perl oder Phython. Im CGI-Verzeichnis des Webservers ist es über CGI möglich, entsprechend unterstützte Programmiersprachen zur Erzeugung dynamischer Webseiten zu verwenden.
Black Hat Black Hats sind bösartige Angreifer (im Volksmund meist als Hacker tituliert), die zumeist mehr als nur »eine Website austauschen« wollen. Ein Black Hat ist eher daran interessiert, unbemerkt zu bleiben, Daten zu stehlen oder den gekaperten Rechner als eine Angriffsplattform für andere Systeme zu missbrauchen.
Cracker Cracker sind fragwürdige Individuen, die Sicherheitsfunktionen wie den Kopierschutz einer Software oder Verschlüsselungsalgorithmen knacken. Häufig wird der Begriff Hacker für Angreifer verwendet, die auf fremde Server einbrechen. Dies ist so nicht richtig. Genau genommen sind damit BlackHats gemeint, die einen Server cracken. Anstelle von Hacker sollte also der Begriff Cracker verwendet werden.
Brute Force Bei einem Brute ForceAngriff wird versucht anhand eines Wörterbuches oder durch simples Ausprobieren verschiedenster Buchstabenkombinationen das Passwort für Dienste wie SSHoder FTP zu erraten. Sperren Sie den Root User-Namen für Logins, um Brute ForceAngriff zu vereiteln. Der Angreifer muss dann die zusätzliche Hürde eines vorhandenen Nutzernamens nehmen, bevor eine Brute Force-Attacke überhaupt erfolgreich sein kann. Siehe dazu Kapitel 3.1, OpenSSH. BSD Die Berkeley Software Distribution (UNIX-Paket der Berkely Universität). Aus BSD entstanden Free- und NetBSD. OpenBSD wurde – nach Differenzen innerhalb des FreeBSD Systems – von einem der FreeBSD-Gründer (Theo De Raadt) entwickelt. Buffer Overflow Programmfehler in der Bearbeitung von Variabeln können zu einem Buffer Overflow führen. Angreifer übermitteln eine bestimmte Länge an unsinnigen Daten, um einen Buffer Over-
474
Anhang
Daemon Bezeichnung für einen Hintergrundprozess, der ununterbrochen zur Verfügung steht, um auf Anfragen oder Ereignisse zu reagieren. Denial Of Service (DOS)-Attacke Bei diesem Angriff wird der Server mit Verbindungsanfragen überschwemmt. Irgendwann ist nicht mehr genügend Rechenleistung oder Bandbreite vorhanden, um weitere Anfragen zu beantworten. Die Folge ist ein scheinbarer Server-Ausfall. Um derartige Attacken erfolgreich zu gestalten, werden sie meist von vielen Rechnern gleichzeitig ausgeführt. Deshalb ist eine Verteidigung äußerst schwierig und bei gleichzeitigem Spoofing der Absenderadressen nahezu unmöglich. DeepLinks Externe Verweise auf Unterseiten einer Homepage oder direkte Downloadlinks. Kommerzielle Anbieter sehen DeepLinks nicht gerne und bestehen
manchmal sogar darauf, lediglich die Startseite zu verlinken. Sie haben übrigens keinen Rechtsanspruch darauf, Links zu externen Inhalten zu setzen, und können bei Nutzung von DeepLinks zudem verklagt werden. DSS/DSA Das amerikanische National Institute of Standards and Technology führte 1994 den Digital Signature Standard ein. Die Details finden Sie unter http:// www.itl.nist.gov/fi-spubs/fip186.htm. Der Standard beinhaltet den Digital Signature Algorithm, der von amerikanischen Behörden zur Signierung des Datenverkehrs verwendet wird und zur Authentifizierung des Absenders eingesetzt werden kann. Exploit Neben den bekannten Sicherheitslücken finden sich häufig Exploits, mit denen ein Angriff automatisiert werden kann. Häufig werden diese Code-Schnipsel mit Programmen verknüpft, die ganze IPAdressräume automatisiert absuchen und dem Angreifer bei Erfolg direkt eine RootShell zum geknackten Rechner öffnen. Fork Das Erzeugen weiterer Instanzen, auch Tochterprozesse genannt, wird als forken bezeichnet. Um mehrere Verbindungsanfragen gleichzeitig bearbeiten zu können, erzeugen Programme wie der Apache Webserver oder die MySQL-Datenbank mehrere Tochterprozesse. GNU Kürzel für Gnu is Not UNIX. Neben der Anspielung auf einen alten Insider-Witz ist dies zudem ein Hinweis darauf, dass GNU(/Linux) kein UNIX-System im Sinne einer offiziellen Zertifizierung ist. UNIX darf sich ein System erst nennen, wenn es von X/Open kostenpflichtig überprüft und für standardkonform befunden wurde (http://www.unix-systems.org). GNU (L)GPL Die GNU General Public License ist wohl die bekannteste und meist gewählte Lizenz für freie Software-Projekte. Sie erlaubt freie Nutzung und Weitergabe. Veränderungen sind ausdrücklich erlaubt, müssen jedoch veröffentlicht werden. Die LGPL (Lesser GPL) sieht neben der
BSD License einen solchen Passus übrigens nicht vor, sondern erlaubt die kommerzielle Nutzung und Erweiterung ohne Verpflichtung, die Code-Zeilen selbst zu veröffentlichen. Hacker Ursprünglich ist mit einem Hacker ein talentierter Programmierer gemeint, der Quellcode flüssig und schnell in die Tastatur »einhackt«. Heute verstehen die meisten unter einem Hacker jedoch den als Cracker zu bezeichnenden Angreifer, der sich Zugang auf fremde Server verschafft. IETF Die Internet Engineering Task Force ist die Vereinigung zur Definition von Internet-Standards. In den RFC-Dokumenten können Sie die Details zu den einzelnen Standards der Internet-Protokolle nachlesen. Inodes Die Daten einer Computer-Festplatte sind nicht in Ordnerhierarchien aufgeteilt, wie die grafische Oberfläche (sowie die Konsole) suggeriert. Eigentlich sind Ordner ebenfalls nichts anderes als Dateien, die anstelle von echten Daten lediglich Verweise (Inodes) auf die eigentlichen Files enthalten. Deshalb ist es einerseits möglich, eine »gelöschte« Datei wiederherzustellen. Solange der Sektor nicht auf der Festplatte überschrieben wird, muss ja nur der InodeVerweis wiederhergestellt werden. Ext2 FS bietet sich für diese Aufgabe recover an. Andererseits ist das »Verschieben« von sehr großen Dateien innerhalb derselben Partition sofort erledigt, da schließlich nur der Verweis aus einer Ordnerdatei gelöscht und in eine andere eingefügt werden muss. MS-IIS Das Kürzel MS-IIS steht für Microsoft Internet Information Server und stellt das kommerzielle Redmonder-Pendant zu Apache dar. RFC Kürzel für Request for Comment. Die IETF legt in RFC-Dokumenten offene Internet-Standards fest. Unter http://www.faqs.org/rfcs/ oder http://www. hio.hen.ne/rfc/ können Sie
Glossar
475
sich über die RFC-Dokumente in die Protokolldetails zu TCP/IP, SMTP, IMAP etc. einarbeiten. Rootkits Rootkits setzen auf KernelEbene ein, um Aktivitäten von BlackHats in Logfiles und in Systemausgaben zu verstecken. Über Rootkits können somit Dateien vor dem Administrator versteckt werden – allerdings können Rootkits ausschließlich im kompromittierten System unbemerkt ihre Arbeit verrichten – wenn Sie von einem CD-Rettungssystem booten und eine aktuelle AIDE-Datenbank auf das kompromittierte System ansetzen, werden Sie das Rootkit und veränderte Systemprogramme schnell entdecken. Eine weitere Hilfe, um Rootkits aufzuspüren, ist das unter Linux und OpenBSD einsetzbare chkrootkit (http://www.chkrootkit.org). Sandbox Eine Sandbox ist ein »Käfig« innerhalb eines Servers, in dem Software sicher ausgetestet werden kann. Programme die chrooted oder jailed ausgeführt werden, sind ohne Root-Rechte nicht in der Lage aus Ihrem »Gefängnis« auszubrechen oder Zugriff auf die eigentlichen Server-Daten zu erhalten. Script Kiddies Script Kiddies werden von Black Hats und White Hats belächelt. Tatsächlich wird unter einem Script Kiddie lediglich ein unbedarfter Anwender verstanden, der sich ausschließlich über Exploits (gänzlich ohne eigenes Fachwissen) Zugang zu einem System verschafft. Dennoch sind Script Kiddies alles andere als ungefährlich – sicherlich gelingen dieser Gruppe die meisten erfolgreichen Angriffe, da sie die neusten Exploits automatisiert auf größere IP-Adressbereiche loslassen. Leider findet sich häufig ein Opfer-Host, dessen Administrator die entsprechende Sicherheitslücke noch nicht gestopft hat. Security by obscurity Security by obscurity beschreibt eine Maßnahme, um Attacken zu erschweren, indem Angreifern möglichst wenig Informationen über laufende Dienste (Versionsnummer und Typ) sowie zum genutzten Betriebssystem
476
Anhang
bereitgestellt werden. Selbstverständlich schützt das Unterdrücken der Versionsnummer und des Namens des Programms nicht vor Exploits. Angreifer müssen jedoch sämtliche Exploits für die verschiedenen Programme und Versionen durchspielen, um erfolgreich zu sein. Allerdings gibt es dafür Automatismen, die dem Cracker diese Arbeit deutlich erleichtern. Scanner Netzwerk-Scanner suchen nach genutzten Serverports, und manche sind wie beispielsweise Nessus zudem in der Lage, das genutzte Betriebssystem zu ermitteln und Schwachstellen automatisiert aufzudecken. Sniffer Sniffer können im Promiscous Modus sämtlichen Netzwerkverkehr des Subnetzes abhören (sofern dies nicht durch einen hochwertigen Switch verhindert wird) und sind so in der Lage, ein im Klartext übertragenes FTP-Passwort abzufangen. Läuft ein Sniffer auf Ihrem Computer, dann ist es dem Angreifer möglich, Tastatureingaben direkt mitzuschneiden und so selbst verschlüsselte Passwörter rekonstruieren zu können. Spoofing Attacke, bei der IP-Absenderadressen gefälscht werden. So ist es möglich, Paketfilter zu umgehen, die lediglich eine bestimmte IP-Adresse für einen SSH-Login zulassen. Allerdings muss diese dem Angreifer natürlich bekannt sein. Weit häufiger wird Spoofing deshalb für DOS-Attacken eingesetzt. Hier wird ein Server mit Verbindungsanfragen von verschiedenen (gefälschten) IP-Absenderadressen überschwemmt, um so nacheinander freie Highports zu schließen. Für Linux siehe auch Syncookies. Unter OpenBSD werden belegte Highports per Zufallsprinzip freigegeben, wenn die Verbindung zur Gegenstelle nicht aufgebaut werden konnte, und keine weiteren Highports zur Verfügung stehen. UUCP Das UNIX to UNIX Copy Protocol wurde in »der Frühzeit« zum Datentransfer zwischen Server-Systemen verwendet. Prinzipiell handelt es sich um eine Art Ano-
nymous FTP mit Up- und Download in ein »sicheres« Systemverzeichnis. Daten die per UUCP auf den Rechner gelangen, sollten erst nach einem Umkopieren durch einen entsprechend privilegierten, lokalen Nutzer ausführbar sein. White Hats White Hats sind wie Black Hats ernst zu nehmende Angreifer. Allerdings betrachten White Hats sich selbst
gerne als die guten Jungs. Das Knacken eines Servers ist für sie in erster Linie eine Frage des Sportsgeists. Erfolgreiche Angriffe werden in der Regel nicht an die große Glocke gehängt (abgesehen von der Veröffentlichung eventuell gefundener, neuer Sicherheitslücken), und ein Schaden wird von White Hats ebenfalls nicht angerichtet. In Deutschland ist diese Form des Crackings übrigens verboten.
Glossar
477
A.3
Bibliografie
Administration P. Albitz & C. Liu, DNS und Bind, O'Reilly Bryan Costales, Eric Allman, Sendmail, O'Reilly Mike Feldmaier, FreeBSD 5, Computer & Literatur Volker Lendecke, Samba für UNIX/Linux-Administratoren, dpunkt Verlag Diverse, Linux im Windows Netzwerk, Franzis' Derek Vadala, Managing Raid on Linux, O'Reilly Programmierung Diverse, Programmieren mit Perl, O'Reilly Helmut Herold, AWK und SED, Addison-Wesley Ulrich Kaiser, C/C ++, Galileo Computing Michael Kofler, MySQL, Addison-Wesley Alexander Mayer, Shell-Programmierung in UNIX, Computer & Literatur Bill McCarty, PHP 4 IT-Tutorial, Mitp Thomas Theis, Einstieg in Python, Galileo Computing Christian Ullenboom, Java ist auch eine Insel, Galileo Computing Sicherheit Anonymous, Linux hacker's guide, Markt & + Technik Wolfgang Barth, Das Firewall Buch, SUSE PRESS Ralf Spenneberg, Intrusion Detection für Linux-Server, Markt + Technik Verschiedenes Ben Marx, Linux Manager Guide, SUSE PRESS Glyn Moody, Die Software Rebellen, Linux Magazin Linus Torvalds, Just For Fun, Hanser
478
Anhang
A.4
Linkliste
Allgemeine Links und Organisationen Bundesamt für Sicherheit in der Informationstechnik: www.bsi.de Chaos Computer Club – eine galaktische Gemeinschaft von Lebewesen, unabhängig von Alter, Geschlecht und Rasse sowie gesellschaftlicher Stellung, die sich grenzüberschreitend für Informationsfreiheit einsetzt und mit den Auswirkungen von Technologie auf die Gesellschaft und den Menschen beschäftigt und das Wissen um diese Entwicklung fördert: http://www.ccc.de/ Chaos Radio – Informationsangebot des Chaos Computer Club Berlin e.V. (CCCB): http://chaosradio.ccc.de/ Internet Engineering Task Force (IETF): http://www.ietf.org Linux Standard Base (LSB): http://www.freestandards.org Free Software Foundation Europe: http://www.fsfeurope.org Bezugsquellen (Allgemeine Downloads) Freshmeat: http://www.freshmeat.net Linuxberg (Tucows): http://www.linuxberg.com Sourceforge: http://sourceforge.net (Online-)Magazine, Dokus und Co. FreeX: http://www.cul.de/freex.html Kritische Informatik – Informationen und Gedanken zu freien UNIX Derivaten: www.kritische-informatik.de Linux Enterprise: http://www.linux-enterprise.de The Linux Documentation Project: http://www.tldp.org Linux Magazin: http://www.linux-magazin.de Pro Linux: http://www.pro-linux.de OpenBSD Journal: http://www.undeadly.org Radio Tux. Kein Online-Radio, sondern Downloadmöglichkeit einzelner Sendungen mit Informationen zu und über Linux: http://www.radiotux.de Seiten rund ums Thema Sicherheit Insecurity (Bugtraq Mailinglistenarchiv): http://lists.insecure.org Cert: http://www.cert.org/advisories/ Nessus, Plug-In-Verzeichnis: http://cgi.nessus.org/plugins/
Linkliste
479
Security Focus: http://online.securityfocus.com Security Tracker: http://www.securitytracker.com Snort: http://www.snort.org Pro-Linux: Sicherheitsservice: http://www.pl-forum.de/security/ Die wichtigsten Linux und BSD- Systeme Adamantix: http://www.trustedlinux.org Debian: http://www.debian.org Fedora: http://fedora.redhat.com Gentoo: http:/www.gentoo.org Knoppix (Linux auf CD-Rom): www.knopper.net/knoppix/ Linux from Scratch: www.linuxfromscratch.org Mandrake: www.mandrakelinux.com/de/ Owl (Fokussierung auf Sicherheit): www.openwall.com/Owl/de/ Red Hat: http://www.RedHat.de Slackware: http://www.slackware.org SUSE: http://www.suse.de Darwin: developer.apple.com/darwin/ FreeBSD: http://www.de.freebsd.org/de/ NetBSD: http://www.netbsd.org/de/ OpenBSD: http://www.openbsd.org/de/
480
Anhang
Index $PATH 89 ./config 101 ./configure 101 .profile 90 /etc/boot.conf 93 /etc/hostname.interfacename 98 /etc/init.d 106 /etc/login.defs 81 /etc/mygate 99 /etc/netstart 98 /etc/network/interfaces 97 /etc/passwd 81 /etc/rc.conf 108 /etc/rc.local 108 /etc/resolv.conf 100 /etc/shadow 81 /etc/sysconfig/network 97 /etc/sysconfig/network/routes 98 ~/.profile 90 4.2BSD 33
A
Abhängigkeiten 102 add net 99 Admin-C 469 administrativer Kontaktpartner 469 Advanced Intrusion Detection Environment 399 AIDE 399 alias 90 Anbieterübersicht 442 anoncvs 361 Apache 139 AddDescription 156 Alias 152 Allow from 159 AllowOverride 156 Auth 160 AuthGroup 162 CustomLog 167 Deny from 159 DirectoryIndex 152 DocumentRoot 150 Dynamische Module 143 ErrorCodes 166
ErrorDocument 166 ExecCGI 153 FancyIndexing 155 Fehlermeldungen 166 FoldersFirst 156 Grundkonfiguration 147 htdigest 161 htpasswd 161 Icons 156 IgnoreCase 156 Includes 153 Indexes 154 IndexIgnore 155 IndexOptions 155 listen 149 LoadModule 143 LogFormat 167, 169 mod_access 159 mod_auth 159 mod_auth_digest 159 mod_cgi 183 mod_logio 170 mod_php → s. PHP 185 mod_suexec 185 MultiViews 155 Optimierung 149 Options 153 require group 163 require user 160 Secure Socket Layer 163 ServerAdmin 148 ServerName 148 ServerSideIncludes 153 ServerSignature 148 ServerTokens 148 Shared Module 143 SSI 153 SSL 163 SSL-Zertifikat 165 SuppressDescription 156 SymLinks 153 VersionSort 156 VirtualHost 151 XBitHack 154 apt/sources.list 37
Index
481
apt-get 39 Arbeitsspeicher Überwachung 301 ARPA 474 at 275 atactl 347 Ausführrecht 77 Ausgabeumleitung 86 Automation 306 Automatische Dateinamenerweiterung 84 awk 67
B
Backbone 97 Backdoor 474 Backup 328 Backup → s. Nutzdaten 332 Bandbreite 293, 296 Bastille 392 Befehlshistorie 84 Befehlsverknüpfungen 88 Beispielskripte 328 Bit 57 Black Hat 474 Boot 33, 92, 118, 348 boot 90 boot.conf 93 Bootable-Flag 33, 92, 118, 348 Bootloader 90 Broadcast 96 Brute Force 474 BSD 474 BSD Process Accounting 111, 113 Buchführungspflicht 448 Buffer Overflow 474
C
cat 56 cfgmaker 296 CGI Absicherung 185 Sicherheitshinweise 185 suExec 185 CGI → s. Common Gateway Interface (CGI) 183 Character-Devices 112 chgrp 80 chmod 53, 77
482
Index
chown 80 chpasswd 81 Chroot 388 Common Gateway Interface (CGI) 183, 474 config 101 configure 101 Connection tracking 111 Courier-IMAP 255 authmysqlrc 256 mkimapdcert 257 mkpop3dcert 257 SSL 257 CPU-Last 298 CPU-Temperatur 303 Cracker 474 Cron 275 Cron-Jobs 276 crontab 276 Cursor-Befehle 85
D
Daemon 474 date 288 Dateigrößen 57, 297 Dateinamenerweiterung 84 Dateirechte 53, 77 De Raadt, Theo 20, 474 DeepLinks 474 Default Policy 366 Deinstallation 105 delete net 99 Denial Of Service (DOS)-Attacke 474 Dennis Ritchie 18 dependencies 102 Dezimalsystem 57 df 69 dig 133 digest 414 disklabel 33, 47 DMA 49, 301, 303 DNS 129 chroot 136 expire 132 IN A 133 IN NS 133 Mail-Exchanger 134 MX-Records 134 named.conf 131, 135
negative caching time to live 132 refresh 132 retry 132 Seriennummer 132 Slave-Nameserver 136 SOA 132 Start Of Authority 132 Time to live 132 TTL 132 Zonenverwalter der Nameserver 469 Domain Name Server → s. DNS 129 Domainrecht 456 Domains registrieren 137 dpkg 39 dselect 35 DSS/DSA 475 du 69 Dualsystem 57 dump 74
G
Gateway 97, 99 Generic Boot Loader for Linux 91 Gesetzliche Regelungen 449 Gewerbeanmeldung 447 Gewerbesteuer 448 GNU 19, 475 GNU (L)GPL 475 GNU/Linux 19 grep 66 groupadd 81, 84 groupdel 81 Gruppe 80 Gruppenquoatas 303
H
echo 56 Eigentümer 80 Eingabeumleitung 86, 276 Eins und Null 57 Emacs 58 exit 62 Exploit 475 ext2 33, 112, 115 ext3 112, 115
Hacker 475 harden-suse 392 Hardlinks 70 Hardware 24 hdparm 49, 50 head 56 Hexadezimalsystems 57 Highport-Bereich 362 Hintergrundprozess 88 Hochverfügbarkeit 342 hosts.allow 390 hosts.deny 390 HURD 19 hwclock 288
F
I
E
fdisk 33, 46, 92, 118, 348 Festplatte 344 fetchipac 291 FHS 20 Filesystem 33, 112, 115 Filesystems Hierarchy Standard 20 File-Transfer-Protokoll 259 Finanzamt 447 find 63, 64 finger 72 Firewall 362 Fork 475 Free-Software-Foundation 19 fsck 74 FSF 19 fstab 74 FTP-Server 259
ICMP 363 IDS 403 IETF 475 Ifconfig 96 IHK 448 IMAP 222 Impressum 449, 450 Industrie- und Handelskammer 448 inetd 390 Initial RAM-disk 350 initrd 91, 350 Inodes 475 insmod 106 Installationspfade 101 Integritätsprüfung 399, 418 interfaces 97 Internet Mail Access Protocol 222
Index
483
Internet Superserver 390 Internet-Control-Message-Protocol 363 Intrusion-Detection-System 403 IP tables support 111 ipac-ng 290 ipacsum 291 IPA-IP 292 ipastat 292 ipfctl 292 iptables 365 ISS 394
J
Jakarta-Tomcat 189 JAR 189 Java-Development-Kit 190 JavaServer Pages 189 JavaServlets 189 JDK 190 Jobsteuerung 275 Journaling-Filesystem 34 JSP 189 JSSE 189
K
Ken Thompson 18 Kernel 109 kill 68, 69 KK-Antrag 137 Konsole 83
L
label 91 lastlog 72 Leserecht 77 lilo 90 lilo.conf 91 Linus Torvalds 19 Linux Standard Base 20, 106 Linux-Bootloader 90 Linux-Loader 91 ln 32, 70 lo 96 Loadbalancing 341 locate 63 Logcheck 408, 413 Logfile-Analyse 407 Logrotate 284
484
Index
Logsentry 414 Logsurfer 408 logtail 413 Lokale IP-Adressen 94 lokales Netz 94 Loopback device 96, 111, 114, 349, 367 ls 53 LSB 20 Lüfterdrehzahl 303
M
Mail Transfer Agent 222 Mail User Agent 222 Mailserver 222 make 101 make bzImage 113 make install 101 make menuconfig 109 make uninstall 105 Makefile 101 Master Boot Record 90, 93 MBR → s. Master Boot Record 90, 93 MIB-Elemente 295 MIB-Tree 294 MINIX 19 mkdir 53 mkisofs 348 mmv 55 modprobe 95 mount 31, 34, 74, 444 mount -o remount 75 Mount Point 74 mpack 287 MRTG 296 Inbetriebnahme 302 indexmaker 302 LoadMIBs 297 MS-IIS 475 MTA 222 MUA 222 Multi Router Traffic Grapher 296 Multiword-DMA 50 mv 54 MySQL 197 Administration 200 Backup 205 create database 201 drop database 201
flush privileges 200 GRANT 201 Logging 206 mysqldump 205 optimize table 204 Privilegien 203 revoke 202 skip-grant-tables 206 Zugriffsprüfung 202
N
Nameserver 94 nano 58 Nessus 394 nessus-adduser 395 nessus-update-plugin 394 Netzwerk-Scanner 394 Plugins 395 Netmask 96 netstat 73 Network device support 112 Network packet filtering 111, 114 Netzwerkeinstellungen 37, 94 Netzwerk-Interface 95 Netzwerkkarte 94 Netzwerk-Scanner 394 Newsyslog 286 nice 339 nmap 397 ntpdate 288 Nutzdaten 332
O
Oktalsystem 57 OpenSSH 121 AllowGroups 122 AllowUsers 122 chroot 126 PasswordAuthentication 122 PermitEmptyPasswords 122 PubkeyAuthentication 123 Rhosts 122 ssh-keygen 123 openssl 163 other 91
P
Packet filtering 111 Paketfilter 362 auth 376 DNS 376 Fragmentation Needed and Don't Fragment was Set 378 FTP 372 http(s) 371 ident 376 Logging 368, 381 Mailserver 375 Parameter Problem 380 SSH 370 Timeserver 378 PAM 339 Partitionen 31, 34, 74, 444 pass 74 passwd 81 PATH 89 pciide 49 Pen 341 Perl 184 Perl-Programmierung 314 Ablaufsteuerung 317 Arrays 316 CGI-Scripte 270, 325 Dateien lesen und erstellen 322 DBD 323 DBI-Modul 323 flock() 322 Funktionen 318 Hashs 316 Kommunikation mit MySQL 323 Mathematische Funktionen 317 open() 322 Reguläre Suchmuster 319 Substitution 319 system () 322 Systembefehle absetzen 322 Variablen 314 pf 367 Pflichtangaben 449 Pflogsumm 252 PHP 175 disable-functions 180 file-uploads 182 magic-quotes-gpc 182
Index
485
max-execution-time 180 open-basedir 179 php_admin_flag 179 php_admin_value 179 phpinfo() 178 register_globals 181 safe-mode 177, 179 phpMyAdmin 207 pico 58 pidof 68 PIO-Modus 50 pkg_add 49 pkg_delete 49 pkg_info 49 Pluggable Authentication Modules 339 POP3 222 POP-before-SMTP 233 Portscans 398 Post Office Protocol 222 Postfix 223 2bounce_notice_recipient 250 access 231 aliases.db 226 allow_untrusted_routing 250 always_bcc 250 append_at_myorigin 250 append_dot_mydomain 250 auxprop 240 bounce_size_limit 250 canonical 230 Catchall 230 Chroot 249 default_destination_recipient_limit 250 default_recipient_limit 250 disable_dns_lookups 251 empty_address_recipient 251 error_notice_recipient 251 Lookup-Tables 229 mail_owner 251 mailbox_size_limit 251 main.cf 225, 244, 249 master.cf 248 maximal_backoff_time 252 maximal_queue_lifetime 251 message_size_limit 251 minimal_backoff_time 252 mydestination 225 mydomain 225
486
Index
myhostname 225 mynetworks 226 myorigin 226 MySQL 243 MySQL-Tabellen 245 MySQL-Zugangsdateien 246 newaliases 227 nqmgr 249 permit_sasl_authenticated 238 Pflogsumm 252 POP-before-SMTP 233 postconf 225, 249 postfix reload 228 postfix start 227 postmap 229 qmgr 249 qmgr_fudge_factor 226 qmgr_message_active_limit 226 qmgr_site_hog_factor 226 realm 238 Realtime Blacklists 241 relocated 230 saslauthd 239 sasldb 238 sasldb2 240 saslpasswd 238 saslpasswd2 240 SMTP 227 smtp_bind_address 252 smtp_destination_concurrency_limit 252 smtpd_banner 226 smtpd_recipient_restrictions 229, 234, 244 smtpd_sender_restrictions 232 Spam Blockade 241 strict_rfc8212_envelopes 252 Traffic-Auswertung 252 transport 231 User unknown in local recipient table 231 virtual 230, 244 PostgreSQL 197, 208 alter user 212 Cannot allocate memory 210 Cluster 209 create database 214 CREATE USER 213 createdb 214 createuser 213
Datenbank-Cluster 209 drop database 214 DROP USER 214 dropdb 214 dropuser 214 initdb 209 pg_ctl 212 pg_dump 218 pg_hba.conf 212 pg_restore 218 postmaster 209 psql 210 psql – interne Befehle 211 prefix 102 Presserecht 451 Processor Family 110, 113 profile 90 ProFTPD 260 AllowOverwrite 263 Anonymous 262 DefaultRoot 263 DefaultServer 261 Directory 262 Global 262 Group 263 Konfiguration 260, 373 limit 263 MaxInstances 261 Port 261 RequireValidShell 263 ServerIdent 261 ServerType 261 SQLAuthenticate 264 SQLAuthTypes 264 SQLConnectInfo 264 SQLDefaultGID 265 SQLDefaultUID 265 SQLLog 264 SQLMinUserGID 265 SQLMinUserUID 265 SQLUserInfo 264 SQLUserWhereClause 264 TimeoutLogin 261 TimeoutNoTransfer 261 Umask 263 unable to chdir 268 unrecoverable backend error 268 User 262
VirtualHost 262 xferlog 272 Prozessor-Typ 110, 113 Prozessverwaltung 67 Prüfsummenvergleich 103 ps 67 ptrace 393 PuTTY 125 pwd 52 pwgen 327 Python 184
Q
Quota 112, 115, 303 automatisierte Infomails 305 Beschränkungen 303 edquota 304 Hardlimits 303 Partition vorbereiten 304 quotacheck 304 quotaoff 304 Regeln 303 repquota 305 Softlimit 305 warnquota 305
R
Raid-Systeme 351 RAM disk Support 111, 114 RAM-Disk 349 read-only starten 346 read-only starten (BSD/Red Hat) 346 Rechtesystem 53, 77 Registrierung von Domains 137 RegTP 447 Reguläre Suchmuster 319 Regulierungsbehörde für Telekommunikation und Post 447 ReiserFS 33 remount 75 renice 339 resolv.conf 100 Ressourcen 338 Rettungssystem 348 RFC 475 Ritchie, Dennis 18 rm 54 Rootkits 476
Index
487
route 98 route del 98 route show 99 Router 94, 97 RPM 43, 44 rsync 331 runlevel 107
S
S.M.A.R.T. 346 Saint 394 Sandbox 476 Satan 394 Scanner 394, 476 Schreibrecht 77 scp 125 Script Kiddies 476 Scriptbeispiele 328 SCSI support 111, 114 Secure Copy 125 Secure-FTP 125 Secure-Shell 121 Security by obscurity 476 sed 313 Self-Monitoring Analysis and Reporting Technology System 346 Set-GID 77 Set-UID 77 sftp 125 SGID 80, 391 shadow 81 Shell 52 Shell-Programmierung 307 Ablaufsteuerung 310 Arrays 309 case 312 for 310 if-then-else 311 let 311 Positions-Variablen 308 shift 310 typeset 311 Variablen 307 Vergleichsoperatoren 312 while 310 Sicherheitsinformationen 416 Siege 337
488
Index
Simple Message Transfer Protocol 222 Simple Network Message Protocol 293 sipcalc 95 Slave-Nameserver 136 Slice 46 smartctl 347 smartd 347 SMTP 227 Sniffer 476 SNMP 293 snmpget 294, 295 snmpset 294 snmptranslate 295 snmpwalk 294, 295 Snort 403 Softlinks 32, 70 sources.list 37 Speicherplatz beschränken 303 Spoofing 476 SquirrelMail 258 SSH 121 Standardeingabe 86 Startscripte 106 Stateful Inspection 363, 366 stderr 86 stdin 86 stdout 86 Sticky-Bit 77, 78 Stream Editor 313 Stress 336 su 62 Suchmuster 66 sudo 82 suExec 185 SUID 31, 80, 391 Support 25 SUSEconfig 43 Swap-Speicher Überwachung 301 symlink 71 Symmetric multi-processing support 110, 114 sysconfdir 102 Syslogd 278 Facility 280 Priority 280 System-Account 81
System-Load 300 Systemüberwachung 289 Neustart 289 Systemzeit 288 Systrace 382 Systrace support 111, 113
T
tail 56 tar 100, 333, 335 tasksel 35 TCP 362 TCP syncookie support 111, 114 TCPD 390 TCP-Wrapper 390 tech-c 469 technische Verwalter 469 Telnet 121 Tepatch 361 Theo De Raadt 20, 474 Thompson, Ken 18 Time-Server 288, 289 Tomcat 189 Absicherung 194 ajp13 196 catalina.policy 195 Context path 192 docBase 192, 193 error-code 194 error-page 194 Fehlermeldungen 194 Host name 192 JAR 189 JAVA_HOME 191 JDK 190 JkUriSet 196 JSSE 189 Konfiguration 191 mod_jk2 195 No Context configured 193 Roles 192 Runtime.getRuntime() 194 Security-Manager 195 server.xml 193 start 191 tomcat-users.xml 192 WAR 189 workers2.properties 196
top 68 Torvalds, Linus 19 Traffic Analyse 290 Transport-Control-Protocol 362
U
Übersicht der Beispielskripte 328 UDP 363 Ultra-DMA 50 Umgebungsvariablen 89 Umleitung von Ein- und Ausgabe 86, 276 umount 31, 34, 74, 444 Umsatzsteuerpflicht 447 unprivilegierte Ports 362 updatedb 63 update-modules 96 uptime 300 useradd 81, 84 User-Datagramm-Protokoll 363 userdel 81, 82, 84 usermod 81, 82, 84 Userverwaltung 81, 84 UUCP 476
V
Vergleich von Prüfsummen 103 Vertrauenswürdigkeit von Programmpaketen 103 vi(m) 58, 59 vimtutor 59 Virtual memory file system support 112 Vollbackup 333 Vserver build 425 chbind 429 foo.conf 427 ONBOOT 430 rebootmgr 431 vhalt 431 vreboot 431 vrpm 432 vunify 432
W
WAR 189 Webalizer 169 HistoryName 173 White Hats 477
Index
489
whoami 62 WinSCP2 126
X
X/Open 18 xferlog 272
Y
YaST 42, 43 Yast Online Update 359 you 359
Z
Zahlensysteme 57 zap 69 zone-c 469 Zonenverwalter der Nameserver 469 Zugriffsrechte 53, 77
490
Index