Port knocking
by admin on Jun.22, 2010, under Linux, Networking, Sicurezza, Tools
Il Port knocking è una tecnica che permette di rafforzare in maniera considerevole la sicurezza di un server che debba garantire servizi non permanenti su indirizzi IP pubblici.
In tal modo un determinato servizio, normalmente invisibile, diventa accessibile in caso di necessità.
Per utilizzare la tecnica del port knocking è necessario installare il pacchetto knockd.
Per installarlo (su una piattaforma Linux Debian-like) è sufficiente un semplicissimo:
# apt-get install knockd
Il server
Knockd è il port-knock server. Esso intercetta tutto il traffico di una interfaccia ethernet (o PPP), alla ricerca di speciali sequenze “knock” su porte particolari. Un client origina tali sequenze inviando dei pacchetti TCP (o UDP) verso una porta del server. Tale porta non deve già essere in stato di open. Dal momento che knockd opera a livello link, esso è in grado di vedere tutto il traffico in ingresso, anche se destinato ad una porta in stato closed.
Quando il server rileva una specifica sequenza destinata a delle porte prestabilite, manda in esecuzione un comando definito nel proprio file di configurazione.
Il comando può essere usato (grazie all’impostazione di appropriate regole di iptables), per aprire dei varchi in un firewall e consentire l’ accesso.
In altri termini una specifica serie di tentativi di connessione verso porte “closed” costituisce un segnale convenuto per aprire una diversa porta.
Alcune impostazioni generali sono a carico del file /etc/default/knockd:
# cat /etc/default/knockd ################################################ # # knockd's default file, for generic sys config # ################################################ # control if we start knockd at init or not # 1 = start # anything else = don't start # # PLEASE EDIT /etc/knockd.conf BEFORE ENABLING START_KNOCKD=0 # command line options #KNOCKD_OPTS="-i eth1"
Per ottenere l’attivazione del daemon knockd all’avviamento occorrerà quindi impostare
START_KNOCKD=1
mentre per indicare su quale interfaccia il demone dovrà rimanere in ascolto, ad esempio ppp0:
KNOCKD_OPTS="-i ppp0"
Impostazioni specifiche sono invece delegate al file /etc/knockd.conf.
Il seguente file knockd.conf è ad esempio configurato per l’apertura di una sola porta:
# cat /etc/knockd.conf [options] UseSyslog # alternativamente: logfile = /var/log/knockd.log [openweb] sequence = 7000,8000,9000 # Questa è la sequenza delle porte sulle quali knockd rimarrà in ascolto. # Per default il protocollo è TCP. # Quali, quante porte, e che protocollo di trasporto usare è assolutamente discrezionale. # sequence = 7000:udp,8000:tcp,9000:udp # Esempio di sequenza con porte miste udp/tcp seq_timeout = 20 # Timeout per completare la sequenza. command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 80 -j ACCEPT # Quando la sequenza verrà ricevuta, verrà attivata una regola che aprirà # la porta 80. tcpflags = syn # Ulteriore filtro, sul tipo di flag del pacchetto inviato alla sequenza di porte. [closeweb] sequence = 9001,9002,9003 # Questa è un'altra sequenza di porte sulle quali knockd rimarrà in ascolto. seq_timeout = 20 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 80 -j ACCEPT # Quando la sequenza verrà ricevuta, verrà pure invocata questa regola, # che cancellerà quella creata in precedenza. tcpflags = syn
La variabile %IP% rappresenta l’indirizzo che ha effettuato la richiesta di connessione, in questo caso verrà permessa l’apertura della porta 80 solo a richieste provenienti da tale IP.
L’esempio precedente si riferisce alla apertura di una sola porta. Se vi fosse però la necessità di aprirne di più si potrebbero creare più sessioni [openService] e [closeService].
Un sistema diretto ad ottenere lo stesso risultato si basa sull’uso di scripts.
In questo senso il file /etc/knockd.conf potrebbe essere impostato come segue:
[options] logfile = /var/log/knockd.log [open] sequence = 7000,8000,9000 seq_timeout = 30 tcpflags = syn command = /usr/local/bin/open_ports %IP% [close] sequence = 9000,8000,7000 seq_timeout = 30 tcpflags = syn command = /usr/local/bin/close_ports %IP%
In questo caso, anziché invocare direttamente iptables, vengono richiamati due script passando loro il parametro %IP% come argomento.
# cat /usr/local/bin/open_ports #! /bin/bash iptables -A INPUT -s $1 -p tcp --dport 21 -j ACCEPT iptables -A INPUT -s $1 -p tcp --dport 22 -j ACCEPT iptables -A INPUT -s $1 -p tcp --dport 80 -j ACCEPT # cat /usr/local/bin/close_ports #! /bin/bash iptables -D INPUT -s $1 -p tcp --dport 21 -j ACCEPT iptables -D INPUT -s $1 -p tcp --dport 22 -j ACCEPT iptables -D INPUT -s $1 -p tcp --dport 80 -j ACCEPT
Il client
L’eseguibile knock (che fa parte del medesimo package) è un port-knock client. Esso invia pacchetti TCP/UDP a ogni porta specificata sul server, creando una speciale knock sequence che il server in ascolto è in grado di rilevare.
Per effettuare la connessione digitare il seguente comando all’interno di una finestra di terminale:
# knock -v porta1 porta2 porta3 ... portaN
Nel caso una o più porte (ad esempio la prima e la terza) siano configurate per utilizzare il protocollo UDP, la sintassi diventa:
# knock -v porta1:UDP porta2 porta3:UDP ... portaN
Limitazioni
Per poter utilizzare la tecnica del port knocking, occorre necessariamente un client. Se da un lato è vero che il client non deve essere necessariamente quello compreso nel package knockd, dato che può benissimo essere sostituito da tools come hping oppure scapy, i dati da associarvi devono essere tenuti segreti, alla stregua di una password.
L’utilizzo del port knocking potrebbe essere impraticabile in talune circostanze, ad esempio a partire da postazioni Internet pubbliche che non permettano l’esecuzione di programmi estranei, o utilizzino un sistema operativo differente. Anche qualora la piattaforma fosse coerente e l’esecuzione consentita, sarebbe necessario portare con sè un supporto rimovibile, tipo una USBkey, contenente il software.
Infine, qualsiasi tecnica che alteri le regole di un firewall in modo automatico richiede una accurata implementazione. Se infatti il daemon in ascolto fallisse o non fosse capace di interpretare correttamente la sequenza di knock, la connessione da remoto diverrebbe impossibile.

