Linuxfibel - Netzwerk Grundlagen - Internet Service Dämon
Aus LinWiki.de
Inhaltsverzeichnis
|
[Bearbeiten] Übersicht
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 xinetd in vergangenen Jahren zu einer ernsthaften Alternative entwickelt.
[Bearbeiten] Der Dämon inetd
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:
[Bearbeiten] 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.
[Bearbeiten] daytime
Gibt die Rechnerzeit in einem für den Mensch verständlichen Format wieder
[Bearbeiten] 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.
[Bearbeiten] echo
Der Dienst sendet die empfangenen Daten unverändert an den Absender zurück.
[Bearbeiten] 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.
[Bearbeiten] Die Datei /etc/inetd.conf
Alle 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:
[Bearbeiten] 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>.
[Bearbeiten] 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 einem Transportprotokoll 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.
[Bearbeiten] 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«.
[Bearbeiten] [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.
[Bearbeiten] Benutzerkennung
Name des Benutzers, in dessen Auftrag der Dienst gestartet wird.
[Bearbeiten] Dienstname
Vollständiger Programmname des Dienstes (inklusive Pfad und Optionen).
Eine Datei »/etc/inetd.conf« könnte dann wir folgt aussehen (Auszüge):
user@sonne> cat /etc/inetd.conf # <service_name> <sock_type> <proto> <flags> <user> <server_path> <args> # # echo stream tcp nowait root internal # echo dgram udp wait root internal # discard stream tcp nowait root internal # discard dgram udp wait root internal daytime stream tcp nowait root internal daytime dgram udp wait root internal # chargen stream tcp nowait root internal # chargen dgram udp wait root internal time stream tcp nowait root internal time dgram udp wait root internal # # These are standard services. # # ftp stream tcp nowait root /usr/sbin/tcpd wu.ftpd -a ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd # # If you want telnetd not to "keep-alives" (e.g. if it runs over a ISDN # uplink), add "-n". See 'man telnetd' for more deatails. telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd nntp stream tcp nowait news /usr/sbin/tcpd /usr/sbin/leafnode smtp stream tcp nowait root /usr/sbin/sendmail sendmail -bs # printer stream tcp nowait root /usr/sbin/tcpd /usr/bin/lpd -i # Shell, login, exec and talk are BSD protocols. # The option "-h" permits ``.rhosts files for the superuser. Please look at # man-page of rlogind and rshd to see more configuration possibilities about # .rhosts files. # shell stream tcp nowait root /usr/sbin/tcpd in.rshd -L # shell stream tcp nowait root /usr/sbin/tcpd in.rshd -aL # login stream tcp nowait root /usr/sbin/tcpd in.rlogind # login stream tcp nowait root /usr/sbin/tcpd in.rlogind -a # exec stream tcp nowait root /usr/sbin/tcpd in.rexecd talk dgram udp wait root /usr/sbin/tcpd in.talkd ntalk dgram udp wait root /usr/sbin/tcpd in.talkd
finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd -w # systat stream tcp nowait nobody /usr/sbin/tcpd /bin/ps -auwwx # netstat stream tcp nowait root /usr/sbin/tcpd /bin/netstat # identd is now started at boot time, the following is not longer necessary. # ident stream tcp wait nobody /usr/sbin/in.identd in.identd -w -e
# swat is the Samba Web Administration Tool swat stream tcp nowait.400 root /usr/sbin/swat swat
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.
[Bearbeiten] Der Dämon xinetd
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.
[Bearbeiten] Die Datei /etc/xinetd.conf
Konfiguriert 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:
defaults
{
<Schlüssel> <Operator> <Parameter> <Parameter> ...
...
}
Die weiteren Einträge betreffen die einzelnen Dienste:
service <Dienstbezeichnung>
{
<Schlüssel> <Operator> <Parameter> <Parameter> ...
...
}
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 »-=« ist vor allem in Verbindung mit dem »default«-Eintrag sinnvoll.
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.
[Bearbeiten] 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.
[Bearbeiten] type
Kombination aus »RPC« (RPC-Dienst), »INTERNAL« (interner Dienst) oder »UNLISTED« (Dienst, der nicht in den Dateien »/etc/rpc« oder »/etc/services« eingetragen ist).
[Bearbeiten] flags
Von den möglichen Einträgen ist »IDONLY« der Interessanteste. Eine Anforderung wird dann nur zugelassen, wenn der entfernte Benutzer identifiziert werden kann.
[Bearbeiten] socket_type
Die Typen sind »stream«, »dgram«, »raw« und »seqpacket« und besitzen dieselbe Bedeutung wie beim inetd beschrieben wurde.
[Bearbeiten] protocol
Name des Protokolls, über das der Dienst arbeitet. Fehlt die Angabe, wird das »übliche« Protokoll des Dienstes angenommen.
[Bearbeiten] 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.
[Bearbeiten] user
Die Nutzerkennung, unter der der Serverprozess gestartet wird.
[Bearbeiten] group
Die Gruppenkennung, unter der der Serverprozess gestartet wird.
[Bearbeiten] instances
Maximal mögliche Anzahl Prozesse, die den Dienst zu einer Zeit ausführen dürfen. Neben der Zahl darf auch »UNLIMITED« stehen.
[Bearbeiten] nice
Priorität des Serverprozesses.
[Bearbeiten] server
Programmname des Servers (inklusive Pfad)
[Bearbeiten] server_args
Argumente des Serverprogrammes
[Bearbeiten] 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)
[Bearbeiten] 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).
[Bearbeiten] access_times
Tageszeit, zu der der Zugriff erlaubt ist
[Bearbeiten] log_type
Wo und wie soll protokolliert werden? Mit »SYSLOG Herkunft [Level]« wird die Protokollierung an den Protokollierung weitergereicht; mit »FILE Datei [soft_limit [hardlimit]]« erfolgt sie in der angegebenen Datei. Die beiden Limits sind die Schranken, wie groß eine Datei maximal werden kann, somit wird ein Volllaufen des Dateisystems ausgeschlossen.
[Bearbeiten] 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«.
[Bearbeiten] 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.
[Bearbeiten] rpc_version
Versionsnummer des RPC-Dienstes
[Bearbeiten] env
Hier lassen sich zu einem Server zusätzliche Umgebungsvariablen angeben
[Bearbeiten] passenv
Liste der Umgebungsvariablen, die der xinetd dem Server vererbt
[Bearbeiten] port
Portnummer, an der der Server wartet, diese muss mit dem Eintrag in der Datei /etc/services (soweit vorhanden) übereinstimmen
[Bearbeiten] redirect
Eine Anforderung wird an den angegebenen Rechner weitergeleitet. Dies ist nur bei TCP-Diensten möglich
[Bearbeiten] 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
[Bearbeiten] 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:
[Bearbeiten] SIGUSR1 (10)
Einlesen der Konfigurationsdatei. Aktive Dienste bleiben aktiv.
[Bearbeiten] SIGUSR2 (12)
Einlesen der Konfigurationsdatei. Aktive Dienste werden sofort beendet.
[Bearbeiten] SIGQUIT (3)
Programmende, ohne laufende Dienste zu beenden
[Bearbeiten] SIGTERM (15)
Programmende, laufende Dienste werden zuvor beendet
[Bearbeiten] SIGHUP (1)
Anlegen eines Speicherauszugs und Programmende
[Bearbeiten] SIGIO (29)
Interne Konsistenzprü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.
defaults
{
log_type = FILE /var/lo/xinetd.log
log_on_success = HOST
log_on_failure = HOST USERID
instance = 5
disabled = finger
}
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:
service telnet
{
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/sbin/in.telnetd
only_from = 192.168.100.0
no_access = 192.158.100.56/192
flags = IDONLY
log_on_failure += RECORD
log_type = SYSLOG auth warn
}
Beispiel 3: »ftp« soll nur in den Nachtstunden erlaubt sein. Gleichzeitig werden 4 Zugriffe zugelassen.
service ftp
{
socket_type = stream
wait = no
user = root
server = /usr/sbin/wu.ftpd
server_flags = -a
log_on_success += DURATION
access_times = 20:00-06:00
instance = 4
}
Beispiel 4: Von den internen Diensten soll »time« sowohl über »udp« als auch über »tcp« bereitgestellt werden:
service time
{
id = time_dgram
socket_type = dgram
wait = no
user = root
}
service time
{
id = time_stream
socket_type = stream
wait = no
user = root
}
Beispiel 5: Zuletzt noch ein Beispiel zu einem RPC-Dienst:
service rstatd
{
type = RPC
socket_type = dgram
wait = yes
user = root
server = /usr/etc/rpc.rstatd
rpc_version = 2-4
env = LD_LIBRARY_PATH=/etc/securelib
}


