Depois de alguns meses ausente (envolvido em outros projetos e por falta de tempo), resolvi tratar um assunto que julgo importante, tenho visto muita discussão e também para deixar documentado – assim, eu mesmo não “patinarei” conforme atualizar o kernel de alguns firewalls (risos).
Alguns protocolos, como FTP e SIP, apresentam uma implementação um pouco mais complexa, separando o fluxo de controle do fluxo de dados.
No caso do protocolo FTP, por exemplo, a primeira conexão, na porta TCP/21 (ftp-control), é utilizada para fins de controle (comandos para o servidor). No entanto, para a troca de dados (ftp-data), na listagem de conteúdo (ls) ou transferência de arquivos (put ou get), o servidor negocia novos sockets dinamicamente para este propósito. Para complicar um pouco mais, o ftp-data ainda pode operar em modo ativo ou passivo.
No modo ativo, a conexão ftp-data é entrante – ou seja, do servidor para os clientes. Neste caso, o servidor conectará aos clientes e utilizará o socket tcp/20 como porta de ORIGEM. Em termos de firewall, fica simples tratar o fluxo porque a porta de origem será sempre a tcp/20. Mas, por ser uma conexão entrante, costuma ser evitado.
Imagem extraída de https://pplware.sapo.pt/
Outra alternativa para o ftp-data é a utilização do modo passivo. Neste caso, a conexão se torna passante – ou seja, do servidor aos clientes (fluxo de saída). Por um lado é considerado mais seguro, mas, por outro, impõe uma dificuldade maior porque trabalha com uma alocação de portas dinamicamente (não privilegiadas).
Imagem extraída de https://pplware.sapo.pt/
É possível tratar estes fluxos manualmente, porém, além de ineficiente, é fácil perceber que será inseguro:
– Modo ATIVO
iptables -A FORWARD -s $client -p tcp --dport 21 --syn -j ACCEPT iptables -A FORWARD -d $client -p tcp --sport 20 -j ACCEPT– MODO PASSIVO
iptables -A FORWARD -s $client -p tcp --dport 21 --syn -j ACCEPT iptables -A FORWARD -s $client -p tcp --dport 1024: -j ACCEPT
“No primeiro caso, teríamos que permitir qualquer conexão entrante (limitada apenas pela porta), pois seria inviável tratar cada servidor na Internet. Logo, qualquer conexão com porta de origem tcp/20 estaria autorizada. Por outro lado, no modo passivo, com a abertura de todas as portas não privilegiadas, o acesso liberado extrapola uma “simples” conexão de FTP. Pois é, não é uma questão muito simples, mas o conntrack controla todas estas questões de forma automática (podemos interferir)!“
Se conceitualmente parece complexo, imagine a implementação interna! 😉
É aí que entra o papel dos helpers…
Para lidar com esta situação, o netfilter provê uma infraestrutura modular conhecida como Connection Tracking helpers, oferecendo toda assistência necessária para o mapeamento destes protocolos. O tratamento das conexões secundárias (reincidentes) é feito através de uma tabela separada conhecida como expected (para lidar com o “tráfego esperado”) e mantido em memória por um intervalo de tempo.
Além de melhorar a eficiência e a facilidade de configuração, alguns helpers oferecem um nível segurança superior porque são capazes de “prever” os envolvidos na conexão (tanto origem como destino). No caso do FTP, por exemplo, o sistema deverá prever quais serão as conexões esperadas para cada comando da sessão de controle (tcp/21).
É claro que alguns helpers podem ser “menos seguros”.
Confiram os principais módulos disponíveis, bem como seu funcionamento:
– Podemos listar os módulos suportados pelo kernel com o comando:
for i in $(find /lib/modules/$(uname -r) -name ??_nat_* -print | grep -i netfilter | \ sed 's/.*\///' | sed 's/\..*\.gz$//; s/\.ko$//'); do echo $i ; donePor exemplo:
root@firewall:~# for i in $(find /lib/modules/$(uname -r) -name ??_nat_* -print | grep -i netfilter | sed 's/.*\///' | sed 's/\..*\.gz$//; s/\.ko$//'); do echo $i ; done nf_nat_snmp_basic nf_nat_pptp nf_nat_h323 nf_nat_ipv4 nf_nat_proto_gre nf_nat_proto_sctp nf_nat_irc nf_nat_proto_udplite nf_nat_proto_dccp nf_nat_amanda nf_nat_sip nf_nat_ftp nf_nat_tftp nf_nat_ipv6 root@firewall:~#
– É possível confirmar quais módulos estão carregados com o comando:
lsmod | grep "_conntrack_\|_nat_"
Na filtragem de pacotes, o netfilter identificará as conexões esperadas (reincidentes) através do estado RELATED. É por esta razão que é comum utilizar regras como esta:
– modo prestes a se tornar depreciado:
... iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT– ou (padrão atual e recomendado):
... iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Para o fluxo principal (conexão única), o conntrack realiza perfeitamente o mapeamento das conexões na Tabela de Estados – algo que ocorrerá com o fluxo de ftp-control. Estas conexões são facilmente identificadas e mapeadas como NEW (na primeira ocorrência) e ESTABLISHED (na confirmação de resposta).
“Graças aos helpers é possível tratar apenas as conexões de controle e deixar que o netfilter cuide do tráfego esperado em seguida.“
É por esta razão que o tráfego de ftp pode ser autorizado com simples regras, como:
... iptables -A FORWARD -s $client -o $ifnet-p udp --dport 53 -j ACCEPT iptables -A FORWARD -s $client -o $ifnet -p tcp --dport 21 -j ACCEPT iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Na Tabela de Estados, o “retorno” será mapeado como ESTABLISHED e as “conexões esperadas” como RELATED. Portanto, o administrador não precisa tratar o ftp-data manualmente. É evidente que o funcionamento depende da presença dos módulos nf_conntrack_ftp e nf_nat_ftp.
Caso os módulos não estejam em memória, carregue com o comand modprobe.
modprobe nf_nat_ftp
“Não, eu não esqueci do módulo conntrack (risos). Ao carregar o módulo nf_nat_ftp, o sistema carregará nf_conntrack_ftp como dependência automática.“
Até aqui, talvez vocês não vejam muita novidade…
Porém, a partir do kernel 4.7 alguns critérios de segurança foram adotados.
Em versṍes anteriores, bastava requisitar acesso a porta tcp/21 (por exemplo) para o helper entrar em ação automaticamente.
O problema é que isto se aplica a qualquer módulo em memória (algo que costuma ser feito em diferentes scripts de firewall) – o mesmo ocorrerá com o SIP ao receber conexão na porta udp/5060, por exemplo. Logo, o processamento automático do helper passou a ser encarado como uma fragilidade passível de ser explorada (abrindo portas de forma indevida).
Já faz algum tempo que o kernel disponibiliza um arquivo de controle (em /proc) para desabilitar o processamento automático do helper.
cat /proc/sys/net/netfilter/nf_conntrack_helper
Anteriormente, por padrão, o conteúdo de nf_conntrack_helper era “1“. A partir da versão de kernel 4.7, o valor padrão foi alterado para “0” – desabilitando o processamento automático.
Parece pouco, mas certamente lhe tomará um belo tempo caso você desconheça esta alteração e adote configuração de firewall como a demonstrada anteriormente (não funcionará). O objetivo, segundo os desenvolvedores, foi reforçar a segurança do sistema.
– A primeira alternativa é reativar o processamento automático (volta ao padrão anterior):
echo 1 > /proc/sys/net/netfilter/nf_conntrack_helper
– Outra alternativa, mais recomendada, é ativar o processamento manualmente:
iptables -t raw -A PREROUTING -p tcp --dport 21 -o $ifnet -j CT --helper ftp
“No exemplo anterior, é possível manter nf_conntrack_helper como ‘0’ e assegurar que o único helper processado será do protocolo FTP e na porta 21. A utilização do alvo CT pode ser útil para casos em que o servidor de FTP atende em outra porta (não padrão).“
Em ambientes corporativos o ideal é tratar cada helper manualmente, conforme demonstrado na regra com alvo CT.
Para navegação (saída de Internet), esta configuração é suficiente e segura.
Porém, caso o administrador disponibilize o acesso remoto aos servidores da rede, é possível reforçar os critérios de acesso para conexões mapeadas como RELATED.
iptables -t raw -A PREROUTING -p tcp --dport 2121 -d $server -j CT --helper ftp iptables -A FORWARD -m conntrack --ctstate RELATED -m helper --helper ftp \ -d $server -p tcp --dport 1024: -j ACCEPT
Assim podemos restringir a utilização do helper de acordo com a topologia da rede.
Espero que vocês gostem do artigo.
Até o próximo!
No Comments Yet