Die aktuellen Nachrichten lassen kaum einen Zweifel zu: Microsofts Windows-Betriebssysteme scheinen sehr viren- und wurmanfällig zu sein. Linux-Anwender dürfen in den meisten Fällen gelassen auf solche Hiobsbotschaften reagieren; ihr Schaden beschränkt sich darauf, dass das höhere Verkehrsaufkommen im Internet auch sie belastet.
Schadenfreude ist hier aber fehl am Platz: Vielleicht gibt es auch bei Linux und seinen Anwendungen ähnlich fatale Sicherheitslücken, die noch nicht erkannt wurden oder in zukünftigen Versionen erst programmiert werden. Gerade der erfolgreiche Angriff auf die zentralen Debian-Server [1] zeigt, dass sich selbst erfahrene Administratoren nicht gegen alle Sicherheitslücken verteidigen können. Daher sollte jeder Linux-Anwender grundlegende Kenntnisse über die Sicherheit seines Systems, das Erkennen von Angriffen und Einbrüchen und die Reaktion darauf erwerben. Dieser Artikel zeigt, wie sich die Gefahr, Opfer eines Angriffs zu werden, gering halten lässt.
Regelmäßige Updates
Viele Hacker veröffentlichen die von ihnen gefundenen Sicherheitslücken, oft in Mailinglisten [2,3]. Häufig erhalten die Anwendungsprogrammierer und die Linux-Distributoren diese Informationen bereits im Vorfeld, so dass sie meist recht zeitnah einen Patch und Updates zur Verfügung stellen.
Am einfachsten und besten schützen sich Linux-Anwender daher vor Einbrüchen, indem sie ihr System auf dem aktuellen Stand halten. Fast jede Distribution bietet hier Update-Möglichkeiten an, die der Benutzer mit Hilfe des Cron-Daemons [4] auch automatisieren kann. Fedora aktualisiert der Anwender mit yum update; Debianer verwenden zum Beispiel die Befehle
/usr/bin/apt-get update -q -y /usr/bin/apt-get upgrade -q -y
Dabei bringt der apt-get update-Befehl die Paketlisten der Distribution auf den aktuellen Stand. Dieser Schritt sollte vor jedem Upgrade erfolgen. Die Option -q unterdrückt unnötige Ausgaben ("quiet") auf dem Bildschirm; -y beantwortet alle auftretenden Fragen automatisch mit Ja ("yes"). Der Befehl apt-get upgrade spielt anschließend die neuesten Versionen aller installierten Pakete ein.
In dieser Form eignen sich beide Kommandos auch für einen automatischen täglichen oder stündlichen Aufruf mit dem Cron-Daemon. Dazu erzeugt der Administrator eine kleine Datei /etc/cron.daily/aktualisierung, in die er die zwei Zeilen einträgt. Nachdem er die Datei mit
chmod 755 /etc/cron.daily/aktualisierung
ausführbar gemacht hat, ruft sie der Cron-Daemon automatisch auf.
Ein sauber gepatchtes System bietet mehr Sicherheit als jede Firewall und jeder Virenscanner: Sein Verwalter muss dann nur neue, noch unbekannte Sicherheitslücken fürchten.
Minimalismus
Der zweite Schritt auf dem Weg zu einem nicht angreifbaren Rechner besteht darin, alle nicht benötigten Dienste abzuschalten. Erfreulicherweise aktivieren moderne Linux-Distributionen nicht mehr per Default sämtliche installierten Dienste.
Will der Administrator die aktuell laufenden ermitteln, so stehen hierfür zwei Möglichkeiten zur Wahl: Er kann lokal den Befehl lsof -i absetzen oder mit nmap den Rechner von außen scannen. Der Befehl lsof zeigt die offenen Dateien auf einem Linux-Rechner an. Getreu dem Unix-Spruch "Alles ist eine Datei" werden auch Netzwerkverbindungen als Dateien verstanden. Mit der Option -i zeigt lsof alle Internet-Verbindungen an; Listing 1 zeigt ein Beispiel.
Listing 1
Beispielausgabe von
lsof -i[root@kermit root]# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME ntpd 882 ntp 4u IPv4 2788 UDP *:ntp ntpd 882 ntp 5u IPv4 2789 UDP localhost:ntp sshd 942 root 3u IPv4 2858 TCP *:ssh (LISTEN) master 1019 root 11u IPv4 2972 TCP *:smtp (LISTEN) cupsd 1569 root 0u IPv4 3720 TCP localhost:ipp (LISTEN) cupsd 1569 root 2u IPv4 3721 UDP *:631
Die erste Spalte verrät den Befehl, der die Netzwerkverbindung geöffnet hat. Rechts daneben steht seine Prozessnummer; die dritte Spalte enthält den Namen des Benutzers, mit dessen Rechten der Dienst läuft. Interessant wird es in den letzten beiden Spalten: Unter der Überschrift NODE steht das Protokoll, das der Dienst für seine Kommunikation mit der Außenwelt benutzt (TCP oder UDP), unter NAME verrät lsof die IP-Adresse und den Port des Dienstes. Dabei setzt das Programm sowohl für die IP-Adresse als auch für den Port die entsprechenden Klartextnamen aus den Dateien /etc/hosts und /etc/services ein. Dieses Verhalten lässt sich mit den Optionen -n ("no host names") und -P ("no port names") unterdrücken.
Auf dem Rechner in Listing 1 sind die folgenden Dienste aktiv: ntpd, sshd, master und cupsd. Hierbei handelt es sich um einen Zeitsynchronisationsserver, den Secure-Shell-Server, den Master-Server des Mail-Servers Postfix und den Cups-Druck-Server. Sobald als Adresse in der letzten Spalte localhost (oder 127.0.0.1) erscheint, lässt sich dieser Dienst nicht von außen, sondern nur lokal erreichen. Am interessantesten sind also die erste und die letzte Spalte der Ausgabe. Dabei kann der lsof-Befehl aber nicht erkennen, ob eine Firewall diese Dienste zusätzlich schützt.
Hierzu dient der Befehl nmap. Er ist in der Lage, die offenen Ports von außen zu erkennen. Jeder offene Port weist auf einen laufenden Netzwerkdienst hin. Anders als lsof überprüft nmap aber nicht, welcher Dienst auf diesem Port läuft, und gibt nur den wahrscheinlichen Service an. Um alle verfügbaren TCP-Dienste anzuzeigen, verwendet der Anwender den Befehl
nmap -sS IP-Adresse
.
Listing 2
-Beispiel
# nmap -sS kermit Starting nmap V. 3.00 ( www.insecure.org/nmap/ ) Interesting ports on kermit (192.168.0.202): (The 1594 ports scanned but not shown below are in state: closed) Port State Service 22/tcp open ssh 25/tcp open smtp Nmap run completed – 1 IP address (1 host up) scanned in 3 seconds
Im Beispiel aus Listing 2 lassen sich von außen nur der Secure-Shell-Server auf dem Port 22 und der Postfix-Mail-Server auf dem Port 25 erreichen. Der Cups-Druckserver, über den Listing 1 informierte, ist über TCP von außen nicht ansprechbar.
Die UDP-Dienste ermittelt die Option -sU anstelle von -sS. Dabei steht hinter dem -s der Scan-Typ. Ein U weist auf einen UDP-Scan hin, während ein S einen sogenannten TCP-Syn-Scan durchführt.
Im Falle eines UDP-Scans kann nmap den Zustand des Ports nicht einwandfrei ermitteln. Da das Programm in diesem Fall auch alle Ports, die nicht antworten, als offen kennzeichnet, kommt es zu einer verwirrenden Situation: Befindet sich eine Firewall vor dem gescannten Rechner, die diese Pakete verwirft, kennzeichnet nmap alle UDP-Ports als offen!
Nicht benötigte Dienste sollten rigoros abgeschaltet werden. Üblicherweise werden sie beim Startvorgang der Linux-Distribution aktiviert. Dabei gibt es grundsätzlich zwei unterschiedliche Methoden: Entweder setzt ein eigenes Startskript im Verzeichnis /etc/init.d den Dienst in Gang oder inetd bzw. xinetd übernehmen diese Aufgabe. Die beiden letztgenannten Dienste öffnen bereits bei ihrem Start den Port und starten erst bei Bedarf den eigentlichen Dienst.
Wie man die verschiedenen Dienste deaktiviert, unterscheidet sich von Distribution zu Distribution zum Teil stark, und selbst innerhalb einer Distribution führen viele verschiedene Wege zum Ziel. (Red Hat bietet zum Beispiel die Befehle chkconfig, ntsysv und redhat-config-services für diesen Zweck an.) Daher sei an dieser Stelle auf die Artikel [5] und [6] verwiesen.
Bei unbekannten Diensten hilft häufig der Befehl man Dienstname, um zu ermitteln, ob sie benötigt werden oder nicht. Für Dienstname setzt man das Kommando ein, das lsof anzeigt. Leider sind die Informationen in diesen Manpages nicht immer sofort verständlich.
Verfügt der Anwender über ein Handbuch zur Distribution, findet er über dessen Index häufig weitere Erläuterungen zum Dienst. Eine Suche auf Google hilft ebenfalls oft weiter. Schließlich spricht nichts dagegen, einfach mal auszuprobieren, was passiert, wenn der Dienst deaktiviert und der Rechner neu gebootet wird. In den seltensten Fällen führt dies zu einem instabilen Rechner.



