zurück zu Linux Zertifizierungen LPIC
1.113.1 – Konfiguration und Verwaltung von inetd, xinetd und verwandten Diensten
Prüfungskandidaten sollten in der Lage sein, die über inetd verfügbaren Dienste zu konfigurieren, tcpwrappers für das Erlauben oder Verweigern von Diensten auf Host-Ebene zu verwenden, Internetdienste manuell zu starten, stoppen und neu zu starten und grundlegende Netzwerkdienste einschließlich Telnet und FTP zu konfigurieren. Ebenfalls enthalten ist das Ausführen von Diensten unter einer anderen als der voreingestellten Benutzerkennung in inetd.conf.
Die wichtigsten Dateien, Bezeichnungen und Anwendungen:
* /etc/inetd.conf
* /etc/hosts.allow
* /etc/hosts.deny
* /etc/services
* /etc/xinetd.conf
* /etc/xinetd.log
Der inetd-Superserver
Bei der großen Anzahl von möglichen Servern, die auf einem Rechner laufen müssten, damit alle Internetdienste immer bereit sind, wäre es schnell soweit, daß der Speicher mit untätigen Servern überfüllt wäre. Damit das vermieden wird, gibt es einen „Superserver“, der alle möglichen Portnummern abhört und bei Anfrage einen entsprechenden Server startet. Damit kann es ermöglicht werden, daß nur die Server laufen, die gerade arbeiten, obwohl alle Dienste verfügbar sind.
Der zuständige Daemon heißt inetd und wird in der Datei /etc/inetd.conf konfiguriert. Der Aufbau dieser Datei ist verhältnismäßig einfach, meist sind alle notwendigen Einträge schon vorhanden. Sie müssen nur jeweils auskommentiert werden, wenn sie nicht erwünscht sind. Das Format der Datei ist folgendermaßen organisiert:
Dienstname Socket-Typ Transportprotokoll Flags User Programm Argumente
Die Felder haben folgende Bedeutung:
Dienstname
Hier steht der Name eines Dienstes, so, wie er in der Datei /etc/services eingetragen ist. Die ganze folgende Zeile bezieht sich darauf, daß ein Client versucht, auf dem Port zuzugreifen, der in /etc/services unter diesem Namen genannt ist.
Socket-Typ
Gültige Werte für den Socket-Typ sind stream, dgram, raw, rdm und seqpacket, wobei in der Praxis meist nur die ersten beiden eine Rolle spielen. Über den Daumen gepeilt kann behauptet werden, daß jedes Programm, daß als Transportprotokoll TCP benutzt, hier ein stream eingetragen hat, jedes, das mit UDP arbeitet hat hier ein dgram benutzt.
Transportprotokoll
Das hier eingetragene Transportprotokoll muß eins der in /etc/protocols angegebenen Protokolle sein. In der Regel spielen hier nur tcp und udp eine Rolle.
Flags
An dieser Stelle gibt es nur zwei gültige Einträge, wait und nowait. Die Unterscheidung spielt nur für UDP-basierte Anwendungen eine Rolle. Alle anderen sollten hier ein nowait eingetragen haben. Wenn ein Datagram-Server (ein Server, der mit UDP arbeitet) nach der Versendung eines Datagrams den benutzten Socket löscht, so daß inetd weitere Anfragen auf diesem Socket empfangen kann, dann spricht man von einem multi-threaded Server und sollte hier nowait benutzen. Datagram-Server, die alle eingehenden Datagramme über einen Socket empfangen und letztendlich mit einem TimeOut reagieren, werden single-threaded genannt und benötigen hier den Wert wait. Typische Vertreter dieses Typs sind die biff und talkd Daemonen.
Optional kann diesem Eintrag noch ein Maximalwert mitgegeben werden, der angibt, wieviele dieser Server maximal innerhalb von 60 Sekunden gestartet werden dürfen. Dieser Wert wird durch einen Punkt getrennt an wait oder nowait angehängt. Seine Voreinstellung ist 40.
User
Der User-Eintrag legt fest, unter welcher UserID das Serverprogramm laufen soll. Nachdem inetd selbst unter der UserID 0 läuft, kann hier verhindert werden, daß bestimmte Dienste auch unter dieser gefährlichen UID laufen. Optional kann diesem Eintrag ein durch Punkt vom Usernamen getrennter Gruppennamen folgen, der entsprechend die GID setzt.
Programm
Hier wird das Programm angegeben, das gestartet werden soll, wenn eine auf diesen Eintrag passende Anfrage eingeht. Es wird der komplette Pfad und Programmname angegeben. Wenn inetd diesen Dienst selbstständig anbietet, so steht hier internal.
Argumente
Die Argumente (Kommandozeilenoptionen) für das zu startende Programm. Normalerweise wird der Programmname selbst (Argument 0) mit angegeben. Auch hier wird das Wort internal angegeben oder der Eintrag wird leer gelassen, wenn inetd den Dienst intern zur Verfügung stellt.
So bedeutet die folgende Zeile also:
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd
Wenn eine Nachfrage nach dem Service ftp ankommt, (über den Sockettyp stream, mit dem Protokoll TCP) wird unter der UserID root das Programm /usr/sbin/in.ftpd ohne weitere Parameter gestartet und mit der Anfrage verbunden.
Die nötigen Portnummern bezieht inetd aus der Datei /etc/services .
Der inetd ließt diese Konfigurationsdatei nur beim Start. Wenn also Veränderungen daran vorgenommen wurden, so muß entweder der inetd neu gestartet werden, oder ihm muß ein HUP-Signal geschickt werden. Dieses Signal zwingt ihn, seine Konfigurationsdatei neu einzulesen.
Der TCP-Daemon (tcpwrapper)
Neben dem oben gezeigten Beispiel gibt es noch eine spezielle Form des Aufrufs über den inetd. In der Datei inetd.conf finden sich oft auch Zeilen wie die folgenden:
klogin stream tcp nowait root /usr/sbin/tcpd rlogind -k
eklogin stream tcp nowait root /usr/sbin/tcpd rlogind -k -x
kshell stream tcp nowait root /usr/sbin/tcpd rshd -k
Hier scheint auf den ersten Blick immer das gleiche Programm aufgerufen zu werden, nämlich /usr/sbin/tcpd. Erst als dessen Parameter kommen die eigentlichen Server an die Reihe. In der Tat ist es so, daß hier der TCP-Daemon (tcpd) aufgerufen wird, der dann erst die Server aufruft. Das klingt auf den ersten Blick unsinnig, aber es ermöglicht eine Einstellung, wer diesen Service benutzen darf.
Der tcpd überprüft anhand der Dateien /etc/hosts.allow und /etc/hosts.deny ob der jeweilige Host überhaupt berechtigt ist, diesen Dienst in Anspruch zu nehmen. Eine genaue Darstellung dieser Technik:
TCP-Wrapper
Ursprünglich alleine für die Verwendung mit inetd gedacht, hat sich das Prinzip des TCP-Wrappers inzwischen auch für Stand-Alone-Dienste wie ssh durchgesetzt. Worum geht es?
Wenn ein bestimmter Dienst aufgerufen wird, so kann er – anstatt direkt aufgerufen zu werden – durch das Programm tcpd aufgerufen werden. Dazu wird einfach statt dem zu startenden Dienst der tcpd aufgerufen und ihm wird der Name des zu startenden Dienstes als Parameter mitgegeben. Das Programm tcpd überprüft jetzt anhand von Einträgen in den Dateien
* /etc/hosts.allow
* /etc/hosts.deny
ob der Dienst von dem entsprechenden Host in Anspruch genommen werden darf. Analog überprüfen auch Stand-Alone-Dienste diese beiden Dateien.
Die Überprüfung erfolgt auf eine etwas eigenwillige Weise:
* Existiert ein passender Eintrag in der Datei /etc/hosts.allow, so wird Zugriff gegeben. Wenn nicht, dann
* Existiert ein passender Eintrag in der Datei /etc/hosts.deny, so wird kein Zugriff gegeben. Wenn nicht, dann
* wird Zugriff gegeben.
Die klassische Form der TCP-Wrapper
Das Format beider Dateien ist in der Handbuchseite hosts_access(5) genauestens dargestellt, es handelt sich um Zeilen des Formats:
Serverliste : Clientliste [: Shellkommando]
* Serverliste ist eine Liste von Servern (Programmnamen), oder Wildcards. Server werden mit ihrem Programmnamen – nicht über ihr Protokoll – angegeben, also z.B.: in.telnetd
* Clientliste ist eine Liste von einem oder mehreren Hostnamen, IP-Adressen, Suchmustern oder Wildcards,
* Shellkommando ist ein Kommando, das die lokale Shell ausführt, wenn der Dienst angefordert wurde und der Eintrag ausschlaggebend für seine Ausführung oder Nichtausführung war. Damit kann etwa eine Warnmeldung an root gegeben werden, wenn jemand versucht auf einen verbotenen Service zuzugreifen.
Als Suchmuster kommen zwei einfache Verfahren in Frage:
1. Beginnt ein Suchmuster mit einem Punkt (z.B. .foo.bar), so gelten alle Hostnamen als Treffer, deren Ende mit dem Muster übereinstimmt also etwa hal.foo.bar
2. Endet ein Suchmuster mit einem Punkt (z.B. 192.168.200.), so gelten alle Namen und Adressen als Treffer, deren erster Teil mit dem Muster übereinstimmt.
Als Wildcards können unter anderem folgende Werte verwendet werden:
ALL
Die universelle Wildcard, alles gilt…
LOCAL
Alle Hostnamen ohne Punkt (also lokale Namen) gelten.
UNKNOWN
Passt auf alle Usernamen, die unbekannt sind und alle Hosts, deren Namen oder Adressen nicht bekannt sind. Wird gerne in /etc/hosts.deny verwendet.
KNOWN
Passt auf alle Hosts und User, die bekannt sind
EXEPT
Ist ein Operator, um zwei Listen auszuschließen (Liste1 EXEPT Liste2) also etwa ALL EXEPT UNKNOWN
Das Shellkommando sollte grundsätzlich mit einem & beendet werden, weil sonst auf seine vollständige Abarbeitung gewartet wird, bevor ein Service evt. gestartet wird. Je nach Kommando kann das natürlich dauern…
Als zusätzliche Platzhalter in Shellkommandos können folgende Konstrukte verwendet werden:
%a
Die IP-Adresse des anfordernden Hosts
%A
Die IP-Adresse des aufgerufenen Servers
%c
Clientinformationen – User@Host oder User@IP-Adresse oder nur IP-Adresse des Anrufers, je nach dem, wieviel Informationen zur Verfügung stehen.
%d
Der Name des Daemon-Prozesses, der angefordert wurde.
%h
Name (oder falls nicht vorhanden IP-Adresse) des Clients
%H
Name (oder falls nicht vorhanden IP-Adresse) des Servers
%p
Die ProzessID des Daemon-Prozesses
%s
Serverinformationen – Daemon@Hostname oder Daemon@Adresse oder nur Daemon, je nach dem, wieviel Informationen zur Verfügung stehen.
%u
Der Username des Anrufers oder „unknown“
%%
Das %-Zeichen
Die modernere Form der Wrapper
Moderne Systeme arbeiten heute zwar immer noch mit dem dargestellten Prinzip, bieten aber auch die Möglichkeit, alle Einstellungen in nur einer der beiden Dateien vorzunehmen. Statt der Handbuchseite hosts_access(5) wird diese Methode in hosts_options(5) beschrieben. Der Aufbau der beiden Dateien sieht jetzt folgendermaßen aus:
Serverliste : Clientliste [: Option ] [: Option …]
Statt einem Shellkommando können also Optionen angegeben werden. Die wichtigsten Optionen sind:
ALLOW
Erlaubt den angegebenen Dienst für die angegebenen Clients.
DENY
Verbietet den angegebenen Dienst für die angegebenen Clients.
spawn Shellkommando
Führt das angegebene Shellkommando aus. Wie in der klassischen Form werden die oben beschriebenen Ersetzungen vorgenommen.
twist Shellkommando
Führt das angegebene Shellkommando aus und schickt seine Ausgaben an den Client, anstatt den gewünschten Dienst zu starten. Wie in der klassischen Form werden die oben beschriebenen Ersetzungen vorgenommen.
user Username[.Gruppe]
Startet den angegebenen Dienst unter der angegebenen User (und optional Gruppen) ID.
Der Vorteil dieser Methode liegt darin, daß alle Einstellungen in einer Datei vorgenommen werden können. Da die Optionen ALLOW und DENY zur Verfügung stehen, können in /etc/hosts.allow auch Verbote ausgesprochen werden und umgekehrt.
Aber Achtung: Es gilt immer noch die oben angegebene Reihenfolge. Es nützt also nichts, einem Host etwas zu erlauben, ohne allen anderen es zu verbieten. Die Einträge werden der Reihe nach gelesen und der erste passende wird benutzt. Um also nur dem Rechner marvin.foo.bar zu erlauben, den FTP-Daemon zu benutzen, müssten wir schreiben:
in.ftpd : marvin.foo.bar : ALLOW
in.ftpd : ALL : DENY
Wenn der Rechner marvin.foo.bar jetzt den Dienst anfordert, greift die erste Zeile und der Zugriff wird gewährt. Versucht aber ein anderer Rechner den Zugriff, so greift die erste Zeile nicht, dafür aber die zweite – der Zugriff wird verwehrt.
Der xinetd-Server
Der Server xinetd ist ein sicherer Ersatz für inetd. Er bietet eine eingebaute Zugriffskontrolle und eine direkte Unterstützung der Dateien /etc/hosts.allow und /etc/hosts.deny ohne den Umweg über tcpd. Außerdem werden noch viele weitere Verbesserungen angeboten wie etwa
* Beschränkung der Verbindungen entweder generell, oder pro Dienst oder pro Client.
* Beschränkung von Verbindungen anhand der Tageszeit.
* Dienste können an bestimmte IP-Adressen gebunden werden, so daß z.B. interne Clients andere Server-Programme nutzen als externe Clients, obwohl sie den selben Dienst aufgerufen haben.
* Schutz vor denial of service Angriffen.
* Ausgiebige Log-Möglichkeiten (auch unabhängig von syslogd).
* Umleitung von TCP-Verbindungen zu einem anderen Rechner, der selbst nicht von außen erreichbar sein muß. Damit können Server hinter einem Masquerading-Server auch von außen benutzt werden.
* Volle Unterstützung von IPv6.
* Interaktion mit dem User des Clients (Meldungen bei erfolgtem oder gescheitertem Zugriff).
Die Konfiguration des xinetd erfolgt analog zu seinem Vorgänger in der Datei /etc/xinetd.conf. Allerdings hat diese Datei einen vollkommen anderen Aufbau als /etc/inetd.conf. Für UmsteigerInnen gibt es ein spezielles Shellscript, das eine bestehende inetd.conf Datei in das neue Format konvertiert. Dieses Programm ist ein Perl-Script (xconv.pl) und wird mit xinetd mitgeliefert.
Die Konfigurationsdatei von xinetd beginnt mit einem Abschnitt für die Voreinstellungen, der default section. Die hier angegebenen Attribute werden von jedem Dienst genutzt, den xinetd verwaltet. Nach diesem Abschnitt folgen für jeden einzelnen zu startenden Dienst ein eigener Abschnitt. Wenn in einem solchen dienstspezifischen Abschnitt Angaben gemacht werden, die denen der default section widersprechen, so gelten die des dienstspezifischen Abschnitts.
Die typische Form einer default section ist folgendermaßen aufgebaut:
defaults
{
Attribut Operator Wert(e)
…
}
Alle weiteren Abschnitte beginnen mit dem Schlüsselwort service, dem der Name des Dienstes (wie er in /etc/services eingetragen ist) folgt.
service Dienstname
{
Attribut Operator Wert(e)
…
}
Es gibt drei unterschiedliche Operatoren, mit denen Attribute mit Werten versehen werden:
=
Setzt einen Wert für ein Attribut.
+=
Fügt einem Attribut einen Wert zu den bereits bestehenden Werten hinzu.
-=
Entfernt einem Attribut den angegebenen Wert.
Es existieren sehr viele möglichen Attribute, deren Beschreibung den Rahmen hier sprengen würde. Ein Beispiel für eine solche Datei sagt hier mehr als eine endlose Beschreibung:
defaults
{
instances = 15
log_type = FILE /var/log/xinetd.log
log_on_success = HOST PID USERID DURATION EXIT
log_on_failure = HOST USERID RECORD
only_from = 192.0.0.0/8
disabled = shell login exec comsat
disabled += telnet ftp
disabled += name uucp tftp
disabled += finger systat netstat
}
service ftp
{
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.ftpd
server_args = -l
instances = 4
access_times = 7:00-12:30 13:30-21:00
nice = 10
only_from = 192.168.1.0/24
}
In der defaults-Section definieren wir hier das Attribut instances mit dem Wert 15. Das bedeutet, daß grundsätzlich nicht mehr als 15 Dienste gleichzeitig gestartet werden können. Später in der Definition des FTP-Dienstes setzen wir den Wert 4 für dieses Attribut. In diesem Fall bezieht es sich auf die Menge der gleichzeitigen FTP-Verbindungen.
Die Angabe log_type = FILE /var/log/xinetd.log bestimmen wir, daß nicht der syslogd benutzt werden soll, sondern xinetd direkt in die angegebene Datei schreibt. Anstatt diesem Eintrag wäre auch folgender möglich gewesen:
log_type = SYSLOG daemon info
Dann wären alle Meldungen über den Syslog-Daemon geschrieben worden und zwar mit der Herkunft daemon und der Priorität info.
Die beiden Angaben log_on_success und log_on_failure legen fest, was alles in das Logbuch aufgenommen werden soll, wenn ein Zugriff erfolgreich war oder abgelehnt wurde.
Die Angabe only_from = 192.0.0.0/8 bestimmt, daß grundsätzlich (wenn beim entsprechenden Dienst nichts anderes angegeben wurde) nur die Rechner Zugriff haben, die auf die angegebene Adresse passen. Das /8 bestimmt, daß nur die ersten 8 Bit der Adresse gewertet werden. In unserem Beispiel werden also alle Rechner Zugriff bekommen, deren erstes Adressenbyte 192 ist.
Die folgenden Zeilen der default section schalten die angegebenen Dienste mit dem Attribut disabled komplett ab.
Im Abschnitt FTP werden jetzt die einzelnen Attribute für den Dienst gesetzt. Die ersten vier Einträge entsprechen dem, was auch in der alten inetd Konfiguration eingetragen war. Interessant sind hier noch die Angaben über die erlaubten Tageszeiten, in denen der Dienst zur Verfügung steht und der gesetzte NICE-Wert, unter dem der Daemon laufen soll. Zugreifen dürfen nur Rechner, deren Adresse mit 192.168.1 beginnt.
Eine Liste aller Attribute und ihrer Bedeutungen sind auf der Handbuchseite von xinetd.conf(5) zu finden. Eine genaue Beschreibung der Formate der Logdateien sind in der Handbuchseite xinetd.log(5) nachlesbar.