Reglas de nftables para endurecer la instalación de Discourse

Gracias @OrkoGrayskull !

¿Hay alguna novedad sobre esto ahora que /etc/docker/daemon.json puede tener firewall-backend establecido en nftables y supongo que ahora estás ejecutando Debian Trixie o Bookworm (estoy experimentando con esto)…

He descubierto que en /etc/sysctl.conf es necesario establecer net.ipv4.ip_forward=1.

La documentación de Docker con nftables dice:

No modifique las tablas de Docker directamente, ya que es probable que las modificaciones se pierdan; Docker espera tener la propiedad total de sus tablas.

Así que espero no tener que tocar las reglas de Docker…

Esto es lo que tengo actualmente, algunas reglas que he añadido a través de Ansible (este servidor tiene reenvío SMTP de Postfix a Discourse, por eso se necesita el puerto 25):

table inet ansible_firewall {
        chain inbound_ipv4 {
                icmp type echo-request limit rate 5/second accept comment "Aceptar pings ICMP con límite de tasa IPv4"
        }

        chain inbound_ipv6 {
                icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept comment "Aceptar descubrimiento de vecinos IPv6"
                icmpv6 type echo-request limit rate 5/second accept comment "Aceptar pings ICMP con límite de tasa IPv6"
        }

        chain inbound {
                type filter hook input priority filter; policy drop;
                ct state vmap { invalid : drop, established : accept, related : accept } comment "Permitir tráfico de paquetes establecidos y relacionados, descartar inválidos"
                iifname "lo" accept comment "Permitir tráfico de bucle invertido"
                meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } comment "Saltar a la cadena según el protocolo de capa 3 usando un mapa de veredictos"
                tcp dport 22 accept comment "Permitir SSH en el puerto TCP/22"
                tcp dport { 80, 443 } accept comment "Permitir HTTP en el puerto TCP/80 y HTTPS en el puerto TCP/443"
        }

        chain forward {
                type filter hook forward priority filter; policy drop;
        }

        chain output {
                type filter hook output priority filter; policy accept;
                oifname "lo" accept comment "Permitir salida desde la interfaz de bucle invertido"
        }
}

Y las reglas de Docker / Discourse (nota: este servidor no tiene una dirección IPv6):

table ip docker-bridges {
        map filter-forward-in-jumps {
                type ifname : verdict
                elements = { "docker0" : jump filter-forward-in__docker0 }
        }

        map filter-forward-out-jumps {
                type ifname : verdict
                elements = { "docker0" : jump filter-forward-out__docker0 }
        }

        map nat-postrouting-in-jumps {
                type ifname : verdict
                elements = { "docker0" : jump nat-postrouting-in__docker0 }
        }

        map nat-postrouting-out-jumps {
                type ifname : verdict
                elements = { "docker0" : jump nat-postrouting-out__docker0 }
        }

        chain filter-FORWARD {
                type filter hook forward priority filter; policy accept;
                oifname vmap @filter-forward-in-jumps
                iifname vmap @filter-forward-out-jumps
        }

        chain nat-OUTPUT {
                type nat hook output priority -100; policy accept;
                ip daddr != 127.0.0.0/8 fib daddr type local counter jump nat-prerouting-and-output
        }

        chain nat-POSTROUTING {
                type nat hook postrouting priority srcnat; policy accept;
                iifname vmap @nat-postrouting-out-jumps
                oifname vmap @nat-postrouting-in-jumps
        }

        chain nat-PREROUTING {
                type nat hook prerouting priority dstnat; policy accept;
                fib daddr type local counter jump nat-prerouting-and-output
        }

        chain nat-prerouting-and-output {
                iifname != "docker0" tcp dport 80 counter dnat to 172.17.0.2:80 comment "DNAT"
                iifname != "docker0" tcp dport 443 counter dnat to 172.17.0.2:443 comment "DNAT"
        }

        chain raw-PREROUTING {
                type filter hook prerouting priority raw; policy accept;
                ip daddr 172.17.0.2 iifname != "docker0" counter drop comment "DROP DIRECT ACCESS"
        }

        chain filter-forward-in__docker0 {
                ct state established,related counter accept
                iifname "docker0" counter accept comment "ICC"
                ip daddr 172.17.0.2 tcp dport 80 counter accept
                ip daddr 172.17.0.2 tcp dport 443 counter accept
                counter drop comment "UNPUBLISHED PORT DROP"
        }

        chain filter-forward-out__docker0 {
                ct state established,related counter accept
                counter accept comment "OUTGOING"
        }

        chain nat-postrouting-in__docker0 {
        }

        chain nat-postrouting-out__docker0 {
                oifname != "docker0" ip saddr 172.17.0.0/16 counter masquerade comment "MASQUERADE"
        }
}
table ip6 docker-bridges {
        map filter-forward-in-jumps {
                type ifname : verdict
        }

        map filter-forward-out-jumps {
                type ifname : verdict
        }

        map nat-postrouting-in-jumps {
                type ifname : verdict
        }

        map nat-postrouting-out-jumps {
                type ifname : verdict
        }

        chain filter-FORWARD {
                type filter hook forward priority filter; policy accept;
                oifname vmap @filter-forward-in-jumps
                iifname vmap @filter-forward-out-jumps
        }

        chain nat-OUTPUT {
                type nat hook output priority -100; policy accept;
                ip6 daddr != ::1 fib daddr type local counter jump nat-prerouting-and-output
        }

        chain nat-POSTROUTING {
                type nat hook postrouting priority srcnat; policy accept;
                iifname vmap @nat-postrouting-out-jumps
                oifname vmap @nat-postrouting-in-jumps
        }

        chain nat-PREROUTING {
                type nat hook prerouting priority dstnat; policy accept;
                fib daddr type local counter jump nat-prerouting-and-output
        }

        chain nat-prerouting-and-output {
        }

        chain raw-PREROUTING {
                type filter hook prerouting priority raw; policy accept;
        }
}

Y todo, excepto los puertos 80 y 443, parece estar bien… :roll_eyes: