13.1. Informazioni di base

xinetd fornisce uno script per fare la conversione in automatico dalla vecchia configurazione di inetd alla nuova versione di file: questo script è xconv.pl, presente nella stessa directory di xinetd (altre distribuzioni, come Mandrake, forniscono un altro script, con risultati medesimi, chiamato inetdconvert). Si usano come segue:

/usr/sbin/xconv.pl < /etc/inetd.conf > /tmp/xinetd.conf
/usr/sbin/inetdconvert -c
     

La differenza principale tra i due script è che quello standard di xinetd riunisce tutte le impostazioni dei servizi nel file xinetd.conf prodotto, mentre quello di Mandrake crea script separati per i singoli servizi nella directory /etc/xinetd.d, cosa che io preferisco, in quanto tutti i file presenti in questa directory vengono inclusi da xinetd tramite la direttiva includedir /etc/xinetd.d del file di configurazione xinetd.conf, e quindi per aggiungere nuovi servizi basta creare un nuovo file nella directory indicata e riavviare il super-demone, senza dover modificare sempre il suo file generale di configurazione. Se la pensate come me, ma non usate Mandrake, ecco quì di seguito lo script in questione:

#!/usr/bin/perl
# -*- Mode: cperl -*-
#--------------------------------------------------------------------------------
# Copyright (C) 2000 by Chmouel Boudjnah <chmouel@mandrakesoft.com>, MandrakeSoft
# Redistribution of this file is permitted under the terms of the GNU 
# Public License (GPL)
#--------------------------------------------------------------------------------
## description: 
# Update a system from inetd file to xinetd.

use strict;

my $inet_files = '/etc/inetd.conf';
my $dir = '/etc/xinetd.d/';
my $remain;
my $choose;

parse_options(@ARGV);
$choose = shift;

die "Need a service to convert\n" if not $choose and not $remain;

system("/bin/mkdir " . "-p " . "$dir") unless -d $dir;

local *F;
open F, $inet_files;
while (<F>) {
    next if /^#/;
    my @t = split;
    my ($service, $socket_type, $protocol, $attente, $user, $server) = split;
    my $programs; $programs .= "$t[$_] " for 6 .. $#t;
    next if -f "$dir/$service";
    next if $service !~ /^$choose$/ and not $remain;
    
    select W; open W, ">$dir/$service";
    print "# Converted by Linux-Mandrake_inetdconvert\n";
    print "service $service\n{\n";
    print "\tsocket_type\t\t= $socket_type\n";
    print "\tprotocol\t\t= $protocol\n";
    print "\twait\t\t\t= ", $attente =~ /yes/ ? "no" : "yes", "\n";
    if ($user =~ /(\w+)\.(\w+)/)  {
    print "\tuser\t\t\t= $1\n";
    print "\tgroup\t\t\t= $2\n";
    } else {
    print "\tuser\t\t\t= $user\n";
    }
    print "\tserver\t\t\t= $server\n";
    print "\tserver_args\t\t= ", $programs, "\n" if $programs;
    print "\tdisable\t\t\t= no\n}\n";
    close W;
}
close F;

sub usage {
    (my $n = $0) =~ s|.*/||g;
    print <<EOF;
Usage: $n -c -d=xinetd-directory -f=inetd-file servie
  
  -c    --convertremaining: Convert all the remainning service.
  -d       --directory=DIR:     Specify another xinetd directory.
  -f     --inetdfiles=FILE:     Specify an another inetd file.
EOF
  exit(0);
}
    
sub parse_options {
    while ($_[0] =~ /^--/ || $_[0] =~ /^-/) {
    $_ = shift;
    if (/-(?-)(directory|d)=([^ \t]+)/) {
        $dir=$1;
    } elsif (/-(?-)(inetdfiles|f)=([^ \t]+)/){
        $inet_files=$1;
    } elsif (/-(?-)(convertremaining|c)/){
        $remain++;
    } elsif (/-(?-)(help|h)/){
        usage();
    } else {
        usage();
    }
    }
}
     

Dovrete renderlo eseguibile col comando chmod 700 inetdconvert. Se lo userete come indicato in precedenza, TUTTI i servizi presenti nel vostro inetd.conf saranno convertiti in script nella directory /etc/xinetd.d, mentre se volete convertire solo determinati servizi, usate lo script senza l'opzione -c, ma indicando invece come parametri dello script i nomi dei servizi che volete. Naturalmente ricordate di aggiungere nel file /etc/xinetd.conf la direttiva includedir /etc/xinetd.d, se non già presente! E tenete comunque conto del fatto che entrambi gli script ignorano completamente le configurazioni dei TCP-Wrappers (i file hosts.allow e hosts.deny), e quindi dovrete comunque modificare i file che vengono generati.

Visto che ci siamo, indichiamo i segnali di sistema che il super-demone accetta per modificare il suo stato. Per prima cosa, EVITATE di dare il segnale SIGHUP! Questo segnale non provoca la rilettura del file di configurazione come ci si aspetterebbe, ricordando il comportamento di inetd, ma provoca il DUMP del demone! Questa, secondo l'autore, è una "feature", in quanto un possibile attacker che volesse inserire una qualche backdoor avviata dal super-demone, nel momento in cui dovesse dare il SIGHUP pensando di avere a che fare con inetd, si ritroverebbe invece senza più il demone in funzione! ;-) Invece, i segnali corretti da usare sono i seguenti:

Ah, non sapete come dare questi segnali? Leggete le manpage di kill e killall! ;-)

Il file di config. /etc/xinetd.conf inizia con una sezione defaults, che contiene i parametri usati da tutti i servizi gestiti da xinetd, se questi in seguito non specificano loro proprie modifiche a queste impostazioni, ed ha il formato seguente:

defaults
{
   attributo operatore valore [valore]
   altro_attributo operatore valore [valore]
   ...
}
     

Ogni sezione relativa a un servizio invece ha una forma simile:

service nomeservizio
{
   attributo operatore valore [valore]
   altro_attributo operatore valore [valore]
   ...
}
     

e ogni servizio come abbiamo detto in precedenza può essere specificato direttamente nel file di configurazione globale, o in un file separato in una directory, poi inclusa dalla direttiva includedir ....

Sono disponibili 3 operatori diversi:

Un elenco invece dei possibili attributi è il seguente (l'elenco non è completo, altri attributi sono nella manpage di xinetd.conf):

Tabella 13-1. Attributi

Attributo Valore e descrizione
includedir Il nome di una directory, nella forma includedir /etc/xinetd.d, i cui file contenuti saranno esaminati in ordine alfabetico come file di configurazione aggiuntivi per altri servizi. Non può essere specificato nella dichiarazione di un servizio, deve essere specificato al di fuori di qualsiasi dichiarazione.
flags Quì sono elencate solo le opzioni più usate, controllate la manpage per le altre opzioni: IDONLY: accetta connessioni solo da client che hanno un server di identificazione; NORETRY: evita che ci sia un fork di un nuovo processo in caso di fallimento; NAMEINARGS: il primo argomento dell'attributo "server_args" viene usato come argv[0] per il server; questo permette di usare tcpd inserendolo nell'attributo "server", e inserendo il nome del server e i suoi argomenti come opzioni in "server_args", come faresti normalmente con inetd.
log_type xinetd usa per default syslogd e il selettore "daemon.info". SYSLOG facility [livello]: permette di scegliere tra daemon, auth, user o local0-7 per syslogd; FILE file_log [max_size [abs_max_size]]: le informazioni finiscono in "file_log", e i 2 parametri opzionali servono ad inviare un messaggio nel file al raggiungimento del primo limite, e a smettere di effettuare il log al raggiungimento del secondo.
log_on_success Si possono indicare quali informazioni includere nei log (l'id del processo è sempre incluso), in fase di avvio e chiusura di un servizio. È ammessa una qualsiasi combinazione dei valori seguenti, separandoli con spazi: PID: l'id del processo avviato, 0 se è interno a xinetd; HOST: l'indirizzo dell'host remoto; USERID: l'identità dell'utente remoto, secondo il protocollo definito nell'RFC1413; EXIT: lo stato di uscita del servizio o il segnale che ne ha provocato la fine; DURATION: la durata della sessione.
log_on_failure Le informazioni da includere quando un servizio non può essere avviato, per carenza di risorse o a causa delle regole d'accesso (l'id del processo è sempre incluso, insieme alla ragione del fallimento). È ammessa una qualsiasi combinazione dei valori seguenti, separandoli con spazi: HOST: l'indirizzo dell'host remoto; USERID: l'identità dell'utente remoto, secondo il protocollo definito nell'RFC1413; ATTEMPT: il tentativo di connessione (questa opzione è implicita se viene inclusa una qualsiasi delle altre opzioni); RECORD: log di qualsiasi informazioni disponibile sul client remoto.
nice Cambia la priorità del server, come farebbe il comando nice.
only_from Elenco dei client che hanno accesso al server. Se questo parametro è presente ma vuoto, l'accesso al servizio è negato. Gli indirizzi IP che hanno accesso possono essere indicati con una qualsiasi combinazione dei valori seguenti: a): un indirizzo nella forma %d.%d.%d.%d, dove %d è un decimale tra 0 e 255, e se l'ultima cifra è 0, viene considerata come un'intera sottorete, mentre 0.0.0.0 indica qualsiasi host; b): un indirizzo fattorizzato nella forma %d.%d.%d.{%d,%d,...}; c): un nome di rete, preso da /etc/networks; d): un nome di host, di cui xinetd esegue il reverse lookup dell'IP del client; e): un intervallo nella forma indirizzo, netmask.
no_access Elenco dei client che non hanno accesso al server, secondo la sintassi vista per il parametro "only_from".
port La porta usata dal server. Se il servizio è presente in /etc/services, i due numeri devono corrispondere.
protocol Il protocollo usato dal servizio, come indicato in /etc/protocols. Se non indicato, viene usato il protocollo di default per il servizio.
server Il percorso del server.
server_args Gli argomenti passati al server.
socket_type stream (TCP), dgram (UDP), raw (IP ad accesso diretto) o seqpacket ().
type xinetd gestisce tre tipi di servizi, e questo parametro accetta qualsiasi combinazione dei parametri seguenti. RPC: per i servizi elencati in /etc/rpc, ma non funziona molto bene, come già detto; INTERNAL: servizi gestiti internamente, come "echo, time, daytime, chargen e discard"; UNLISTED: per servizi che non sono elencati né in /etc/rpc, né in /etc/services.
wait Definisce il comportamento da seguire per i thread dei servizi. yes: il servizio è mono-thread, può gestire una sola connessione per volta; no: per ogni nuova connessione, xinetd avvia una nuova copia del server.
cps Limita il numero di connessioni in ingresso. Accetta due argomenti, il primo indica appunto questo numero massimo di connessioni, raggiunto il quale il servizio viene disattivato per un tempo pari al secondo parametro, espresso in secondi.
instances Definisce il numero massimo di server dello stesso tipo che possono funzionare in parallelo.
max_load Il carico massimo per un server, raggiunto il quale il servizio smette di accettare nuove connessioni. Il numero è in virgola mobile, e indica il carico medio in un minuto. UNLIMITED per connessioni infinite.
per_source Un numero intero o UNLIMITED, per limitare il numero massimo di connessioni da uno stesso IP origine verso un server. Può essere anche specificato nella sezione "defaults".

Le ultime quattro opzioni permettono di controllare le risorse in base al server, permettendo di limitare possibile attacchi DoS (Denial of Service), che saturano le risorse.