O assunto de hoje é sobre firewall |
Hoje vou falar sobre o nftables. Um sistema de firewall para Linux que pretende substituir o atual iptables, ip6tables e qualquer outro tables que trabalha com as regras de permissão de acesso e encaminhamento de pacotes. Por ser tudo reunido em um único aplicativo ele tem a vantagem de evitar a duplicação de códigos e qualquer outro problemas em que ocorre em um dos apps em separado.
O pior é que vivi esta parte da pior maneira quando compilei o kernel 4.14 da primeira vez. Na verdade demorou alguns dias já que não notei falhas de rede até que tentei acessar algo, da rede interna, exclusivamente em ipv6. A conexão não ia de maneira alguma, mesmo com todas as regras do ip6tables corretas. Voltando para o kernel 4.13 a conexão ipv6 normalizou.
A regra que deu problema foi essa:
ip6tables -t nat -A POSTROUTING -s fd08:7d11:7db1:1ecb::/64 -j MASQUERADE
Ou seja. Tirando a máquina principal, que é roteadora e o ipv6 funciona de qualquer maneira. Qualquer dispositivo, na rede interna, tem conexão ipv6 normal no kernel 4.13. Mas falha quando utiliza o kernel 4.14. O ipv4 roda normal em todas as situações.
Não entendi nada. Funciona em um e não em outro. |
Então foram feitos vários testes com o kernel 4.14 tanto em Debian, quanto em Ubuntu e no CentOS. O resultado foi o mesmo e o ip6tables não encaminhava nenhum pacote para fora.
Então resolvi fazer um teste com um nftables com o kernel 4.14 e ver como se comportava. Fui ver como adiciona uma regra parecida com aquela acima e cheguei no seguinte:
table ip6 nat {
chain prerouting {
type nat hook prerouting priority 0;
}
chain postrouting {
type nat hook postrouting priority 0;
oifname "ens33" masquerade
}
}
Coloquei a regra em um arquivo do tipo teste.firewall e rodei o seguinte comando.
nft -f teste.firewall
Esse comando carrega as regras contidas nos arquivos. Fui fazer um teste e... funcionou.
Até que enfim deu certo. Então o erro é em algo no ip6tables que ainda não foi identificado. Mas já que a tendência é do iptables se juntar ao antigo ipchans como 'deprecated' nos próximos anos. Então vamos pegar as regras atuais e repassar para o nftables.
Mas como migrar tudo que é feito em iptables/ip6tables para nftables???
Por sorte os desenvolvedores criaram duas maneiras de migrar as regras de um para outro. Um deles é pelo uso do iptables-nftables-compat, aonde não muda as regras atuais e deixa o nftables fazer as coisas, nos bastidores. Mas o melhor é aprender os novos comandos. Por isso foi utilizado ip(6)tables-translate, que pega as antigas regras do iptables e mostra qual o comando equivalente para o nftables.
Depois de rodar o comando em quase todas as regras (depois explico o porquê). Chegou a hora de mudar as regras locais.
A regra do nat é mais fácil já que precisa repetir apenas o a regra, no mesmo arquivo só que muda o ip6 para ip, para uso do ipv4 e colocar para carregar quando rodar o nft -f teste.firewall
As demais regras tem umas pegadinhas:
Antes de rodar qualquer comando é necessário adicionar, no inicio de cada arquivo de firewall, os seguintes comandos:
nft add table ip filter
nft add chain ip filter INPUT { type filter hook input priority 0\; policy accept\; }
nft add chain ip filter FORWARD { type filter hook forward priority 0\; policy accept\; }
nft add chain ip filter OUTPUT { type filter hook output priority 0\; policy accept\; }
nft add table ip6 filter
nft add chain ip6 filter INPUT { type filter hook input priority 0\; policy accept\; }
nft add chain ip6 filter FORWARD { type filter hook forward priority 0\; policy accept\; }
nft add chain ip6 filter OUTPUT { type filter hook output priority 0\; policy accept\; }
chain prerouting {
type nat hook prerouting priority 0;
}
chain postrouting {
type nat hook postrouting priority 0;
oifname "ens33" masquerade
}
}
Coloquei a regra em um arquivo do tipo teste.firewall e rodei o seguinte comando.
nft -f teste.firewall
Esse comando carrega as regras contidas nos arquivos. Fui fazer um teste e... funcionou.
Até que enfim deu certo. Então o erro é em algo no ip6tables que ainda não foi identificado. Mas já que a tendência é do iptables se juntar ao antigo ipchans como 'deprecated' nos próximos anos. Então vamos pegar as regras atuais e repassar para o nftables.
Mas como migrar tudo que é feito em iptables/ip6tables para nftables???
Por sorte os desenvolvedores criaram duas maneiras de migrar as regras de um para outro. Um deles é pelo uso do iptables-nftables-compat, aonde não muda as regras atuais e deixa o nftables fazer as coisas, nos bastidores. Mas o melhor é aprender os novos comandos. Por isso foi utilizado ip(6)tables-translate, que pega as antigas regras do iptables e mostra qual o comando equivalente para o nftables.
Depois de rodar o comando em quase todas as regras (depois explico o porquê). Chegou a hora de mudar as regras locais.
A regra do nat é mais fácil já que precisa repetir apenas o a regra, no mesmo arquivo só que muda o ip6 para ip, para uso do ipv4 e colocar para carregar quando rodar o nft -f teste.firewall
As demais regras tem umas pegadinhas:
Antes de rodar qualquer comando é necessário adicionar, no inicio de cada arquivo de firewall, os seguintes comandos:
nft add table ip filter
nft add chain ip filter INPUT { type filter hook input priority 0\; policy accept\; }
nft add chain ip filter FORWARD { type filter hook forward priority 0\; policy accept\; }
nft add chain ip filter OUTPUT { type filter hook output priority 0\; policy accept\; }
nft add table ip6 filter
nft add chain ip6 filter INPUT { type filter hook input priority 0\; policy accept\; }
nft add chain ip6 filter FORWARD { type filter hook forward priority 0\; policy accept\; }
nft add chain ip6 filter OUTPUT { type filter hook output priority 0\; policy accept\; }
Detalhe para o \ antes do ; para evitar problemas na hora de executar via shell script.
Esses comandos criam as tables e chains necessárias para o uso das regras. Sem isso qualquer comando pode acarretar em erro.
Depois de criado, pode conferir através do comando 'nft list tables'
yoda:~# nft list tables
table ip6 filter
table ip6 nat
table ip filter
table ip nat
table ip6 filter
table ip6 nat
table ip filter
table ip nat
Agora é adcionar as regras.
Se, antes, foi utilizado a regra:
iptables -A INPUT -i ppp0 -p tcp --destination-port 700 -j REJECT
ele agora pode ser executado dessa maneira:
nft add rule ip filter INPUT iifname ppp0 tcp dport 700 counter reject
O mesmo vale para o ipv6 já que só precisa alterar uma coisa no comando:
nft add rule ip6 filter INPUT iifname ppp0 tcp dport 700 counter reject
O resto pode ser feito em todos os comandos... Não exatamente...
Apenas um comando no iptables e um comando em ip6tables não dá para ser migrado, por enquanto.
Esse comando é o:
iptables -t mangle -o ppp0 --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN
-m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu
-m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu
E o seu equivalente no ip6tables.
Justamente o comando que regula o tamanho do mtu para evitar problemas no envio de alguns pacotes um pouco grandes em conexões ppp. Até hoje ele ainda está no TODO do projeto.
nftables frontend
-----------------
- Define lexical distinction between keywords, symbolic constants and
identifiers
- Define syntax for changing data (connmark, meta etc.)
- payload syntax for matching on IP headers of IPIP/GRE tunnels etc.
- netlink monitor for CLI
Kernel
------
- netlink set API
- kernel set implementation selection
- TC hookup - use dummy classifier or hook "natively" ?
- kill mangle table, make rerouting a configurable table/chain property
- kill nat table? harder because of more special handling
- multi-family tables
- IPv6 ext header matching
- IP style options (IP/TCP/DCCP) matching
- IPsec policy matching
- hashlimit
- quota
- recent(?)
- TCPMSS target - generic packet editor?
- include NLM_F_ ... flags in notifications?
A solução, neste caso, é manter os antigos comandos, sendo os dois últimos remanescentes do antigo ip(6)tables até que os desenvolvedores criem um comando equivalente.
Com isso a rede interna volta a usar tanto o ipv4, quanto o ipv6. Mas, caso precisem saber como anda as regras, pode usar os seguintes comandos:
nft list tables - Exibe os nomes das tabelas criadas
nft list table ip6 nat - Exibe os códigos utilizados na tabela nat do ipv6. Para ipv4 troque ip6 por ip.
nft list ruleset - Exibe o código completo utilizado no nftables tanto no ipv4 quanto no ipv6.
Mais detalhes:
Tenham uma boa semana.
uma possível tradução do TCPMSS é:
ResponderExcluirnft add rule ip filter FORWARD oifname ppp0 tcp flags \& syn\|rst == syn tcp option maxseg size set rt mtu counter
Disponível em nftables 0.8 e kernel 4.14 :)
Pode ser uma boa opção. Depois vou fazer uns testes para ver se funciona. Valeu! :)
ResponderExcluir