Home

Info

Artikel

Produkte

Stickers

UserGroups

Events

Bücher


Suchen:



Akademie_Workshop
Jetzt bestellen! > Abo-Bestellung
> Jahres-CD 2001

xinetd und g2s

Und Du auch nicht!

von Michael Weyrauch


Wenn vom zuständigen Administrator keine Vorkehrungen getroffen wurden, können die zahlreichen Netzwerkdienste eines Unix-artigen Rechners von jedem Netzteilnehmer angesprochen werden. Auch wer im Netz nur Freunde hat, möchte wohl kaum, daß jeder zu seinem Rechner eine Telnet-Verbindung aufbauen oder mit finger den Terminkalender auslesen kann.

Wir haben uns das letzte Mal mit dem TCP-Wrapper die klassische Variante der Zugriffskontrolle über die Netzwerkdienste angesehen. Eine andere, mittlerweile sehr gebräuchliche Möglichkeit ist, den Standard-inetd durch den xinetd zu ersetzen. Von ihrer grundsätzlichen Funktion her unterscheiden sich die beiden Super-Daemonen nicht. Beide ermitteln beim Start aus ihren jeweiligen Konfigurationsdateien die von ihnen zu verwaltenden Netzwerk-Dienste samt den dazugehörigen Portnummern. Geht auf einem dieser Ports eine Verbindungsanforderungen für einen dieser Dienste ein, starten sie den entsprechenden Daemon, um die Verbindung mit ihm herzustellen. Aber im Gegensatz zum Standard-inetd kann der xinetd auch rpc-basierte Dienste starten und bietet von sich aus Möglichkeiten, den Zugriff auf die Netzwerkdienste zu steuern und zu kontrollieren.

xinetd selbstgebacken

Wer eine Linux-Distribution benutzt, die xinetd nicht bereits im Lieferumfang enthält, muß selbst ein wenig Hand anlegen. Die Übersetzung der Sourcen des xinetd ist jedoch denkbar einfach: man rufe das Shellscript compile-src auf, beantworte die Frage nach dem Betriebssystem mit linux und verneine die Frage, ob man die Man-Pages konvertieren wolle. Anschließend kann root mit

# make INSTALLDIR=/usr/sbin install
# make MANPATHDIR=/usr/man install.man

die Dateien in die entsprechenden Verzeichnisse kopieren lassen. Mit dem Programm itox, das bei der Übersetzung der Sourcen neben dem xinetd erzeugt wurde, kann man die Konfigurationsdatei /etc/inetd.conf des Standard-inetd in das neue Dateiformat konvertieren:

# itox </etc/inetd.conf >/etc/xinetd.conf

Dabei ist zu beachten, daß itox nur die Netzwerkdienste in die /etc/xinetd.conf übernimmt, die in der Standard-Konfigurationsdatei freigeschaltet waren. Wer also alle möglichen Einträge aus der /etc/inetd.conf übernehmen möchte, muß diese entweder vor der Konvertierung aktivieren (und kann sie anschließend - beispielsweise mit dem Eintrag disabled - in der Konfigurationsdatei wieder deaktivieren) oder muß die Dienste später mit einem Editor nachtragen.

Da sich der xinetd mit der so erstellten Konfigurationsdatei nicht anders verhält als der inetd, kann man bereits jetzt die beiden Daemonen tauschen. Idealerweise wechselt man dazu in den Einzelbenutzermodus, erstellt Sicherungskopien der Start-Skripten, ehe man diese so verändert, daß statt des inetd der xinetd aufgerufen wird. Ganz vorsichtige Naturen können auch den inetd an ein sicheres Plätzchen verschieben und anschließend mit

# ln -s /usr/sbin/xinetd /usr/sbin/inetd

vom xinetd einen Link auf den inetd erzeugen.

Zähmung der Daemonen

Die Konfigurationsdatei unterscheidet sich in der Syntax erheblich von der des Standard-inetd und ist trotz der eigentlich guten Dokumentation wegen der mehr als zwei Dutzend Schlüsselwörter, die /etc/xinetd.cfg kennt, anfänglich nicht leicht zu überblicken. Dennoch erweist sich die Konfiguration als erheblich einfacher und weniger fehleranfällig, verglichen mit der Konfiguration des TCP-Wrappers (tcpd), mit dem wir uns das letzte Mal beschäftigt haben.

Die Syntax der /etc/xinetd.conf

Für die Voreinstellungen:

default
     {
          <Schlüssel> <Operator> <Parameter>
<Parameter> ...
     }

Für den jeweiligen Netzwerkdienst:
service <Service-Name>
     {

          <Schlüssel> <Operatoren> <Parameter>
<Parameter> ...

     }

Als Operatoren kommen =, -= und += in Frage. Die meisten Attribute unterstützen nur den Operator =, doch kann man einigen Attributen durch += weitere Werte zuweisen oder mit -= Werte wegnehmen.

Der erste Eintrag in der Konfigurationsdatei /etc/xinetd.conf ist optional und erlaubt es einem, beispielsweise folgende Voreinstellungen vorzunehmen:

default
     {
          log_type        = FILE /var/log/services.log
          log_on_success  = PID
          log_on_failure  = HOST RECORD
          instances       = 10
     }

Die Einstellungen für log_type und instances werden überschrieben, wenn in den Einträgen für die jeweiligen Services etwas anderes festgelegt wird, wohingegen für alle anderen Attribute die Default-Einstellungen mit den in den Services festgelegten Werten kombiniert werden.

Mit der Anweisung log_type kann festgelegt werden, ob - wie in diesem Fall - die Ausgabe direkt in ein Logfile geschrieben wird oder dem Syslog-Daemon übergeben werden soll. Werden hohe Sicherheitsanforderungen gestellt, sollte man sich allerdings überlegen, ob man nicht besser die Protokollierung dem Syslog-Daemon überläßt, um mögliche Angriffe auf das Logfile des xinetd zu verhindern. Mit log_on_success und log_on_failure wird eingestellt, was im Logfile festgehalten werden soll, wenn das Starten des Netzwerkdienstes erfolgreich verläuft oder fehlschlägt. Und über den Wert für instances kann die maximal mögliche Zahl der Daemonen des jeweiligen Services begrenzt werden, wodurch der Rechner vor einer absichtlichen oder unabsichtlichen Überlastung durch eine Vielzahl von gleichzeitigen Verbindungen (denial-of-access-Angriff) geschützt wird.

Alle weiteren Einträge sehen ähnlich aus wie der default-Eintrag, umfassen aber nur die Konfiguration des jeweiligen Netzwerkdienstes, wie hier zum Beispiel für finger:

service finger
     {
          socket_type  = stream
          protocol     = tcp
          wait         = no
          user         = nobody
          server       = /usr/sbin/in.fingerd
          server_args  = -w
     }
Das Schlüsselwort socket_type bezeichnet die Art des sockets (stream, dgram, raw oder seqpacket) und protocol das Protokoll (meist tcp oder udp), welches der jeweilige Netzwerkdienst benutzt. Das Schlüsselwort wait legt fest, ob der xinetd darauf warten muß, daß der Daemon den Port freigibt, ehe er weitere Verbindungsanforderungen für den gleichen Port bearbeiten kann. Im Feld user wird festgelegt, unter welcher Benutzer-ID der Daemon gestartet wird. Unter server ist der absolute Pfadname des Daemons registriert, der gestartet werden soll und mit dem Attribut server_args wird angegeben, welche Parameter dem Daemon beim Start übergeben werden sollen.

Der xinetd verfügt über einige interne Dienste (echo, time, daytime, chargen, discard), die in der Konfiguration mit

type     = INTERNAL

als solche gekennzeichnet werden müssen, andernfalls geht xinetd davon aus, daß es sich um externe Dienste handelt. Bei Services wie echo, die sowohl als tcp- wie auch udp-basierte Dienste existieren, muß nicht nur der socket_type entsprechend angegeben, sondern sie müssen auch im id-Feld so benamt werden, daß sie eindeutig identifizierbar sind. Hier ein Beispiel für echo:

service echo
     {
          id          = echo-stream
          type        = INTERNAL
          socket_type = stream
          user        = root
          wait        = no
     }

service echo
     {
          id          = echo-dgram
          type        = INTERNAL
          socket_type = dgram
          user        = root
          wait        = no
     }

Hat man im laufenden Betrieb die Konfiguration verändert, sollte man nicht versuchen, den xinetd mit einem kill -1 pid oder kill -HUP pid neu zu starten, da der Daemon aus Sicherheitsgründen darauf mit einem schweren Fehler und der Erstellung eines Speicherabzugs reagiert. Man muß also, will man xinetd dazu veranlassen, seine Konfigurationsdatei neu einzulesen, die Signale SIGUSR1 oder SIGUSR2 schicken (siehe Kasten Signalbehandlung).

Signalbehandlung des xinetd

SIGUSR1
xinetd liest die Konfigurationsdatei neu ein und paßt seine Aktionen entsprechend an; gerade laufende Netzwerkdienste bleiben davon unberührt.
SIGUSR2
xinetd liest ebenfalls seine Konfigurationsdatei neu ein, jedoch werden Netzwerkdienste, die aus der Konfiguration genommen wurden, sofort beendet. Noch laufende Netzwerkdienste werden auf evtl. neu definierte Zugriffsrechte, Anzahl der Daemonen eines Services etc. überprüft und ggf. beendet.
SIGQUIT
beendet xinetd.
SIGTERM
beendet alle laufenden Services, dann erst den xinetd.
SIGHUP
Erstellung eines Speicherabzuges
SIGIOT
veranlaßt xinetd, eine interne Konsistenzprüfung vorzunehmen, um sicherzustellen, daß das Programm nicht verfälscht wurde.

Kontrollierter Zugriff

Der xinetd kennt im Wesentlichen 4 Parameter, mit denen die Zugriffskontrolle gesteuert werden kann: only_from, no_access, access_time und disabled.

service telnet
     {
          socket_type     = stream
          protocol        = tcp
          wait            = no
          user            = root
          server          = /usr/sbin/in.telnetd
          only-from       = 192.168.200.3 192.168.200.7 192.168.200.9
          only-from      += 192.168.200.10 192.168.200.12
          no_access       = 192.168.100.0
          flags           = IDONLY
          access_times    = 07:00-21:00
     }

Mit Ausnahme von disabled können sie alle entweder im defaults-Abschnitt als Voreinstellung oder für die jeweiligen Services einzeln definiert werden. Mit only_from kann festgelegt werden, welche Hosts welchen Dienst nützen können, während umgekehrt mit no_access Hosts vom Zugriff ausgeschlossen werden. Es können entweder vollständige IP-Adressen von Rechnern oder Netzen aber auch Netz- und Hostnamen angegeben werden. access_times legt fest, zu welchen Zeiten der Dienst verfügbar ist, dabei erfolgt die Angabe im 24-Stunden-Format. Mit disabled läßt sich der jeweilige Dienst ganz abschalten, d.h. auch die Protokollierung von versuchten Zugriffen.

Stellt man an seine Zugriffskontrolle hohe Ansprüche, kann man über die Parameter INTERCEPT und IDONLY des flags-Eintrages noch weiter an der Sicherheitsschraube drehen. Wurde der Parameter USERID bei den Einträgen log_on_access und log_on_failure gesetzt, stellt IDONLY sicher, daß nur dann eine Verbindung zum Netzwerkdienst zugelassen wird, wenn der Benutzer-Identifizierungsdienst (z.B. identd) des den Netzwerkdienst anfordernden Hosts die Benutzer-ID übermittelt. Und ist der Parameter INTERCEPT eingetragen, versucht xinetd auch bei bereits bestehenden Verbindungen sicherzustellen, daß auf der anderen Seite ein autorisierter Host ist, also die Verbindung nicht entführt wurde. Die Überwachung von Verbindungen funktioniert allerdings nur, wenn es sich dabei nicht um einen multi-threaded oder um einen xinetd-internen Dienst handelt und belastet zudem die Netzwerkverbindung und die Performance des Netzwerkdienstes erheblich.

Spurenleser

Da fast jeder Angreifer mehrere Anläufe benötigt und sich viel Zeit nehmen muß, ehe er Erfolg hat, braucht derjenige, der seine Rechner schützen will, nicht nur Software, die Angriffen standhält, sondern braucht auch Protokolle, aus denen er lesen kann, daß jemand versucht, seinen Rechner zu attackieren. Es ist also nicht sinnvoll, Unbefugte einfach nur abzuhalten, vielmehr müssen zur Aufrechterhaltung der Systemsicherheit unter Umständen auch fehlgeschlagene und unautorisierte Verbindungsversuche festgehalten werden. Will man also einen Dienst abschalten, aber die Protokollierung für diesen Dienst aufrechterhalten, setzt man den Schlüssel only_from einfach ohne jeden weiteren Parameter.

Die Protokollierung des xinted wird neben der Anweisung log_type, die wir schon besprochen haben, noch durch die Attribute log_on_success und log_on_failure gesteuert. Damit kann man dann nicht nur festhalten lassen, von welchem Host aus zugegriffen wurde und wie lange der Zugriff dauerte, sondern auch, wenn der ferne Host dies unterstützt, welcher User den Dienst in Anspruch nahm. Darüber hinaus können auch die Umstände, wie und warum der Netzwerkdienst endete, protokolliert werden.

Aber das beste Protokoll nutzt nichts, wenn es nicht regelmäßig und in geringen Zeitabständen auf fehlgeschlagene Verbindungsanforderungen hin kontrolliert wird. Die meisten Eintragungen werden dabei hoffentlich nur auf Fehlkonfigurationen oder Fehlbedienungen und nicht auf Einbruchversuche hinweisen.

g2s - frisch und halbgar

Mit g2s tritt eine Neuentwicklung in den Ring der Super-Daemonen. Die Entwickler verfolgen hochgesteckte Ziele: Robust, klein, portabel soll er werden, besser gegen DNS- und Name-Spoofing schützen und zudem eine ganze Palette an Protokollen unterstützen. Die Konfiguration erinnert etwas an die des xinetd, ist allerdings noch komplexer. g2s befindet sich in einem frühen Beta-Stadium und viele Features sind noch nicht oder nur teilweise implementiert, so daß wir das Programm hier nicht weiter vorstellen wollen, aber für den, der sich für derartige Software interessiert, ist g2s mehr als einen Blick wert.

Infos

[1] Der xinetd (aktuelle Version: 2.2.1) ist zu finden bei ftp://ftp.irisa.fr%20/pub/mirrors/xinetd.
[2] Die neueste Version des g2s - derzeit Version 0.3.4 - bekommt man unter ftp://ftp.rtc-one.net/j/g2s.

Der Autor

Michael Weyrauch beschäftigt sich schon seit vielen Jahren mit Linux. Zu erreichen ist er unter wey@pipe.berlin.fido.de.

Copyright © 1998 Linux-Magazin Verlag