RHEL / CentOS ¿Ahora para agregar reglas nftable a firewalld en el arranque del sistema?

Dec 15 2020

Estoy usando firewalld en RHEL 8 y también necesito agregar algunas reglas nftable.

(Las reglas nftable se basan en la respuesta a CentOS 8 como enrutador NAT con nft y firewalld: ¿cómo hacer que pase TFTP? )

En un firewall en ejecución, esto funciona bien con el comando nft -f.

Sin embargo, esto se pierde al reiniciar.

La documentación de RedHat (detrás de paywall) sugiere usar el servicio nftables.service para cargar reglas al reiniciar, pero esto no funciona junto con firewalld. Los dos servicios se enumeran como en conflicto, e incluso si no lo estuvieran, firewalld probablemente eliminaría las reglas nftables.

¿Hay otra forma de hacer que las reglas nftable se carguen al reiniciar?

Respuestas

2 A.B Dec 15 2020 at 18:45

La utilidad firewalld , cuando usa el backend nftables , no vaciará las tablas que no le pertenecen :

Solo elimina las reglas de Firewalld

Dado que nftables permite espacios de nombres (a través de tablas), firewalld ya no realiza una limpieza completa de las reglas del firewall . Solo arrojará reglas en la mesa de Firewall . Esto evita situaciones en las que las reglas de usuario personalizadas o las reglas instaladas por otras herramientas se borran inesperadamente cuando se reinicia o se vuelve a cargar firewalld.

Lo mismo debe hacerse cuando se administran otras tablas.

En realidad, en la respuesta anterior, ya está hecho: los nftables reglas idempotently elimina solamente su propia tabla: handletftp.

Lamentablemente, ese no es el caso nftables.servicede la acción de parada :

ExecStop=/sbin/nft flush ruleset

Uno solo debe asegurarse de que la parte de detención del servicio systemd no elimine directamente todas las reglas mientras sigue haciendo el trabajo. Este trabajo se delegará en reglas nftables dedicadas para la acción de detención .

Así que aquí hay un método práctico: duplicar (por ejemplo systemctl cat nftables.services:) y modificar nftables.serviceen una versión instanciada [email protected]para colocarla /etc/systemd/system/[email protected]:

[Unit]
Description=Idempotent nftables rules for %I
Wants=network-pre.target
Before=network-pre.target

[Service]
Type=oneshot
ProtectSystem=full
ProtectHome=true
ExecStart=/sbin/nft -f /etc/nftables/idempotent/%I.nft
# As the rules are idempotent, ExecReload is same as ExecStart
ExecReload=/sbin/nft -f /etc/nftables/idempotent/%I.nft
# The stop rules should only have the first boilerplate parts
ExecStop=/sbin/nft -f /etc/nftables/idempotent/stop-%I.nft
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Cree el directorio de configuración dedicado utilizado anteriormente:

mkdir -p /etc/nftables/idempotent

Coloque reglas que para cada tabla definida, siempre comiencen así, por lo que cargar las reglas es independiente de otras tablas e idempotente (ejemplo con tablas ip fooy bridge bar):

table ip foo
delete table ip foo

table bridge bar
delete table bridge bar

table ip foo {
    ...
}

table bridge bar {
    ....
}

o simplemente use una tabla por archivo. La flush rulesetdeclaración está prohibida porque es global.

La razón por la que se crea, elimina y recrea una tabla es para obtener el resultado idempotente: mientras que eliminar una tabla que no existe es un error y haría fallar atómicamente toda la carga, declarando una tabla existente sin definirla (agregando una tabla vacía) nunca falla y no hace nada excepto crearlo vacío si no existía antes. En ambos casos (no existía en el arranque, existe en la recarga), eliminar ahora puede funcionar, dejando el lugar para definir realmente la tabla inmediatamente después. Todo esto está sucediendo en la misma transacción y sigue siendo atómico: ningún paquete será evaluado con una tabla ip foo faltante si existió antes durante esto.

Prepare una versión de detención de lo anterior que solo se eliminará (aquí las declaraciones vacías no son estrictamente necesarias y podrían eliminarse si solo hubiera una tabla, pero deben mantenerse si hay más de una tabla: la falla es para toda la transacción):

table ip foo
delete table ip foo

table bridge bar
delete table bridge bar

y poner todo en su ubicación:

/etc/nftables/idempotent/foobar.nft
/etc/nftables/idempotent/stop-foobar.nft

Esto ahora se puede activar con:

systemctl enable --now local-idempotent-nft@foobar

Ejemplo de la pregunta del OP anterior:

en /etc/nftables/idempotent/handletftp.nft:

table ip handletftp
delete table ip handletftp

table ip handletftp {
    ct helper helper-tftp {
        type "tftp" protocol udp
    }

    chain sethelper {
        type filter hook forward priority 0; policy accept;
        ip saddr 192.168.1.0/24 ip daddr 10.0.10.10 udp dport 69 ct helper set "helper-tftp"
    }
}

En /etc/nftables/idempotent/stop-handletftp.nft

table ip handletftp
delete table ip handletftp

Habilitarlo e iniciarlo:

systemctl enable --now local-idempotent-nft@handletftp

Detenerlo:

systemctl stop local-idempotent-nft@handletftp

lo que dejará las reglas de firewalld en su lugar. Del mismo modo, detener o reiniciar Firewalld dejará estas reglas en su lugar.

Probablemente haya mejoras por hacer:

  • nftables tiene una declaración de inclusión que podría usarse de alguna manera para evitar la duplicación del texto estándar.
  • el ejemplo específico sobre TFTP se basa en la carga del nf_nat_tftpque no se hará automáticamente (al contrario de lo nf_conntrack_tftpque se carga automáticamente desde la referencia en las reglas o al contrario de firewalld que se cargaría nf_nat_tftpexplícitamente). Por lo tanto, se deben tener en cuenta las configuraciones relacionadas pero no estrictamente nftables (esta configuración podría simplemente colocarse /etc/modules-load.d/).