Tenho usado o iptables-save
comando recentemente (combinado com iptables-restore
) e notei um comportamento inconsistente que não entendo. Tenho certeza de que não é um bug, pois é um comando muito popular para ter passado despercebido, o que significa que é meu próprio entendimento que está falho. Dei uma olhada nas páginas de manual e em várias fontes de documentação, mas não consegui encontrar nada que explicasse o que observei.
O problema é que quando executo o comando iptables-save
, espero ver a filter
tabela despejada no stdout (conforme a documentação). O que vejo de fato é absolutamente nada, por exemplo:
[root@rhel9 ~]# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@rhel9 ~]#
...
[root@rhel9 ~]# iptables-save
[root@rhel9 ~]#
Como você pode ver, não há saída para nada stdout
do comando. Da mesma forma, se eu executar o comando e tentar redirecionar a saída ou passar a -f <output file>
opção, a saída ainda estará em branco.
Se eu especificar a tabela que desejo visualizar, obtenho uma saída, por exemplo:
[root@rhel9 ~]# iptables-save -t filter
# Generated by iptables-save v1.8.8 (nf_tables) on Wed Jan 8 16:43:11 2025
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Wed Jan 8 16:43:11 2025
Se eu salvar essa saída em um arquivo, digamos ipv4backup
, e então chamar iptables-restore
esse arquivo, o comportamento iptables-save
será diferente:
[root@rhel9 ~]# iptables-restore ipv4backup
[root@rhel9 ~]#
[root@rhel9 ~]# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@rhel9 ~]#
[root@rhel9 ~]# iptables-save
# Generated by iptables-save v1.8.8 (nf_tables) on Wed Jan 8 16:44:03 2025
*filter
:INPUT ACCEPT [5:305]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5:914]
COMMIT
# Completed on Wed Jan 8 16:44:03 2025
As tabelas contêm o mesmo conteúdo do exemplo acima, mas há um comportamento diferente dependendo iptables-save
se iptables-restore
foi chamado anteriormente.
Testei isso no RHEL9 e no Ubuntu 22.04 e ambos apresentam o mesmo comportamento. No SuSE 15, o comando foi executado e produziu saída de todas as tabelas, independentemente de iptables-restore
terem sido executadas anteriormente. Os ip6tables...
comandos equivalentes apresentam o mesmo comportamento.
Então, a questão é (com base no comportamento observado acima): por que iptables-save
não produz saída quando as tabelas estão vazias, mas se restaurarmos tabelas vazias e chamarmos o comando novamente, obtemos a saída esperada (que são tabelas vazias)?
É assim que eu entendo.
iptables-save consultará o Netfilter para ver quais tabelas existem e então também verificará o iptables /proc/net/ip_tables_names. Se ambos derem resultados vazios, então iptables-save não produzirá nada. Se houver nomes de tabela retornados, então iptables-save mostrará alguma saída, mesmo se as tabelas em si estiverem vazias.
Quando iptables-restore for executado da maneira que você descreve e com a entrada que você descreve, uma tabela de "filtro" será criada, mesmo que ela esteja vazia.
Pelo que entendi, o antigo framework iptables está obsoleto e foi substituído pelo Netfilter. Nesse caso, os comandos iptables estão, na verdade, usando o novo Netfilter no backgroud. Ou seja, seu /proc/net/ip_tables_names pode estar vazio o tempo todo. Supondo que esse seja o caso do seu sistema, você pode usar o comando:
para verificar quais tabelas existem explicitamente. Tente esse comando antes e depois de executar seu iptables-restore.
De acordo com a página de manual do nft, há substituições do Netfilter para os antigos iptables-save e iptables-restore: