Druckversion | ||||||||||||||||||
Damit ein Client einen entsprechenden Server findet, benötigt er neben Kenntnis der IP-Adresse des Serverrechners auch noch die Portnummer, an der der Dienst wartet. In den ersten Unix-Systemen mit TCP/IP-Unterstützung wurden bereits während des Systemstarts sämtliche Serverprozesse aktiviert, die ihre Ports initialisierten und auf eintreffende Anforderungen warteten. Traf ein Verbindungswunsch ein, erzeugte ein Server einen Kindprozess, vererbte diesem die geöffnete Verbindung, schloss seinerseits die Verbindung und begab sich selbst erneut in den Wartezustand, um eintreffende Anfragen entgegenzunehmen. Bald erkannte man, dass die meisten Serverprozesse vollkommen umsonst gestartet wurden, sie wurden im Laufe der Aktivität des Systems nicht oder nur selten in Anspruch genommen. Mit den von den warteten Prozessen in Anspruch genommenen CPU-Zeiten konnte man noch gut leben, denn da sie nichts zu erledigen hatten, erzeugten sie auch nur geringe Rechenlast, aber der ständig reservierte Hauptspeicher, zumal in jenen Zeiten die heutigen RAM-Dimensionen ins Reich der Fantasie gehörten, entpuppte sich bald als Schwachpunkt. Die Lösung kam, wie so viele Anreize aus jenen Tagen, aus Berkeley und wurde mit dem inetd als erstem »Superserver« mit 4.3BSD veröfentlicht. Anstelle der Aktivierung sämtlicher Netzwerkdienste wurde nun nur noch der Superserver beim Start des Systems zum Leben erweckt. Dieser entnahm alle zu eröffnenden Portnummern einer Konfigurationsdatei und überwachte diese auf eintreffende Verbindungsanforderungen. Lag irgendwo eine Anfrage an, startete der Superserver den entsprechenden Serverdienst und vermachte ihm die bereits offene Verbindung. Als Konsequenz hieraus ist die meiste Zeit über stets nur ein Server aktiv und alle weiteren können bei Bedarf nachgeladen und nach Erfüllung der Anforderung auch wieder beendet werden. Der inetd ist der Standard-Superserver für Linux, jedoch lässt er in Sachen Zugriffssteuerung viele Wünsche offen. So hat sich der xinitd in vergangenen Jahren zu einer ernsthaften Alternative entwickelt.
Der inetd ist der mit Abstand beliebteste Superdämon. Er ist in der Lage sowohl TCP- als auch UDP-basierte und in aktuellen Versionen sogar RPC-Dienste zu starten. Dazu überwacht er die Ports (oft wird in diesem Zusammenhang auch von Internet Sockets gesprochen) der ihm anvertrauten Server und entscheidet anhand der Portnummer, an der eine Anforderung eintrifft, welcher Netzwerkdienst zu starten ist. Nicht alle Dienste, die der Rechner im Netzwerk anbieten soll, werden von einem Superserver verwaltet. Einige hochverfügbare Server wird man schon während des Systemstarts aktivieren, man denke nur einen http-Dämonen auf einem frequentierten Webserver. Für welche Dienste sich der inetd letztlich verantwortlich zeichnet, muss ihm deshalb in seiner Konfigurationsdatei /etc/inetd.conf mitgeteilt werden. Es gibt Dienste, die sind in ihrer Art so einfach, dass es vergebene Mühe wäre, sie in ein eigenes Programm zu packen. Der inetd verfügt deswegen über einige interne Dienste, deren Anforderung er höchst persönlich erfüllt: chargen
Der »Zeichengenerator«. Trifft ein Verbindungswunsch für diesen Dienst ein, wird
mit einem ununterbrochenen Zeichenstrom geantwortet, solange, bis der Client die Verbindung beendet.
Der Service kann zur Performance-Messung eingesetzt werden.
daytime Gibt die Rechnerzeit in einem für den Mensch verständlichen Format wieder
discard
Der Dienst basiert auf dem Initial Connection Protocol und anwortet bei eintreffendem
Verbindungswunsch mit dem Aufbau einer Verbindung in die Gegenrichtung. Anschließend wartet
discard auf eine Anwort und leitet diese nach /dev/null. Ist die Anwort »verarbeitet«,
beendet sich der Prozess. Der Dienst wird zu Testzwecken eingesetzt.
echo Der Dienst sendet die empfangenen Daten unverändert an den Absender zurück.
time Gibt die Rechnerzeit in einem maschinenlesbaren Format wieder
»time« und »daytime« werden bei einem Zeitserver benötigt, die anderen Dienste sollten nur temporär für Testzwecke geöffnet werden, da sie von außen zum Erzeugen unnötiger Rechenlast missbraucht werden können. Die Datei /etc/inetd.confAlle Dienste, die der inetd starten soll, müssen in dessen Konfigurationsdatei /etc/inetd.conf aufgeführt sein. Beginnt eine Zeile mit dem Doppelkreuz, so handelt es sich um einen Kommentar, alle anderen Zeilen bestehen aus 6 Feldern: Dienstbezeichnung
Name des Serverdienstes, so wie er in der Datei /etc/services
eingetragen ist. Im Falle eines RPC-Dienstes muss zusätzlich dessen Versionsnummer angegeben
werden. Der RPC-Dienstname steht in der Datei /etc/rpc, ein gültiger Eintrag lautet dann
<RPC-Dienst>/<Version>.
Sockettyp
Die Art des Sockets muss hier angegeben werden. Als Schlüsselwörter sind zulässig:
stream, dgram, raw, rdm und seqpacket. stream ist dabei ein
Socket, in dem ein Datenfluss (»streaming«) eintrifft, so wie sie das Transportprotokoll
TCP implementiert. dgram ist der »Telegrammtyp« und korrespondiert mit dem
UDP-Protokoll. raw sind Rohdaten, also Daten, die nicht in einemTransportprotokoll verpackt
sind; sie werden direkt an die Anwendung weitergereicht. rdm (reliably delivered message) sind
»sicher verteilte« Daten, so dass in den oberen Schichten des TCP-Protokollstacks von ihrer
Unversehrtheit ausgegangen werden kann. seqpacket ist eine Sequenz von Paketen.
Protokoll
Ist der Name des Protokolls, über den der Dienst arbeitet, in den meisten Fällen wird es
sich um tcp oder udp handeln. Im Falle eines RPC-Dienste steht hier z.B. »rpc/tcp« oder
»rpc/udp«.
[no]wait
Eines der Schlüsselworte ist immer anzugeben, wobei die Angabe sich einzig auf das
UDP-Protokoll auswirkt. wait bewirkt, dass der inetd nach dem Verbindungsaufbau neue
Anforderungen erst entgegennimmt, wenn der UDP-Dienst seine Arbeit beendet hat. Mit nowait wird
unverzüglich auf neue Anforderungen gewartet.
Benutzerkennung Name des Benutzers, in dessen Auftrag der Dienst gestartet wird.
Dienstname Vollständiger Programmname des Dienstes (inklusive Pfad und Optionen).
Eine Datei »/etc/inetd.conf« könnte dann wir folgt aussehen (Auszüge):
Der einigen Diensten vorgeschaltete TCP-Wrapper »/usr/sbin/tcpd« implementiert eine dedizierte Zugangskontrolle für den jeweiligen Netzwerkdienst. Er ist eine relevante Komponente der Netzwerksicherheit und wird im Kapitel Netzwerk-Sicherheit TCP-Wrapper vorgestellt.
Im vergangenen Abschnitt lernten Sie den inetd kennen. Die Bemerkungen zur nichtvorhandenen Zugangskontrolle sollten Ihnen ebenso wenig entgangen sein, wie der Kompromiss des TCP-Wrappers, der die Sicherheitsmängel des inetd teilweise beheben kann. Dennoch kann die Vorgehensweise des »alles ist erlaubt, solange es nicht explizit verboten wurde« bei halbherziger Konfiguration schnell zu unbemerkten Sicherheitslöchern führen. Der xinetd ist ein vollwertiger Ersatz für den inetd. Das »x« deutet hier nicht etwa ein X-Window-Programm an, sondern steht für »extended« (erweitert). Er implementiert dieselben internen Dienste wie der »inetd« (chargen, daytime, discard, echo, time). Des Weiteren ermöglicht der xinetd die Protokollierung aller Zugriffe. Die Datei /etc/xinetd.confKonfiguriert wird der xinetd mittels der Datei /etc/xinetd.conf. Er kennt zwei Typen von Einträgen. Zum einen handelt es sich um den optionalen »default«-Eintrag, der auf alle anderen Einträge angewandt wird, insofern diese die Optionen nicht selbst definieren. Dieser default-Eintrag besitzt folgende Struktur:
Die weiteren Einträge betreffen die einzelnen Dienste:
Als Operatoren sind zulässig: die normale Zuweisung mit »=«, das Hinzufügen eines weiteren Schlüssels mit »+=« und das Entfernen eines Schlüssels mit »-=«. Die Verwendung der Operatoren »+=« und »-=« macht vor allem in Verbindung mit dem »default«-Eintrag Sinn. Von den nachfolgend beschriebenen Schlüsseln sind im Falle des default-Eintrags nicht alle sinnvoll. Erlaubt sind hier »log_type«, »log_on_success«, »log_on_failure«, »only_from«, »no_access«, »passenv«, »instances« und »disabled«. »disabled« kann nur im »default«-Eintrag stehen und sperrt den Zugang zu den angegebenen Diensten. id
Jeder Dienst muss eindeutig identifiziert werden können, die Angabe ist für
Mulit-Protokoll-Dienste notwendig. Fehlt sie, so wird der Name des Dienstes
(»Dienstbezeichnung«) als ID angenommen.
type
Kombination aus »RPC« (RPC-Dienst), »INTERNAL« (interner Dienst) oder
»UNLISTED« (Dienst, der nicht in den Dateien »/etc/rpc« oder
»/etc/services« eingetragen ist).
flags
Von den möglichen Einträgen ist »IDONLY« der Interessanteste. Eine
Anforderung wird dann nur zugelassen, wenn der entfernte Benutzer identifiziert werden kann.
socket_type
Die Typen sind »stream«, »dgram«, »raw« und
»seqpacket« und besitzen dieselbe Bedeutung wie beim inetd beschrieben wurde.
protocol
Name des Protokolls, über das der Dienst arbeitet. Fehlt die Angabe, wird das
»übliche« Protokoll des Dienstes angenommen.
wait
Steht hier »yes«, wartet der xinitd nach einem Verbindungsaufbau auf das Ende
des Servers, bevor er neue Anforderungen entgegen nimmt. Mit »no«, startet er ggf. weitere
Serverprozesse.
user Die Nutzerkennung, unter der der Serverprozess gestartet wird.
group Die Gruppenkennung, unter der der Serverprozess gestartet wird.
instances
Maximal mögliche Anzahl Prozesse, die den Dienst zu einer Zeit ausführen dürfen.
Neben der Zahl darf auch »UNLIMITED« stehen.
nice Priorität des Serverprozesses.
server Programmname des Servers (inklusive Pfad)
server_args Argumente des Serverprogrammes
only_from
Liste von Rechnern, von denen der Zugang erlaubt ist. Die Angabe kann eine IP-Adresse, ein
Rechnername, eine Netzwerkadresse oder ein Adressbereich sein (192.168.100.12/100 erlaubt den Zugriff
von den Rechner 192.168.100.12 bis 192.168.100.100)
no_access
Rechner, denen der Zugriff verwehrt wird. Die Angaben erfolgen wie unter »only_from«,
wobei bei Mehrfachnennung die »bessere« Übereinstimmung gilt (wurde der Zugriff den
Rechern eines Netzwerks erlaubt und ist nun ein konkreter Rechner aus jedem Netzwerk in der verbotenen
Liste enthalten, so wird ihm der Zugang verwehrt).
access_times Tageszeit, zu der der Zugriff erlaubt ist
log_type
Wo und wie soll protokolliert werden? Mit »SYSLOG Herkunft [Level]« wird die
Protokollierung an den syslogd weitergereicht; mit »FILE Datei
[soft_limit [hardlimit]]« erfolgt sie in der angegebenen Datei. Die beiden Limits sind die
Schranken, wie größ eine Datei maximal werden kann, somit wird ein Volllaufen des
Dateisystems ausgeschlossen.
log_on_success
Was wird protokolliert, falls der Server erfolgreich startet? Mögliche Einträge sind:
Prozessnummer des Servers »PID«, Rechnername, von dem die Anforderung kam
»HOST«, Benutzernummer, von dem die Anforderung kam »USERID«, der Exit-Status
des Servers »EXIT« und die Dauer des Serverlaufs »DURATION«.
log_on_failure
Was wird protokolliert, falls der Server nicht gestartet werden konnte? Neben »HOST«
und »USERID« (wie oben) sind möglich »ATTEMPT«, das die Tatsache des
fehlgeschlagenen Starts notiert und »RECORD«, das weiterführende Informationen (sofern
ermittelbar) vom entfernten Aufruf protokolliert.
rpc_version Versionsnummer des RPC-Dienstes
env Hier lassen sich zu einem Server zusätzliche Umgebungsvariablen angeben
passenv Liste der Umgebungsvariablen, die der xinetd dem Server vererbt
port
Portnummer, an der der Server wartet, diese muss mit dem Eintrag in der Datei /etc/services (soweit
vorhanden) übereinstimmen
redirect Eine Anforderung wird an den angegebenen Rechner weitergeleitet. Dies ist nur bei TCP-Diensten möglich
bind
Bindet einen Dienst an ein spezielles Device. So kann z.B. bei einem Rechner mit zwei
Netzwerkkarten sicher gestellt werden, dass der Dienst nur über die eine Karte zugänglich ist
banner
Enthält einen Dateinamen, deren Inhalt auf dem zugreifenden Rechner angezeigt wird, falls ihm
der Zugang verwehrt wird.
Bevor wir uns den Beispielen zuwenden, sind noch einige Anwendungen zu den vom xinetd akzeptierten Signalen notwendig. Bislang konnten Sie nahezu jeden Prozess mit dem Signal SIGHUP (1) zum erneuten Einlesen seiner Konfigurationsdateien bewegen. Im Falle des xinetd erreichen Sie damit allerdings nur, dass dieser sich mit einem Speicherabzug verabschiedet. Aus Sicherheitsgründen reagiert der xinetd auf einige Signale anders als gewohnt: SIGUSR1 (10) Einlesen der Konfigurationsdatei. Aktive Dienste bleiben aktiv.
SIGUSR2 (12) Einlesen der Konfigurationsdatei. Aktive Dienste werden sofort beendet.
SIGQUIT (3) Programmende, ohne laufende Dienste zu beenden
SIGTERM (15) Programmende, laufende Dienste werden zuvor beendet
SIGHUP (1) Anlegen eines Speicherauszugs und Programmende
SIGIO (29) Interne Konsitenzprüfung des xinetd
Beispiel 1: Mit dem default-Eintrag spezifizieren wir einige Voreinstellungen, die für alle Dienste gelten, in denen sie nicht explizit überschrieben werden.
Beispiel 2: »telnet« soll nur von Rechnern des Netzwerkes 192.168.100 möglich sein, wobei die Rechner mit den Endnummern 56-192 ausgenommen werden sollen. Alle fehlgeschlagenen Kontaktversuche sollen über den Syslog-Mechanismus protokolliert werden, wobei die Herkunft den Sicherheitdiensten (auth) zugeordnet werden soll und die Meldung das Level »Warnung« erhält:
Beispiel 3: »ftp« soll nur in den Nachtstunden erlaubt sein. Gleichzeitig werden 4 Zugriffe zugelassen.
Beispiel 4: Von den internen Diensten soll »time« sowohl über »udp« als auch über »tcp« bereitgestellt werden:
Beispiel 5: Zuletzt noch ein Beispiel zu einem RPC-Dienst:
|
||||||||||||||||||
Korrekturen, Hinweise? |