Servknock - Port knocking server

Servknock e' un sistema di portknocking composto da client e server, chiamati con estrema fantasia knock e servknock, caratterizzato dalle seguenti features :

- Rilevamento delle sequenze tramite la libreria libPcap;
- Utilizzo di sequenze di knock crittate, comprendenti anche l'indirizzo IP del richiedente;
- Possibilita' di includere nella sequenza di knock sia pacchetti TCP, UDP che ICMP;
- Possibilita' di discriminare i pacchetti TCP della sequenza in base ai flag impostati.;
- Possibilita' di specificare diverse sequenze di knock per eventi differenti
- Elementi della sequenza di knock mischiati con un pattern casuale di traffico di rete.;
- Possibilita' di eseguire comandi shell arbitrari e non solamente manipolare le regole di filtraggio del firewall.
- Possibilita' di eseguire piu' di un comando al riconoscimento di una sequenza
- Possibilita' di eseguire due differenti serie di comandi, la prima al riconoscimento della sequenza , e la seconda trascorso un timeout specificato.


Installazione

Il sistema su cui si desidera installare servknock non necessita di particolari configurazioni.
E' infatti sufficiente avere netfilter correttamente configurato, ed i moduli necessari caricati (ad esempio iptable_nat, ipt_MASQUERADE, ip_conntrack in caso si abbia la necessita' di ricorrere alla Network Address Translation), a meno che essi non siano gia' stati inclusi direttamente nel kernel in fase di compilazione.
Come sistema di riferimento e' stata utilizzata debian GNU/Linux 3.1 con kernel della serie 2.6 .

I passi da seguire per l'installazione del programma sono i seguenti :

1. Installare le librerie Libpcap, LibMcrypt, LibMhash e LibNet 1.1 necessarie per compilare i sorgenti. :

apt-get install libpcap-dev
apt-get install libmcrypt-dev
apt-get install limhash-dev
apt-get install libnet1-dev

2. Scaricare e decomprimere il tarball di servknock dall'url http://stargazer.altervista.org/pk/servknock_1.12.tar.gz :

wget http://stargazer.altervista.org/pk/servknock_1.12.tar.gz
tar -zxvf servknock_1.12.tar.gz

3. Se si desidera compilare esclusivamente il portknocking server digitare il comando : make servknock
Il sistema comprende anche un client per la generazione delle sequenza di knock, che puo' essere compilato come segue: make knock.
Per avviare invece la compilazione di entrambi i programmi e' sufficiente digitare: make all
Se il processo e' andato a buon fine, nella directory saranno presenti due nuovi eseguibili, chiamati knock e servknock.

4. Per non specificare l'intero percorso ad ogni esecuzione dei due programmi, copiarli all'interno di una directory compresa nella variabile d'ambiente $PATH, ad esempio /usr/sbin. E' inoltre necessario creare la directory /etc/servknock e copiare al suo interno il file servknock.conf. Tale procedura puo' essere effettuata in modo automatizzato direttamente con il comando : make install


Configurazione del server

La prima parte del file di configurazione del server (servknock.conf) e' costituita dalla successiva serie di coppie chiave=valore, che descrivono le opzioni di configurazione generali :

- iface : nome del'interfaccia sulla quale catturare il traffico, come ad esempio eth0, ppp0 ecc.
- cypher : l'algoritmo da utilizzare nelle operazioni di cifratura/decifratura delle sequenze di knock. Attualmente gli cifrari supportati sono gli algoritmi a chiave simmetrica blowfish, twofish, xtea, rijndael e serpent.
- password : la stringa necessaria per generare la chiave utilizzata nelle operazioni crittografiche. Ovviamente lavorando con algoritmi a chiave simmetrica, anche il richiedente deve utilizzare la medesima chiave per la costruzione delle sequenze di knock dirette al server.
- iv : stringa utilizzata per generare il vettore di inizializzazione. Come per la chiave, deve essere uguale sia lato server che client.
- span : gli intervalli di porte monitorati da servknock , per il riconoscimento delle sequenze. Perche' il programma possa essere correttamente avviato e' necessario che la somma di tutti i range di porte valga esattamente 255.
- logfile : il nome del file dove loggare le sequenze riconosciute ed i comandi eseguiti.

Nella seconda parte vengono invece definite le diverse sequenze di knock.
Ognuna di esse e' compresa entro i tag &lt:seq> e </seq>, ed include le seguenti opzioni :

- name : il nome della sequenza;
- sequence : i pacchetti di rete che la compongono, comprese le rispettive porte di destinazione, nel caso si dei pacchetti TCP ed UDP ;
- tcp_flags : i flag che devono essere settati nei pacchetti TCP ;
- seq_timeout : intervallo di tempo espresso in secondi entro il quale deve venire completata la sequenza;
- command : comando da eseguire al riconoscimento della sequenza. Nel caso alla sequenza fossero associati piu'  comandi, devono essere presenti diverse linee con l'opzione command : una per ognuno di essi.
- cmd_timeout : intervallo di tempo a partire dal momento del riconoscimento della sequenza, trascorso il quale eseguire i comandi specificati dall'opzione stop_command.
- stop_command : comando da eseguire una volta trascorsi un numero di secondi secondi pari al valore specificato in cmd_timeout, a partire dal riconoscimento della sequenza di knock. Nel caso si desideri associare piu' comandi alla sequenza, e' sufficiente inserire diverse righe stop_command.

Per la manipolazione delle regole di filtraggio, e' qundi possibile seguire due approcci : avere sequenze diverse per l'inserimento e la rimozione della regola stessa, oppure una sequenza singola, utilizzando le opzioni cmd_timeout e stop_command. A titolo esemplificativo, viene riportato il seguente stralcio di file di configurazione:

###############################
# Portknocking server
###############################

iface=eth0
# blowfish |twofish | xtea | rijndael-128 | serpent
cypher=rijndael-128
password=metALm3lTd0wn
iv=Pa1nkilL3r
span=7000-7100,7500-7655
logfile=/var/log/servknock.log


<seq>
name=ssh_open
sequence=UDP:222,ICMP,TCP:56,UDP:22,TCP:99
seq_timeout=60
tcp_flags=ack,psh
command=iptables -A INPUT -s $IP -p tcp --dport 22 -j ACCEPT
</seq>

&lt:seq>
name=ssh_close
sequence=UDP:212,TCP:149,ICMP,UDP:42,TCP:199,TCP:180
seq_timeout=60
tcp_flags=syn,psh,fin
command=iptables -D INPUT -s $IP -p tcp --dport 22 -j ACCEPT
</seq>

&lt:seq>
name=apache
sequence=TCP:90,UDP:44,ICMP
tcp_flags=syn,ack,psh
seq_timeout=60
command=iptables -A INPUT -s $IP -p tcp --dport 80 -j ACCEPT
cmd_timeout=1000
stop_command=iptables -D INPUT -s $IP -p tcp --dport 80 -j ACCEPT
</seq>

Perche' il sistema funzioni correttamente e' infine necessario impostare le regole iniziali di filtraggio di netfilter, ricorrendo ad iptables. All'interno del tarball di ServkKnock e' compreso a titolo esemplificativo lo shellscript
fwall.sh, utilizzabile per i test. Naturalmente esso non e' indicato per l'utilizzo in un ambiente di produzione.


Esecuzione del server

ServKnock puo' essere semplicemente avviato con il comando servknock . Un'altro metodo, utilizzabile nei sistemi con init System-V, e' quello di inserire uno shellscript per l'avvio di ServKnock (chiamandolo ad esempio
servknock.sh) nella directory /etc/init.d .In questo modo sara' possibile avviare e fermare il programma con i comandi /etc/init.d/servknock.sh start ed /etc/init.d/servknock.sh stop
Infine se si desidera avviare il server in fase di boot, o comunque associarne l'esecuzione ad uno specifico runlevel  e' necessario aggiungere una chiamata a servknock nella struttura di init del sistema con un link simbolico del tipo /etc/rc3.d/S90servknock.sh che punti a /etc/init.d/servknock.sh).
Per semplicita', negli esempi riportati ServKnock verra' sempre avviato direttamente da shell, dove la linea di comando da utilizzare e' cosi' strutturata : servknock [OPTION] [ -f <conf_file> ].

Le opzioni ammissibili sono le seguenti :

-d : daemon mode. Permette di fare girare il programma come un processo demone, eseguito in background.
-h : stampa a video una pagina di help
-D : debug mode . Se specificata, questa opzione consente di stampare sullo standard output diverse informazioni, relative ai parametri di configurazione, le operazioni svolte ed i pacchetti analizzati. Non e'  consentito specificare contemporaneamente le opzioni -d e -D .
-f : permette di utilizzare un file di configurazione alternativo a quello di default ( /etc/  servknock.conf ). E' possibile specificare sia path relativi che assoluti.
-V : verbose mode. Consente di stampare sullo standard output alcune informazioni sintetiche sulle sequenze riconosciute ed i comandi eseguiti. Come per il debug mode, non e' permesso specificare contemporaneamente le opzioni  -V e -d .


Esecuzione del client

Nel tarball di ServKnock e' presente anche un secondo programma chiamato knock, utilizzato per generare le sequenze di  knock ed inviarle al PortKnocking server, dal quale possono essere riconosciute e di conseguenza portare all'esecuzione delle azioni previste in risposta.
Come per il PortKnocking server, anche per il client esiste un relativo file di configurazione, chiamato knockrc. La sua struttura e' del tutto simile a quella di servknock.conf, con la prima parte del file costituita da una serie di coppie chiave=valore, che descrivono le opzioni di configurazione generali, e la seconda in cui sono definite le diverse sequenze.
Il significato delle opzioni ammissibili in knockrc, sono del tutto identiche a quelle del file di configurazione di servknock. E' comunque necessario ricordare come alcune di esse siano specifiche di servknock.conf e quindi non utilizzabili. Non e' infatti prevista l'opzione logfile, mentre nella  definizione di una sequenza di knock sono ammesse esclusivamente name, sequence, e tcp_flags.
Ovviamente perche' le sequenze possano essere riconosciute, le opzioni utilizzate debbono corrispondere con quelle definite nel file di configurazione del PortKnocking server, con name come unica possibile eccezione.

################################
# Knock Client conf file
###############################

# blowfish | twofish | xtea | rijndael-128 | serpent
cypher=rijndael-128
iv=Pa1nkilL3r
password=metALm3lTd0wn
span=7000-7100,7500-7655

#open port 22
<seq>
name=open_ssh
sequence=UDP:222,ICMP,TCP:56,UDP:22,TCP:99
tcp_flags=ack,psh
</seq>

#close port 22
<seq>
name=close_ssh
sequence=UDP:212,TCP:149,ICMP,UDP:42,TCP:199,TCP:180
tcp_flags=syn,psh,fin
</seq>

#open port 80
<seq>
name=apache
sequence=TCP:90,UDP:44,ICMP
tcp_flags=syn,ack,psh
</seq>

Il programma puo' venire invocato con la seguente linea di comando : knock -d <host> -i <interface> -s <sequence name> [-g <address>] [-f <conf file>] .

Le opzioni ammissibili sono le seguenti :

-d : indica l'host al quale inviare la sequenza di knock. E' possibile specificare indifferentemente un nome oppure direttamente l'indirizzo IP di destinazione.
-f : permette di utilizzare un file di configurazione alternativo a quello di default (~/.knockrc).
-g : indica l'indirizzo IP dell'eventuale gateway utilizzato.
-h : stampa a video una pagina di help
-i : l'interfaccia da utilizzare per l'invio dei pacchetti, ad esempio eth0, eth1, ppp0 ecc.
-s : il nome della sequenza di knock da generare. Tale nome deve coincidere con l'opzione name di una delle sequenze definite nel file di configurazione. Se tutti i parametri necessari sono stati specificati correttamente, il programma e' in grado di creare i pacchetti della sequenza ed inviarli a destinazione, utilizzando il device indicato :

[TCP] 10359 Smoke packet
[TCP] 7559 Knock packet
[TCP] 5805 Smoke packet
[UDP] 8272 Smoke packet
[TCP] 2567 Smoke packet
[UDP] 7612 Knock packet
[TCP] 7656 Smoke packet
[TCP] 12807 Smoke packet
[ICMP] Knock packet
[TCP] 14457 Smoke packet
[TCP] 7582 Knock packet
[TCP] 8303 Smoke packet
[TCP] 7525 Knock packet
[UDP] 12872 Smoke packet
[TCP] 9951 Smoke packet
[TCP] 7569 Knock packet
[UDP] 4006 Smoke packet
[TCP] 7620 Knock packet
[TCP] 6497 Smoke packet

Come si puo' notare come gli elementi della sequenza di knock vengono inviati all'interno di una sequenza casuale di pacchetti TCP ed UDP.
E' possibile impostare alcuni parametri in fase di compilazione riguardanti la generazione degli smoke packets, modificando il valore delle seguenti costanti definite in knock.h :

/*max nr. of smoke elements between right packets*/
#define SMOKE_NR 3
/*prob. of a smoke packet to be included in the sequence*/
#define SMOKE_PERC 60
/*max port number in a smoke packet, max 65535*/
#define SMOKE_MAX_PORT 9000
/*min port number in a smoke packet, min 1024*/
#define SMOKE_MIN_PORT 4000

NOTA: Nel caso il server non riesca a rilevare correttamente le sequenze, e' necessario rallentare il ritmo di  invio dei pacchetti, decomenntando la riga #define MODULE_KNOCK nel file knock.h e ricompilando il client. Se il tempo totale per l'invio della sequenza dovesse a questo punto superare il valore di seq_timout specificato nel file di configurazione del server e' sufficiente aumentare tale valore.


Esempio di utilizzo

1. Il client con indirizzo IP 192.168.0.4 invia una specifica sequenza di knock al server, con il comando knock -d stargazer.localdomain -i eth0 -s apache :

[TCP] 9543 Smoke packet
[UDP] 4328 Smoke packet
[TCP] 7055 Knock packet
[TCP] 6293 Smoke packet
[TCP] 9625 Smoke packet
[UDP] 7005 Knock packet
[UDP] 8424 Smoke packet
[UDP] 11426 Smoke packet
[ICMP] Knock packet
[TCP] 14587 Smoke packet
[TCP] 7014 Knock packet
[TCP] 7554 Knock packet
[UDP] 6726 Smoke packet
[TCP] 8073 Smoke packet
[TCP] 13369 Smoke packet
[UDP] 4020 Smoke packet
[TCP] 7618 Knock packet
[UDP] 8396 Smoke packet
[UDP] 13206 Smoke packet
[UDP] 9848 Smoke packet
[TCP] 7526 Knock packet
[UDP] 13656 Smoke packet
[TCP] 11985 Smoke packet

2. Il server riconosce tra i pacchetti ricevuti la sequenza TCP:90,UDP:44,ICMP ed esegue i comandi ad essa associati :

[apache] Knock sequence completed
[apache] Command iptables -A INPUT -s $IP -p tcp --dport 80 -j ACCEPT    [OK]


3. Il client puo' connettersi all'applicazione protetta, in esecuzione sul webserver.

4. Allo scadere del timeout specificato nel file di configurazione il server
esegue i comandi di "chiusura" associati alla sequenza riconosciuta in
precedenza :

[apache] Command iptables -D INPUT -s $IP -p tcp --dport 80 -j ACCEPT    [OK]


Privacy Policy