Como muchos de vosotros sabréis una conexión TCP no se considera establecida hasta que se han intercambiado una seria de paquetes, el archiconocido TCP-Handshake, este consta de un paquete inicial SYN otro de respuesta SYN/ACK y un último ACK, en ese momento se encarga de enviar información la aplicación bindeada a ese puerto.
Portknocking consiste en utilizar este tipo de tráfico para realizar ciertas operaciones en el equipo servidor, de este modo mediante una combinación de intentos de conexión podremos aplicar reglas de firewall o ejecutar cualquier otro comando.
Lo primero que haremos será instalar el servicio de portknocking en el servidor:
Ahora realizamos la configuración según necesidades, en mi caso al enviar la combinación mágica 7000 8000 9000 permitiré el acceso por ssh insertando una regla de iptables para tal fin:
[options]
logfile = /var/log/knockd.log
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -I INPUT 1 -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
Finalizamos la configuración indicando en que interfaz debe permanecer a la escucha knockd:
IFACE="eth0"
OPTS=""
Arrancamos el servicio y lo añadimos al arranque:
rc-update add knock default
Insertamos la ACL que se encargará de bloquear el tráfico ssh si no se ha enviado el portknock:
Si tenemos las reglas por defecto para que bloqueen el tráfico debemos abrir los puertos utilizados por knockd ya que si no lo hacemos iptables que está a nivel de kernel interceptará el tráfico antes que knockd y será como si nunca se hubiese enviado el knock:
iptables -I INPUT 1 -p tcp –dport 8000 -j ACCEPT
iptables -I INPUT 1 -p tcp –dport 9000 -j ACCEPT
Podemos ver los logs en /var/log/knockd.log:
En la parte del cliente tendremos que instalar algún software capaz de generar el tráfico esperado por knockd, en mi caso netcat pero cualquier otro serÃa igualmente válido:
Generamos le tráfico esperado por knockd:
En el servidor podemos ver como se ha aplicado la regla de firewall:
[2014-10-30 16:46] E.F.G.H: openSSH: Stage 1
[2014-10-30 16:46] E.F.G.H: openSSH: Stage 1
[2014-10-30 16:46] E.F.G.H: openSSH: Stage 2
[2014-10-30 16:46] E.F.G.H: openSSH: Stage 3
[2014-10-30 16:46] E.F.G.H: openSSH: OPEN SESAME
[2014-10-30 16:46] openSSH: running command: /sbin/iptables -I INPUT 1 -s E.F.G.H -p tcp --dport 22 -j ACCEPT
Además si consultamos las reglas de iptables:
ACCEPT tcp -- E.F.G.H 0.0.0.0/0 tcp dpt:22
Cuando hayamos terminado de realizar las tareas administrativas podemos cerrar la brecha mediante:
NOTA: Una posible forma de aumentar la seguridad de este sistema podrÃa ser reconfigurando la combinación de puerto según la franja horaria o mediante un algoritmo propio, de este modo una combinación válida puede que deje de serlo en X tiempo.
No hay duda de que esta técnica puede resultar de mucha utilidad en entornos donde la paranoia prima sobre la funcionalidad, de este modo el servicio solo estarÃa expuesto un tiempo limitado para una ip origen en concreto ;)