8.7.3.2.1. Creación del armazón

Para poder escribir reglas necesitamos crear un armazón previo de tablas y reglas que, a diferencia de iptables, está sin definir.

8.7.3.2.1.1. Tablas

Tienen el propósito de albergar cadenas (que a su vez son contenedores de reglas), pero no hay predefinida ninguna. Para crearlas basta con indicar de qué familia son:

# nft add table [<familia>] <nombre>

Si no se especifica familia, se sobrentiende ip. Por ejemplo:

# nft add table ip filter
# nft add table nat

que crea dos tablas llamadas «filter» y «nat» para IPv4.

Nota

Es posible usar create en vez de add. La única diferencia es que la primera alternativa falla cuando se intenta crear una tabla que ya existe:

# nft create table filter
Error: Could not process rule: File exists
create table ip filter
^^^^^^^^^^^^^^^^^^^^^^^
# echo $?
1
# nft add table filter
# echo $?
0

En la creación de cadenas también es valida esta nota.

Podemos listar las tablas definidas:

# nft list tables
table ip filter
table ip nat

O listas las reglas dentro de una cadena con:

# nft list table [<familia>] <nombre>

En nuestro caso:

# nft list table filter
table ip filter {
}
# nft list table ip nat
table ip nat {
}

Por último, para borrar una tabla creada:

# nft delete table [<familia>] <nombre>

Por ejemplo:

# nft create table inet efimera
# nft list table inet efimera
table inet efimera {
}
# nft delete table inet efimera

Ahora bien, antes de la versión 3.18 del kernel, para poder borrar una tabla, ésta no debía contener cadenas y. si las contienía, debía vaciarse primero:

# nft flush table [<familia>] <nombre>

Es también intersante saber que podemos deshabilitar temporalmente una tabla, lo que supone que no se comprobaran las reglas de sus cadenas:

# nft add table filter { flags dormant\;}

8.7.3.2.1.2. Cadenas

Las cadenas son, simplemente, colecciones de reglas y, como en el caso de iptables hay de dos tipos:

  • Las cadenas base que son las cadenas que se enganchan al flujo y que se comprueban cuando el paquete llega a uno de esos enganches. En iptables estas cadenas ya estaban definidas, pero en nftables es el adminsitrador el encargado de crearlas y engancharlas.

  • Las cadenas de usuario cuyas reglas se comprueban sólo cuando alguna regla salta a ellas. No están pues enganchadas al flujo, sino referidas en otra cadena. Su naturaleza, pues, es la misma que en iptables.

Para crear el segundo tipo de cadenas, amén del nombre, sólo hay que indicar la familia y la tabla para la se crea la cadena:

# nft add chain [<family>] <table> <nombre>

Por ejemplo:

# nft add chain filter INVALIDO
# nft list table filter
table ip filter {
        chain INVALIDO {
        }
}

Esta cadena, aun conteniendo reglas, será totalmente inútil hasta que al menos desde una cadena base no saltemos a ella para que operen las reglas que contiene.

Las cadenas base, sin embargo, exigen para su creación indicar más propiedades:

# nft add chain [<family>] <table> <nombre> { type <tipo> hook <enganche> priority <prio>\; [policy <politica>] }

esto es:

  • El tipo de cadena.

  • A qué punto del flujo se enganchan.

  • Cuál es la prioridad de la cadena. A partir de nftables v0.9.1 pueden usarse los nombres referidos en las tablas de ese enlace, incluso sumándole o restándole un entero (p.e. filter - 5).

  • La política se refiere a la política predeterminada para los paquetes a los que no sea aplicable ninguna regla. Puede indicarse cualquiera de las acciones terminales, excepto reject. Típicamente se usan accept o drop. Si no se especifica, se sobreentiende accept. En caso de aceptación, el paquete continuará fluyendo (aunque no comprobará más reglas de esa cadena); en caso de rechazo, el paquete se descartará sin más.

Por ejemplo:

# nft add chain filter INPUT { type filter hook input priority 0\; }
# nft add chain filter FORWARD { type filter hook forward priority 0\; }
# nft add chain filter OUTPUT { type filter hook output priority 0\; }

estas tres instrucciones crearían unas tablas para filtrar paquetes equivalentes a las existentes en iptables.

En el caso de que se cree una cadena enganchada a ingress es necesario, además, definir la interfaz a la que se conectará:

# nft add table netdev ingress
# nft add chain netdev ingress INGRESS {type filter hook ingress device eth0 priority 0\;}

Para borrar cadenas basta con:

# nft delete chain [<family>] <table> <nombre>

Por ejemplo:

# nft delete chain netdev ingress INGRESS

aunque no podrá borrarse hasta que no esté completamente vacía, lo cual puede hacerse borrando reglas una a una o de un tirón con:

# nft flush chain [<family>] <table> <nombre>