Hoy vamos a ver cómo ocultar un servicio que tengamos publicado en Internet aprovechándonos de una técnica conocida como Port Knocking. En nuestro caso lo haremos con el servicio SSH.

Máquina servidor

Lo primero es instalar el paquete de EPEL para posteriormente instalar el paquete knock-server. También es necesario instalar libpcap.

[root@knockd ~]# yum install libpcap

[...]

[root@knockd ~]# yum install epel-release

[...]

[root@knockd ~]# yum install knock-server

[...]

El siguiente paso es eliminar de nftables la regla que permite las conexiones SSH remotas mediante el siguiente comando. Ten en cuenta que en mi instalación se usa la zona por defecto llamada public.

[root@knockd ~]# firewall-cmd --zone=public --remove-service=ssh --permanent
success
[root@knockd ~]# firewall-cmd --reload

El siguiente paso es modificar el fichero /etc/knockd.conf y dejarlo con el siguiente contenido. Por favor, cambiad los puertos a otra secuencia. 😜

[options]
        UseSyslog

[opencloseSSH]
        sequence      = 51234:udp,55678:tcp,59124:udp
        seq_timeout   = 15
        tcpflags      = syn,ack
        start_command = /bin/firewall-cmd --zone=public --add-rich-rule "rule family="ipv4" source address="%IP%" service name="ssh" accept"
        cmd_timeout   = 10
        stop_command  = /bin/firewall-cmd --zone=public --remove-rich-rule "rule family="ipv4" source address="%IP%" service name="ssh" accept"

El último paso es habilitar e iniciar el servicio knockd.

sudo systemctl enable knockd && sudo systemctl start knockd

Máquina cliente

En la máquina cliente desde la que vamos a acceder por SSH es necesario instalar el cliente de knock. Al igual que en el servidor es necesario disponer del repositorio EPEL.

yum install epel-release

[...]

yum install knock

[...]

Vamos a una un primer intento de conexión mediante SSH para que veamos que no es posible conectar.

[ignacio@knock-client ~]$ ssh root@192.168.122.186
ssh: connect to host 192.168.122.186 port 22: No route to host
[ignacio@knock-client ~]$  

Ahora vamos a usar el cliente de knock que hemos instalado para hacer la “llamada” y que se abra la puerta.

[root@knock-client ~]# knock -v -d 1 192.168.122.186 51234:udp 55678:tcp 59124:udp
hitting udp 192.168.122.186:51234
hitting tcp 192.168.122.186:55678
hitting udp 192.168.122.186:59124
[root@knock-client ~]# ssh root@192.168.122.186
root@192.168.122.186's password:  
Last failed login: Sun Aug  1 20:51:14 WEST 2021 from knock-client on ssh:notty
Last login: Sun Aug  1 20:25:03 2021 from knock-client
[root@knockd ~]# 

En el fichero messages del servidor podemos ver lo siguiente:

Aug  1 20:51:26 knock-client knockd: 192.168.122.136: opencloseSSH: Stage 1
Aug  1 20:51:26 knock-client knockd: 192.168.122.136: opencloseSSH: Stage 2
Aug  1 20:51:26 knock-client knockd: 192.168.122.136: opencloseSSH: Stage 3
Aug  1 20:51:26 knock-client knockd: 192.168.122.136: opencloseSSH: OPEN SESAME
Aug  1 20:51:26 knock-client knockd: opencloseSSH: running command: /bin/firewall-cmd --zone=public --add-rich-rule "rule family="ipv4" source address="192.168.122.136" service name="ssh" accept"
Aug  1 20:51:31 knock-client systemd-logind: New session 4 of user root.
Aug  1 20:51:31 knock-client systemd: Started Session 4 of user root.
Aug  1 20:51:37 knock-client knockd: 192.168.122.136: opencloseSSH: command timeout
Aug  1 20:51:37 knock-client knockd: opencloseSSH: running command: /bin/firewall-cmd --zone=public --remove-rich-rule "rule family="ipv4" source address="192.168.122.136" service name="ssh" accept"