Xinetd

Résumé:

xinetd - extented Internet services daemon - fournit une excellente sécurité contre les intrusions, et limite certains risques d'attaques par Deny of Services (DoS). Comme la paire plus connue (inetd+tcpd), il permet de fixer des droits d'accès à une machine, mais ses capacités s'étendent bien au-delà. Cet article vous propose de les découvrir.

Le désormais classique inetd a rendu de fiers services pour contrôler les connexions vers une machine. Lorsqu'une requête arrive sur un port géré par inetd, celui-ci la transmet alors au wrapper qui décide de l'action à entreprendre relativement aux instructions contenues dans hosts.{allow, deny}. Si la requête est autorisée, le serveur associé la traite.

xinetd offre des capacités de contrôle d'accès similaires à celles offertes par tcp_wrapper. Toutefois, ses possibilités s'étendent bien au-delà :

Le principal inconvénient, déjà mentionné, concerne les RPC qui ne sont pas encore très bien supportés. Toutefois, portmap et xinetd cohabitent parfaitement :)

La première partie de cet article explique le fonctionnement général de xinetd. Nous nous attarderons, par l'intermédiaire d'exemples, sur la configuration générale d'un service, sur quelques options particulières (attachement à une interface, redirection). La seconde partie illustre le fonctionnement de xinetd, les logs qu'il génère et finit avec une petite astuce très utile.
 

Compilation & Installation

Vous pouvez récupérer xinetd sur le site http://www.xinetd.org/. La version utilisée pour cet article est la 2.1.8.9pre10.
La compilation et l'installation sont tout à fait classiques : le triplet ./configure; make; make install fait tout :) Les options habituelles sont supportées par le configure. Trois options particulières sont également disponibles pour compiler ce programme:

  1. --with-libwrap : avec cette option, xinetd commence par examiner les fichiers de configuration de tcpd (/etc/hosts.{allow, deny}) et ensuite, si l'accès est accordé, il utilise ses propres mécanismes de contrôle. Cette option nécessite la présence du tcp_wrapper et des bibliothèques qui l'accompagnent. (Note de l'auteur : ce qui est réalisable avec le wrapper l'est tout aussi bien par xinetd. Autoriser cette compatibilité conduit à multiplier les fichiers de configuration, ce qui complique l'administration ... bref, je ne le recommande pas);

  2. --with-loadavg : cette option permet à xinetd de supporter l'option de configuration max_load (charge maximale). Cela permet de désactiver certains services lorsque la charge de la machine dépasse le seuil donné, ce qui est essentiel pour prévenir certains DoS (voir l'attribut max_load dans le tableau 1 ;

  3. --with-inet6 : si vous voulez utiliser IPv6, cette option en garantit le support. Les connexions IPv4 et IPv6 sont gérées, mais les adresses IPv4 se transforment au format IPv6.

Avant de démarrer xinetd, il n'est pas obligatoire d'arrêter inetd. Toutefois, ne pas le faire entraîne un comportement relativement imprévisible des deux démons!

Certains signaux influencent le comportement de xinetd:

Il en existe quelques autres (signalons juste une erreur dans les documentations et pages man: le signal SIGHUP génère son dump dans le fichier /var/run/xinetd.dump et non dans /tmp/xinetd.dump), mais ces trois là permettent d'écrire rapidement un petit script pour le gérer facilement à l'aide des options start, stop, restart, soft, hard (ces deux dernières correspondent respectivement aux signaux SIGUSR1 et SIGUSR2).

Configuration

Le fichier /etc/xinetd.conf configure, par défaut, le démon xinetd (une option de la ligne de commande permet d'en désigner un autre). Si la configuration de xinetd n'est pas très compliquée, elle est longue et la syntaxe diffère malheureusement de celle employée par son prédécesseur inetd.

Deux utilitaires (itox et xconv.pl) sont fournis avec xinetd et permettent de convertir le fichier /etc/inetd.conf en fichier de configuration pour xinetd. Bien évidemment, ceci ne suffit pas dans la mesure où les règles stipulées dans les fichiers de configuration du wrapper sont ignorées. itox n'évolue plus, même s'il est encore maintenu. xconv.pl offre une meilleure solution, même si le résultat nécessite d'être modifié, ne serait-ce que parce que xinetd offre plus de possibilités qu'inetd.

>>/usr/local/sbin/xconv.pl < /etc/inetd.conf > /etc/xinetd.conf

Le fichier de configuration commence par une section par défaut dont les attributs seront utilisés pour tous les services pris en charge par xinetd. Suivent alors autant de sections que de services désirés, chacun pouvant redéfinir des options qui lui seront spécifiques par rapport à celles par défaut.

La section des valeurs par défauts s'écrit:

defaults
{
    attribut opérateur valeur(s)
    ...
}

Chacun des attributs défini dans cette section conserve la (les) valeur(s) fournie(s) pour les services décrits ensuite. Ainsi, l'attribut only_from permet de stipuler une liste d'adresses autorisées à se connecter aux serveurs:

only_from = 192.168.1.0/24 192.168.5.0/24 192.168.10.17

Par la suite, tous les services déclarés autorisent l'accès aux machines dont les adresses correspondent à l'une de celles indiquées. Il est toutefois possible de modifier ces valeurs par défaut au sein de chaque service (voir les opérateurs expliqués ci-après). Cependant, cette démarche comporte certains risques. En effet, il vaut mieux, pour des raisons de simplicité et de sécurité, ne jamais définir de valeur par défaut qui soit ensuite modifiée dans un service. Dans le cas de droits d'accès par exemple, la politique la plus simple et la plus efficace consiste à interdire par défaut l'accès à tout le monde pour ensuite autoriser l'accès à chaque service seulement à ceux qui en ont besoin (avec tcp_wrapper, cette politique se traduit par un hosts.deny contenant ALL:ALL@ALL, et un hosts.allow ne contenant que les services autorisés avec les adresses adéquates).

Chaque section décrivant un service dans le fichier de configuration est de la forme:

service nom_du_service
{
    attribut opérateur valeur(s)
    ...
}

Il existe trois opérateurs: '=', '+=' et '-='. La plupart des attributs ne supporte que l'opérateur '=', qui fixe une valeur à un attribut. L'opérateur '+=' ajoute un élément à une liste de valeurs, alors que '-=' retire cet élément.

Le tableau 1 décrit succinctement quelques uns des attributs. Nous verrons leur utilisation dans les exemples qui suivront. La lecture de la page man de xinetd.conf fournit de plus amples informations.
 
   

Attribut

Valeurs et description

flags

Seules les valeurs les plus courantes sont décrites ici, regarder dans la documentation pour découvrir les autres:

  • IDONLY: n'accepte de connexions que des clients qui disposent d'un serveur d'identification;

  • NORETRY : évite que le processus soit à nouveau "forké" en cas d'échec;

  • NAMEINARGS: le premier argument de l'attribut server_args est utilisé en tant que argv[0] pour le server. Ceci permet d'utiliser tcpd en le mettant dans l'attribut server, puis d'écrire le nom du serveur et ses arguments comme server_args, exactement comme avec inetd.

log_type

xinetd utilise syslogd et le sélecteur daemon.info par défaut.

  • SYSLOG sélecteur [level]: permet de choisir parmi les entrées daemon, auth, user ou local0-7 de syslogd ;

  • FILE [taille_max [taille_max_absolue]]: le fichier spécifié reçoit les informations. Les deux options fixent des limites de taille du fichier. La première, lorsqu'elle est atteinte, provoque l'émission d'un message vers syslogd, la seconde arrête l'enregistrement des logs pour le service concerné (s'il s'agit d'un fichier commun - ou fixé par défaut - plusieurs services peuvent alors être affectés).

log_on_success

Différentes informations sont enregistrables quand un serveur démarre:

  • PID: le PID du serveur (s'il s'agit d'un service interne à xinetd, le PID vaut alors 0);

  • HOST: l'adresse du client;

  • USERID: l'identité de l'utilisateur distant, en accord avec la RFC1413 qui définit le protocole d'identification;

  • EXIT: le statut de sortie du processus;

  • DURATION: la durée de la session.

log_on_failure

Là encore, xinetd dispose de multiples informations à enregistrer quand un serveur ne peut démarrer, soit par manque de ressources, soit à cause des règles d'accès:

  • HOST, USERID: comme ci-dessus;

  • ATTEMPT: enregistre le fait qu'une tentative d'accès a eu lieu. Cette option est automatique dès qu'une autre valeur est stipulée ;

  • RECORD: enregistre toutes les informations disponibles sur le client.

nice

Modifie la priorité du serveur, exactement comme avec la commande nice.

no_access

Liste de clients dont on refuse les connexions à ce service.

only_from

Liste de clients autorisés. Si cet attribut n'a pas de valeur, l'accès à ce service est interdit.

port

Le port associé au service. Si celui-ci est également défini dans /etc/services, les 2 numéros de port doivent correspondre.

protocol

Le protocole stipulé doit exister dans /etc/protocols. S'il n'en est pas fournit, le protocole par défaut associé à ce service est employé.

server

Le chemin vers le serveur à utiliser.

server_args

Des arguments à passer au serveur.

socket_type

stream (TCP), dgram (UDP), raw (accès direct à IP) ou seqpacket ().

type

xinetd gère 3 types de services:

  1. RPC: pour ceux décrit dans /etc/rpc ... mais ne fonctionne pas très bien;

  2. INTERNAL: pour les services pris directement en charge par xinetd (echo, time, daytime, chargen et discard);

  3. UNLISTED : pour les services non décrits soit dans /etc/rpc, soit dans /etc/services;

Notons qu'il est possible de combiner plusieurs de ces valeurs, comme nous le verrons avec les services internes servers, services et xadmin.

wait

Définit le comportement du service vis-à-vis des threads. Deux valeurs sont possibles:

  • yes: le service est mono-thread, une seule connexion de ce type peut-être gérée à la fois par le service;

  • no: à chaque nouvelle requête vers le service, un nouveau serveur est démarré par xinetd, dans la limite maximale définie (Attention, cette limite est infinie par défaut).

cps

Limite le nombre de connexions entrantes. Le premier argument est ce nombre lui-même. Lorsque ce seuil est dépassé, le service se désactive pour un délai, exprimé en secondes, fourni par le second argument.

instances

Détermine le nombre maximal de serveurs d'un même type pouvant fonctionner en même temps.

max_load

Ce réel indique la charge maximale que peut occuper un serveur (par exemple, 2 ou 2.5). Au-delà de cette limite, les requêtes sur ce serveur sont rejetées.

per_source

Soit un entier, soit UNLIMITED, pour restreindre le nombre de connexions ayant une même origine  à un serveur 

Tab. 1: quelques attributs utilisables avec xinetd

Les quatre derniers attributs présentés dans le tableau 1 permettent de contrôler les ressources attachées aux serveurs. Ceci permet de lutter efficacement contre certaines attaques par Deny of Service (DoS), dont le but est de paralyser une machine en occupant toutes ses ressources.

Cette partie présentait quelques unes des possibilités offertes par xinetd. Les parties suivantes montrent comment s'en servir et précisent certaines règles de bon fonctionnement.  

defaults pour les services

La section defaults permet de fixer des valeurs pour certains attributs (voir les documentations pour la liste complète). Parmi cette liste, certains (only_from, no_access, log_on_success, log_on_failure, ...) cumulent les valeurs allouées dans cette section avec celles fournies dans les services.

Interdire, par défaut,  tout accès à sa machine est la première étape d'une politique de sécurisation viable. Ensuite, il ne restera qu'à autoriser, en fonction des services, l'accès à qui de droit. Nous avons vu deux attributs permettant de contrôler l'accès à sa machine fondés sur les adresses IP: only_from et no_access. Choisir le second en mettant:

no_access = 0.0.0.0/0

bloque complètement l'accès aux services. Cependant, si vous souhaitez autoriser tout le monde à accéder, par exemple, à echo, vous devrez alors mettre dans le service echo:

only_from = 0.0.0.0/0

Voici le message enregistré dans les logs avec cette configuration:

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

En fait, le contrôle d'accès se fait en comparant les listes d'adresses contenues dans les deux attributs. Quand l'adresse du client correspond aux 2 listes, la liste la moins générale l'emporte. En cas d'égalité, comme c'est le cas dans notre exemple, xinetd se met dans une situation d'indécidabilité et refuse la connexion.  Pour lever l'ambiguité, il aurait suffit de mettre:

only_from = 192.0.0.0/8

Un autre solution, moins problématique, consiste à contrôler l'accès uniquement avec l'attribut:

only_from =

Ne rien préciser comme valeur condamne toutes les connexions à l'échec :) Ensuite, chaque service délivre ses autorisations d'accès au moyen de ce même attribut.

Détail important, voire essentiel: en cas d'absence complète de règles d'accès (i.e. ni only_from, ni no_access) pour un service (allouées soit de manière directe, soit par le biais de la section default), l'accès au service est autorisé!

Voici un exemple de defaults :

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
}

Parmi les services internes, servers, services, et  xadmin permettent de gérer xinetd. Nous en reparlerons plus loin.  

Configurer un service

Pour configurer un service, nous avons besoin de... rien :) En fait, tout se comporte exactement comme avec les valeurs par défaut: il suffit de préciser les attributs et leur(s) valeur(s) pour paramétrer le service en question. Ceci entraîne soit une modification des valeurs par défaut, soit l'ajout d'un attribut pour ce service.

Certains attributs doivent impérativement apparaître en fonction du type du service (INTERNAL, UNLISTED ou RPC) :
 
 

Attribut

Commentaire

socket-type

Tous les services.

user

Uniquement pour les services non INTERNAL

server

Uniquement pour les services non INTERNAL

wait

Tous les services.

protocol

Tous les services RPC et absents de /etc/services.

rpc_version

Tous les services RPC.

rpc_number

Tous les services RPC, absents de /etc/rpc.

port

Tous les services non RPC, absents de /etc/services.

Tab. 2: attributs obligatoires

L'exemple ci-dessous illustre la définition de services :

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
}

 Constatons que ces services ne sont autorisés que sur le réseau interne (192.168.1.0/24). Pour le FTP, des restrictions supplémentaires sont prévues: le nombre d'instances est limité à 4 et il ne sera possible de l'utiliser que pendant certaines plages horaires.  

Attachement à un port: l'attribut bind

Cet attribut permet de lier (to bind en Anglais) un service à une adresse IP. Si votre machine ne dispose que d'une adresse, ceci ne sert à rien. En revanche, prenons le cas d'un ordinateur sur un réseau local mais également connecté à Internet: il dispose au moins de deux adresses.

Par exemple, une société veut mettre en place un serveur FTP pour ses employés (afin qu'ils puissent consulter des documents internes). Elle tient également à fournir à ses clients un accès FTP vers ses produits: bind est fait pour cette société :) Nous allons définir deux services FTP. Toutefois, xinetd doit pouvoir les distinguer: c'est là qu'intervient l'attribut id, qui définit de manière unique un service (lorsqu'il n'est pas défini dans un service, il vaut, par défaut, le nom du service).
 

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 #autorisation pour tous les clients
  bind         = 212.198.253.142 #adresse IP publique de ce serveur
}

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 #usage interne seulement
  bind         = 192.168.1.1  #adresse IP locale de ce serveur (charly)
}

L'utilisation de bind va permettre, selon la destination des paquets, d'invoquer le démon correspondant. Ainsi, un client sur le réseau local, dans cette configuration, doit préciser l'adresse locale (ou le nom qui y est associé) pour accéder aux données internes. Dans le fichier de logs, les traces suivantes apparaissent:

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-interne pid=26864 from=192.168.1.1
00/9/17@16:48:19: EXIT: ftp-interne status=0 pid=26864 duration=15(sec)

La première série résulte de la commande ftp 212.198.253.142, alors que la seconde, exécutée directement de charly vers lui-même: ftp 192.168.1.1.

Un problème apparaît clairement: que se passe-t-il si la machine ne dispose pas de deux adresses IP fixes? Ce cas de figure se produit par exemple avec des connexions ppp ou si vous utilisez le protocole dhcp. Il semble donc qu'il vaudrait mieux lier les services aux interfaces qu'aux adresses. Toutefois, ceci n'est pas encore prévu avec xinetd et pose de nombreux problèmes (entre autres, écrire un module C pour accéder aux interfaces et aux adresses dépend fortement de l'OS de l'ordinateur, or xinetd est supporté par beaucoup d'OS différents...) L'utilisation d'un script permet de résoudre ce problème à moindre coût:

#!/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

Ce script prend le fichier /etc/xinetd.base, qui contient la configuration souhaitée avec  PUBLIC_ADDRESS à la place de l'adresse variable, et le transforme en /etc/xinetd.conf, en remplaçant la chaîne de caractères PUBLIC_ADDRESS par l'adresse associée à l'interface passée en argument du script. Ensuite, l'appel de ce script dépend du type de connexion utilisé: le plus simple consiste à en ajouter l'appel dans le fichier ifup-* adéquate et de (re)lancer xinetd.  

Redirection d'un service vers une autre machine: l'attribut redirect

xinetd peut se transformer en une sorte de proxy transparent (enfin, presque ... comme nous le verrons) grâce à l'attribut redirect. Il permet de réacheminer la requête parvenant à un service vers une autre machine sur le port voulu.

service telnet
{
  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
}

Regardons ce qui se passe maintenant :

>>telnet charly
Trying 192.168.1.1...
Connected to charly.
Escape character is '^]'.
 

Digital UNIX (sabrina) (ttyp1)

login:

Effectivement, la connexion semble se faire sur charly, sauf que la suite montre bien qu'en fait, sabrina (une alpha, d'où le "Digital UNIX") a pris le relais. Ce mécanisme peut s'avérer à la fois utile et dangereux. Lors de sa mise en place, des logs doivent avoir lieu à chaque extrémité de la connexion. De plus, pour ce type de service, l'utilisation d'une DMZ et de firewalls n'est pas à négliger ;-)  

Services spéciaux

xinetd dispose de trois services qui lui sont propres. Ces services n'apparaissant ni dans /etc/rpc, ni dans /etc/services, doivent avoir également le flag UNLISTED (en plus du flag INTERNAL qui signale qu'il s'agit de services de xinetd)

  1. servers: révèle les serveurs actuellement en cours d'utilisation ;

  2. services: affiche les services disponibles, leur protocole et leur port ;

  3. xadmin: mélange les fonctions des deux précédents.

Bien évidemment, ces services exposent votre ordinateur. Ils dévoilent des informations importantes. Pour l'instant, leur accès n'est pas protégé (par un mot de passe par exemple). Vous ne devez vous en servir que lors de la configuration de xinetd. Ensuite, dans la section defaults, leur usage doit être prohibé:

defaults {
  ...
  disabled = servers services xadmin
  ...
}

Avant de les initaliser, mieux vaut prendre quelques précautions :

  1. seule la machine sur laquelle tourne xinetd doit pouvoir s'y connecter ;

  2. limiter le nombre d'instances à une;

  3. n'autoriser l'accès qu'à la machine sur laquelle tourne le serveur.

Prenons le cas du service xadmin (les deux autres se configurent exactement de la même manière, au numéro de port près ;-):

service xadmin
{
  type  = INTERNAL UNLISTED
  port  = 9100
  protocol = tcp
  socket_type = stream
  wait  = no
  instances = 1
  only_from = 192.168.1.1  #charly
}

Le service xadmin dispose de 5 commandes :

  1. help ...

  2. show run: comme pour le service servers, montre les serveurs actuellement utilisés;

  3. show avail: comme pour le service services, affiche les services disponibles (et quelques autres informations qui n'apparaissent pas services);

  4. bye ou exit ...

Vous savez maintenant qu'ils existent: oubliez-les ;-) Vous pouvez tout à fait faire vos tests sans ces services Des commandes comme (netstat, fuser, lsof, ... vous permettent justement de savoir exactement ce qui se passe sur votre machine sans l'exposer autant que ces services!

Jouons un peu ...

 

Une énigme pour commencer

Voici un petit exercice pour ceux qui ont survécu ;-) Après avoir expliqué la configuration utilisée, une requête donne un résultat surprenant. Nous mènerons l'enquête pour découvrir ce qui se passe.

Nous n'avons besoin que du service finger :

service finger
{
  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 n'a pas été compilé avec l'option --with-libwrap (voir l'attribut server). La section defaults est du même genre que celle fournie précédemment: tout accès est interdit vers charly quelle que soit la source de la connexion. Le service finger n'est pas désactivé, et pourtant:

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

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

pappy@bosley >>


Il semble que la requête n'ait pas fonctionné correctement, qu'elle soit exécutée de charly (192.168.1.1), machine autorisée, ou bien de bosley (192.168.1.10). Examinons les fichiers de logs:

/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

La requête en provenance de charly (les deux premières lignes) se déroule bien du point de vue de xinetd: l'accès est autorisé et la requête prend 5 secondes. En revanche, la requête de issue de bosley est rejeté (le FAIL).
Si on regarde la configuration du service finger, le serveur employé n'est pas directement in.fingerd, mais le tcp_wrapper tcpd. Les logs du wrapper contiennent les lignes suivantes:

/var/log/services:
Sep 18 17:15:42 charly in.fingerd[28857]: refused connect from 192.168.1.1

Remarquons que nous ne découvrons qu'une seule ligne correspondant à nos deux requêtes! En effet, celle en provenance de bosley (la seconde) a été interceptée par xinetd, donc, il est tout à fait normal de ne pas la retrouver dans ce fichier. La ligne sélectionnée correspond bien à la requête qu'a autorisée xinetd émise depuis charly vers charly (la première): l'heure et surtout le PID sont identiques.

Résumons les éléments en notre possession:

  1. xinetd a autorisé la requête;

  2. la requête finger passe par tcpd;

  3. in.fingerd a refusé cette même requête.

Alors que se passe-t-il? Puisque la requête est acceptée par xinetd, elle est transmise au serveur spécifié (tcpd ici). Or, tcpd refuse cette connexion. Il faut donc aller voir du côté de hosts.{allow,deny}. En examinant ces fichiers, /etc/hosts.deny ne contient que ALL:ALL@ALL, ce qui explique que la requête soit rejetée par le wrapper!

En fait, telles que les lignes server et server_args du service ont été définies, les capacités du wrapper restent accessibles (banner -il existe aussi un attribut banner avec xinetd-, spawn, twist, ...). Rappelons que l'option de compilation --with-libwrap ajoute uniquement une vérification préalable, à l'aide des hosts.{allow,deny}, des droits d'accès avant que le processus propre à xinetd ne s'enclenche. Les écritures présentées ici permettent donc de continuer à employer les mécanismes mis en oeuvre avec le wrapper.

Ce chevauchement des capacités, s'il peut fonctionner, peut également conduire à d'étranges comportements. Pour faire cohabiter xinetd, inetd et portmap, il vaut mieux qu'un service ne soit géré que par un seul de ces "super-démons".

 

chrooter un service

Il est souvent conseillé de restreindre les domaines de certains services, voire de créer un nouvel environnement. La commande chroot permet de changer le répertoire racine pour la commande (ou le script) qui sera exécutée ensuite:

chroot [options] nouvelle_racine

Ceci s'utilise couramment pour protéger des services tels que bind/DNS ou ftp. Pour reproduire ce comportement tout en bénéficiant des capacités de xinetd, il suffit de déclarer chroot en tant que serveur. Il ne reste plus alors qu'à passer les autres arguments par l'intermédiaire de l'attribut server_args :)

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
}

Ainsi, lorsqu'une requête est destinée à ce service, la première instruction utilisée est chroot. Ensuite, le premier argument qui lui est passé est le premier de la ligne server_args, c'est-à-dire la nouvelle racine. Enfin, le serveur désiré est démarré.

Conclusion

Vous pouvez vous demander quel démon choisir entre xinetd et inetd. En fait, xinetd demande un petit effort supplémentaire d'administration, surtout tant qu'il ne sera pas inclus directement dans les distributions (il l'est dans la Red Hat 7.0). La solution la plus sûre consiste à utiliser xinetd sur votre (vos) machine(s) ayant un accès public (comme Internet) car il offre une meilleure ligne de défense. Pour les autres, à l'intérieur de votre réseau, inetd suffit amplement. Ne pas négliger toutefois l'emploi d'un firewall: son travail ne se situe pas au même niveau.