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