Blog - 0x00


Conexiones (ssh) no deseadas

2021/10/09

Tabla de contenidos


#

Hace unos días arrendé un servidor en un proveedor de VPS con una IP pública IPv4, para probar algunas herramientas, aprender otras nuevas y quizás tener algunos servicios personales funcionando. Así que instalé Rocky Linux 8.4 para probarlo y una de las primeras cosas que quise verificar fueron los intentos de ssh a mi servidor, ya que era el único servicio abierto a internet, pero noté que no había ningún archivo que registrara esto, así que tuve que editar el archivo /etc/rsyslog.conf y me aseguré de que esta línea estuviera descomentada:

# El archivo authpriv tiene acceso restringido.
authpriv.*                                              /var/log/secure

Una vez hecho esto, reinicié el servicio rsyslog:

[root@rockylinux ~]# systemctl restart rsyslog

y los intentos de ssh comenzaron a aparecer en /var/log/secure.

Fue muy interesante ver los intentos, los usuarios con los que intentaban iniciar sesión y las IPs. Empezaré con los números, todo esto es en 24 horas:

Ciertamente sería más interesante en un periodo de tiempo más largo, pero 24 horas de intentos de ssh aún pueden mostrar algunas cosas.

Dentro de los logs vi lo que supongo que es alguien ejecutando un script fallido, estaba intentando usar IPs como el nombre de usuario para iniciar sesión (ni siquiera era la IP de mi máquina). También vi dos peticiones HTTP GET, sí, intentaron hacer un GET al puerto 22 en mi servidor. (Las IPs han sido cambiadas)

error: kex_exchange_identification: client sent invalid protocol identifier "GET / HTTP/1.1"
...
Invalid user admin from 192.168.32.3 # Intento normal al usuario 'admin'
Invalid user 10.23.2.1 from 172.16.2.1 # Intento con username IP
Invalid user 10.23.3.25 from 172.16.2.1 # Otro más

Después de revisar los logs pensé, ¿cómo podría detener los intentos? Estaban usando bruteforcing para entrar, llenando los logs y no tenía mucho sentido permitir conexiones desde fuera del país en el que vivo. Así que usé nftables, la nueva herramienta que está reemplazando a iptables.

Busqué en internet por Chile IP Blocks/CIDR y los descargué como un archivo de texto para poder crear una lista de las IPs a las que se permitiría conectar a mi servidor, permitiendo solo IPs de Chile. Luego tuve que configurar nftables, lo cual fue un poco difícil porque solo había usado iptables antes y los comandos para crear reglas, chains, etc. eran diferentes, pero afortunadamente Red Hat proporciona buena documentación sobre nftables llamada “Getting started with nftables”.

Así que con nft una de las primeras cosas que hice fue crear una tabla llamada “filter”. Es importante en este caso, antes del nombre de la tabla, establecerla como ip porque las reglas en esa tabla coincidirán con paquetes IPv4 y hay otras opciones para el filtrado de paquetes: ip6, inet, arp, bridge, netdev

[root@rockylinux ~]# nft add table ip filter
[root@rockylinux ~]# nft add chain ip filter input { type filter hook input priority filter\; policy accept\; }

El segundo comando añade una chain llamada “input” y es importante que la política sea “accept” ya que intenté primero establecerla como “drop” y perdí la conexión al servidor y no podía conectarme a través de ssh ya que bloquea cualquier conexión entrante.

# No somos un router así que podemos descartar de forma segura los paquetes "forward"
[root@rockylinux ~]# nft add chain ip filter forward { type filter hook forward priority filter\; policy drop\; }
[root@rockylinux ~]# nft add chain ip filter output { type filter hook output priority filter\; policy accept\; }
# Permitir conexiones "related" y "established"
[root@rockylinux ~]# nft add rule ip filter input ct state related,established  counter accept
# Permitir paquetes de entrada de la interfaz loopback
[root@rockylinux ~]# nft add rule ip filter input iifname "lo" counter accept

Ahora que he establecido las reglas básicas para los paquetes entrantes, puedo empezar a añadir las IPs que quiero permitir que entren, PERO no quiero simplemente “aceptar” la conexión a cualquier puerto, así que crearé una nueva chain donde pueda controlar qué puertos están abiertos y cuáles no, y luego cualquier conexión entrante desde una IP en Chile saltará a mi chain “personal” donde añadiré reglas para los puertos, en este caso el puerto 22 para poder hacer ssh al servidor.

[root@rockylinux ~]# nft add chain ip filter personal
# ip-chile.txt contiene cidr ips que serán las IPs que se permite conectar
[root@rockylinux ~]# while read line; do nft add rule ip filter input ip saddr "${line}" counter jump personal; done < ip-chile.txt
[root@rockylinux ~]# nft add rule ip filter personal tcp dport 22 counter accept
# Una vez terminado, por defecto podemos descartar paquetes en input
[root@rockylinux ~]# nft add chain ip filter input { type filter hook input priority filter\; policy drop\; }

Y listo. Solo las IPs que estaban en el archivo ip-chile.txt serán permitidas Y solo a través del puerto 22 usando TCP, cualquier otra IP que no coincida con ninguna de las reglas en la chain input será descartada.

Si intentas hacer ping a la máquina desde cualquier lugar, no responderá; dejé esto intencionalmente porque usualmente si quieres saber si una máquina está viva usas ping y prefiero que mi servidor se mantenga “oculto” o parezca muerto en lugar de que alguien sepa que hay un servidor en mi IP y probablemente intente bruteforcing o un exploit.

Ahora, en las últimas 24 horas, lo único que se ha escrito en /var/log/secure han sido mis inicios de sesión, así que nftables han “descartado” completamente los paquetes que vienen de todas partes excepto de las IPs que permití, incluso si de alguna manera consiguieran mi llave privada para ssh no podrían conectarse al servidor debido a las reglas en nftables (a menos que conocieran también y además tuvieran una IP de Chile).

Aprendí cómo habilitar los logs para la autenticación de ssh, también pude ver interesantes intentos de bruteforcing en mi máquina, logré aprender más sobre nftables ya que solo conocía iptables. Espero que haya sido una lectura interesante y también haber aprendido un poco con lo que escribí.