[successivo] [precedente] [inizio] [fine] [indice generale] [licenze] [indice analitico] [tomo] [parte]


Capitolo 235.   TCP wrapper più in dettaglio

L'uso del TCP wrapper (il programma tcpd) è già stato descritto in modo sommario nel capitolo 97. In quella fase sono state trascurate le sue potenzialià di controllo, che possono estendersi fino all'utilizzo del protocollo IDENT.

La configurazione del TCP wrapper avviene esclusivamente attraverso i file /etc/hosts.allow e /etc/hosts.deny, all'interno dei quali si possono utilizzare direttive più complesse di quelle già viste in precedenza. In ogni caso, è bene ribadire che lo scopo di questi file è quello di trovare una corrispondenza con l'utente e il nodo che tenta di accedere a uno dei servizi messi sotto il controllo del supervisore Inet. La verifica inizia dal file /etc/hosts.allow e continua con /etc/hosts.deny, fermandosi alla prima corrispondenza corretta. Se la corrispondenza avviene con una direttiva del file /etc/hosts.allow, l'accesso è consentito; se la corrispondenza avviene con una direttiva di /etc/hosts.deny, l'accesso è impedito; se non avviene alcuna corrispondenza l'accesso è consentito.

235.1   Dichiarazione all'interno di /etc/inetd.conf

La dichiarazione di un servizio all'interno del file /etc/inetd.conf può avvenire fondamentalmente in due modi possibili: con o senza il filtro del TCP wrapper. Si osservino i due esempi seguenti.

# /etc/inetd.conf
#...
telnet  stream  tcp     nowait  root    /usr/sbin/in.telnetd    in.telnetd
#...
# /etc/inetd.conf
#...
telnet  stream  tcp     nowait  root    /usr/sbin/tcpd  in.telnetd
#...

Nel primo caso, quando si instaura una connessione TELNET, il supervisore Inet avvia direttamente il binario /usr/sbin/in.telnetd, senza altre intermediazioni. L'albero dei processi potrebbe apparire come nell'esempio seguente:

init-+-inetd---in.telnetd---login---bash---...
     |
     ...

Nel secondo caso, invece, un'eventuale connessione TELNET viene preceduta dalla verifica attraverso il TCP wrapper, che potrebbe anche rifiutarla, oppure semplicemente aggiungere dei controlli. Ma una volta completati i controlli, se il servente può essere avviato, il programma tcpd si toglie di mezzo, per cui l'albero dei processi appare esattamente uguale a quanto già visto.

Quando si decide di utilizzare il TCP wrapper, si possono presentare altre possibilità. Per la precisione, perché funzioni quanto visto nell'ultimo esempio, occorre che l'eseguibile in.telnetd si trovi nella directory prevista dal programma tcpd, secondo quanto definito in fase di compilazione dei sorgenti. In pratica, per GNU/Linux si tratta di /usr/sbin/.

Se il demone di un determinato servizio si trova in una collocazione differente rispetto a quella standard, questo potrebbe essere indicato utilizzando il percorso assoluto, come nell'esempio seguente:

# /etc/inetd.conf
#...
telnet  stream  tcp     nowait  root    /usr/sbin/tcpd  /root/bin/in.telnetd
#...

In questo caso, viene specificato che il demone necessario a ricevere le connessioni TELNET è precisamente /root/bin/in.telnetd.

Nella documentazione del TCP wrapper si mostra la possibilità di utilizzare questo programma solo a scopo di verifica dei tentativi di accesso, che vengono annotati nel registro del sistema, sostituendo il demone che dovrebbe essere avviato con una copia di tcpd stesso. Supponendo di volere eliminare il servizio Finger pur continuando a monitorare le richieste di questo, si potrebbe agire come segue:

mkdir /directory/segreta

mv /usr/sbin/in.fingerd /directory/segreta

cp /usr/sbin/tcpd /usr/sbin/in.fingerd

In alternativa, si può ottenere un risultato simile semplicemente togliendo il programma demone del servizio, lasciando però la dichiarazione nel file /etc/inetd.conf. La differenza che si può avvertire sta nelle ulteriori segnalazioni di errore che si ritrovano nel registro del sistema, che avvisano dell'impossibilità di avviare il programma corrispondente.

235.2   Limiti e particolarità del TCP wrapper

In generale, le connessioni RPC non si riescono a controllare facilmente con il TCP wrapper. In particolare, i servizi annotati come rpc/tcp nel file /etc/inetd.conf non sono gestibili attraverso il programma tcpd.

Alcuni demoni UDP e RPC rimangono attivi al termine del loro lavoro, in attesa di un'ulteriore richiesta eventuale. Questi servizi sono registrati nel file /etc/inetd.conf con l'opzione wait e così si possono riconoscere facilmente. Come si può intuire, solo la richiesta che li avvia può essere controllata da tcpd.

Alcuni dettagli di funzionamento di tcpd sono definiti in fase di compilazione dei sorgenti. Si tratta in particolare dell'opzione di compilazione -DPARANOID, con la quale è come se fosse sempre attivo il jolly PARANOID nei file /etc/hosts.allow e /etc/hosts.deny. Di solito, i pacchetti già compilati del TCP wrapper sono stati ottenuti senza questa opzione, in modo da lasciare la libertà di configurarlo come si vuole.

Un altro elemento che può essere definito con la compilazione è il tipo di direttive che si possono accettare nei file /etc/hosts.allow e /etc/hosts.deny. Le due sintassi possibili sono descritte in due documenti separati: hosts_access(5) e hosts_options(5).

235.3   /etc/hosts.allow /etc/hosts.deny

In questa sezione viene mostrata in particolare la sintassi dei file /etc/hosts.allow e /etc/hosts.deny, quando nella fase di compilazione di tcpd non è stata abilitata l'estensione PROCESS_OPTIONS; in pratica quella più limitata. Negli esempi si mostreranno anche le corrispondenze con il secondo tipo di formato, che può essere approfondito leggendo hosts_options(5).

elenco_di_demoni  :  elenco_di_clienti[ :  comando_di_shell]

La sintassi mostrata, che si riferisce al tipo più semplice di formato delle direttive di questi file, potrebbe essere trasformata in quello più complesso nel modo seguente:

elenco_di_demoni  :  elenco_di_clienti[ : spawn  comando_di_shell]

Quando non si sa quale sia il formato giusto per il proprio tcpd, basta provare prima quello più semplice. Se non va bene si vede subito la segnalazione di errore nel registro del sistema.

I primi due elementi, l'elenco di demoni e l'elenco di clienti, sono già stati descritti nel capitolo 97. Vale forse la pena di ricordare che questi «elenchi» sono semplicemente nomi o modelli separati da spazi orizzontali, cosa che spiega la necessità di separare i vari campi delle direttive attraverso i due punti verticali.

Ciò che appare a partire dal terzo campo di queste direttive (nel caso mostrato si tratta di un comando di shell, ma con la sintassi più complessa si parla piuttosto di opzioni), può contenere delle variabili, rappresentate da un simbolo di percentuale (%) seguito da una lettera, che vengono espanse da tcpd ogni volta che viene verificata la corrispondenza con quella direttiva determinata che le contiene (tabella 235.1).

Variabile Contenuto
%a L'indirizzo del cliente.
%A L'indirizzo del servente.
%c L'informazione completa del cliente per quanto disponibile.
%d Il nome del processo del demone.
%h Il nome del cliente o l'indirizzo se il nome non è disponibile.
%H Il nome del servente o l'indirizzo se il nome non è disponibile.
%n Il nome del cliente o unknown o paranoid.
%N Il nome del servente o unknown o paranoid.
%p Il numero del processo del demone.
%s Informazione completa del servente per quanto disponibile.
%u Il nome dell'utente del cliente o unknown.
%% Un simbolo di percentuale singolo.

Tabella 235.1. Elenco delle variabili utilizzabili in alcune parti delle direttive dei file di controllo degli accessi.

Una direttiva può contenere il simbolo di due punti (:) all'interno di certi campi. In tal caso, per evitare che questi si confondano con la separazione dei campi, occorre precedere tale simbolo con la barra obliqua inversa: \:.

Una direttiva può essere interrotta e ripresa nella riga successiva se alla fine della riga appare una barra obliqua inversa, subito prima del codice di interruzione di riga.

Ogni volta che si modifica uno di questi file, è indispensabile verificare che nel registro di sistema non appaiano indicazioni di errori di sintassi. Un problema tipico che si incontra è dovuto al fatto che ogni direttiva deve terminare con un codice di interruzione di riga. Se alla fine di una direttiva terminasse anche il file, questo costituirebbe un errore che ne impedirebbe il riconoscimento.

235.3.1   Demoni e clienti specificati in modo più preciso

I primi due campi delle direttive di questi file, permettono di indicare con più precisione sia i demoni che i clienti che accedono.

Quando il servente ha diversi indirizzi IP con cui può essere raggiunto, è possibile indicare nel primo campo un demone in combinazione con un indirizzo particolare dal quale proviene la richiesta. In pratica, il primo campo diventa un elenco di elementi del tipo seguente:

demone @ modello_servente

Il demone può essere indicato per nome, oppure può essere messo al suo posto il jolly ALL che li rappresenta tutti.

Il modello del servente serve a rappresentare questi indirizzi per nome o per numero. Valgono anche in questo caso le regole con cui si possono definire i nomi e gli indirizzi di clienti, anche per quanto riguarda le indicazioni parziali (un intero dominio o un gruppo di indirizzi).

Più interessante è invece la possibilità di ottenere dal TCP wrapper la verifica del nominativo-utente del processo avviato dal cliente per la connessione. Si veda per questo, quanto già descritto in precedenza al riguardo del protocollo IDENT. Basta utilizzare nel secondo campo la sintassi seguente:

modello_utente @ modello_cliente

Utilizzando questa forma, tcpd, prima di concedere l'accesso al servizio, interpella il cliente attraverso il protocollo IDENT, per ottenere il nome dell'utente proprietario del processo che ha instaurato la connessione.

Se il cliente non risponde a questo protocollo, si crea un pausa di ritardo di circa 10 secondi. Implicitamente si penalizzano tutti gli utenti che usano sistemi operativi diversi da Unix e derivati.

Una volta ottenuta la risposta, o quando scade il tempo, può essere fatto il confronto con la direttiva. In ogni caso, questo tipo di direttiva fa sì che venga aggiunta questa informazione nel registro del sistema.

Il modello dell'utente può essere un nome puro e semplice, oppure un jolly: ALL, KNOWN e UNKNOWN. Il significato è intuitivo: tutti gli utenti; solo gli utenti conosciuti; solo gli utenti sconosciuti.

Il modello del cliente è quello già visto in precedenza: nomi interi; nomi parziali che iniziano con un punto; indirizzi IP interi; indirizzi IP parziali che terminano con un punto; jolly vari.

È bene ribadire che l'informazione sull'utente restituita dal protocollo IDENT, non è affidabile. Un sistema compromesso potrebbe essere stato modificato in modo da restituire informazioni false.

235.3.2   Comandi di shell

Il terzo campo delle direttive di questi file, permette di inserire un comando di shell. Quando un accesso trova corrispondenza con una direttiva contenente un comando di shell, questo comando viene eseguito; mentre l'accesso viene consentito se la corrispondenza avviene all'interno del file /etc/hosts.allow.

Il comando può contenere le variabili descritte nella tabella 235.1, che sono utili per dare un senso a questi comandi.

Il comando viene eseguito utilizzando l'interprete /bin/sh, connettendo standard input, standard output e standard error al dispositivo /dev/null. Generalmente, alla fine del comando viene indicato il simbolo &, in modo da metterlo sullo sfondo, per evitare di dover attendere la sua conclusione.

Questi comandi non possono fare affidamento sulla variabile di ambiente PATH per l'avvio degli eseguibili, per cui si usando generalmente percorsi assoluti, a meno che questa variabile sia inizializzata esplicitamente all'interno del comando stesso.

235.3.3   Esempi e trappole

Seguono alcuni esempi che dovrebbero chiarire meglio l'uso delle direttive dei file /etc/hosts.allow e /etc/hosts.deny.

In tutti gli esempi mostrati si suppone che il file /etc/hosts.deny contenga solo la direttiva ALL:ALL, in modo da escludere ogni accesso che non sia stato previsto espressamente nel file /etc/hosts.allow.

# /etc/hosts.allow
#
ALL : ALL@ALL

Supponendo che questa sia l'unica direttiva del file /etc/hosts.allow, si intende che vengono consentiti esplicitamente tutti gli accessi a tutti i servizi. Tuttavia, avendo utilizzato la forma ALL@ALL nel secondo campo, si attiva il controllo dell'identità dell'utente del cliente, ottenendone l'annotazione del registro del sistema.

# /etc/hosts.allow
#
ALL : KNOWN@ALL

La direttiva combacia solo con accessi in cui gli utenti siano identificabili.

# /etc/hosts.allow
#...
in.telnetd : ALL : ( /usr/sbin/safe_finger -l @%h | \
        /bin/mail -s '%d-%u@%h' root ) &

Si tratta di una trappola con cui l'amministratore vuole essere avvisato di ogni tentativo di utilizzo del servizio TELNET. Il comando avvia safe_finger (una versione speciale del comando finger che accompagna il TCP wrapper) in modo da conoscere tutti i dati possibili sugli utenti connessi alla macchina cliente, inviando il risultato al comando mail per spedirlo a root.

Molto probabilmente, l'amministratore che prepara questa trappola, farà in modo che il demone in.telnetd non sia disponibile, in modo tale che la connessione venga comunque rifiutata.

Se fosse stato necessario utilizzare l'altro tipo di formato per le direttive di questi file, l'esempio appena mostrato sarebbe il seguente: si aggiunge la parola chiave spawn che identifica l'opzione corrispondente.

# /etc/hosts.allow
#...
in.telnetd : ALL : spawn ( /usr/sbin/safe_finger -l @%h | \
        /bin/mail -s '%d-%u@%h' root ) &

L'esempio seguente mostra un tipo di trappola meno tempestivo, in cui ci si limita ad aggiungere un'annotazione particolare nel registro del sistema per facilitare le ricerche successive attraverso grep.

in.telnetd : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.rshd    : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.rlogind : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.rexecd  : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
ipop2d     : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
ipop3d     : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
imapd      : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.fingerd : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &

Trattandosi di servizi che non si vogliono offrire (altrimenti non ci sarebbe ragione di registrare tanto bene gli accessi), anche in questo caso è opportuno che i demoni corrispondenti non ci siano, oppure che i rispettivi eseguibili siano sostituiti da una copia dello stesso programma tcpd.

Si osservi in particolare che all'interno del comando appare il simbolo di due punti protetto da una barra obliqua. Se non si facesse così, potrebbe essere interpretato come l'inizio di un nuovo campo.

235.3.4   Comandi e servizi UDP

I servizi UDP non si prestano tanto per la creazione di trappole, a causa del fatto che non si instaura una connessione duratura come nel caso del protocollo TCP. Il caso più importante di questo problema è rappresentato dal servizio TFTP, che di solito viene indicato nel file /etc/inetd.conf nel modo seguente:

tftp    dgram   udp     wait    root    /usr/sbin/tcpd  in.tftpd

Se si creasse una direttiva come la seguente,

# /etc/hosts.allow
#...
in.tftpd : ALL : ( /usr/sbin/safe_finger -l @%h | \
        /bin/mail -s '%d-%u@%h' root ) &

si rischierebbe di avviare il comando di shell un gran numero di volte. Si può limitare questo problema modificando la riga contenuta nel file /etc/inetd.conf nel modo seguente:

tftp    dgram   udp     wait.2  root    /usr/sbin/tcpd  in.tftpd

In tal modo, si accetterebbero un massimo di due connessioni al minuto.

In generale, dovendo realizzare delle trappole per servizi UDP, conviene eliminare del tutto il demone dal file system.

235.4   # tcpdchk

tcpdchk [opzioni]

tcpdchk permette di controllare la configurazione del TCP wrapper, indicando problemi possibili ed eventualmente anche dei suggerimenti per la loro sistemazione.

tcpdchk analizza i file /etc/inetd.conf, /etc/hosts.allow e /etc/hosts.deny. Tra i vari tipi di verifiche che vengono eseguite, ci sono anche i nomi utilizzati per i nodi e i domini NIS. In tal senso, per avere un controllo più preciso, è opportuno utilizzare tcpdchk anche quando il sistema viene collegato in rete, avendo accesso alla configurazione reale del DNS e del NIS.

Alcune opzioni
-d

Esamina i file ./hosts.allow e ./hosts.deny, cioè quelli che si trovano nella directory corrente.

-i  file_inetd

Specifica il file da utilizzare al posto di /etc/inetd.conf.

235.5   # tcpdmatch

tcpdmatch [opzioni]demone[@ servente] [utente @]cliente

tcpdmatch permette di verificare il comportamento della configurazione simulando delle richieste. In pratica, verifica il contenuto di /etc/inetd.conf, /etc/hosts.allow e /etc/hosts.deny, mostrando quello che succederebbe con una determinata richiesta di connessione.

È obbligatoria l'indicazione di un demone, con l'eventuale aggiunta dell'indicazione del servente quando si possono distinguere per questo degli indirizzi diversi; inoltre è obbligatoria l'indicazione del cliente, con l'eventuale aggiunta dell'utente.

Nell'indicazione del servente si possono usare anche i jolly UNKNOWN e PARANOID; il valore predefinito, se questa indicazione manca, è UNKNOWN.

L'utente può essere indicato per nome o per numero UID; anche in questo caso si ammette il jolly UNKNOWN, che è il valore predefinito in mancanza di questa indicazione.

Alcune opzioni
-d

Esamina i file ./hosts.allow e ./hosts.deny, cioè quelli che si trovano nella directory corrente.

-i  file_inetd

Specifica il file da utilizzare al posto di /etc/inetd.conf.

Esempi

tcpdmatch in.telnetd localhost

Verifica il comportamento della configurazione per una richiesta di accesso al servizio TELNET, corrispondente al demone in.telnetd, da parte del nodo localhost.

tcpdmatch in.telnetd tizio@roggen.brot.dg

Verifica il comportamento della configurazione per una richiesta di accesso al servizio TELNET, corrispondente al demone in.telnetd, da parte dell'utente tizio dal nodo roggen.brot.dg.

tcpdmatch in.telnetd@dinkel.brot.dg tizio@roggen.brot.dg

Verifica il comportamento della configurazione per una richiesta di accesso al servizio TELNET, corrispondente al demone in.telnetd, proveniente dall'interfaccia corrispondente al nome dinkel.brot.dg, da parte dell'utente tizio dal nodo roggen.brot.dg.

235.6   $ safe_finger

safe_finger è un cliente Finger che, da quanto indicato nella documentazione originale, dovrebbe essere più adatto per la creazione di trappole attraverso i comandi di shell.

Le sue funzionalità sono le stesse del comando finger normale e non viene indicato altro nella documentazione originale.

235.7   $ try-from

try-from permette di verificare il funzionamento del sistema di identificazione del servente e del cliente. Si utilizza nel modo seguente:

rsh  host  /usr/sbin/try-from

Di solito, questo programma si utilizza per verificare il proprio sistema. Per fare un esempio, si immagina di essere l'utente caio che dal nodo dinkel.brot.dg si connette al suo stesso elaboratore per avviare try-from.

rsh dinkel.brot.dg /usr/sbin/try-from[Invio]

client address  (%a): 192.168.1.1
client hostname (%n): dinkel.brot.dg
client username (%u): caio
client info     (%c): caio@dinkel.brot.dg
server address  (%A): 192.168.1.1
server hostname (%N): dinkel.brot.dg
server process  (%d): try-from
server info     (%s): try-from@dinkel.brot.dg

Dal risultato che si ottiene, si può determinare che anche il servizio IDENT dell'elaboratore dinkel.brot.dg (visto come cliente) funziona correttamente.

Appunti di informatica libera 2001.01.30 --- Copyright © 2000-2001 Daniele Giacomini --  daniele @ swlibero.org

Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome tcp_nbsp_wrapper_pi_ugrave_in_dettaglio.html

[successivo] [precedente] [inizio] [fine] [indice generale] [licenze] [indice analitico] [tomo] [parte]