Nftables, el sustituto de iptables

By | October 22, 2019

Una de las novedades que trae Debian Buster es nftables. Sustituye a iptables como framework de gestión de filtrado de paquetes, aunque tenemos la opción de seguir utilizando aún éste último si lo deseamos. No obstante, ya que de forma gradual se irá implantando nftables (en RHEL 8 también) resulta interesante irle echando un vistazo o directamente migrar nuestras reglas de iptables para acostumbrarnos al uso de la nueva herramienta.

Ya contaba con diversas reglas de iptables como las que podéis ver en mi repo. Podemos migrarlas fácilmente tal y como describen en la wiki de nftables, pero creo que es más interesante configurar un nuevo conjunto de reglas desde 0 en nftables directamente para coger práctica.

A la hora de crear los conjuntos de reglas debemos tener en cuenta una serie de premisas muy parecidas a las de iptables:

  • Organización de las reglas en tablas (tables) y sobre ellas se crean cadenas (chains) input, output y forward. En mi caso mis sistemas no actúan como enrutadores de paquetes por lo que no permito tráfico en la cadena forward.
  • Como en iptables, denegamos el tráfico de cada cadena por defecto y damos permisos de forma discreta posteriormente para cada unos de los servicios que queremos permitir.
  • Tendremos que guardar las reglas para que sean permanentes y se carguen al arrancar el sistema. Las reglas se guardan en /etc/nftables.conf.
  • El servicio de nftables debe estar levantado para que el conjunto de reglas se aplique al sistema ( systemctl start nftables && systemctl enable nftables )

Teniendo esto en cuenta podemos utilizar por ejemplo este conjunto de reglas para tráfico IPv4 en un equipo de usuario con Linux:

#!/usr/sbin/nft -f
#
# Author        :Julio Sanz
# Website       :www.elarraydejota.com
# Email         :juliojosesb@gmail.com
# Description   :nftables desktop ruleset for IPv4 network traffic
# Dependencies  :nftables
# License       :GPLv3
#


#
# VARIABLES
#

define lan_segment = 192.168.1.0/24
define dns_servers = { 208.67.222.222, 208.67.220.220 }


#
# MAIN
#

flush ruleset


# IPv4
table ip filter {
    chain INPUT {
        # Filter definition and Default Policy
        type filter hook input priority 0; policy drop;

        # Drop invalid connections
        ct state invalid drop

        # Allow loopback
        iifname lo accept

        # Accept established connections
        ct state { established,related } accept

        # Allow Steam
        udp dport 27015 accept
        tcp dport 27015 accept
        udp dport { 27031, 27036 } accept
        tcp dport { 27036, 27037 } accept

        # Allow LAN traffic
        ip saddr $lan_segment accept

        log prefix "nftables-INPUT-Dropped: "
    }

    chain FORWARD {
        # Filter definition and Default Policy
        type filter hook forward priority 0; policy drop;

        log prefix "nftables-FORWARD-Dropped: "
    }

    chain OUTPUT {
        # Filter definition and Default Policy
        type filter hook output priority 0; policy drop;

        # Allow loopback
        oifname lo accept

        # DNS
        ip daddr $dns_servers tcp dport 53 accept
        ip daddr $dns_servers udp dport 53 accept

        # SSH
        tcp dport 22 accept

        # HTTP, HTTPS
        tcp sport 1024-65535 tcp dport { 80, 443 } accept

        # SMTP
        tcp dport 587 accept

        # Steam
        udp dport 27000-27100 accept
        udp dport { 3478, 4379, 4380 } accept

        # LAN traffic
        ip daddr $lan_segment accept

        log prefix "nftables-OUTPUT-Dropped: "
    }
}

Y este otro conjunto de reglas también para tráfico IPv4 en un servidor:

#!/usr/sbin/nft -f
#
# Author        :Julio Sanz
# Website       :www.elarraydejota.com
# Email         :juliojosesb@gmail.com
# Description   :nftables server ruleset for IPv4 network traffic
# Dependencies  :nftables
# License       :GPLv3
#


#
# VARIABLES
#

define dns_servers = { 0.0.0.0, 8.8.8.8 }
define mail_server = "mail.example.com"
admin_servers = { 192.168.1., 192.168.2.2 }


#
# MAIN
#

flush ruleset


# IPv4
table ip filter {
    chain INPUT {
        # Filter definition and Default Policy
        type filter hook input priority 0; policy drop;

        # Drop invalid connections
        ct state invalid drop

        # Allow loopback
        iifname lo accept

        # Allow HTTP and HTTPS
        tcp dport { 80, 443 } accept

        # Allow SSH from Admin servers
        ip saddr $admin_servers tcp dport 22 accept

        log prefix "nftables-INPUT-Dropped: "
    }

    chain FORWARD {
        # Filter definition and Default Policy
        type filter hook forward priority 0; policy drop;

        log prefix "nftables-FORWARD-Dropped: "
    }

    chain OUTPUT {
        # Filter definition and Default Policy
        type filter hook output priority 0; policy drop;

        # Accept loopback
        oifname lo accept

        # Accept established connections
        ct state { established,related } accept

        # DNS
        ip daddr $dns_servers tcp dport 53 accept
        ip daddr $dns_servers udp dport 53 accept

        # Allow SMTP
        ip daddr $mail_server tcp dport 587 accept

        log prefix "nftables-OUTPUT-Dropped: "
    }
}

Podemos guardar estas reglas en un script, darles permisos de ejecución y ejecutarlo para cargarlas en sistema. Podemos comprobar las reglas aplicadas ejecutando nft list ruleset. Para que los cambios sean permanentes debemos guardarlas en /etc/nftables:

nft list ruleset > /etc/nftables.conf

Recordad que el servicio de nftables debe estar arrancado como comentaba al principio:

[root@jota-node1 system]# systemctl status nftables.service 
● nftables.service - nftables
   Loaded: loaded (/lib/systemd/system/nftables.service; enabled; vendor preset: enabled)
   Active: active (exited) since Sep 2019-09-17 22:30:11 CEST; 33s ago
     Docs: man:nft(8)
           http://wiki.nftables.org
  Process: 13494 ExecStart=/usr/sbin/nft -f /etc/nftables.conf (code=exited, status=0/SUCCESS)
 Main PID: 13494 (code=exited, status=0/SUCCESS)

Sep 17 22:30:11 jota-node1 systemd[1]: Starting nftables...
Sep 17 22:30:11 jota-node1 systemd[1]: Started nftables.

Todo esto lo he subido al repo My Tux y lo iré actualizando allí. Son sólo un ejemplo más, plantillas que se pueden modificar según las necesidades de cada uno 😉