RHEL / CentOS Agora para adicionar regras nftable ao firewalld na inicialização do sistema?

Dec 15 2020

Estou usando o firewalld no RHEL 8 e preciso adicionar algumas regras nftable também.

(As regras nftable são baseadas na resposta ao CentOS 8 como roteador NAT com nft e firewalld - como fazê-lo passar TFTP? )

Em um firewall em execução, isso funciona bem com o comando nft -f.

No entanto, isso se perde na reinicialização.

A documentação do RedHat (por trás do acesso pago) sugere o uso do serviço nftables.service para carregar regras na reinicialização, mas isso não funciona em conjunto com o firewalld. Os dois serviços são listados como conflitantes e, mesmo se não fossem, o firewalld provavelmente eliminaria as regras nftable.

Existe outra maneira de fazer com que as regras nftable carreguem na reinicialização?

Respostas

2 A.B Dec 15 2020 at 18:45

O utilitário firewalld , ao usar o back-end nftables , não irá liberar tabelas que não pertencem a ele :

Limpe apenas as regras do Firewalld

Como o nftables permite namespaces (por meio de tabelas), o firewalld não libera mais as regras de firewall . Isso apenas irá liberar regras na tabela firewalld . Isso evita cenários em que regras de usuário personalizadas ou regras instaladas por outras ferramentas são eliminadas inesperadamente quando o firewalld foi reiniciado ou recarregado.

O mesmo deve ser feito ao gerenciar outras tabelas.

Na verdade na resposta anterior, ele já está feito: os nftables governa idempotently exclui única sua própria mesa: handletftp.

Infelizmente, esse não é o caso nftables.servicepara a ação de interrupção :

ExecStop=/sbin/nft flush ruleset

Deve-se apenas garantir que a parte de parada do serviço systemd não libere diretamente todas as regras enquanto ainda está fazendo o trabalho. Este trabalho será delegado em regras nftables dedicadas para a ação de parada .

Portanto, aqui está um método prático: duplicar (por exemplo systemctl cat nftables.services:) e alterar nftables.serviceem uma versão instanciada [email protected]para ser colocada em /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

Crie o diretório de configuração dedicado usado acima:

mkdir -p /etc/nftables/idempotent

Coloque regras que para cada tabela definida, sempre iniciem assim, então o carregamento das regras é independente das outras tabelas e idempotente (exemplo com tabelas ip fooe bridge bar):

table ip foo
delete table ip foo

table bridge bar
delete table bridge bar

table ip foo {
    ...
}

table bridge bar {
    ....
}

ou apenas use uma tabela por arquivo. A flush rulesetdeclaração é proibida por ser global.

A razão pela qual uma tabela é criada, excluída e recriada é para obter o resultado idempotente: enquanto a exclusão de uma tabela não existente é um erro e faria atomicamente toda a falha de carregamento, declarando uma tabela existente sem defini-la (adicionando uma tabela vazia) nunca falha e não faz nada exceto criá-lo vazio se não existisse antes. Em ambos os casos (não existia no boot, existe no reload) delete agora pode funcionar, deixando o lugar para realmente definir a tabela logo em seguida. Tudo isso está acontecendo na mesma transação e ainda é atômico: nenhum pacote será avaliado com uma tabela ip foo ausente se ela existia antes durante isso.

Prepare uma versão de parada de acima que apenas excluirá (aqui as declarações vazias não são estritamente necessárias e podem ser removidas se houver apenas uma tabela, mas devem ser mantidas se houver mais de uma tabela: a falha é para toda a transação):

table ip foo
delete table ip foo

table bridge bar
delete table bridge bar

e coloque tudo em seu local:

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

Isso agora pode ser ativado com:

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

Exemplo da pergunta do OP anterior:

em /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"
    }
}

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

table ip handletftp
delete table ip handletftp

Ativando e iniciando:

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

Parando:

systemctl stop local-idempotent-nft@handletftp

que deixará as regras do firewalld em vigor. Da mesma forma, interromper ou reiniciar o firewalld deixará essas regras em vigor.

Provavelmente, há melhorias a serem feitas:

  • nftables tem uma instrução de inclusão que pode ser usada de alguma forma para evitar a duplicação do clichê.
  • o exemplo específico sobre TFTP depende do carregamento do nf_nat_tftpqual não será feito automaticamente (ao contrário do nf_conntrack_tftpque é carregado automaticamente a partir da referência nas regras ou contrário ao firewalld que carregaria nf_nat_tftpexplicitamente). Portanto, configurações relacionadas, mas não estritamente nftables, devem ser mantidas em mente (esta configuração pode simplesmente ser inserida /etc/modules-load.d/).