Configuración de un cortafuegos perimetral con nftables en un escenario con una red DMZ
- Javi Huete
- Seguridad
- February 25, 2025
Índice
En este post se recoge un ejemplo práctico de la implantación de un sistema de cortafuegos perimetral usando la herramienta nftables
para filtrar el tráfico que circula por la red en escenario que está formado por dos máquinas virtuales y dos contenedores. Las máquinas virtuales, Luffy y Zoro funcionan como router/cortafuegos y servidor web respectivamente. Además, Luffy tiene dos contenedores: Nami y Sanji. Nami es el servidor DNS de la red y Sanji tiene un servidor de correos y un servidor de base de datos MariaDB al que accede el servidor web instalado en Zoro.
Los contenedores forman parte de la red interna y el servidor web forma parte de la red DMZ.

Configuración del cortafuegos perimetral en Luffy
En este caso, se usa la herramienta nftables para implementar el cortafuegos en el escenario.
sudo apt update
sudo apt install nftables
Creación de las tablas y cadenas
A diferencia de iptables
, nftables
no cuenta con tablas predefinidas. Por tanto, para poder usar esta herramienta como cortafuegos perimetral es necesario crear las tablas.
En este escenario, el cortafuegos cumple con dos funciones: por una parte, filtra el tráfico que circula por la red y; por otra, modifica los paquetes traduciendo las direcciones IP de una red a otra cuando es necesario a través de las reglas de NAT. Por tanto, el cortafuegos necesita usar las tablas filter
y nat
.
En este caso, la tabla filter
es de tipo inet
para que el filtrado de paquetes afecte, de forma indiferente, al tráfico IPv4 y al tráfico IPv6. En cambio, puesto que el NAT es una técnica específica de las direcciones IPv4, la tabla nat
es de tipo ip
.
nft add table inet filter
nft add table ip nat
Dentro de cada tabla, es necesario crear también las cadenas en las que se organizan las reglas tanto de filtrado como de NAT. En la tabla nat
, las cadenas necesarias son prerouting
y postrouting
. En la tabla filter
se pueden definir cadenas específicas para cada tráfico en concreto. Así, en esta tabla se establecen las siguientes cadenas:
Cadena | Descripción | Tipo |
---|---|---|
Input | Tráfico destinado a Luffy | Input |
Output | Tráfico que origina Luffy | Output |
Forward | Tráfico que pasa por Luffy pero ni se dirige ni se origina en el cortafuegos | Forward |
Lan-ext y ext-lan | Tráfico que circula entre Nami o Sanji y el exterior | Sin hook |
Lan-dmz y dmz-lan | Tráfico que circula entre Nami o Sanji y Zoro | Sin hook |
Dmz-ext y ext-dmz | Tráfico que circula entre Zoro y el exterior | Sin hook |
Aunque la política por defecto de todas estas cadenas será drop
, en un primer momento se crean con una política por defecto accept
para no perder la conexión por SSH a ellas. Para crear las cadenas se usa el comando nft add chain
de nftables
.
Si se crean diferentes cadenas con el hook forward el cortafuegos no funciona porque sólo permitiría pasar el tráfico que cumpliese con una regla en cada una de las cadenas. Esto ocurre porque, si la política por defecto de varias cadenas de tipo forward es drop, el cortafuegos rechaza el tráfico que no cumpla con ninguna regla de esa cadena.
Para solucionar esto y poder usar cadenas personalizadas en la configuración del cortafuegos, se crea una cadena genérica de tipo forward y, después se crean varias cadenas sin hook según el origen y destino del tráfico que atraviese el cortafuegos. Este tráfico se redirige después a cada una de las cadenas personalizadas según su origen y destino con la orden jump
.
#Tabla filter
nft add chain inet filter input { type filter hook input priority 0 \; counter \; policy accept \; }
nft add chain inet filter output { type filter hook output priority 0 \; counter \; policy accept \; }
nft add chain inet filter forward { type filter hook forward priority 0 \; counter \; policy drop \; }
nft add chain inet filter lan-ext
nft add chain inet filter ext-lan
nft add chain inet filter lan-dmz
nft add chain inet filter dmz-lan
nft add chain inet filter dmz-ext
nft add chain inet filter ext-dmz
# Redirigir tráfico de Nami y Sanji al exterior
nft add rule inet filter forward iifname "br-intra" oifname "ens3" jump lan-ext
# Redirigir tráfico del exterior a Nami y Sanji
nft add rule inet filter forward iifname "ens3" oifname "br-intra" jump ext-lan
# Redirigir tráfico de Nami y Sanji a la dmz
nft add rule inet filter forward iifname "br-intra" oifname "ens4" jump lan-dmz
# Redirigir tráfico de Nami y Sanji a la dmz
nft add rule inet filter forward iifname "ens4" oifname "br-intra" jump dmz-lan
# Redirigir tráfico de la dmz al exterior
nft add rule inet filter forward iifname "ens4" oifname "ens3" jump dmz-ext
# Redirigir tráfico del exterior a la dmz
nft add rule inet filter forward iifname "ens3" oifname "ens4" jump ext-dmz
#Tabla nat
nft add chain ip nat prerouting { type nat hook prerouting priority 100 \; }
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
Reglas de cortafuegos para permitir el funcionamiento del escenario
Antes de cambiar la política por defecto de las cadenas de filtrado a drop
hay que garantizar el acceso a la máquina cortafuegos por SSH.
nft add rule inet filter input ip saddr 172.22.0.0/16 tcp dport 22 ct state new,established counter accept
nft add rule inet filter output ip daddr 172.22.0.0/16 tcp sport 22 ct state established counter accept
Aunque para poder acceder por SSH a la máquina, además, desde la VPN que permite el acceso remoto a la red de OpenStack es necesario usar unas reglas algo más permisivas.
nft add rule inet filter input tcp dport 22 ct state new,established counter accept
nft add rule inet filter output tcp sport 22 ct state established counter accept
Además, también se permite el acceso por SSH desde Luffy al resto de máquinas del escenario.
#Acceso por SSH de Luffy a Nami y Sanji
nft add rule inet filter output oifname "br-intra" tcp dport 22 ct state new,established counter accept
nft add rule inet filter input iifname "br-intra" tcp sport 22 ct state established counter accept
#Acceso por SSH de Luffy a Zoro
nft add rule inet filter output oifname "ens4" tcp dport 22 ct state new,established counter accept
nft add rule inet filter input iifname "ens4" tcp sport 22 ct state established counter accept
Una vez que se ha garantizado el acceso a la máquina del cortafuegos, se puede cambiar la política por defecto de todas las cadenas de la tabla filter
a drop
.
nft chain inet filter input { policy drop \; }
nft chain inet filter output { policy drop \; }
nft chain inet filter forward { policy drop \; }
Al hacer un ping entre dos máquinas cualquiera del escenario, se puede comprobar que no hay conexión entre ellas.
root@luffy:~# ping -w4 zoro
PING zoro.javi.gonzalonazareno.org (172.16.0.200) 56(84) bytes of data.
--- zoro.javi.gonzalonazareno.org ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3074ms
Para garantizar el correcto funcionamiento del escenario, es necesario incluir reglas de cortafuegos que permitan las conexiones necesarias para cada uno de los servicios instalados en estas máquinas.
Permitir el tráfico al servidor DNS
Para que funcione la resolución de nombres de dominios en el escenario es necesario permitir el tráfico por el puerto 53 UDP:
- Desde Nami hacia el exterior
- Desde el exterior hacia Nami
- Desde Zoro hacia Nami
- Desde Nami hacia Zoro
- Desde Luffy hacia Nami
- Desde Nami hacia Luffy
#Peticiones DNS de Nami al exterior
nft add rule inet filter lan-ext udp dport 53 ct state new,established counter accept
#Respuesta DNS del exterior a Nami
nft add rule inet filter ext-lan udp sport 53 ct state established counter accept
#Peticiones DNS de Zoro a Nami
nft add rule inet filter dmz-lan udp dport 53 ct state new,established counter accept
#Respuesta DNS de Nami a Zoro
nft add rule inet filter lan-dmz udp sport 53 ct state established counter accept
#Peticiones DNS de Luffy a Nami
nft add rule inet filter output oifname "br-intra" udp dport 53 ct state new,established counter accept
#Respuesta DNS de Nami a Luffy
nft add rule inet filter input iifname "br-intra" udp sport 53 ct state established counter accept
Así, se pueden hacer resoluciones de nombres de dominio desde todas las máquinas del escenario.
root@luffy:~# dig javihuete.site
; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> javihuete.site
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41601
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 0ac70611e3934a4c0100000067c89697aed0469ea41d3509 (good)
;; QUESTION SECTION:
;javihuete.site. IN A
;; ANSWER SECTION:
javihuete.site. 887 IN A 216.24.57.1
;; Query time: 0 msec
;; SERVER: 192.168.0.2#53(192.168.0.2) (UDP)
;; WHEN: Wed Mar 05 18:23:19 UTC 2025
;; MSG SIZE rcvd: 87
Permitir el tráfico al servidor de correos
Para que el servidor de correos pueda enviar y recibir correos desde el exterior es necesario permitir el tráfico por el puerto 25 TCP:
- Desde Sanji hacia el exterior
- Desde el exterior hacia Sanji
Además, hay que configurar en la tabla nat
una regla de DNAT que reenvíe los correos que lleguen al router, Luffy, al servidor de correos en Sanji.
#Envío de correos de Sanji al relay host en Macaco (172.22.0.1)
nft add rule inet filter lan-ext ip saddr 192.168.0.3 tcp dport 25 ct state new,established counter accept
#Recepción de correos del exterior de Sanji
nft add rule inet filter ext-lan ip daddr 192.168.0.3 tcp dport 25 ct state new,established counter accept
#Regla DNAT para reenviar los correos de Luffy a Sanji
nft add rule ip nat prerouting iifname "ens3" tcp dport 25 counter dnat to 192.168.0.3
#Regla SNAT para que puedan salir los correos de Luffy
nft add rule ip nat postrouting oifname "ens3" ip saddr 192.168.0.0/24 counter masquerade
Permitir el tráfico al servidor MariaDB
Al servidor MariaDB instalado en Sanji debe acceder el servidor web instalado en Zoro. Por tanto, para que este servicio funcione correctamente es necesario permitir el tráfico por el puerto 3306 TCP:
- Desde Zoro hacia Sanji
- Desde Sanji hacia Zoro
#Conexiones desde el servidor web a la base de datos
nft add rule inet filter dmz-lan tcp dport 3306 ct state new,established counter accept
#Respuestas de la base de datos al servidor web
nft add rule inet filter lan-dmz tcp sport 3306 ct state established counter accept
[usuario@zoro ~]$ mysql -u wp-user -p -h sanji
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 33
Server version: 10.6.18-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
Permitir el tráfico al servidor web
Al servidor web sólo es necesario acceder desde el exterior y se hace a través de una regla DNAT en el router. Por tanto, para permitir el correcto funcionamiento del servidor web es necesario permitir el tráfico por el puerto 80 TCP:
- Desde el exterior hacia Zoro
- Desde Zoro hacia el exterior
#Peticiones HTTP desde el exterior al servidor web
nft add rule inet filter ext-dmz ip daddr 172.16.0.200 tcp dport 80 ct state new,established ct count 10 counter accept
#Respuesta HTTP desde el servidor web al exterior
nft add rule inet filter dmz-ext ip saddr 172.16.0.200 tcp sport 80 ct state established counter accept
#Regla DNAT
nft add rule ip nat prerouting iifname "ens3" tcp dport 80 counter dnat to 172.16.0.200
#Regla SNAT
nft add rule ip nat postrouting oifname "ens3" ip saddr 172.16.0.0/32 counter masquerade
Note
En este caso, a la regla que permite el paso de peticiones HTTP desde el exterior al servidor web se le añade una condición que limita a 10 el número de conexiones simultáneas.
Permitir el tráfico al servidor LDAP
Para que funcione el servidor LDAP en el escenario es necesario permitir el tráfico por el puerto 389 TCP de petición desde todas las máquinas a Luffy y de respuesta desde Luffy a todas las máquinas.
#Peticiones LDAP de la LAN a Luffy
nft add rule inet filter input ip saddr 192.168.0.0/24 tcp dport 389 counter accept
#Respuesta LDAP de Luffy a la LAN
nft add rule inet filter output ip daddr 192.168.0.0/24 tcp sport 389 counter accept
#Peticiones LDAP de la DMZ a Luffy
nft add rule inet filter input ip saddr 172.16.0.0/32 tcp dport 389 counter accept
#Respuesta LDAP de Luffy a la DMZ
nft add rule inet filter output ip daddr 172.16.0.0/32 tcp sport 389 counter accept
Una vez configuradas todas las reglas del cortafuegos, para que esta configuración sea persistente entre reinicios es necesario volcar la información al fichero /etc/nftables.conf.
nft list ruleset > /etc/nftables.conf
Además, también hay que habilitar y arrancar el servicio nftables
, que se encarga de cargar las reglas a partir del fichero de configuración en cada reinicio.
sudo systemctl enable nftables
sudo systemctl start nftables
La máquina Luffy tiene un servidor ssh escuchando por el puerto 22, pero al acceder desde el exterior habrá que conectar al puerto 2222
Para acceder por SSH a Luffy usando el puerto 2222 en vez del 22 sin modificar la configuración del servidor SSH se puede usar la siguiente regla de DNAT en el cortafuegos:
nft add rule ip nat prerouting iifname "ens3" tcp dport 2222 counter dnat to 10.0.200.61:22
❯ ssh luffy -p 2222
Linux luffy 6.1.0-31-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.128-1 (2025-02-07) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Wed Mar 5 18:17:59 2025 from 172.210.0.6
usuario@luffy:~$ hostname
luffy
Desde Sanji y Zoro se debe permitir la conexión ssh por el puerto 22 a la máquina Luffy
Para permitir que Luffy reciba conexiones SSH desde Sanji y Zoro se añaden al cortafuegos las siguientes reglas:
#Peticiones SSH de Sanji a Luffy
nft add rule inet filter input ip saddr 192.168.0.3 tcp dport 22 ct state new,established counter accept
#Respuestas SSH de Luffy a Sanji
nft add rule inet filter output ip daddr 192.168.0.3 tcp sport 22 ct state established counter accept
#Peticiones SSH de Zoro a Luffy
nft add rule inet filter input ip saddr 172.16.0.200 tcp dport 22 ct state new,established counter accept
#Respuestas SSH de Luffy a Zoro
nft add rule inet filter output ip daddr 172.16.0.200 tcp dport 22 ct state established counter accept
Desde Sanji se puede conectar por SSH a Luffy.
usuario@sanji:~$ ssh luffy
Linux luffy 6.1.0-31-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.128-1 (2025-02-07) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Wed Mar 5 17:09:30 2025 from 172.210.0.6
usuario@luffy:~$ hostname
luffy
Igualmente, desde Zoro también se puede acceder a Luffy.
[usuario@zoro ~]$ ssh luffy
Linux luffy 6.1.0-31-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.128-1 (2025-02-07) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Wed Mar 5 18:38:02 2025 from 172.16.0.200
usuario@luffy:~$ hostname
luffy
La máquina Luffy debe tener permitido el tráfico para la interfaz loopback
Para permitir el tráfico para la interfaz loopback en el cortafuegos:
nft add rule inet filter input iifname "lo" counter accept
nft add rule inet filter output oifname "lo" counter accept
A la máquina Luffy se le puede hacer ping desde la DMZ, pero desde la LAN se le debe rechazar la conexión (REJECT) y desde el exterior se rechazará de manera silenciosa
En este caso se configuran las reglas que:
- Permitan las peticiones ping desde Zoro a Luffy
- Permitan las respuestas ping desde Luffy a Zoro
- Rechacen las peticiones ping desde Nami o Sanji
- Rechacen de manera silenciosa las peticiones ping desde el exterior
#Peticiones ping de Zoro a Luffy
nft add rule inet filter input iifname "ens4" icmp type echo-request counter accept
#Respuestas ping de Luffy a Zoro
nft add rule inet filter output oifname "ens4" icmp type echo-reply counter accept
#Rechazar las peticiones ping desde la LAN
nft add rule inet filter input iifname "br-intra" icmp type echo-request reject with icmp type admin-prohibited
#Rechazar de manera silenciosa las peticiones ping desde el exterior
nft add rule inet filter input iifname "ens3" icmp type echo-request counter reject
Desde Zoro se puede hacer ping a Luffy
[usuario@zoro ~]$ ping -c1 luffy
PING 172.16.0.1 (172.16.0.1) 56(84) bytes of data.
64 bytes from 172.16.0.1: icmp_seq=1 ttl=64 time=0.261 ms
--- 172.16.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.261/0.261/0.261/0.000 ms
En el caso de las peticiones ping desde la red interna a Luffy, este tipo de comunicación no se permite.
usuario@sanji:~$ ping -w2 luffy
PING luffy.javi.gonzalonazareno.org (192.168.0.1) 56(84) bytes of data.
--- luffy.javi.gonzalonazareno.org ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1012ms
En el caso de las peticiones ping desde el exterior a Luffy no se informa de la prohibición pero tampoco se permite este tipo de conexiones.
❯ ping -w2 172.22.201.28
PING 172.22.201.28 (172.22.201.28) 56(84) bytes of data.
--- 172.22.201.28 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1013ms
La máquina Luffy puede hacer ping a la LAN, la DMZ y al exterior
Para permitir que Luffy pueda hacer ping por todas sus interfaces hay que escribir las reglas que permitan:
- Peticiones ping de Luffy a Zoro
- Respuestas ping de Zoro a Luffy
- Peticiones ping de Luffy a Nami y Sanji
- Respuestas ping de Nami y Sanji a Luffy
- Peticiones ping de Luffy al exterior
- Respuestas ping desde el exterior a Luffy
#Peticiones ping de Luffy a Zoro
nft add rule inet filter output oifname "ens4" icmp type echo-request counter accept
#Respuestas ping de Zoro a Luffy
nft add rule inet filter input iifname "ens4" icmp type echo-reply counter accept
#Peticiones ping de Luffy a Nami o Sanji
nft add rule inet filter output oifname "br-intra" icmp type echo-request counter accept
#Respuestas ping de Nami o Sanji a Luffy
nft add rule inet filter input iifname "br-intra" icmp type echo-reply counter accept
#Peticiones ping de Luffy al exterior
nft add rule inet filter output oifname "ens3" icmp type echo-request counter accept
#Respuestas ping del exterior a Luffy
nft add rule inet filter input iifname "ens3" icmp type echo-reply counter accept
Así, Luffy puede hacer ping por todas sus interfaces.
root@luffy:~# ping -c1 sanji
PING sanji.javi.gonzalonazareno.org (192.168.0.3) 56(84) bytes of data.
64 bytes from sanji.javi.gonzalonazareno.org (192.168.0.3): icmp_seq=1 ttl=64
time=0.086 ms
--- sanji.javi.gonzalonazareno.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.086/0.086/0.086/0.000 ms
root@luffy:~# ping -c1 zoro
PING zoro.javi.gonzalonazareno.org (172.16.0.200) 56(84) bytes of data.
64 bytes from zoro.javi.gonzalonazareno.org (172.16.0.200): icmp_seq=1 ttl=64
time=1.71 ms
--- zoro.javi.gonzalonazareno.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.705/1.705/1.705/0.000 ms
root@luffy:~# ping -c1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=106 time=17.4 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.415/17.415/17.415/0.000 ms
Desde la máquina Zoro se puede hacer ping y conexión ssh a las máquinas de la LAN
Para que Zoro pueda hacer ping y conectarse por SSH a Nami y Sanji hay que establecer las siguientes reglas en el cortafuegos:
- Peticiones ping de Zoro a Nami o Sanji
- Respuestas ping de Nami y Sanji a Zoro
- Peticiones SSH de Zoro a Nami o Sanji
- Respuestas SSH de Nami y Sanji a Zoro
#Peticiones ping de Zoro a Nami o Sanji
nft add rule inet filter dmz-lan icmp type echo-request counter accept
#Respuestas ping de Nami o Sanji a Zoro
nft add rule inet filter lan-dmz icmp type echo-reply counter accept
#Peticiones SSH de Zoro a Nami o Sanji
nft add rule inet filter dmz-lan tcp dport 22 ct state new,established counter accept
#Respuestas SSH de Nami o Sanji a Zoro
nft add rule inet filter lan-dmz tcp sport 22 ct state established counter accept
Zoro puede conectarse por SSH y hacer ping a ambos contenedores de la red LAN.
[usuario@zoro ~]$ ssh sanji
The authenticity of host 'sanji (192.168.0.3)' can't be established.
ED25519 key fingerprint is SHA256:js8NZC99EMo1ukuhti5Z/YjQqKme0y8bhVI6/eGyAh0.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'sanji' (ED25519) to the list of known hosts.
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 6.1.0-31-amd64 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
You have no mail.
Last login: Wed Mar 5 18:42:02 2025 from 192.168.0.1
usuario@sanji:~$ hostname
sanji
Desde cualquier máquina de la LAN se puede conectar por ssh a la máquina Zoro
Para permitir que desde Nami y Sanji se pueda hacer SSH a Zoro hay que:
- Permitir las peticiones SSH de Nami y Sanji a Zoro
- Permitir las respuestas SSH de Zoro a Sanji y Nami
#Peticiones SSH de Nami o Sanji a Zoro
nft add rule inet filter lan-dmz tcp dport 22 counter accept
#Respuestas SSH de Zoro a Nami o Sanji
nft add rule inet filter dmz-lan tcp sport 22 counter accept
Con esta regla, Nami y Sanji pueden conectarse por SSH a Zoro.
usuario@sanji:~$ ssh zoro
The authenticity of host 'zoro (172.16.0.200)' can't be established.
ED25519 key fingerprint is SHA256:mPxa3RuInTQPneT1b/7k0XK4E8uYJN1af3evQt/2C7w.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'zoro' (ED25519) to the list of known hosts.
Last login: Wed Mar 5 18:43:36 2025 from 172.16.0.1
[usuario@zoro ~]$ hostname
zoro.javi.gonzalonazareno.org
Configura la máquina Luffy para que las máquinas de LAN y DMZ puedan acceder al exterior
Para que las máquinas tanto de la LAN como de la DMZ puedan acceder al exterior a través de ping hay que permitir:
- Las peticiones ping de Nami y Sanji al exterior
- Las respuestas ping del exterior a Nami y Sanji
- Las peticiones ping de Zoro al exterior
- Las respuestas ping del exterior a Zoro
#Peticiones ping de Nami y Sanji al exterior
nft add rule inet filter lan-ext icmp type echo-request counter accept
#Respuestas ping del exterior a Nami y Sanji
nft add rule inet filter ext-lan icmp type echo-reply counter accept
#Peticiones ping de Zoro al exterior
nft add rule inet filter dmz-ext icmp type echo-request counter accept
#Respuestas ping del exterior a Zoro
nft add rule inet filter ext-dmz icmp type echo-reply counter accept
Ahora las máquinas de la LAN y la DMZ pueden hacer ping al exterior.
usuario@nami:~$ ping -c1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=105 time=17.2 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.196/17.196/17.196/0.000 ms
Las máquinas de la LAN pueden hacer ping al exterior y navegar
Para que Nami y Sanji puedan navegar por Internet y hacer ping al exterior hay que permitir en el cortafuegos:
- Las peticiones ping de Nami y Sanji al exterior
- Las respuestas ping del exterior a Nami y Sanji
- Las peticiones HTTP y HTTPS de Nami y Sanji al exterior
- Las respuestas HTTP y HTTPS del exterior y Nami y Sanji
#Peticiones ping de Nami y Sanji al exterior
nft add rule inet filter lan-ext icmp type echo-request counter accept
#Respuestas ping del exterior a Nami y Sanji
nft add rule inet filter ext-lan icmp type echo-reply counter accept
#Peticiones HTTP y HTTPS de Nami y Sanji al exterior
nft add rule inet filter lan-ext tcp dport { 80,443 } ct state new,established counter accept
#Respuestas HTTP y HTTPS del exterior a Nami y Sanji
nft add rule inet filter ext-lan tcp sport { 80,443 } ct state established counter accept
Tanto desde Nami como desde Sanji se puede hacer ping al exterior y consultar páginas web.
usuario@nami:~$ curl example.org
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
La máquina Zoro puede navegar. Instala un servidor web, un servidor ftp y un servidor de correos si no los tienes aún
Para que Zoro pueda navegar por Internet es necesario permitir por los puertos 80 y 443 TCP:
- Las peticiones de Zoro al exterior
- Las respuestas del exterior a Zoro
#Peticiones HTTP y HTTPS de Zoro al exterior
nft add rule inet filter dmz-ext tcp dport { 80,443 } ct state new,established counter accept
#Respuestas HTTP y HTTPS del exterior a Zoro
nft add rule inet filter ext-dmz tcp sport { 80,443 } ct state established counter accept
Al permitir este tráfico Zoro ya puede navegar por Internet, así como instalar paquetes.
[usuario@zoro ~]$ curl example.org
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
Configura la máquina Luffy para que los servicios web y ftp sean accesibles desde el exterior
Para que los servicios web y ftp instalados en Zoro sean accesibles desde el exterior hay que añadir al cortafuegos una regla de DNAT para cada uno de ellos.
Además, hay que permitir que atraviesen el router:
- Las peticiones HTTP y HTTPS del exterior a Zoro
- Las respuestas HTTP y HTTPS de Zoro al exterior
- Las peticiones FTP del exterior a Zoro
- Las respuestas FTP de Zoro al exterior
#Peticiones HTTP y HTTPS del exterior a Zoro
nft add rule inet filter ext-dmz tcp dport { 80,443 } ct state new,established counter accept
#Respuestas HTTP y HTTPS de Zoro al exterior
nft add rule inet filter dmz-ext tcp sport { 80,443 } ct state established counter accept
#Peticiones FTP del exterior a Zoro
nft add rule inet filter ext-dmz tcp dport 21 ct state new,established counter accept
#Respuestas FTP de Zoro al exterior
nft add rule inet filter dmz-ext tcp sport 21 ct state established counter accept
#DNAT para el servidor web
nft add rule ip nat prerouting iifname "ens3" tcp dport { 80,443 } counter dnat to 172.16.0.200
#DNAT para el servidor FTP
nft add rule ip nat prerouting iifname "ens3" tcp dport 21 counter dnat to 172.16.0.200
Así, tanto el servidor web como el FTP de Zoro son accesibles desde el exterior.
❯ curl 172.22.201.28
<h1>Francisco Javier Huete Mejías</h1>
<h2>Jueves, 30 de enero de 2025</h2>
❯ telnet 172.22.201.28 21
Trying 172.22.201.28...
Connected to 172.22.201.28.
Escape character is '^]'.
220 (vsFTPd 3.0.5)
El servidor web y el servidor ftp deben ser accesibles desde la LAN y desde el exterior
Para que estos servicios sean accesibles también desde la LAN hay que permitir:
- Las peticiones HTTP y HTTPS desde Nami y Sanji a Zoro
- Las respuestas HTTP y HTTPS desde Zoro a Nami y Sanji
- Las peticiones FTP desde Nami y Sanji a Zoro
- Las respuestas FTP desde Zoro a Nami y Sanji
#Peticiones HTTP y HTTPS de Nami y Sanji a Zoro
nft add rule inet filter lan-dmz tcp dport { 80,443 } ct state new,established counter accept
#Respuestas HTTP y HTTPS de Zoro a Nami y Sanji
nft add rule inet filter dmz-lan tcp sport { 80,443 } ct state established counter accept
#Peticiones FTP de Nami y Sanji a Zoro
nft add rule inet filter lan-dmz tcp dport 21 ct state new,established counter accept
#Respuestas FTP de Zoro a Nami y Sanji
nft add rule inet filter dmz-lan tcp sport 21 ct state established counter accept
Así, desde Nami y Sanji se puede acceder a ambos servicios en Zoro.
usuario@nami:~$ curl zoro
<h1>Francisco Javier Huete Mejías</h1>
<h2>Jueves, 30 de enero de 2025</h2>
usuario@nami:~$ telnet zoro 21
Trying 172.16.0.200...
Connected to zoro.javi.gonzalonazareno.org.
Escape character is '^]'.
220 (vsFTPd 3.0.5)
El servidor de correos sólo debe ser accesible desde la LAN
Para que el servidor de correos en Zoro sea accesible sólo desde la LAN hay que permitir el tráfico por el puerto 25 TCP:
- Desde Sanji y Nami a Zoro
- Desde Zoro a Nami y Sanji
#Peticiones al servidor de correos de Nami y Sanji a Zoro
nft add rule inet filter lan-dmz tcp dport 25 ct state new,established counter accept
#Respuestas del servidor de correos de Zoro a Nami y Sanji
nft add rule inet filter dmz-lan tcp sport 25 ct state established counter accept
En la máquina Nami instala un servidor Postgres si no lo tiene aún. A este servidor se puede acceder desde la DMZ, pero no desde el exterior
Para acceder al Postgres de Nami desde Zoro hay que permitir el tráfico por el puerto 5432 TCP:
- Desde Zoro a Nami
- Desde Nami a Zoro
#Peticiones al servidor Postgres de Zoro a Nami
nft add rule inet filter dmz-lan ip daddr 192.168.0.2 tcp dport 5432 ct state new,established counter accept
#Respuestas del servidor Postgres de Nami a Zoro
nft add rule inet filter lan-dmz ip saddr 192.168.0.2 tcp sport 5432 ct state established counter accept
Evita ataques DoS por ICMP Flood, limitando a 4 el número de peticiones por segundo desde una misma IP
Para limitar el número de peticiones ICMP por segundo se usa el parámetro limit rate
. Esta regla tiene que estar antes de las que se usan para permitir el tráfico de entrada ICMP a Luffy, así que se crea con la opción postion
para colocarla al principio de la lista de reglas del cortafuegos.
nft insert rule inet filter input position 0 icmp type echo-request limit rate 4/second counter drop
Evita ataques DoS por SYN Flood
Para evitar ataques DoS por SYN Flood se puede limitar el número de paquetes por segundo que se reciben marcados con la bandera SYN. Por ejemplo, se puede permitir la entrada de 5 paquetes SYN por segundo y bloquear el resto.
nft add rule inet filter input tcp flags syn limit rate 5/second counter accept
nft add rule inet filter input tcp flags syn counter drop
Evita que realicen escaneos de puertos a Luffy
Para evitar que se realice un escaneo de puertos a Luffy se pueden limitar las conexiones a aquellos puertos del router que no están abiertos.
nft add rule inet filter input tcp dport != { 22, 80, 443 } limit rate 5/minute counter accept