xinetd

ArticleCategory:

System Administration

AuthorImage:

TranslationInfo:

Original in fr Frédéric Raynal

fr to en Georges Tarbouriech

en to de Harald Radke

AboutTheAuthor:

Frédéric Raynal verfasst eine Doktorabeit über den Einsatz von Wasserzeichen für die Validierung digitaler Bilder. Er arbeitet zur Zeit am INRIA (Institut National de Recherche en Informatique et Automatique).

Abstract

Das Programm xinetd, extended Internet services daemon, stellt eine guten Schutz gegenüber unbefugten Zugriffen dar und vermindert die Gefahr eines DoS, Denial of Service, Angriffes. Ebenso, wie die bewährte Kombination von inetd+tcpd, steuert es die Zugriffsrechte des Rechners, leistet darüberhinaus aber noch viel mehr. In diesem Artikel werden die Fähigkeiten von xinetd vorgestellt.

ArticleIllustration

security

ArticleBody

Was ist xinetd ?

Das klassische inetd dient der Steuerung und Überwachung von Netzwerkverbindungen eines Rechners. Trifft eine Anfrage auf einem Port ein, der von xinetd verwaltet wird, wird diese an ein Programm namens tcpd weitergeleitet. Dieses entscheidet auf Basis der Regeln in den Dateien hosts.allow und hosts.deny, ob die Anfrage zulässig ist. Ist dies der Fall, so wird der entsprechende Serverprozess , zum Beispiel ftpd, gestartet und die Anfrage bearbeitet. Dieser Mechanismus ist auch als tcp_wrapper bekannt.

xinetd bietet ähnliche Möglichkeiten zur Zugriffssteuerung an, wie der tcp_wrapper. Zusätzlich leistet es noch mehr:

Das Hauptproblem, wie schon erwähnt, stellt die Abwicklung von RPC Aufrufen dar. Jedoch arbeiten portmap und xinetd großartig zusammen.

Im ersten Teil dieses Artikels wird erklärt, wie xinetd funktioniert. Ausführlich wird die Konfiguration des Systems, sowie einige spezielle Optionen (Beschränkung auf ein Netzinterface, Umleitung) beschrieben. Dabei werden zur Veranschaulichung einige Beispiel vorgestellt. Im zweiten Teil schließlich wird xinetd im laufen Betrieb betrachtet und ein Blick auf die Protokolldateien geworfen. Zum Schluß gibt es dann noch einen nützlichen Tip.

Übersetzen & Installatieren

Von www.xinetd.org kann man das Programm beziehen. In diesem Artikel wurde Version 2.1.8.9pre10 verwendet.
Übersetzung und Installation sehen wie üblich aus:

./configure
make
make install,
das wars :)

configure bietet auch hier die üblichen Optionen. Desweiteren gibt es zur Übersetzungszeit drei spezielle Schalter:

  1. --with-libwrap : wird diese Option verwendet. so überprüft xinetd, ob die Konfigurationsdateien für tcpd (/etc/hosts.allow und /etc/hosts.deny) zu finden sind. Falls auf diese zugegriffen werden kann, verwendet xinetd seine Kontrolmechanismen. Soll diese Option verwendet werden, so müssen tcp_wrapper und die notwendigen Bibliotheken auf dem System installiert sein (Bemerkung: alles, was der Wrapper leistet, kann auch mit xinetd realisiert werden. Entscheidet man sich dennoch dafür, steigt die Zahl der Konfigurationsdateien unnötig an, die Administration wird aufwendiger... kurz: es ist nicht zu empfehlen).
  2. --with-loadavg : übersetzt man xinetd mit dieser Option, kann später bei der Konfiguration des Programmes die Option max_load verwendet werden. Durch diese können Server deaktiviert werden, sollte der Rechner zu überlasten drohen, eine wesentliche Einstellung zur Abwehr von DoS Angriffen (siehe auch den max_load Eintrag in Tabelle 1).
  3. --with-inet6 : Unterstützung für IPv6. Sowohl IPv4, als auch IPv6 Verbindungen werden verwaltet, allerdings werden ggfs. IPv4 Adressen in das IPv6 Format umgewandelt.
Es ist nicht notwendig, vor dem Start von xinetd das Programm inetd zu beenden. Dies kann aber zu einem unerwarteten Verhalten beider Programme führen!

Über folgende Signale kann man das Verhalten von xinetd beeinflussen:

Es gibt noch weitere Signale (hier sollte ein Fehler in der Dokumentation und den Manpages erwähnt werden: SIGHUP speichert die Ausgabe unter /var/run/xinetd.dump und nicht unter /tmp/xinetd.dump). Die oben erwähnten Signale können recht bequem mittels eines Skriptes verwendet werden, und z.B. über Stichworte wie start, stop, restart, soft und hard als Parameter des Skriptes gesendet werden (die letzten beiden korrespondieren zu SIGUSR1 und SIGUSR2).

Konfiguration

Die Datei /etc/xinetd.conf dient standardmäßig der Konfiguration des xinetd Daemons (eine alternative Datei kann als Kommandozeilenparameter übergeben werden). Ist die Konfiguration von xinetd auch nicht allzu komplex, so doch ein wenig aufwendiger und die Syntax unterscheidet sich erheblich von der des Vorgängerprogrammes inetd.

Es gibt zwei Werkzeuge namens itox und xconv.pl, welche mit xinetd mitkommen und den Inhalt von /etc/inetd.conf als Basis für die Konfigurationsdatei von xinetd verwenden. Damit ist es das natürlich nicht gewesen, da die Regeln, definiert in der Wrapper Konfiguration, nicht berücksichtigt werden. itox wird wohl nicht mehr weiterentwickelt. Generell ist xconv.pl die bessere Wahl, auch wenn die Ergebnisse noch zusätzlich per Hand angepaßt werden müssen, da xinetd mehr Funktionalität als inetd bietet.

/usr/local/sbin/xconv.pl < /etc/inetd.conf > /etc/xinetd.conf
Am Anfang der Konfigurationsdatei stehen die Standardeinstellungen. Alle Attribute, die hier zu finden sind, werden für jeden Dienst,der von xinetd verwaltet wird, verwendet. Für jeden Dienst folgt nun ein eigener Bereich, in welchem Standardeinstellungungen angepaßt werden können.

Der Eintrag für die Standardeinstellungen sieht so aus:

	defaults
	{
		attribut operator wert(e)
		...
	}

Die Werte jedes Attributes, die diesem hier zugwiesen werden, sind für alle folgenden Dienste gültig. Deswegen kann man mittels des Attributes only_from eine feste Liste von IP Adressen angeben, die die Dienste nutzen dürfen:

only_from = 192.168.1.0/24/192.168.5.0/24 192.168.10.17
Dadurch dürfen alle Rechner mit obigen Adressen alle hier konfigurierten Dienste in Anspruch nehmen. Aber natürlich können diese Werte zusätzlich noch für jeden Dienst einzeln modifiziert werden (man werfe ein Blick auf die weiter unten vorgestellten Operatoren). Dies ist allerdings ein wenig riskant. Es ist besser, will man das System einfach und sicher halten, nicht erst Standardwerte zu definieren, die dann später für einzelne Dienste wieder angepaßt werden. Betrachtet man beispielsweise Zugriffsrechte, so besteht die einfachste Vorgehensweise darin, zuerst generell den Zugriff zu verbieten und dann für jeden Dienst einzeln die anvisierten Benutzer anzugeben und diesen den Zugriff zu ermöglichen (bei tcp_wrapper wird dies dadurch realisiert, dass zuerst in der Datei hosts.deny die Regel ALL:ALL@ALL eingetragen wird und dann in hosts.allow alle zugelassenen Dienste und die erlaubten IP Adressen etwaiger Benutzer angegeben werden).

Die Syntax eines Eintrags für einen Dienst in xinetd.conf sie folgendermaßen aus:


	service
	{
		attribut operator wert(e)
		...
	}

Als Operatoren stehen zur Auswahl: =, += und -=. Die meisten Attribute lassen jedoch nur den Operator = zu. Dieser weist einem Attribut einen bestimmten Wert zu. Durch += wird ein Eintrag einer Liste von Werten hinzugefügt, mittels -= hingegen wird der Eintrag aus der Liste entfernt.

Tabelle 1 gibt eine kurze Übersicht der Attribute. Deren Einsatz wird in einigen Beispielen verdeutlicht werden. Weitergehende Informationen kann man der Manpage zu xinetd.conf entnehmen.

Attribut Werte und Beschreibung
Flags Nur die gängigsten Werte werden hier aufgeführt; weitere sind in der Dokumentation zu finden:
  • IDONLY : es werden nur Verbindungen mit Client-Rechnern zugelassen, auf denen ein Server zur Identifikation läuft
  • NORETRY : unterbindet das Anlegen eines neuen Prozesses im Fehlerfall
  • NAMEINARGS : Das erste Argument des Attributes server_args wird als argv[0] des servers verwendet. Dadurch wird es möglich, tcpd zu verwenden, indem es dem Attribut server zugewiesen wird, gefolgt vom Namen des Servers und dessen Parameter als sever_args, genau, wie bei inetd.
log_type xinetd verwendet syslogd, als Selektor wird standardmäßig daemon.info gewählt.
  • SYSLOG Selektor [level] : Auswahl zwischen daemon, auth, user oder local0-7 des syslogd Daemons.
  • FILE [max_size [absolute_max_size]] : In die hier angegebene Datei wird die Ausgabe gesichert. Die beiden Optionen begrenzen die Dateigröße. Wird der erste Wert erreicht, wird eine Nachricht an syslogd gesendet. Die Protokollierung des jeweiligen Dienstes wird eingestellt, sobald die Dateigröße den zweiten Parameter erreicht (sollte es sich um eine mehrfach verwandte Datei oder um eine Standardeinstellung in xinetd.conf handeln, können auch mehrere Dienste betroffen sein).
log_on_success Bei Start eines Servers können mehrere unterschiedliche Informationen festgehalten werden:
  • PID : die Server PID (handelt es sich um einen internen Dienst von xinetd ist die PID 0)
  • HOST : Die Adresse des Clients
  • USERID : die ID des Benutzers, der den Dienst in Anspruch nimmt, entsprechend dem in der RFC1413 definierten Protokolles
  • EXIT : Der Statuswert, den der Prozess bei Beendigung zurückliefert
  • DURATION : Verbindungsdauer
log_on_failure Hierdurch kann eine Vielzahl an Informationen protokoliert werden, sobald ein Server nicht gestartet werden kann, sei es aufgrund fehlender Resourcen oder der Verletzung der Zugriffsregeln:
  • HOST, USERID : wie oben
  • ATTEMPT : hält einen Zugriffsversuch fest. Diese Option wird automatisch gewählt, sobald ein weiterer Wert gesetzt wird
  • RECORD : protokolliert alle Informationen, die über den Client verfügbar sind
nice Ändert die Priorität des Servers, analog dem Unixbefehl nice.
no_access Liste der Clients, denen der Zugriff auf den jeweiligen Dienst verweigert werden soll
only_from Liste aller akzeptierten Rechner. Wird diesem Attribut kein Wert zugewiesen, so ist kein Zugriff auf den Dienst möglich
port Port, unter dem der Dienst erreichbar ist. Sollte dieser auch in der Datei /etc/services stehen, müssen beide Wert übereinstimmen.
protocol Das hier angegebene Protokoll muss in der Datei /etc/protocols aufgeführt sein. Wird dieses Attribut nicht gesetzt, wird das Standardprotokoll des Servers verwendete
server Pfad, unter dem der Server zu finden ist
server_args Parameter, die an den Server übergeben werden sollen
socket_type stream (TCP), dgram (UDP), raw (IP Direktzugriff) oder seqpacket ()
type xinetd verwaltet drei Arten von Diensten:
  1. RPC : alle, die in der Datei /etc/rpc zu finden sind...funktioniert nicht allzu gut
  2. INTERNAL :Dienste, die direkt von xinetd verwaltet werden (echo, time, daytime, chargen und discard)
  3. UNLISTED : Dienste, die weder in /etc/rpc noch in etc/services stehen.
Bemerkung: man kann mehrere Wert kombinieren, wie bei den internen Diensten servers, services und xadmin gezeigt wird
wait Legt das threading Verhalten des Dienstes fest. Es gibt zwei Möglichkeiten:
  • yes : der Dienst ist mono-threaded, dass heißt es kann immer nur eine Verbindungen dieses Types unterhalten werden
  • no : für jede neue Anfrage startet xinetd einen neuen Serverprozess, unter Berücksichtigung etwaiger Beschränkungen der maximalen Zahl an Servern (Achtung: standardmäßig gibt es keine Obergrenze für die Serverzahl)
cps Beschränkt die Zahl der zugelassenen Verbindungen. Als erster Parameter wird die Zahl selbst angeben. Der zweite Wert legt die Zeit fest, die der Dienst für weitere Verbindungen erreichbar ist, sobald das Limit erreicht wurde.
instances Maximale Zahl an Servern des gleichen Types, die simultan laufen dürfen
max_load Tatsächliche maximale Last eines Servers (z.B. 2 oder 2.5). Wird dieser Wert überschritten, nimmt der Server keine weiteren Anfragen an
per_source Ein Zahlenwert oder UNLIMITED. Ermöglicht es, die Zahl der Verbindungen, die ein Dienst mit einem einzelnen Clientrechner unterhält, zu beschränken.
Tab. 1 : einige Attribute von xinetd

Die letzten vier Attribute in Tabelle 1 bieten die Möglichkeit, die Resourcen je nach Server zu verwalten. Dies stellt einen effizient Schutz vor Denial of Service Angriffen dar (Lahmlegen eines Rechners, indem dessen Resourcen komplett belegt werden).

In diesem Abschnitt wurden ein wenig von der Funktionalität von xinetd vorgestellt. Im nächsten wird nun gezeigt, wie diese angewandt wird und einige Regeln erläutert, so dass xinetd korrekt funktioniert.

Die Sektion: default

In diesem Abschnitt können Standardwerte für eine Anzahl von Attributen (eine komplette Liste ist in der Dokumentation zu finden) gesetzt werden. Einige der Attribute, wie etwa only_from,no_access, log_on_success oder log_on_failure, können gleichzeitig Werte dieser Sektion und der der einzelnen Dienste beinhalten.

Der erste Schritt hin zu einem sicheren System ist, standardmäßig allen Rechnern den Zugriff zu verweigern. Danach wird dann für den jeweiligen Dienst separat festgelegt, wer diesen nutzen darf. Wie gesehen gibt es zwei Attribute, die den Zugriff auf Basis der IP Adresse eines Rechners steuern: only_from und no_access. Unter Verwendung des letzteren:

no_access = 0.0.0.0/0

wird der Zugriff auf alle Dienste unterbunden. Soll dann etwa echo (ping) allen zugängig gemacht werden, sollte in der Sektion für den echo Dienst folgendes stehen:

only_from = 0.0.0.0/0

Unter Verwendung dieser Einstellungen erhält man folgende Ausgabe:

Sep 17 15:11:12 charly xinetd[26686]: Service=echo-stream: only_from list and no_access list match equally the address 192.168.1.1

Bei der Entscheidung, ob ein Zugriff erlaubt werden soll, werden die Adresslisten beider Attribute überprüft. Wird die Adresse des Clientrechners von beiden Listen überdeckt, so ist das Attribut relevant, welches weniger allgemein ist. Kann dies nicht festgestellt werden (beide gleich allgemein), so wird die Verbindung nicht zugelassen. Um dies zu beheben, sollte man stattdessen folgendes schreiben:

only_from = 192.0.0.0/8
Eine einfachere Lösung besteht darin, in der Sektion defaults folgendes Attribut zu verwenden:
only_from =
Wird kein Wert zugewiesen, scheitert jeder Verbindungsaufbau :)
Danach kann jeder Dienst den Zugriff über eine entsprechende Zuweisung an dieses Attribut regeln.

Wichtig, ganz wichtig: wird gar keine Zugriffsregel (also weder das Attribut only_from, noch no_access) für einen Dienst aufgestellt (weder in dessen, noch in der defaults Sektion), so kann jeder diesen Dienst nutzen!

Ein Beispiel für die defaults Sektion:

defaults
{
  instances       = 15
  log_type        = FILE /var/log/servicelog
  log_on_success  = HOST PID USERID DURATION EXIT
  log_on_failure  = HOST USERID RECORD
  only_from       =
  per_source      = 5

  disabled = shell login exec comsat
  disabled = telnet ftp
  disabled = name uucp tftp
  disabled = finger systat netstat

  #INTERNAL
  disabled = time daytime chargen servers services xadmin

  #RPC
  disabled = rstatd rquotad rusersd sprayd walld
}

Mittels servers, services und xadmin unter #INTERNAL kann xinetd gesteuert werden. Später dazu mehr.

Konfiguration eines Dienstes

Was muss man nun noch zusätzlich tun, um einen Dienst zu konfigurieren ? Beinahe nichts... :) Naja, es müssen halt gegebenenfalls die Standardwerte einiger Attribute angepasst bzw. weitere Attribute für den jeweiligen Dienst verwendet werden.

Einige Attribute müssen, je nach Art des Dienstes (INTERNAL, UNLISTED oder RPC), angegeben werden:

Attribut Verwendung
socket-type Jeder Dienst
user Nur Dienste, die keine INTERNAL Dienste sind
server Nur Dienste, die keine INTERNAL Dienste sind
wait Alle Dienste
protocol Alle RPC Dienste und solche, die nicht in /etc/services zu finden sind
rpc_version Jeder RPC Dienst.
rpc_number Jeder RPC Dienst ohne Eintrag in /etc/rpc.
port Jeder Dienst, der kein RPC Dienst ist und nicht in/etc/services steht
Tab. 2: notwendige Attribute

Hier ein Beispiel, wie die Konfiguration von Diensten aussieht:

service ntalk
{
  socket_type   = dgram
  wait          = yes
  user          = nobody
  server        = /usr/sbin/in.ntalkd
  only_from     = 192.168.1.0/24
}

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
}

Man beachte, dass diese Dienste nur im lokalen Netzwerk zugäglich sind (293.268.1.0/24). Was FTP angeht, so wurde der Zugriff noch weiter eingeschränkt: Nur 4 Rechnern wurde der Zugriff gestattet und dies auch nur zu bestimmten Zeiten.

Ports an Adressen binden: Das Attribut bind

Mittels diesem Attribut kann man einen Dienst an eine IP Adresse binden. Besitzt der Rechner sowieso nur eine Adresse, ist dies nicht sehr sinnig. Ein Rechner allerdings, der einerseits an einem lokalen Netzwerk, andereseits an das Internet angebunden ist, besitzt mindestens zwei Adressen.

Angenommen, eine Firma möchte einen FTP Server füpr ihre Angestellten installieren, etwa, damit diese auf interne Dokumente zugreifen und diese lesen können. Desweiteren sollen Kunden mittels FTP auf die Firmenprodukte zugreifen können. bind ist wie geschaffen für diesen Fall :) Es werden zwei FTP Dienste definiert. Diese müssen allerdings von xinetd unterschieden werden können. Dazu wird das Attribut id verwendet. Durch dieses wird ein Dienst eindeutig identifiziert. Sollte ein Dienst dem Attribut keinen Wert zuweisen, so wird standardmäßig der Dienstname als Wert verwendet.

service ftp
{
  id           = ftp-public
  wait         = no
  user         = root
  server       = /usr/sbin/in.ftpd
  server_args  = -l
  instances    = 4
  nice         = 10
  only_from    = 0.0.0.0/0 #allows every client
  bind         = 212.198.253.142 #public IP address for this server
}

service ftp
{
  id           = ftp-private
  socket_type  = stream
  wait         = no
  user         = root
  server       = /usr/sbin/in.ftpd
  server_args  = -l
  only_from    = 192.168.1.0/24 #only for internal use
  bind         = 192.168.1.1  #local IP address for this server (charly)
}

Durch den Einsatz von bind kann das jeweilige Daemonprogramm angesprochen werden, abhängig von der Zieladresse der Pakete. Will ein Client im lokalen Netzwerk auf intere Daten zugreifen, so muss er die lokale Adresse (bzw. den assoziierten Rechnernamen) des FTP Servers verwenden. In der Protokolldatei steht dann:
00/9/17@16:47:46: START: ftp-public pid=26861 from=212.198.253.142
00/9/17@16:47:46: EXIT: ftp-public status=0 pid=26861 duration=30(sec)
00/9/17@16:48:19: START: ftp-internal pid=26864 from=192.168.1.1
00/9/17@16:48:19: EXIT: ftp-internal status=0 pid=26864 duration=15(sec)
Der erste Teil stammt vom Befehl ftp 212.198.253.142, während der zweite Teil vom Aufruf von charly auf sich selbst resultiert: ftp 192.168.1.1.

Was passiert aber nun, falls ein Rechner keine zwei statischen IP Adressen hat ? Dies ist zum Beispiel bei PPP Verbindungen oder beim Einsatz von DHCP der Fall. Es wäre besser, könnten Dienste an Netzwerkschnittstellen selbst, anstatt an Adressen gebunden werden. Dies jedoch ist bei xinetd noch nicht in Sicht und stellt ein wirkliches Problem dar. Das Design eines C Modules beispielsweise, dass auf ein Netzwerkinterface oder eine Adresse zugreifen soll, ist stark vom jeweiligen Betriebssystem abhängig, und da xinetd auf vielen Plattformen arbeiten soll...Unter Verwendung eines Skriptes kann das Problem gelöst werden:

#!/bin/sh

PUBLIC_ADDRESS=`/sbin/ifconfig $1 | grep "inet addr" | awk '{print $2}'| awk -F: '{print $2}'`
sed s/PUBLIC_ADDRESS/"$PUBLIC_ADDRESS"/g /etc/xinetd.base > /etc/xinetd.conf

Dieses Skript liest die gewünschte Konfiguration aus der Datei /etc/xinetd.base aus, wobei PUBLIC_ADDRESS als Platzhalter für die dynamische Adresse steht und nimmt die entsprechenden Änderungen in /etc/xinetd.conf vor. Hierbei wird PUBLIC_ADDRESS durch die Adresse ersetzt, die dem Interface zugeordnet ist, welches dem Skript als Parameter übergeben wird. Der Aufruf des Skriptes hängt von der Art der Verbindung ab: am einfachsten ist es, den Aufruf in die jeweilige ifup-* Datei einzutragen und xinetd neu zu starten.

Umleiten eines Dienstes auf einen anderen Rechner: das Attribut redirect

xinetd kann auch als ein transparenter Proxy verwendet werden (jedenfalls beinahe, wie später zu sehen sein wird) und zwar mittels dem Attribut redirect. Dieses erlaubt es, eine Anfrage an einen Dienst an einen anderen Rechner und einem bestimmten Port weiterzuleiten.
telnet service
{
  flags  = REUSE
  socket_type = stream
  wait  = no
  user  = root
  server = /usr/sbin/in.telnetd
  only_from = 192.168.1.0/24
  redirect = 192.168.1.15 23
}
Dabei passiert folgendes:
>>telnet charly
Trying 192.168.1.1...
Connected to charly.
Escape character is '^]'.

Digital UNIX (sabrina) (ttyp1)

login:

Es scheint, als ob eine Verbindung mit dem Rechner charly aufgebaut worden ist. Tatsächlich aber befindet sich sabrina auf der anderen Seite der Verbindung (eine Alpha Maschine, auch an "Digital UNIX" zu erkennen). Die Weiterleitung kann recht nützlich, aber auch gefährlich sein. Wird sie eingerichtet, so muss auf beiden Rechnern protokolliert werden. Desweiteren wird für diese Art von Dienst der Einsatz von DMZ und Firewall empfohlen ;-)

Spezielle Dienste

Es gibt drei Dienste, die nur für xinetd verwendet werden. Diese sind weder in /etc/rpc, noch in /etc/services zu finden und müssen das UNLISTED Flag setzen (neben dem INTERNAL Flag, welches anzeigt, dass sie xinetd Dienste sind).
  1. servers: Auskunft über die gerade laufenden Server
  2. services: liefert Informationen über die angebotenen Dienste, ihre Protokolle und Ports
  3. xadmin: bietet Funktionen der beiden oben genannten Dienste
Es ist offensichtlich, dass durch diese Dienste das System verletzbarer wird . Sie stellen wichtige Informationen zu Verfügung. Zur Zeit gibt es keine Sicherheitsmechanismen für den Zugriff auf diese Dienste (etwa Passwortschutz). Sie sollten nur in der Einrichtungsphase verwendet werden. Zunächst wird der Zugriff auf sie in dem Abschnitt defaults generell gesperrt:
defaults {
  ...
  disabled = servers services xadmin
  ...
}
Bevor sie dann aktiviert werden sollten einige Vorkehrungen getroffen werden:
  1. Der Rechner, auf dem xinetd läuft, sollte der einzige Rechner sein, dem es erlaubt ist, die Dienste zu nutzen
  2. Die Anzahl der gleichzeitig erlaubten Serverinstanzen sollte eins sein
  3. Zugegriffen werden darf nur von dem Rechner aus, auf dem der Server läuft.
Hier ein Beispiel für die Konfiguration des xadmin Dienstes. Die Einstellung der beiden anderen Dienste erfolgt analog, bis auf die Portnummer natürlich ;-) :
service xadmin
{
  type  = INTERNAL UNLISTED
  port  = 9100
  protocol = tcp
  socket_type = stream
  wait  = no
  instances = 1
  only_from = 192.168.1.1  #charly
}
Der Dienst xadmin bietet fünf Befehle:
  1. help ...
  2. show run : gleicht dem Dienst servers und gibt Auskunft über die zur Zeit laufenden Server
  3. show avail : gleicht dem Dienst services und informiert über die verfügbaren Dienste (und ein wenig mehr)
  4. bye oder exit ...
Nun da man weiss, dass diese Dienste existieren, sollte man sie direkt wieder vergessen ;-)
Das System kann auch ohne diese Dienste getestet werden. Befehle, wie netstat, fusert, lsof... geben ebenfalls einen Überblick über das, was auf dem Rechner vonstatten geht, ohne ihn ein wenig unsicherer durch die Verwendung der Dienste zu machen!

Zeit, ein wenig zu spielen

Ein Rätsel zu Beginn

Es folgt eine kleine Übungsaufgabe für alle, die noch dabei sind ;-)
Zuerst wird die hier verwendete Konfiguration erläutert. Danach wird versucht herauszufinden, was passiert und warum es nicht funktioniert.

Es wird nur der Dienst finger benötigt

finger service
{
  flags  = REUSE NAMEINARGS
  server = /usr/sbin/tcpd
  server_args = in.fingerd
  socket_type = stream
  wait  = no
  user  = nobody
  only_from = 192.168.1.1  #charly
}
xinetd wurde ohne die Option --with-libwrap übersetzt (siehe das Attribut server). Der Abschnitt defaults sieht wie weiter oben aus, jeder Zugriff auf charly wird unterbunden, egal, woher die Anfrage kommen mag. Der finger Dienst ist nicht deaktiviert, und dennoch:
pappy@charly >> finger pappy@charly
[charly]
pappy@charly >>

pappy@bosley >>  finger pappy@charly
[charly]

pappy@bosley >>


Die Anfrage scheint weder von charly(192.168.1.1), einem autorisierten Rechner, noch von bosley (192.168.1.10) zu funktionieren.
Ein Blick in die Protokolldatei:

/var/log/servicelog :
00/9/18@17:15:42: START: finger pid=28857 from=192.168.1.1
00/9/18@17:15:47: EXIT: finger status=0 pid=28857 duration=5(sec)
00/9/18@17:15:55: FAIL: finger address from=192.168.1.10
xinetd zufolge wurde die Anfrage von charly aus korrekt bearbeitet (die beiden ersten Zeilen): Zugriff wurde gestattet, der Vorgang dauerte 5 Sekunden. Der Zugriff von bosley aber wurde abgelehnt (FAIL).
Ein Blick in die Konfiguration des finger Dienstes zeigt, dass der Server nicht wirklich in.fingerd, sondern tcp_wrapper tcpd verwendet. Das Protokoll des Wrappers zeigt:
/var/log/services :
Sep 18 17:15:42 charly in.fingerd[28857]: refused connect from 192.168.1.1
Es existiert dort nur Eintrag, der auf die beiden Anfragen passt! Die Anfrage von bosley (die zweite) wurde von xinetd abgefangen, weswegen sie auch in dessen Protokolldatei auftaucht. Obige Zeile also ist wirklich das Resultat der Anfrage von charly an charly, Zeit und PID sind gleich. Diese wurde von xinetd eigentlich zugelassen.

Zusammengefasst:

  1. xinetd erlaubt die Anfrage
  2. Die Anfrage an finger durchläuft tcpd
  3. in.fingerd lehnt den Zugriff ab
Was passiert hier? Da die Anfrage von xinetd zugelassen wird, geht sie an den angegebenen Server (hier tcpd). Dieser jedoch lehnt den Zugriff ab. Also muss man sich die Dateien /etc/hosts.allow und /etc/hosts.deny anschauen. Letztere enthält nur die Zeile ALL:ALL@ALL, was die Zurückweisung des Wrappers erklärt!

Durch die Art und Weise, wie die Einträge server und server_args der Dienste definiert worden sind, ist die Wrapperfunktionalität verwendbar (banner - es gibt ein Attribut namens banner, spawn, twist,...). Es darf nicht vergessen werden, dass durch die Option --with-libwrap zur Übersetzungszeit nur die Steuerung der Zugriffsrechte (unter Zuhilfenahme von hosts.allow und hosts.deny) durch xinetd selbst ermöglicht wird, bevor dann der jeweilige Prozess gestartet wird. Dieses Beispiel zeigt, dass es mit obiger Konfiguration weiterhin möglich ist, die Funktionalität des TCP Wrappers zu nutzen.

Die Überschneidung von Funktionalitäten kann, falls sie überhaupt funktioniert, zu recht merkwürdigen Ergebnissen führen. Statt xinetd zusammen mit inetd und portmap einzusetzen, sollten Dienste besser von nur einem dieser "Super Daemonen" verwaltet werden.

chroot für einen Dienst

Oft wird empfohlen, die Bereiche eines Dienstes einzuschränken oder eine neue Umgebung zu generieren. Der Befehl chroot ändert das Wurzelverzeichnis für einen Befehl oder ein Skript:
chroot [options] new_root
Auf diese Weise werden häufig Dienste wie bind/DNS oder FTP gesichert. Um dies zuerreichen und dabei gleichzeitig die Vorzüge von xinetd nutzen zu können, muss chroot als Server deklariert werden. Die Parameter werden dann über das Attribut server_args übergeben :)
service ftp
{
  id           = ftp
  socket_type  = stream
  wait         = no
  user         = root
  server       = /usr/sbin/chroot
  server_args  = /var/servers/ftp /usr/sbin/in.ftpd -l
}
Sobald nun eine Anfrage, den jeweiligen Dienst betreffend, eintrifft, wird als erstes chroot ausgeführt. Das erste Argument, dass diesem übergeben wird, ist der erste Eintrag in sever_args: das neue Wurzelverzeichnis. Zuletzt wird der Server gestartet.

Fazit

Es mag sich nun die Frage stellen, ob nun xinetd oder inetd verwendet werden sollte. Es ist nun einmal so, dass xinetd ein wenig mehr Administration verlangt, vorallem, solange es nicht mit den Linux Distributionen mitkommt (Aussnahme: RedHat 7.0). Eine sichere Lösung stellt der Einsatz von xinetd auf Rechnern dar, die eine Verbindung mit dem Rest der Welt (etwa dem Internet) haben. xinetd bietet einfach den besseren Schutz. Für Rechner in einem lokalen Netzwerk sollte inetd vollkommen ausreichend sein.