“Bussare” sulle porte di rete
Mi è capitato spesso di avere una macchina che deve esporre dei servizi in rete su alcune porte tcp/udp che però volevo evitare di mostrare al “mondo”.
Ad esempio può essere che voglio aprire un server ssh. Indipendentemente dal servizio e dalla porta, può essere poco raccomandabile lasciarlo lì aperto “a tutti”.
Potremmo allora pensare di aggiungere una regola sul firewall (iptables) per abilitare l’accesso solo da daterminati ip sorgenti. Peccato che molto spesso gli indirizzi sorgente possono cambiare (indirizzi ip dinamici e altro).
Il port-knocking permette di risolvere queste ed altre situazioni.
Supponiamo appunto di avere la porta del servizio ssh (la 22) che vogliamo aprire solo per certe persone, però non sappiamo i loro indirizzi ip. Con la tecnica del port-knocking possiamo avviare un demone che resta “in ascolto” sulle interfacce di rete per tutte le richieste di connessione a basso livello. Quando questo demone vede delle richieste di connessione ad alcune porte (anche “chiuse”) in successione con una certa sequenza, lancia un comando.
Richieste a porte in successione alla fine è una sorta di codice segreto per sbloccare una porta “bussando” su altre ben definite.
Un caso tipico potrebbe essere questo: diciamo al demone che quando vede delle richieste di connessione alle porte 77,98,1044,1066 (esattamente in quest’ordine e fatte entro un certo tempo massimo l’una dall’altra), decide di guardare l’indirizzo ip di chi ha “bussato” e sbloccare solo per lui la porta di ingresso sulla 22 (lanciando una regola di iptables).
Altra cosa molto utile è richiudere la porta appena aperta dopo alcuni secondi. In questo modo l’utente remoto che deve collegarsi “bussa” e si collega, poi richiudendo la porta la connessione oramai stabilita con ftp non cadrà (dato che supponiamo che sul server ci sia una regola iptables per mantenere sempre attive le connessioni stabilite) e altre persone, anche con lo stesso indirizzo sorgente (dentro la stessa NAT dell’utente magari) non potranno collegarsi.
Per prima cosa dobbiamo procurarci il demone, che si chiama knockd. Nelle maggiori distribuzioni lo trovate facilmente nei repository. Lo stesso pacchetto comprende al suo interno anche il “client”, anche se per client potreste usare normalmente netcat o altro (basta solo “bussare” alla fine :D).
Il file di configurazione si trova in /etc/knockd.conf
La configurazione di default dovrebbe essere qualcosa di simile:
[openSSH] sequence = 7000,8000,9000 seq_timeout = 5 command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 9000,8000,7000 seq_timeout = 5 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn
Questa configurazione significa che quando knockd vede dei pacchetti syn (richiesta di connessione) sulle porte 7000,8000,9000 (in questo preciso ordine), “bussando” in un massimo di 5 secondi, allora viene lanciato il comando “command”.
Quel comando iptables specifica che vengano accettate tutte le connessioni provenienti dall’indirizzo IP di chi ha “bussato” e dirette alla porta tcp 22 (solitamente adibita al protocollo SSH).
Nella sezione seguente, chiamata “[closeSSH]” viene fatto esattamente l’opposto in corrispondenza della sequenza di porte 9000,8000,7000.
Di default il demone knockd non si avvierà se non modificate prima il file /etc/default/knockd impostando:
START_KNOCKD=0
Sempre nello stesso file possiamo specificare su quale interfaccia di rete dovrà lavorare knockd (di default penso le utilizzi tutte):
KNOCKD_OPTS="-i eth0"
Per “bussare” sulle porte utilizzando il client apposito incluso nel pacchetto di knockd ci basterà lanciare un comando tipo questo:
knock 1.2.3.4 7000 8000 9000
Ma usare knock non è obbligatorio. Se siamo su un pc dove non lo abbiamo a portata di mano possiamo anche optare per una soluzione del genere:
for i in 7000 8000 9000; do nc 1.2.3.4 $i & done;
In questo modo vengono lanciate in background varie istanze di netcat in successione.
Una volta collegati ad ssh si suppone che il firewall iptables sulla macchina che configuriamo sia già impostato per accettare in ingresso connessioni stabilite, di modo che quando la porta viene chiusa la connessione non cade.
Solitamente questo lo si fa con una regola tipo (che comunque dovreste già avere se avete la policy di iptables in DROP):
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
Nella configurazione che abbiamo visto prima la porta viene aperta e chiusa con una combinazione. Una soluzione più furba potrebbe essere di farla chiudere “automaticamente” qualche secondo dopo che la sequenza è stata lanciata e si è aperta
Un esempio di config per fare cio è il seguente:
[openBITS] sequence = 9132,4367,8371,1321,5239 seq_timeout = 30 tcpflags = syn start_command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT cmd_timeout = 60 stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
In questo modo avremo 30 secondi per “bussare” ed una volta aperta la porta, lo resterà per soli 60 secondi.
Per debugging e controllare altro potete sempre visionare il file di log di knockd su /var/log/knockd.log
Come altri spunti interessanti vi avverto che è possibile anche specificare se la porta su cui bussare sia TCP o UDP (per complicare la sequenza) ed è anche possibile verificare la presenza/assenza di determinati flag tcp. In ogni caso trovate altre informazioni sulla pagina ufficiale o nella documentazione.
Filed under: HowTo, informatica | 2 Comments
Tag:door, iptables, knock, knockd, knocking, linux, port
2 Responses to ““Bussare” sulle porte di rete”