GoRiX blog

A blog about things

Toc-Toc...Quién es?

June 03, 2024 — n4ch0m4n

Cuando eran chicos nunca jugaron que para entrar a algún lado a través de una puerta debían golpear de determinada forma la misma para que del otro lado sepan que era uno y lo dejen entrar?

Bueno les diré que es posible hacerlo volcado al tema de redes y puertos. Por ejemplo golpear antes de determinada manera para que podamos hacer uso del servidor de correo, entrar a una web, entrar por ftp, por ssh, etc

En esta caso no vamos a golpear con las manos (no somos violentos) sino con puertos, sí con puertos!

La idea es la siguiente, enviar peticiones a diferentes puertos seteados anticipadamente en un cierto orden para abrir un puerto de interés, y finalmente poder conectarme a este último.

La idea gráfica sería:


Como verán un cliente envía port-hits (en realidad son paquetes tcp o udp) a determinados puertos en un cierto orden, luego de ello del lado del servidor abre el puerto final (que no es ninguno de los que hice port-hits) para que podamos conectarnos.

También podríamos hacer lo mismo, hacer port-hits para volver a cerrar el puerto.

Como se abren o cierran los puertos? con un firewall….iptables por ejemplo.

Ahora bien, como logramos todo esto antes mencionado? Con el servicio knockd. Seguramente está en tu distro para instalar o sino a compilar desde su repo oficial. En ambos casos esto instala tanto el servicio como el cliente para hacer toc-toc ;-) … ah y no te olvides de instalar iptables o nftables (yo estoy acostumbrado a iptables)

Vamos con un ejemplo para que se entienda desde lo práctico, vamos a hacerlo con el puerto 22 para el servicio SSH.

1. Primero que todo debemos cerrar el puerto 22 en nuestro FW (o tener dropeado todo por defecto y solo habilitado lo que necesitamos, como corresponde en un FW bien configurado):

iptables -A INPUT -p tcp –dport 22 -j DROP

Esta línea podría ser agregada a /etc/rc.local para que inicie con el servidor, eso es tu decisión.

2. Habilitamos el servicio, editando el archivo /etc/default/knockd, que por default está deshabilitado (cambiamos START_KNOCKD 0 por 1). Podemos indicar también la interfaz con la cual trabajar. Por defecto tomará la primer nic que encuentre:

# 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=1

# command line options
#KNOCKD_OPTS="-i eth0"

3. Ahora bien, como bien dice ahi ahora debemos editar el archivo /etc/knockd.conf :

[options]
        UseSyslog

[openSSH]
        sequence    = 7000,8000,9000
        seq_timeout = 10
        command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

[closeSSH]
        sequence    = 9000,8000,7000
        seq_timeout = 10
        command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

En este ejemplo, explico brevemente cada línea:

  • UseSyslog, de donde el servicio leerá los eventos para saber que está pasando, el cual será /var/log/messages o equivalente. Podés cambiar por logfile = /var/log/knockd.log, para que la depuración vaya a un archivo exclusivo para ello.
  • Tenemos dos secciones luego, openSSH y closeSSH para establecer condiciones para abrir y cerrar puertos respectivamente. En ambas las opciones son las mismas, solo cambia si acepta (-A) o dropea (-D):
    • sequence: de que forma voy a golpear la puerta…definir los puertos y en que orden los tocaré para que me “abran/cierren la puerta”. Obviamente los puertos pueden ser cambiados y se aconseja que sean puertos altos.
    • seq_timeout: acá está definido el tiempo de espera máximo para completar la secuencia de "golpeteo"
    • command: la regla que aplicará nuestro FW cuando se cumplan las dos anteriores condiciones; en el caso de open abrir el puerto en cuestión (el 22) o cerrar close
    • tcpflags: no voy a ser muy extenso en esto, porque sino me voy a ir por las ramas. Un tcp flags es un bit que va en el encabezado del paquete tcp y existen distintos tipos (ACK, FIN, RST, etc) y el que interesa acá que es el SYN que es justamente el primer paquete enviado por un cliente cuando quiere establecer una conexión con un servicio o servidor.

Iniciamos/restarteamos el servicio knockd y ya estamos en condiciones de hacer pruebas. Primero que todo necesitamos para golpear la puerta (los puertos) y para ello tenemos "knock" o podemos usar el potente NetCat:

1. Primero abramos el puerto 22 (supongamos que el server es de ip 192.168.0.2):

knock -v 192.168.0.2 7000 8000 9000

o con Netcat

nc -z 192.168.0.2 7000 8000 9000

Podemos verificar en el firewall si algo ha cambiado:

iptables -L

Y deberíamos ver una nueva línea en nuestro FW que indique estamos aceptando peticiones hacia el puerto 22.

2. Bien terminamos lo que teníamos que hacer y hacemos el paso inverso para cerrar de vuelta el puerto:

knock -v 192.168.0.2 9000 8000 7000

o con Netcat

nc -z 192.168.0.2 9000 8000 7000

Podemos verificar en el firewall si algo ha cambiado:

iptables -L

Y deberíamos ver una nueva línea en nuestro FW que indique estamos rechazando peticiones hacia el puerto 22.

Si bien no conozco mucho sysadmin que lo use, es interesante tenerlo en cuenta y no solo para SSH sino para segurizar cualquier otro tipo de acceso.

Se me ocurre que quizás no se, tener una web pública en el puerto 80 (este blog por ej) y una ultra privada en el 81 que solo puedan acceder quien conozcan como golpear la puerta… fueron a probar http://url:81, no? … les faltó les pase como golpear mi puerta ;-)

Tienen más ejemplos interesantes en la fuente.

Espero les haya parecido interesante!

Fuente: https://linux.die.net/man/1/knockd

Tags: Servidores, Seguridad