xinetd

ArticleCategory:

System Administration

AuthorImage:

TranslationInfo:

Original in fr Frédéric Raynal

AboutTheAuthor:

Frédéric Raynal prépare actuellement une thèse en informatique sur le tatouage d'images à l'INRIA (Institut National de Recherche en Informatique et Automatique).

Abstract:

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.
 

ArticleIllustration:[This is the title picture for your article]

ArticleBody:[The article body]

Kesako xinetd ?

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 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.

    Un serveur pop3

    Un service très populaire semble être pop3 : j'ai reçu beaucoup de messages concernant sa mise en oeuvre au travers de xinetd. Voici la configuration nécessaire :

         service pop3
         {
                 disable = no
                 socket_type             = stream
                 wait                    = no
                 user                    = root
                 server                  = /usr/sbin/ipop3d
         #       log_on_success          += USERID
         #       log_on_failure          += USERID
         }
    
    Il faut que vous placiez, à la ligne contenant server, le chemin vers le serveur que vous utilisez.

    L'utilisation de pop3 via xinetd peut s'avérer laborieuse selon les directives de logs que vous donnez. En effet, comme nous l'avons vu, l'emploi de la valeur USERID provoque une requête de xinetd vers un serveur identd du client pop. Or, si aucun serveur de ce type ne fonctionne, le timeout est de 30 secondes.

    Ainsi, lorsqu'une personne se connecte pour retirer son courrier, elle devra attendre au moins 30 secondes si aucun serveur identd ne fonctionne chez elle. Vous devez donc choisir entre :

    1. installer un serveur identd sur toutes les machines clientes afin de conserver des logs complets (attention toutefois: les informations délivrées par un serveur identd peuvent être modifiées) ;
    2. dégrader la qualité de vos logs pour ce service afin de ne pas ralentir les requêtes d'accès au courrier des utilisateurs.


    Erreurs de configuration avec la RH7.0, la Mandrake 7.2 et peut-être d'autres ...

    bug 24279 rapporté sur bugzilla. Certains services configurés dans le répertoire /etc/xinetd.d ne sont pas définis dans le fichier /etc/services.

    [pappy@rootdurum xinetd.d]# grep service *udp
    chargen-udp:service chargen-udp
    daytime-udp:service daytime-udp
    echo-udp:service echo-udp
    time-udp:service time
    

    Le responsable du bug chez RH signale qu'on ne peut pas utiliser la correction que j'ai suggérée car ça poserait des problèmes de manipulation avec chkconfig et ntsysv. Entre ces outils et l'utilisation de xinetd, mon choix est vite fait ;-)