Druckversion | |||||||||||||||||
»Vertrauen ist gut - Kontrolle ist besser«. Jeder Netzwerker dürfte mittlerweile genügend Beispiele kennen, wie Dienste ausgenutzt, Sicherheitsbarrieren unterlaufen und Schäden durch böswillge Zugriffe von »außen« verursacht wurden. Wenn hoffentlich nicht am eigenen Netzwerk, so doch zumindest durch Artikel und Mundpropaganda. Ein einfach zu verwendende und dennoch recht effektive Vorsichtsmaßnahme gegen unberechtigten Zugriff auf lokale Dienste bietet der TCP-Wrapper, der mittlerweile etliche Internetdienste von der Außenwelt abschirmen sollte.
Abbildung 1: Arbeitsweise des TCP-Wrappers Die meisten Netzwerkdienste, die der lokale Rechner anbietet, werden nicht unmittelbar mit den Start des Systems ins Leben berufen, sondern erst, wenn tatsächlich eine Anforderung für sie eintrifft. Damit kein Verbindungswunsch eines Clients verschlafen wird, überwacht ein Internet-Dämon, meist der inetd, stellvertretend alle Ports der Dienste. Welche das konkret sind, erfährt der inetd aus den Dateien /etc/inetd.conf und /etc/services. Der inetd vermag nun den jeweiligen Dienst zu starten, sobald eine Anforderung an dessen Port anliegt und für einige Dienste, die zumeist als »sicher« gelten, wird dies auch so gehandhabt. Sobald der entsprechende Service aktiv ist, und der inetd ihm die bereits geöffnete Verbindung vererbt hat, legt der inetd sich zur Ruhe und wartet auf neue Arbeit... Im inetd selbst sind keinerlei Sicherheitsmechanismen implementiert. Deswegen wurde ein Filter geschaffen, der sich zwischen den inetd und den zu startenden Dämonen spannt. Der inetd startet nun nicht mehr den für den Port zuständigen Dienst, sondern den so genannten TCP-Wrapper »tcpd«, der den Programmnamen des Dienstes als Argument erhält. Der Name TCP-Wrapper ist etwas irreführend, da der Wrapper ebenso UDP-Ports überwachen kann. Der Wrapper arbeitet für Server und Client transparent, er verschwindet aus dem Hauptspeicher, sobald die Verbindung zwischen den beiden besteht. Zuvor jedoch protokolliert (syslogd) und überprüft er die Zulässigkeit des Zugriffs und betrachtet zunächst den Inhalt der Datei /etc/hosts.allow. Hier steht, welcher Dienst für welchen Rechner gestattet ist. Findet er dort eine den Dienst betreffende Zeile, kann er entscheiden, ob der Start des Serverdienstes erlaubt ist oder nicht. Fehlt ein passender Eintrag oder existiert die Datei nicht, schaut der Wrapper als nächstes nach einer Datei /etc/hosts.deny. Ist dort ein entsprechender Eintrag vorhanden, verfährt der Wrapper analog zur /etc/hosts.allow, nur dass, wenn der zugreifende Rechner hier genannt wird, er den Serverstart verweigert. Ist kein Eintrag zum Dienst vorhanden, gilt der Zugriff als zulässig, der Wrapper wird den Dämon starten und sich selbst beenden. Den Aufbau der beiden Dateien /etc/hosts.allow und /etc/hosts.deny schauen wir uns weiter unten an.
Ein einmal aktivierter Serverprozess kann durchaus so implementiert sein, dass er von sich aus weitere Verbindungen annimmt. Solange er seine Ports nun selbst im Auge behält, bleiben der inetd und damit auch der TCP-Wrapper außen vor, wenn es um die Annahme neuer Client-Wünsche geht. Auch schließen manche Server aus Effzienzgründen ihre Ports nicht unverzüglich, sondern lauschen bis zu einer Zeitüberschreitung weiter. Kommt in dem Augenblick eine Anforderung herein geschneit, wird sie ebenso akzeptiert werden. Und Dienste, die den inetd umgehen (z.B. RPC-Dienste), lassen sich niemals durch den TCP-Wrapper überwachen.
Der Aufbau beider Dateien ist identisch. Bevor wir uns diesem zuwenden, soll nochmals die Reihenfolge der Bearbeitung verdeutlicht werden:
Server ist dabei der Dienst, den der Client in Anspruch zu nehmen wünscht und Client ist der Rechner, von dem die Anforderung ausging. Eine Zeile in den beiden Dateien hat nun folgenden Aufbau:
An Stelle von Dienst kann entweder der Programmname dessen stehen oder das Schlüsselwort ALL, falls die Zeile alle Dienste betreffen soll. Einem ALL kann ein EXCEPT Dienstname folgen, dann sind alle Dienste mit Ausnahme der benannten gemeint. Per Komma getrennt, lassen sich mehrere Dienste angeben. Die möglichen Einträge sind Rechnernamen, IP-Adressen oder die folgenden Schlüsselworte: ALL Alle Rechner
KNOWN
Rechner, deren Namen der tcpd ermitteln kann (Auflösung über DNS ist sowohl von
Name zu Adresse als auch umgekehrt möglich und die Ergebnisse sind identisch).
LOCAL
Alle Rechner, deren Namen keinen Punkt enthalten (Rechner, die in der /etc/hosts unter einem
Kurznamen aufgeführt sind).
UNKOWN Rechner, deren Namen der tcpd nicht ermitteln kann.
PARANOID
Alle Rechner, deren Namens- und Adressauflösung über DNS widersprüchliche Angaben
ergibt (so etwas ist z.B. bei Rechnern mit mehreren Netzwerkkarten möglich, da diese auch mehrere
IP-Adressen besitzen).
Schließlich kann ein optionales Kommando angegeben werden, dass immer dann ausgeführt wird, wenn diese Zeile für eine Anforderung zutrifft. Falls auf diese Möglichkeit zurückgegriffen wird, dann meist zum Zwecke des detaillierten Protokollierens. Im Argument des Kommandos können einige Sonderzeichen verwendet werden, die folgende Bedeutung haben: %a Liefert die IP des rufenden Rechners
%c
Gibt den Namen des Nutzers und Rechners zurück, sofern die Informationen vom entfernten
Rechner geholt werden können
%d Name des gewünschten Dienstes
%h Name des zugreifenden Rechners oder dessen IP
%n Name des zugreifenden Rechners (oder unknown oder paranoia)
%p Prozessnummer des Dienstes
%s Name des Serves in Verbindung mit dem Rechnernamen
%u Name des Nutzers auf Clientseite, sofern er ermittelt werden kann
Konkrete Beispiele sollen den Aufbau der Dateien /ect/hosts.allow und /etc/hosts.deny und den Gebrauch der Schlüsselwörter verdeutlichen:
Erklärung: In der letzten Zeile der Beispieldatei /etc/hosts.allow wird »finger« gestattet, wobei gleichzeitig versucht wird, Information vom rufenden Rechner zu gewinnen. Nun könnte es durchaus sein, dass der Gegenüber seinen »finger«-Zugang mit eben diesem Mechanismus umgeben hat. Die Folge wäre eine Endlosschleife sich gegenseitig initiierender finger-Aufrufe. Um so etwas auszuschließen, existiert das Kommando »safe_finger«, das den einmaligen Aufruf sicher stellt. »spawn« erzeugt einen neuen Kindprozess, der die nachfolgenden Kommandos ausführt.
Erstes Hilfsmittel ist das Kommando tcpdchk. Dieses Programm findet Unstimmigkeiten in der Datei /etc/inetd.conf, wie z.B. fehlende Netzwerkdienste. Des Weiteren werden Syntaxfehler der Dateien /etc/hosts.allow und /etc/hosts.deny und unbekannte Rechnernamen aufgespürt. Zur Identifizierung von logischen Fehlern hilft das Kommando allerdings nicht. Jetzt kommt tcpdmatch zum Zuge. Das Kommando erwartet als Argumente den zu verifizierenden Dienst (eventuell in der Form »Dienst@Server«) und den Nutzer oder Host (»user@host« bzw. nur »host«). Anschließend berichtet das Kommando, wie der tcpd die Anforderung erfüllen würde:
|
|||||||||||||||||
Korrekturen, Hinweise? |