Cortafuegos I: De nodo con iptables
Introducción
Vamos a realizar los primeros pasos para implementar un cortafuegos en un nodo de una red, aquel que se ejecuta en el propio equipo que trata de proteger, lo que a veces se denomina un cortafuegos personal.
Preparando el entorno
Vamos a utilizar una máquina en openstack, que vamos a crear con la siguiente receta. La receta heat ha deshabilitado el cortafuego que nos ofrece openstack (todos los puertos de todos los protocolos están abiertos). La máquina creada tendrá un servidor web instalado. Vamos a trabajar con la red de las ips flotantes: 172.22.0.0/16.
Y nos logueamos en la máquina:
Limpiamos el entorno
Para asegurarnos de que nuestro escenario está limpio, vamos a eliminar todas las reglas que haya en la tabla de filtrado de iptables:
iptables -F
iptables -t nat -F
iptables -Z
iptables -t nat -Z
Vamos a permitir ssh
Cómo estamos conectado a la máquina por ssh, vamos a permitir la conexión ssh desde la red 172.22.0.0/16, antes de cambiar las políticas por defecto a DROP, para no perder la conexión:
iptables -A INPUT -s 172.22.0.0/16 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d 172.22.0.0/16 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
#Añado estas reglas para no perder la conexión, dado que es la VPN del instituto
iptables -A INPUT -s 172.29.0.0/16 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d 172.29.0.0/16 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
Política por defecto
En este punto, vamos a cambiar la política por defecto de la tabla de filtrado de iptables a DROP, para que no se permita nada que no hayamos especificado explícitamente:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
Y comprobamos que no podemos hacer ping ni a la máquina ni a internet:
Permitimos tráfico para la interfaz de loopback
Para poder hacer ping, vamos a permitirlo:
iptables -A INPUT -i lo -p icmp -j ACCEPT
iptables -A OUTPUT -o lo -p icmp -j ACCEPT
ping -c 3 127.0.0.1
Peticiones y respuestas protocolo ICMP
Vamos a añadir las reglas necesarias para permitir las peticiones y respuestas del protocolo ICMP, pero primero, comprobemos que no tenemos conexión a internet:
ping -c 3 8.8.8.8
iptables -A INPUT -i ens3 -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A OUTPUT -o ens3 -p icmp --icmp-type echo-request -j ACCEPT
Y comprobamos que podemos realizar la ejecución de ping -c 5 1.1.1.1:
Consultas y respuestas DNS
iptables -A OUTPUT -o ens3 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT
Y comprobamos que funciona haciendo una consulta dns a www.josedomingo.org:
dig 1.1.1.1 www.josedomingo.org
Aprovechando que tengo una aplicación web en mi VPS, vamos a comprobar que podemos hacer una petición http:
dig 1.1.1.1 bookmedik.mariatec.es
Tráfico HTTP
Podemos hacer un par de reglas que permitan el tráfico http/https (los dos puntos anteriores) usando la extensión multiport:
iptables -A OUTPUT -o ens3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
Con estas reglas, podremos permitir las peticiones http. Para comprobarlo, vamos a realizarlo con la ejecución del comando curl:
curl portquiz.net:80
Tráfico HTTPS
iptables -A OUTPUT -o ens3 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
Una vez aplicadas estas reglas, vamos a comprobar que podemos hacer una petición https:
curl portquiz.net:443
Tráfico HTTP/HTTPS
iptables -A INPUT -i ens3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
Y comprobamos que podemos hacer una petición http y https:
curl portquiz.net:80
curl portquiz.net:443
Permitimos el acceso de nuestro servidor web
iptables -A INPUT -i ens3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
Y comprobamos que podemos acceder a nuestro servidor web:
Configuración en un solo paso
### Limpiamos las tablas
iptables -F
iptables -t nat -F
iptables -Z
iptables -t nat -Z
### Establecemos la política
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -i lo -p icmp -j ACCEPT
iptables -A OUTPUT -o lo -p icmp -j ACCEPT
iptables -A INPUT -s 172.22.0.0/16 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d 172.22.0.0/16 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A OUTPUT -o ens3 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -i ens3 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens3 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens3 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
Para guardarlas, podemos usar el comando iptables-save o podemos guardarlas con el comando iptables-save.
Ejercicios tras la configuración
Ejercicio 1: Permite poder hacer conexiones ssh al exterior.
iptables -A OUTPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
Tras implementar estas reglas, podemos comprobar que podemos hacer una conexión ssh al exterior:
ssh maria@172.22.6.19
Ejercicio 2: Deniega el acceso a tu servidor web desde una ip concreta.
Para realizar este ejercicio, lo primero que vamos a comprobar las reglas que tenemos creadas:
iptables -L -n -v --line-numbers
Una vez sabido esto, añadimos la regla que nos permite denegar el acceso a una ip concreta, en mi caso, la ip de mi máquina alfa de mi escenario:
iptables -I INPUT 7 -s 172.22.201.46 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j DROP
Ya incluida la regla, comprobamos que no podemos acceder a nuestro servidor web desde la ip
curl 172.22.200.153
Para cerciorarnos de la regla, podemos comprobar que si accedemos desde otra ip, si podemos acceder:
curl 172.22.200.153
Ejercicio 3: Permite hacer consultas DNS sólo al servidor 192.168.202.2. Comprueba que no puedes hacer un dig @1.1.1.1.
Lo primero será borrar las antiguas reglas:
iptables -D OUTPUT -o ens3 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -D INPUT -i ens3 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT
Añadimos las reglas nuevas, que nos permitirán hacer consultas DNS sólo al servidor
iptables -A OUTPUT -d 192.168.202.2 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -s 192.168.202.2 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT
Una vez incluidas, comprobamos que no podemos hacer una consulta DNS. La primera consulta la haremos al dns 1.1.1.1:
dig @1.1.1.1 bookmedik.mariatec.es
dig @192.168.202.2 bookmedik.mariatec.es
Ejercicio 4: No permitir el acceso al servidor web de www.josedomingo.org (Tienes que utilizar la ip). ¿Puedes acceder a fp.josedomingo.org?
Para realizar este ejercicio, lo primero que vamos a comprobar es la IP de www.josedomingo.org:
dig www.josedomingo.org
Vamos a mirar la posición en la que se encuentra la regla que nos permite el acceso tanto al protocolo http como al protocolo https:
iptables -L -n -v --line-numbers
Y añadimos la regla que se encuentra por encima de la regla que nos permite el acceso a nuestro servidor web:
iptables -I OUTPUT 5 -d 37.187.119.60 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j DROP
Si intentamos acceder a www.josedomingo.org, no podremos:
curl www.josedomingo.org
dig www.josedomingo.org
Ejercio 5: Permite mandar un correo usando nuestro servidor de correo: babuino-smtp. Para probarlo ejecuta un telnet babuino-smtp.gonzalonazareno.org 25.
Creamos lasreglas que nos permitirán mandar un correo usando nuestro servidor de correo:
iptables -A OUTPUT -d 192.168.203.3 -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -s 192.168.203.3 -p tcp --sport 25 -j ACCEPT
Y comprobamos que funciona:
telnet babuino-smtp.gonzalonazareno.org 25
Ejercicio 6: Instala un servidor mariadb, y permite los accesos desde la ip de tu cliente. Comprueba que desde otro cliente no se puede acceder.
Instalamos mariadb:
apt install mariadb-server
Modificamos el fichero /etc/mysql/mariadb.conf.d/50-server.cnf y configuramos el parámetro bind-address a 0.0.0.0 para que escuche en todas las interfaces:
bind-address = 0.0.0.0
Reiniciamos el servicio de mariadb:
systemctl restart mariadb
Configuramos las reglas para permitir el tráfico entrante desde mi máquina:
iptables -A INPUT -s 172.22.6.19 -p tcp --dport 3306 -j ACCEPT
iptables -A OUTPUT -d 172.22.6.19 -p tcp --sport 3306 -j ACCEPT
Comprobamos que funciona:
nc -zvw10 172.22.200.153 3306