Impostazioni per un server
Telnet in una
gabbia chroot
(ovvero: come ho imparato ad avere un server telnet
pubblico e a dormire tranquillo)
Il server telnet installato è il telnetd classico del
Linux NetKit (0.17): "DARPA telnet protocol server".
Non lo credo insicuro per quanto riguarda la vulnerabilità del
suo codice, contrariamente a quanto so per esempio a proposito del
demone gopher dell'Università del Minnesota.
Per usarlo, si deve avere una directory dove sia possibile fari
girare i servizî di rete in chroot,
e che quindi comprenda al suo
interno le varie librerie condivise necessarie. Sebbene non
strettamente necessario, trovo che il modo più semplice di
garantirsi un tale risultato (insieme alla facile manutenzione per gli
aggiornamenti di sicurezza) sia di avere una distribuzione completa
(sebbene minimale) installata in una partizione montata nella directory
scelta. Negli esempî che seguono si userà, come
esempio, la partizione /dev/sdb2.
Fatto questo e installato il demone telnetd nella partizione
autonoma, creiamo una directory arbitraria dove montare questa
partizione e montiamocela (negli esempi che seguono si userà a
tale scopo la directory "/usr/sandbox"):
# mkdir
/usr/sandbox
# mount -t
ext2 /dev/sdb2 /usr/sandbox
Per automatizzare la cosa, si può mettere la riga
seguente nel file /etc/fstab:
/dev/sdb2
/usr/sandbox ext2
noatime,nouser 0 2
Si è scelto il filesystem ext2 perché la
partizione usata non ospita dati soggetti a cambiamenti rapidi e
frequenti e perché questi dati sono comunque ritenuti non
vitali, di secondaria importanza. Inoltre la macchina sulla quale
era stato implementato la prima volta quanto di seguito esposto era
poco potente,
una SS5 con microprocessore MicroSPARC-II da 85 MHz, con Debian
GNU/Linux come sistema operativo. Usare quindi
il filesystem ext2 e l'opzione "noatime" permette di abbassare al
minimo il lavoro del microprocessore per gestire il filesystem.
Si avvierà il server telnetd usando il superdemone
internet xinetd, il quale sarà configurato in modo che all'avvio
legga i file presenti nella directory /etc/xinetd.d/ (basta
specificare
"includedir
/etc/xinetd.d" nel suo file
di configurazione, tipicamente "/etc/xinetd.conf").
Siccome in
quest'esempio si userà il demone telnet per servire dei giochi
interattivi in modalità testo, si creerà in questa
directory il file "giochi-telnet",
perché non intralci un file
"telnet" che può
forse essere già presente.
Ecco come può essere preparato questo file:
# cat /etc/xinetd.d/giochi-telnet
service giochi
{
socket_type = stream
protocol = tcp
wait = no
disable = no
user = root
port = 23
server = /usr/sbin/chroot
server_args = /usr/sandbox /usr/sbin/in.telnetd -h
flags = NORETRY
instances = 32
per_source = 2
cps = 5 10
max_load = 2
nice = 10
log_type = FILE /usr/sandbox/var/log/chroot_telnetd 80K 100K
log_on_success = PID HOST USERID EXIT DURATION
log_on_failure = HOST USERID ATTEMPT
banner_fail = /usr/sandbox/etc/fuori_di_qui
}
Segue la spiegazione delle voci che compaiono nel file:
socket_type =
tipo di socket da usarsi per la comunicazione; può
assumere uno di questi valori:
- stream,
per i servizi che scambiano i dati in un flusso
(tipicamente i servizî TCP);
- dgram,
per i servizi che scambiano i dati per datagrammi
(tipicamente i servizî UDP);
- raw,
per i servizi che necessitano dell'accesso diretto allo IP;
- seqpacket,
per i servizi che necessitano di una trasmissione
affidabile e sequenziale di datagrammi;
- protocol
=
protocollo della comunicazione, può essere uno di
quelli elencati in /etc/protocols;
- wait =
se impostato a "yes"
istruisce xinetd ad attendere che ogni
singola istanza del server mandato in esecuzione esca prima di mandarne
in esecuzione un altro per un'altra richiesta di servizio (si fa
così per i demoni che non sono "multithread", altrimenti si
mette "no");
- disable
=
disabilita il servizio descritto dal file;
- user =
utente che possiede il processo del server;
- port =
numero della porta alla quale è reso disponibile il
servizio;
- server =
file eseguibile da lanciare ogni volta che si deve servire una
richiesta legittima (/usr/sbin/chroot
su Debian Woody, /usr/bin/chroot
su Gentoo 1.12.11.1);
- server_args
=
parametri da inserire sulla linea di comando
dell'eseguibile specificato dalla voce "server"
ogni volta che si
lancia in esecuzione il server;
- flags =
opzioni supplementari, quali: KEEPALIVE e
NODELAY
(per le
connessioni TCP), IDONLY, NORETRY;
quest'ultima impedisce, per un certo
lasso di tempo, che sia lanciato di nuovo il server per servire una
richiesta di servizio se in precedenza lo stesso server aveva fallito
il suo proprio avvio;
- instances
=
essendo il server capace di numerosi thread, si può
specificare in questa voce quante istanze al massimo avere in
esecuzione in ogni dato momento;
- per_source
=
numero massimo di richieste di servizio da servire verso
uno stesso IP;
- cps =
limite per unità di tempo del numero di connessioni
servite: il primo numero è il numero di connessioni al secondo
da gestirsi prima di disattivare temporaneamente il servizio; il
secondo numero è il numero di secondi da attendere prima di
riattivare il servizio;
- max_load
=
carico massimo di elaborazione del sistema raggiunto prima
che sia disattivato il servizio;
- nice =
livello al quale abbassare (numero positivo) o innalzare (numero
negativo) la priorità del processo che servirà le
richieste di servizio;
- log_type =
determina la destinazione dei log del servizio; i suoi due
valori possibili sono: SYSLOG syslog_facility [syslog_level]
se si intende avvalersi del log di sistema UNIX di tipo syslog_facility e
(opzionalmente) di livello syslog_level;
FILE file [soft_limit [hard_limit]]
se si intende convogliare tutti i messaggi di log in un file specifico
imponendone, se desiderato, uno o due limiti nelle dimensioni: il
primo, una volta superato, causa la produzione di messaggi di allarme
(nel syslog di sistema a
livello alert); il
secondo invece, una volta superato, impone al server di cessare dal
registrare ulteriori messaggi di log nel file;
- log_on_success
=
determina quali informazioni sono registrate nel log quando il server
riesce ad aprire una nuova sessione e quando la cessa; può
consistere in una lista di uno o più di queste voci: PID, che
è il numero identificativo del processo del server, HOST, che
è l'indirizzo dell'host
remoto, USERID, che
è l'identificativo numerico dell'utente del
sistema remoto ottenuto dal completamento di una richiesta di
riconoscimento utente ivi diretta tramite il protocollo specificato
nella RFC 1413,
EXIT, che registra la
cessazione del processo del server insieme al suo codice di uscita, DURATION, che riporta la durata
totale della sessione una volta conclusa, TRAFFIC, che registra gli
ottetti totali che sono stati ricevuti o trasmessi per una sessione che
è stata rediretta;
- log_on_failure
=
determina quali informazioni sono registrate nel log quando il server NON
riesce ad aprire una nuova sessione; può
consistere in una lista di uno o più di queste voci: HOST, che
è l'indirizzo dell'host
remoto, USERID, che
è l'identificativo numerico dell'utente del
sistema remoto ottenuto dal completamento di una richiesta di
riconoscimento utente ivi diretta tramite il protocollo specificato
nella RFC 1413,
ATTEMPT, che registra
il fatto che un tentativo di avviare il servizio non è riuscito;
- banner_fail
= specifica il file il cui contenuto è inviato all'host
remoto cui è stata negata la connessione a causa di restrizioni
esplicite sull'accesso al server (ad esempio, se il server è
stato compilato con il supporto delle libwrap, per via dell'assenza di
righe che consentino l'accesso al servizio nei file /etc/hosts.allow e /etc/hosts.deny, vedasi in
proposito la pagina man
di hosts_access(5)
tenendo conto che il server da configurarsi non è telnetd, ma chroot).
Adesso il server è pronto per funzionare, rimanendo da
configurarsi l'ambiente nella gabbia chroot,
ossia nella cartella /usr/sandbox
nel caso qui esposto. Per funzionare quest'ambiente dovrà
contenere:
- degli utenti locali cui permettere l'accesso tramite telnet;
- le cartelle HOME degli utenti definiti nel punto (1);
- i comandi e gli applicativi che devono essere a disposizione
degli utenti dell'ambiente di chroot;
- le cartelle con le librerie condivise necessarie ai comandi e
agli applicativi del punto (3).
Un'eventuale versione futura di questa guida potrebbe fornire i
dettagli della realizzazione di un ambiente completo di chroot che soddisfi i punti
numerati in alto. Per il momento invece si limita a fornire i
dettagli della configurazione del solo server. Una cosa
però è necessario che si descriva per far funzionare il
server. Il comando chroot cerca infatti il server
/usr/sbin/telnetd nella gabbia di chroot, non nel filesystem naturale
del sistema operativo. Per prima cosa bisogna quindi creare la
cartella /usr/sandbox/usr/sbin e copiarvi il file /usr/sbin/telnetd:
[root@cratere6 ~]# mkdir -p /usr/sandbox/usr/sbin
[root@cratere6 ~]# cp /usr/sbin/telnetd /usr/sandbox/usr/sbin/
Questo probabilmente non basterà per far funzionare il server
perché questo sarà stato compilato lincato dinamicamente
a delle librerie di sistema che mancano nell'ambiente di chroot.
In un sistema di prova (Gentoo 1.12.11.1) infatti è successo
quanto segue:
[alessandro@cratere6 ~]$ telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
chroot: cannot run command `/usr/sbin/telnetd': No such file or
directory
Connection closed by foreign host.
[alessandro@cratere6 ~]$
Per trovare a quali librerie è lincato il server telnetd si
è usato il comando ldd:
[root@cratere6 ~]# ldd /usr/sbin/telnetd
linux-gate.so.1 =>
(0xb7f03000)
libutil.so.1 =>
/lib/libutil.so.1 (0xb7ef0000)
libc.so.6 =>
/lib/libc.so.6 (0xb7db6000)
/lib/ld-linux.so.2
(0xb7f04000)
Si è proceduto a creare la cartella delle librerie nell'ambiente
di chroot e vi si sono copiate le librerie necessarie:
[root@cratere6 ~]# mkdir /usr/sandbox/lib
[root@cratere6 ~]# cp /lib/{libutil.so.1,libc.so.6,ld-linux.so.2}
/usr/sandbox/lib/
[root@cratere6 ~]#
[root@cratere6 ~]#
< Torna
al livello superiore <
<< Torna alla
pagina
iniziale <<