¿Quién no ha visto en algún tebeo o película al protagonista golpeando unos puntos concretos en la pared o moviendo unos libros de la librería para que mágicamente se abra un acceso oculto? Quizás surgió de ahí la idea de crear Port Knocking, un script cuyo funcionamiento se podría comparar al de una combinación que permite abrir una caja fuerte.
El objetivo de esta herramienta es habilitar de forma temporal el puerto al que se quiere conectar mediante una serie de llamadas previas a otros puertos (knocks) en un orden determinado. El único requisito previo para que funcione es tener instalado un firewall a nivel local, que será quien habilite y bloquee los accesos realmente. En nuestro caso utilizaremos iptables, el cual ya viene incluido en distribuciones como Debian, junto a iptables-persistent para no perder los cambios que vayamos realizando.
Comenzaremos con una configuración inicial del firewall. En este ejemplo hemos reutilizado una Raspberry Pi con un WordPress y Owncloud instalados a los que no queremos bloquear. Para no extender demasiado la longitud del post, vamos a indicar brevemente los comandos de iptables junto a su utilidad:
1. Habilitar el tráfico a nivel local:
sudo iptables -A INPUT -i lo -j ACCEPT
2. No cerrar el tráfico a conexiones ya establecidas:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
3. Permitir el tráfico a servicios como páginas web:
sudo iptables -A INPUT -p tcp --dport <PUERTO> -j ACCEPT
(En nuestro caso usaremos la regla con los puertos 80 y 443).
4. Rechazar todas las demás conexiones:
sudo iptables -A INPUT -j DROP
Estas reglas se aplican inmediatamente. Podemos comprobar que si intentamos abrir una segunda conexión SSH no responde y gracias a la segunda regla que hemos introducido no hemos perdido la conectividad que ya teníamos establecida anteriormente.
Realizamos a continuación la instalación del paquete con sudo apt-get install knockd. Una vez termine, se nos muestra un mensaje de warning para avisarnos que el servicio viene deshabitado por defecto como medida de precaución:
El siguiente paso consiste en configurar los puertos a los que vamos a llamar para que se abra el tráfico SSH hacia nuestro servidor. En la instalación se incluye un ejemplo de fichero de configuración donde se muestran dos acciones: una para abrir el puerto ([openSSH])y otra para cerrarlo ([closeSSH]). En nuestro caso utilizaremos una única acción que cerrará automáticamente la conexión:
[options] UseSyslog [SSH] sequence = 1414,28493,10300 tcpflags = syn seq_timeout = 15 start_command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT cmd_timeout = 10 stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
En sequence especificamos los puertos a los que tendremos que llamar en orden para que se ejecute start_command para abrirnos la conexión SSH. Una vez pase el tiempo de cmd_timeout (medido en segundos) se lanzará stop_command para cerrarla de nuevo. En la documentación que aparece en este enlace se pueden ver más opciones de configuración.
Terminaremos habilitando el servicio editando el fichero /etc/default/knockd, donde también podremos especificar la interfaz donde se va a aplicar:
# PLEASE EDIT /etc/knockd.conf BEFORE ENABLING START_KNOCKD=1 # command line options #KNOCKD_OPTS="-i eth1"
Relanzamos el servicio con sudo service knockd restart y ya tendremos preparado el servidor. Para acceder en la parte del cliente utilizaremos el comando knock para llamar a los diferentes puertos, aunque se pueden usar otras opciones como nmap.
Mostramos a continuación un ejemplo de cómo se realizaría la conexión con ambos métodos. Destacar que, aunque es más sencillo con knock, es posible que en alguna situación no dispongamos del mismo, pero que ello no nos limita a la hora de poder establecer la conexión.
KNOCK: knock 192.168.1.50 1414 28493 10300 NMAP: for x in 1414 28493 10300; do nmap -Pn --host_timeout 201 --max-retries 0 -p $x 192.168.1.50 && sleep 1; done && ssh pi@192.168.1.50
Fuentes: Zeroflux
Muy chulo el post y muy bueno el titulo David :D
Gracias Maite!
Como añadido, cuidado cuando se quiera desactivar o eliminar el servicio, ya que se tienen que borrar también las reglas en iptables o podemos quedarnos sin acceso (que a mi casi me pasa).
Muy interesante. Muchas gracias