Bloquear Escaneo de Puertos en Linux

Seguro en algún momento de tu carrera profesional, o como aficionado, escaneaste algún servidor con nmap en busca de puertos abiertos ¿Quién no? A veces es divertido. Pero cuando un desconocido con oscuras intensiones, escanea los puertos de nuestros servidores, ahí sí la cosa ya no es tan divertida. Por eso en este artículo te explico un método para bloquear escaneo de puertos en Linux.

Existen herramientas en GNU/Linux que funcionan para detectar algunas técnicas de escaneo de puertos, y bloquearlas. Algunas son Snort y Psad, incluso podemos recurrir a IPTABLES para hacerlo con el mismo kernel. Con estas herramientas podemos detectar tres tipos de escaneos, llamados así: Escaneo Null, Escaneo Fin y Escaneo Xmas.

Podemos cercar nuestro servidor de esos sondeos con IPTABLES, así:

Escaneo Null

Escaneo Xmas

Para Escaneo Fin

Cada una de las anteriores bloquea la IP del atacante durante 3600 segundos.

 

Sin embargo, hay otro tipo de escaneo que es díficil de detectar, y es el más simple de todos: el escaneo simple ó SYN Stealth Scan. Se trata un sencillo nmap y la IP objetivo:

_$ nmap "dirección IP"

Es díficil de detectar porque usa el paquete SYN por cada puerto sondeado, el mismo que usan los dispositivos para iniciar una comunicación TCP normal (complicado).

Bloquear escaneo de puertos

Bloquear escaneo de puertos en Linux


Vamos a Implementar esta medida de seguridad dentro de un script tipo Bash, y toma cinco pasos (al menos para mí):

1- Configurar el demonio rsyslog para que registre las bitácoras de IPTABLES en el
archivo /var/log/iptables/iptables.log (puede ser el que tu quieras).

  • Creamos el archivo 10-iptables.conf

_$ sudo touch /etc/rsyslog.d/10-iptables.conf

  • Le ponemos esta configuración (son dos líneas)

:msg,regex,"iptables: " -/var/log/iptables/iptables.log
& stop

  • Reiniciamos el demonio rsyslog

_$ service rsyslog restart

2- Creamos dos reglas IPTABLES. Una para que los paquetes SYN que lleguen a nuestro servidor, sean registrados en /var/log/iptables/iptables.log, excepto los que van al puerto 22, 20, 21 y 2256, pues son los puertos de uso oficial para mí caso. Asi, no se registrará nuestra IP al conectarnos desde afuera (con este regla evitamos caer en la trampa que estamos colocando para los escaneadores).

La segunda regla IPTABLES es para reducir la velocidad de llegada de los paquetes SYN, a 17 paquetes/segundo, excepto a los puertos de uso oficial. Esto debido a que NMAP puede enviar más de 1200 paquetes por segundo. Con esta regla le damos tiempo a nuestro script de reaccionar:

3- Creamos la cadena SOSPECHOSOS en IPTABLES. Ahí vamos a meter las direcciones IP que intentan escanearnos:

4- Instalamos las librerías de Inotify Tools:

_$ sudo apt install inotify-tools

Inotify Tools es una solución a nivel que de kernel, que actúa como vigilante de los cambios que se producen en los archivos que le indiquemos. Esta solución la vamos a usar dentro del siguiente script:

5- Creamos el script scan_brake.sh:

Funcionamiento del Script scan_brake.sh


Un escaneo de puertos simple, producido por ejemplo con nmap, envía a cada puerto un paquete SYN en busca de una respuesta. Si la obtiene, pues el puerto está disponible. Este mismo mecanismo lo usa una conexión TCP normal, por eso es que es díficil dicernir entre un escaneo y el inicio de una conexión normal.

La único que diferencia una conexión normal de un escaneo simple, es que este último puede lanzar más de 1200 paquetes SYN en un segundo, a los puertos más conocidos. Así es como nmap obtiene sus resultados en 9 segundos (de un escaneo simple). Es ahí donde podemos detectarlo y atajarlo.

De esta forma, la primera regla IPTABLES que creamos (punto 2), registra en el archivo iptables.log todos los paquetes SYN que llegan a nuestro servidor. El script por su parte mantiene verificando algún cambio producido en dicho archivo, por medio de inotifywait (línea 7).

Entonces, llega un paquete SYN, se registra. La línea 10 del script verifica si además se han registrado más de 15 paquetes SYN en ese instante, de ser cierto, toma las direcciones IP registradas en iptables.log y las bloquea (línea 14).

El detalle aquí es que todas las direcciones IP que esten registradas en iptables.log serán bloqueadas, sin importar su origen. Por eso en la regla IPTABLES somos claros en no registrar paquetes SYN a puertos, o servicios, que nosotros de antemano ya sabemos que necesitamos usar (solo nosotros lo sabemos, nadie más tiene por qué, esa es la razón de bloquear los escaneos de puertos).

La variable bantime define el tiempo (en segundos) en que las direcciones IP quedarán bloquedas. Un valor recomendable es de 3600 segundos, o mucho más.

Contener Intentos de Conexión


Por otro lado, en caso de que ya sepan de nuestros puertos y despleguen una oleada de intentos de conexión, típicos de fuerza bruta, acudimos a soluciones tipo Fail2Ban.

Otra práctica recomendada es cambiar el número puerto estándar (bien conocido por todo el mundo), a otro diferente para despistar. Por ejemplo, para SSH cambiando el 22 por el 8122.

Posible Contramedida


La única contramedida posible que yo veo para este caso, y a la que puede acudir un atacante de escaneos, es hacer un escaneo simple más suave, obteniendo un informe individual por puerto, y no en conjunto como normalmente se hace (para evitar el envío masivo de SYN).

De todas formas quedará la IP origen registrada y tarde que temprano será bloqueada si continúa su comportamiento, y si hay más atacantes haciendo lo mismo, peor para ellos, serán bloqueados más rápidamente. Claro, con esta contramedida se puede obtener información de a un puerto a la vez, pero así les tomará más tiempo, de manera que no se las dejamos tan fácil 😉

Alternativas a este script


Bueno, después de este recorrido puedes asegurar que otra solución, llamada Portsentry, también tiene capacidad de detectar y bloquear un escaneo simple. Pero Portsentry siempre deja pasar el primer escaneo del atacante para identificarlo y proceder a bloquearlo. Y con el primer escaneo el atacante ya tiene suficiente información de nuestros puertos. Como puedes comprobar, esta solución que ofrezco no deja pasar ni a la primera.

Variante 1 del Script scan_brake.sh


El siguiente código es una variante del script que acabamos de ver:

Lo único que hace este cambio es bloquear la dirección IP del escaner de puertos, desde la tabla de enrutamiento de Linux, y no desde IPTABLES. Luego, pasado el tiempo de bantime, se desbloquean por medio de la función desbloquea (línea 20).

Dato Curioso


El moderno kernel de Linux puede gestionar más de 4 millones de rutas estáticas en su tabla de enrutamiento. Incluso puede registrar rutas estáticas a razón de 300000/hora, u 83/segundo, bueno, al menos en una máquina con Intel Xeon E5410 Quad Core, a 2,4 GHz y 33 GB de RAM, como la mía. Registrar 1000000 (un millón) de rutas estáticas representa un costo de memoria de 1,5 GB.

Variante 2 del script para Bloquear Escaneo de Puertos


Si vamos a definir un bantime superior a los 900, 1800, 3600 segundos, entonces separemos el fragmento del código que se encarga de desbloquear las IP de los escaneadores, en otro script (lo llamaré contadorban.sh), de lo contrario el scan_brake.sh se quedará esperando todo el tiempo de bantime para seguir vigilando el archivo iptables.log:

El script contadorban.sh:


Variante 3 para Bloquear Escaneo de Puertos


El punto débil de la variante 2 es que los bots escaneadores de puertos «spoofean» todo el espectro del direccionamiento IP, por lo que la IP de nuestra casa, así como la de nuestro smartphone, o la de nuestros clientes, algún día caerá en la trampa, por suplantación.

La siguiente variante soluciona dicha debilidad, acudiendo nuevamente a IPTABLES, «baneando» las direcciones IP excepto a nuestros puertos oficiales. Así, si nuestras direcciones IP caen por suplantación, seguiremos teniendo acceso a nuestros servicios.

Bueno, también tiene una condición adicional para no «banear» ciertas IP específicas.

El script contadorban.sh:


Revisando la trampa


Como ya habrás visto en el algoritmo del script, scan_brake.sh genera dos archivos de texto con el propósito de visualizar las direcciones IP bloqueadas y desbloqueadas. Si necesitamos visualizar las IP que han caído en la trampa, miremos la tabla SOSPECHOSOS:

Con el paso de las horas podemos revisar más, y observarémos cientos de direcciones IP sospechosas. Algunas provienen de verdaderas intenciones oscuras. Otras son de motores de búsqueda de vulnerabilidades de Internet, tales como los del Project Sonar, así como los Censys, y de Internet Census Group. Con los sondeos realizados por estos proyectos, se elaboran estadísticas acerca de los servicios de red que usamos en Internet, y su seguridad (o vulnerabilidad) relacionada.

No más imagina que tengas un router cuya vulnerabilidad sea detectada y explotada por SSH desde Internet, con privilegios de Administrador. Prácticamente una puerta trasera. Semejante situación pudiera sucederle a alguien con un router marca Zyxel funcionando con el firmware 4.60 Zyxel USG. Eso fue lo que le encontró a esos artefactos la empresa neerlandesa, consultora en servicios de seguridad informática, EYE Control. Más o menos el 10 % de esos dispositivos estuvieron trabajando con ese firmware por más de tres meses.

También es frecuente encontrar en la trampa las IP de botnets, tales como los crawlers de Google y del buscador de Microsoft.

(Puede que te interese leer sobre Web Scraping y cómo protegerse)

Qué es el web scraping y cómo protegerse


Valora este artículo:

Bloquear escaneo de puertos en Linux
5,0 rating based on 12.345 ratings
Overall rating: 5 out of 5 based on 1 reviews.

 

Name
Email
Review Title
Rating
Review Content

 

Muy bueno

★★★★★
“ Súper interesante!”
- Rodolfo Saavedra
Comparte esto en
Publicado en Seguridad Informática.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *