Table of Contents
Introducción
En este artículo quiero profundizar en algunas posibilidades complementarias a las que expuse en mi primer artículo, algunas más conocidas que otras, pero que añaden un nivel de control y protección de sistemas, dentro de nuestra casa, bastante alto. Dejará a criterio del lector la elección de aplicarlas o no, en función de sus necesidades.
SSL interno
Muchas veces, cuando tenemos un ecosistema variado de aplicaciones en la red interna de casa, debido a que suele ser parte de proyectos personales, subestimamos la seguridad interna en favor de soluciones sencillas como utilizar una VPN.
Una de las cosas que se suelen olvidar es la creación de certificados SSL para los servicios internos. Recordemos que la utilidad de un certificado SSL no es solo que los navegadores muestren que la autoridad certificadora es de confianza, sino que independientemente de que lo sea, permiten utilizar cifrado en la comunicación entre servicios.
Algunas de las posibles opciones que tenemos para tener certificados SSL internos:
- Creación de certificados SSL mediante línea de comandos: Es la opción que menos trabajo inicial requiere. Básicamente, creamos un certificado SSL para un dominio cualquiera, utilizando OpenSSL por ejemplo. Podemos incluso generar un certificado que caduque en 100 años. Por supuesto, tendremos que instalar dicho certificado en nuestros servicios internos, añadir excepciones a los navegadores, para que no aparezcan advertencias, y entender que no se tiene la parte de «confianza» que suele llevar asociado el protocolo HTTPS.
- Implementar automatismos de generación de certificados: Uno de ellos es certbot, el cual permite, teóricamente, automatizar la generación, y en ocasiones la instalación, de certificados SSL (por ejemplo, los de Let’s Encrypt). Se puede instalar como servicio en docker incluso.
Port Knocking
Todos sabemos que para poder conectarnos a un servidor, necesitamos hacer algunas concesiones en cuanto a la superficie de ataque a dicho servidor. Uno de estos ejemplos es la apertura de puertos. Para poder conectar a un servidor de manera segura, hoy en día podemos utilizar un servidor ssh conectado en él, con un puerto abierto. Debido a que no sabemos en qué momento vamos a querer conectar, debemos dejar abierto este puerto todo el tiempo.
¿Podríamos, previo acuerdo entre cliente y servidor, disminuir esta superficie de ataque? Esto es lo que intenta responder el concepto de port knocking.
La idea la hemos visto en películas de mafiosos y clubs ilegales. Una puerta cerrada, sin ningún tipo de marca, y para entrar debes golpear un determinado número de veces, en caso contrario, no abrirán. En caso del port knocking, tendremos cerrados absolutamente todos los puertos del servidor, y solo ante una determinada secuencia de «golpes», en este caso, envío de paquetes a determinados puertos, abriremos un puerto (el del servidor ssh, normalmente).
¿Y cómo se enterará el servidor de que están «llamando» a su puerta? Simplemente logueando los paquetes que llegan a puertos vacíos y analizando dicho log.
Para poder configurar port knocking, suponiendo un servidor ubuntu, ejecutaremos:
sudo apt install -y knockd
Después, abriremos el fichero de configuración:
sudo nano /etc/knockd.conf
[options]
UseSyslog
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
Aquí podemos observar:
- sequence: Los puertos, en orden, a los que se tendrá que llamar para activar esta regla
- seq_timeout: los segundos totales durante los que se tendrá que ejecutar la secuencia completa
- command: la apertura de puerto, en formato de ejecución de iptables
- OpenSSH, closeSSH: nombres identificativos de reglas (se puede poner el que queramos)
Usualmente modificaríamos la lista de puertos (incluso se puede indicar en cada puerto el protocolo específico, por ejemplo 2222:udp,5736:tcp) y en caso de no estar seguros de que entrando remotamente tengamos poca latencia, aumentaríamos el timeout.
Una vez configurado esto, tenemos varias opciones para realizar la «llamada». Existen aplicaciones móviles de port knocking, y de base, el paquete knockd, instalado en otra máquina, viene con el cliente knock, el cual se puede ejecutar por comando de esta manera:
knock –v ip_servidor 7000 8000 9000
DNS y Qname minimization
Muchas veces las decisiones en torno a seguridad teórica rozan otros dos conceptos, privacidad y control.
Como bien sabemos, existen unas máquinas que ayudan al funcionamiento global de internet llamadas DNS, que traducen las direcciones web que escribimos en un navegador, o mediante las cuales accedemos a diversas apis, a direcciones IP.
Existe un tipo de ataque llamado DNS spoofing o DNS cache poisoning, consistente en controlar o engañar a un servidor DNS, para que sirva una dirección IP errónea, para una dirección web, normalmente apuntando a una copia maligna del servicio original, para secuestrar los datos que el usuario introduzca.
¿De qué manera podríamos protegernos contra este ataque? Una de las posibles respuestas es el control.
Si recordamos mi anterior artículo tenemos un sistema de filtrado de DNS llamado PiHole, que bloquea posibles amenazas, a nivel de dirección web. Pero Pi-Hole por debajo, con configuración estándar, utiliza DNS propietarios, como Cloudflare.
Podemos ejercer un poco más de control, instalando (por ejemplo en la misma máquina de Pi-Hole, o en un contenedor diferente) nuestro propio DNS, en este caso con Unbound. No entraré en la instalación en concreto, ya que existe una guía oficial.
Una vez configurado Unbound, ya tenemos nuestro propio DNS, pero hay una opción para poder tener incluso más control (y en este caso, también añade privacidad), QName Minimization.
Para explicar esto, usaremos un ejemplo. Nuestro DNS saca su información de los servidores globales TLD (Top Level Domains). Imaginemos que pedimos la web foo.bar.com, para poder recuperar la IP de esta dirección web, pongamos que se tiene que consultar con los siguientes TLD:
- TLD 1, el cual sabe sobre .com
- TLD 2, el cual sabe sobre .bar
En un uso normal, enviaremos a ambos servidores la dirección completa, foo.bar.com. Pero si activamos QName Minimization, únicamente enviaremos el trozo de dirección que aplica a cada uno:
- TLD 1, «.com»
- TLD 2, «.bar»
De esta manera, evitamos enviar información innecesaria a los TLD, y también evitamos que todos los TLD implicados sepan la dirección completa que se está buscando.
Conclusión:
En este artículo he querido entrar en algunos puntos avanzados de protección y control sobre nuestra infraestructura local. Como ya he comentado, no en todos los casos se necesita llegar a estos casos (aunque puede ser un buen ejercicio para aumentar conocimiento). Para aquellos casos en los que creáis que es necesario espero que os ayude.
Author
-
Professional with more than 13 years of experience in software development focused on the back-end area using Java and Kotlin.
Ver todas las entradas