nftables es un proyecto que proporciona filtrado de paquetes y clasificación de paquetes en Linux, destinado a reemplazar los frameworks existentes iptables, ip6tables, arptables y ebtables. Nftables es una combinación del núcleo Linux y una utilidad espacio de usuario.
Diferencias entre iptables y nftables
- la sintaxis: iptables usa un parseador basado en getopt_long(), donde las órdenes van precedidas por guiones (por ejemplo, ‘-m conntrack –ctstate’). Ahora nftables usa una sintaxis más compacta e intuitiva que fue inspirada por la herramienta tcpdump.
- las tablas y cadenas son totalmente configurables. En nftables, las tablas son meros contenedores de cadenas, sin una semántica determinada. En iptables, hay una serie de tablas y cadenas predeterminadas que son registradas en el sistema de manera obligatoria aunque no vayas a usarlas. Los nombres de estos objetos (tablas y cadenas) son también arbitrarios.
los conceptos de ‘target’ y ‘match’ desaparecen. En nftables, las reglas están compuestas de expresiones. - nftables permite especificar varias acciones en una única regla. En iptables, solo podías seleccionar un ‘target’ por regla.
no hay contadores integrados en reglas y cadenas. Son opcionales y pueden habilitarse bajo demanda. - soporte mejorado para actualizaciones dinámicas del conjunto de reglas.
administración simplificada para conjuntos de reglas IPv4/IPv6. - infraestructura genérica de conjuntos y mapeos de datos, directamente integrada en el núcleo de nftables. En iptables, existe la herramienta externa ipset.
- soporte para nuevos protocolos sin actualizaciones del kernel Linux, dado que la complejidad del manejo de protocolos se encuentra en espacio de usuario y no en el kernel.
A modo de ejemplo, esta sería una equivalencia entre reglas similares. En iptables:
% iptables -t filter -A FORWARD -s 1.1.1.1 -d 2.2.2.2 -p tcp --dport 123 -m conntrack --ctstate -j ACCEPT
En nftables:
% nft add rule filter forward ip saddr 1.1.1.1 ip daddr 2.2.2.2 tcp dport 123 ct state new accept
Configuraciones previas
Recomiendo recrear el escenario con KVM
, por eso podréis observar en el post que utilizo «br0»
Instalacion de nftables
Es recomendable que se instale en una versión de «Debian», a partir de la «9» e instalamos el paquete apt install nftables
y activamos el ip de forward para que actué como router echo 1 > /proc/sys/net/ipv4/ip_forward
, el cliente debe de tener configurado con la ip del cortafuegos, para ello, primero deberemos eliminar si viniera la ip o por defecto ip r del default
y añadimos la nueva ip r add default via [IP_Interna_Cortafuegos]
Cargar modulos nftables
Cargamos los modulos para nftables.
modprobe nf_tables modprobe nf_tables_ipv4 modprobe nf_tables_bridge modprobe nf_tables_inet modprobe nf_tables_arp
Aplicar política por defecto DROP
Si estamos conectado por ssh, para no perder la conexión vamos a añadir las misma reglas pero sin aplicar la política DROP
El primer paso de todos es crear la tabla en la cual vamos a añadir las cadenas y las reglas en este caso la vamos a llamar filter pero podemos llamarla como queramos.
Y añadimos las reglas sin la politica explicada antes DROP
nft add table ip FILTER nft add chain ip FILTER INPUT { type filter hook input priority 0 \;} nft add chain ip FILTER OUTPUT { type filter hook output priority 0 \; } nft add chain ip FILTER FORWARD { type filter hook forward priority 0 \; }
SSH accesible desde el exterior
Antes de aplicar las políticas DROP
añdimos las siguientes reglas para poder acceder desde el exterior:
nft add rule ip FILTER INPUT iif eth0 tcp dport 22 counter accept nft add rule ip FILTER OUTPUT ct state established,related counter accept
Esto hace que sabemos el puerto por el que vamos a entrar a la conexión que es el 22
, pero no el puerto por el que vamos a establecer la conexion desde fuera por eso establecemos la segunda regla.
Y ya si podemos añadir la politica DROP
:
nft add chain ip FILTER INPUT { type filter hook input priority 0 \; policy drop \;} nft add chain ip FILTER OUTPUT { type filter hook output priority 0 \; policy drop \;} nft add chain ip FILTER FORWARD { type filter hook forward priority 0 \; policy drop \;}
Permitir conexiones SSH desde el cortafuegos
Para ello establecemos las siguientes reglas:
nft add rule ip FILTER OUTPUT oif eth0 tcp dport 22 counter accept nft add rule ip FILTER INPUT ct state established,related counter accept
Permitir resolución DNS, HTTP, HTTPS
Al desactivar todos los puertos nuestro cortafuego no puede resolver el nombre de ninguna pagina:
Por lo tanto agregamos las reglas correspondientes para poder acceder a las distintas paginas tanto DNS
, http
como https
DNS
En el caso de dns vamos a utilizar upd, es un protocolo no orientado a conexión. Es decir cuando una maquina A envía paquetes a una maquina B, el flujo es unidireccional.
nft add rule ip FILTER OUTPUT oif eth0 udp dport 53 counter accept
HTTP
nft add rule ip FILTER OUTPUT oif eth0 tcp dport 80 counter accept
Intentamos acceder a esta misma pagina w3m www.juanluramirez.com
HTTPS
Igual que en el paso anterior accedemos a una pagina la cual tenga autentificación w3m https://www.google.es
:
nft add rule ip FILTER OUTPUT oif eth0 tcp dport 443 counter accept
Hacer que los clientes tengan acceso a internet
Para hacer que los clientes tengan acceso a internet vamos a agregar una regla de NAT, para poder ejecutar esta regla debemos tener mínimo la version del kernel 3.8
, creamos una tabla que se llame nat
y agregamos las cadenas correspondientes:
nft add table NAT nft add chain NAT PREROUTING { type nat hook prerouting priority 1 \; } nft add chain NAT POSTROUTING { type nat hook postrouting priority 1 \; } nft add rule ip FILTER FORWARD oif eth1 ct state established,related counter accept nft add rule NAT POSTROUTING ip saddr 192.168.100.0/24 oif eth1 nftrace set 1 masquerade
Al no tener ping
con los clientes, vamos a comprobar que tienen acceso a Internet a traves de el paquete w3m
, y debemos añadir en la cadena FORWARD
de la tabla FILTER
lo siguiente:
#DNS nft add rule ip FILTER FORWARD oif eth0 udp dport 53 counter accept #HTTP nft add rule ip FILTER FORWARD oif eth0 tcp dport 80 counter accept #HTTPS nft add rule ip FILTER FORWARD oif eth0 tcp dport 443 counter accept
Denegar acceso a una web en concreto
Si queremos denegar el acceso a una pagina en concreto deberemos cortar el trafico con esa dirección ip, por tanto, tendremos que saber cual es para ello realizamos un dig [Direccion_WEB]
.
Y ejecutamos la siguiente regla de nftables
:
#Sintaxis nft add rule ip NAT PREROUTING ip saddr [Red_Interna] ip daddr [Direccion_IP] counter drop #Ejemplo ip www.as.com nft add rule ip NAT PREROUTING ip saddr 192.168.100.0/24 ip daddr 185.43.182.75 counter drop
Intentamos acceder con w3m-
a «www.as.com» y no cargara dicha pagina:
Permitir trafico loopback en el cortafuegos
Para permitir el acceso vamos a agregar estas dos reglas, tanto de salida como de entrada:
nft add rule ip FILTER INPUT iif lo counter accept nft add rule ip FILTER OUTPUT oif lo counter accept
Ofrecer un Servidor WEB desde maquina en red interna
Para ello en una de las maquinas vamos a instalar un Servidor WEB y agregamos la siguiente regla en el cortafuegos para permitir el acceso desde el exterior:
#Sintaxis nft add rule ip NAT PREROUTING iif [Interfaz] tcp dport 80 counter dnat to [IP_Maquina_Red_Interna] nft add rule FILTER FORWARD oif [Interfaz_sale_Exterior] tcp sport 80 accept #Ejemplo nft add rule ip NAT PREROUTING iif eth0 tcp dport 80 counter dnat to 192.168.100.2 nft add rule FILTER FORWARD oif eth0 tcp sport 80 accept
En nuestra maquina física añadimos añadimos una ruta hacia la red interna por la interfaz de salida de nuestro cortafuego:
#Sintaxis ip r add 192.168.100.0/24 via [IP_Salida_Cortafuego] dev [Interfaz_Maquina_Anfitriona] #Ejemplo ip r add 192.168.100.0/24 via 192.168.1.62 dev br0
Ofrecer un Servidor FTP desde la maquina en red interna
Para ello en la otra maquina vamos a instalar un Servidor FTP y agregamos la siguiente regla en el cortafuegos para permitir el acceso desde el exterior:
#Sintaxis nft add rule ip NAT PREROUTING iif eth1 tcp dport 21 counter dnat to [IP_Maquina_Red_Interna] nft add rule FILTER FORWARD oif [Interfaz_sale_Exterior] tcp sport 21 accept #Ejemplo nft add rule ip NAT PREROUTING iif eth1 tcp dport 21 counter dnat to 192.168.100.3 nft add rule FILTER FORWARD oif eth0 tcp sport 21 accept
Ya tenemos agregada la ruta del apartado anterior por lo tanto no es necesario añadirlo otra vez.
Hacer ping desde una sola maquina de la red interna
En este momento no tenemos ping desde ninguna de las maquinas, pero si internet, por lo tanto solo queremos que tenga red PC1, para ello añadimos las siguientes reglas:
nft add rule ip FILTER FORWARD ip saddr 192.168.100.2 icmp type echo-request ct state new,related,established counter accept nft add rule ip FILTER FORWARD ip daddr 192.168.100.2 icmp type echo-reply ct state related,established counter accept
Borrar cualquier regla añadida
Para borrar cualquier regla añadida, primero vamos a listar las reglas añadidas nft list ruleset -n -a
una vez listadas, dependiendo de las tablas que introdujéramos, nos saldra distintas cosas, pero para la sintaxis para borrar cualquier regla es nft delete rule [Nombre_tabla] [Nombre_Cadena] handle [Numero_Regla]
Script en bash nftables
En mi github podeis encontrar un script de nftables
Es mejor usar un script nativo de nftables y recargar las reglas con nft -f, de lo contrario las reglas no se cargan de manera atómica. El tiempo de carga también va a ser mucho mayor.
En mi github puedes encontrar un script en bash para poder mas tarde automatizarlo en el cual añado todas las reglas, instalar nftables y ademas habilita los módulos necesarios.
Gracias por tu comentario.