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