Criando firewalls dinâmicos com Iptables Recent

Não seria interessante montar um firewall com regras dinâmicas que permitisse por exemplo, bloquear algum IP por ter tentado acessar o serviço de SSH mais de 3 vezes em menos de 1 minuto? Ou ainda criar alguma logística de batidas de porta e só assim permitir a entrada da conexão ao IP que acertou a combinação de portas!? Tudo isso e muito mais é possível com o módulo recent do Netfilter.

[ Hits: 33.500 ]

Por: Marcelo Moreira de Mello em 19/12/2009 | Blog: http://tchellomello.blogspot.com


Introdução



Não seria interessante montar um firewall com regras dinâmicas que permitisse por exemplo, bloquear algum IP por ter tentado acessar o serviço de SSH mais de 3 vezes em menos de 1 minuto? Ou ainda criar alguma logística de batidas de porta (é!!! igual ao famoso tãn tãn rãn rãn tãn... tãntãn) e só assim permitir a entrada da conexão ao IP que acertou a combinação de portas!? Tudo isso e muito mais é possível com o módulo recent do Netfilter.

Para começarmos, criei uma máquina virtual chamada guardiao.home onde iremos utilizar como cenário para demonstrar a utilização do módulo recent.

# hostname
guardiao.home
# ifconfig eth0 | grep "inet addr"
inet addr:192.168.122.97 Bcast:192.168.122.255 Mask:255.255.255.0

Objetivo: Permitir apenas 1 conexão via SSH no período de 2 minutos por origem.

Para iniciarmos, criaremos uma regra que permite tudo que for de entrada para a interface de loopback, uma segunda regra para permitir todas conexões estabelecidas ou originadas pela própria máquina guardiao.home, uma terceira que cria a cadeia chamada SSH para direcionarmos todas as conexões SSH e por fim a própria regra que irá direcionar as conexões SSH para a cadeia recém criada.

# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -N SSH
# iptables -A INPUT -p tcp --dport 22 -j SSH
# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source        destination        
ACCEPT     all  --  0.0.0.0/0     0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0     0.0.0.0/0      state RELATED,ESTABLISHED
SSH         tcp  --  0.0.0.0/0    0.0.0.0/0      tcp dpt:22
Chain FORWARD (policy ACCEPT)
target     prot opt source        destination         
Chain OUTPUT (policy ACCEPT)
target     prot opt source        destination        
Chain SSH (1 references)
target     prot opt source        destination        

Com o setup inicial do firewall pronto, podemos agora chamar o módulo recent para tornar nossas regras dinâmicas. Para facilitar o entendimento das próximas regras que iremos trabalhar, vejamos algumas opções do recent:
  • --name: seta o nome da lista que iremos trabalhar. Obs.: quando não informado, é utilizado DEFAULT;
  • --set: irá adicionar o endereço de origem do pacote na lista. Se o endereço já estiver na lista, então irá atualizar o registro;
  • --rcheck: verifica se o endereço de origem do pacote está atualmente na lista;
  • --update: verifica e atualiza o timestamp do campo "last seen" se o endereço de origem do pacote já estiver na lista;
  • --seconds: especifica se a regra terá validade somente se o endereço de origem do pacote estiver dentro do valor especificado;
  • --hitcount: verifica se o endereço de origem do pacote esta na lista e se o número de pacotes recebido desse endereço é igual ou maior do valor estipulado.

Com essas opções explicadas (para maiores informações man 8 iptables), podemos criar nossa primeira regra para cadastrar todas as tentativas de conexões via SSH para uma tabela que será criada pelo recent chamada de conexoes_ssh.

# iptables -A SSH -m recent --set --name conexoes_ssh
# iptables -L SSH -n

Chain SSH (1 references)
target     prot opt source        destination
           all  --  0.0.0.0/0     0.0.0.0/0      recent: SET name: conexoes_ssh side: source

Com a regra "iptables -A SSH -m recent --set --name conexoes_ssh" criamos a tabela conexoes_ssh que será alimentada com todas as conexões direcionadas para a cadeia SSH. O que precisamos fazer agora é permitir apenas 1 conexão no intervalo de 2 minutos por vez em nosso servidor. Para isso iremos usar os parâmetros --seconds 120 e --hitcount 2, pois queremos determinar 120 segundos e quando o contador for maior ou igual a 2.

# iptables -A SSH -m recent --name conexoes_ssh --update --seconds 120 --hitcount 2 -j REJECT
# iptables -vnL SSH
Chain SSH (1 references)
pkts bytes target     prot opt in     out     source               destination
    0     0            all  --  *      *       0.0.0.0/0            0.0.0.0/0           recent: SET name: conexoes_ssh side: source
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           recent: UPDATE seconds: 120 hit_count: 2 name: conexoes_ssh side: source reject-with icmp-port-unreachable

Após a execução da regra, nosso firewall já esta monitorando tentativas de conexão via SSH e irá permitir a primeira tentativa de cada IP de origem. Vejamos:

Máquina externa - primeira conexão:

date ; ssh root@guardiao
Wed Dec 9 01:34:11 BRST 2009
root@guardiao's password:
Last login: Wed Dec 9 01:30:24 2009 from 192.168.122.1

# iptables -nvL SSH
Chain SSH (1 references)
pkts bytes target     prot opt in     out     source               destination
    1    60            all  --  *      *       0.0.0.0/0            0.0.0.0/0           recent: SET name: conexoes_ssh side: source
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           recent: UPDATE seconds: 120 hit_count: 2 name: conexoes_ssh side: source reject-with icmp-port-unreachable
# cat /proc/net/xt_recent/conexoes_ssh
src=192.168.122.1 ttl: 64 last_seen: 6084651 oldest_pkt: 1 6084651

Máquina externa - segunda conexão:

date ; ssh root@guardiao
Wed Dec 9 01:34:45 BRST 2009
ssh: connect to host guardiao port 22: Connection refused

# iptables -nvL SSH
Chain SSH (1 references)
pkts bytes target     prot opt in     out     source               destination
    2   120            all  --  *      *       0.0.0.0/0            0.0.0.0/0           recent: SET name: conexoes_ssh side: source
    1    60 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           recent: UPDATE seconds: 120 hit_count: 2 name: conexoes_ssh side: source reject-with icmp-port-unreachable
# cat /proc/net/xt_recent/conexoes_ssh

src=192.168.122.1 ttl: 64 last_seen: 6119177 oldest_pkt: 3 6084651, 6119177, 6119177

Máquina externa - terceira conexão (depois de 3 minutos):

date ; ssh root@guardiao
Wed Dec 9 01:37:19 BRST 2009
root@guardiao's password:
Last login: Wed Dec 9 01:34:11 2009 from 192.168.122.1

Como podem perceber, o recent cria um arquivo dentro do diretório /proc/net/xt_recent chamado conexoes_ssh (que é o nome de nossa tabela) para controle das conexões. Se tivéssemos criado outras tabelas, também seriam criados outros arquivos respectivos. O interessante é que podemos manipular esses arquivos e consequentemente manipular as tabelas. Perceba também que a cada conexão que fizemos, o campo last seen foi modificado, informando para a regra que houve uma nova tentativa. Para manipularmos as tabelas podemos:
  • echo +192.168.122.15 > /proc/net/xt_recent/conexoes_ssh - para adicionarmos um endereço na tabela
  • echo -192.168.122.1 > /proc/net/xt_recent/conexoes_ssh - para removermos um endereço da tabela
  • echo / > /proc/net/xt_recent/conexoes_ssh - para limparmos a tabela

# cat /proc/net/xt_recent/conexoes_ssh
src=192.168.122.1 ttl: 64 last_seen: 6273353 oldest_pkt: 4 6084651, 6119177, 6119177, 6273353
# echo +192.168.122.15 > /proc/net/xt_recent/conexoes_ssh
# cat /proc/net/xt_recent/conexoes_ssh

src=192.168.122.1 ttl: 64 last_seen: 6273353 oldest_pkt: 4 6084651, 6119177, 6119177, 6273353
src=192.168.122.15 ttl: 0 last_seen: 6847221 oldest_pkt: 1 6847221
# echo -192.168.122.1 > /proc/net/xt_recent/conexoes_ssh
# cat /proc/net/xt_recent/conexoes_ssh

src=192.168.122.15 ttl: 0 last_seen: 6847221 oldest_pkt: 1 6847221
# echo /> /proc/net/xt_recent/conexoes_ssh
# cat /proc/net/xt_recent/conexoes_ssh


E finalizando, um ponto importante que precisa ser colocado é que se você for trabalhar com um firewall com grande número de conexões, por padrão o recent irá armazenar apenas 100 endereços nas tabelas criadas. Para alterar esse valor por exemplo para 1024, precisamos passar para o módulo xt_recent algumas flags:

# modinfo xt_recent
filename:       /lib/modules/2.6.29.4-167.fc11.i686.PAE/kernel/net/netfilter/xt_recent.ko
alias:          ip6t_recent
alias:          ipt_recent
license:        GPL
description:    Xtables: "recently-seen" host matching for IPv4
author:         Jan Engelhardt
author:         Patrick McHardy
srcversion:     0CA8710587603DFF5C5923B
depends:       
vermagic:       2.6.29.4-167.fc11.i686.PAE SMP mod_unload 686
parm:           ip_list_tot:number of IPs to remember per list (uint)
parm:           ip_pkt_list_tot:number of packets per IP to remember (max. 255) (uint)
parm:           ip_list_hash_size:size of hash table used to look up IPs (uint)
parm:           ip_list_perms:permissions on /proc/net/xt_recent/* files (uint)
parm:           ip_list_uid:owner of /proc/net/xt_recent/* files (uint)
parm:           ip_list_gid:owning group of /proc/net/xt_recent/* files (uint)

# echo "options xt_recent ip_list_tot=1024" ; /etc/modprobe.d/xt_recent.conf

Obs.: Não esqueça de descarregar o módulo e recarregá-lo para honrar as configurações.

Ah! Para finalizar não esqueça de salvar suas regras e ativar o serviço de firewall persistente ao reboot.

# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]

# chkconfig iptables on

Pretendo em outro post demonstrar como podemos criar algumas regras para que o iptables trabalhe com port knocking, assim permitindo que o serviço somente seja liberado se a sequência de portas estiver correta.

E agora vivente, prepara o teu chimarrão e a tua mateira e se arranca índio véio configurar o teu firewall tchê! :)

   

Páginas do artigo
   1. Introdução
Outros artigos deste autor

Transportando dados com segurança - encripte seu pendrive em 5 passos

Instalação automatizada de servidores com kickstart

Instalação automatizada de servidores com Kickstart (parte 2)

Leitura recomendada

Configurando firewall básico para compartilhar internet

Implementando prioridade nos serviços com TOS no Iptables

Firewall Linux - Roteamento avançado usando iproute2 e iptables (load balance)

L7-filter (funcionando) no Slackware 10.2

Conexões redundantes e com balanceamento de carga - Ubuntu 9.04

  
Comentários
[1] Comentário enviado por Win7User em 19/12/2009 - 14:36h

Bello topico Chello!
bem interessante este recurso do iptables ,no caso tem como limitar o tamanho "log" do historico ou nao?
abraços

[2] Comentário enviado por magnolinux em 19/12/2009 - 21:16h

Boa chello..

utilizo o modulo recent para fazer port knocking...

funciona muito bem...

Continue contribuindo com otimos artigos..

abraço...

[3] Comentário enviado por d3lf0 em 21/12/2009 - 10:07h

Grato pela contribuição, otimo artigo.
bem interessante mesmo.

[4] Comentário enviado por fmpfmp em 21/12/2009 - 10:45h

Na minha opinião a medida mais simples e eficiente que existe contra ataques de força bruta é a mudança de porta padrão. Ao invés de 22 dp ssh coloque outra alta, como 34834. Dificilmente alguém ou algum bot vai encontrá-la.

[5] Comentário enviado por elgio em 21/12/2009 - 11:01h

Muito bom artigo. Parabéns. Além de explicar o modulo Recent ainda entrou, de tabelinha, na parte de criação de chains.

Só tenho uma critica a fazer...

Aqui mesmo no VOL, muitos outros autores escreveram sobre Iptables. Um deles inclusive sobre Recent (http://www.vivaolinux.com.br/artigo/Iptables-+-modulo-recent/)

Eu entendo ser muito interessante (e podem discordar de mim) quando se escreve um assunto procurar no VOL quem já escreveu sobre ele antes e referenciar, citar estes outros artigos. Valoriza o trabalho dos outros colaboradores do Viva o Linux.

Mas claro, isto é uma opinião minha, uma dica.

No mais, gostei muito mesmo do artigo. Entrou para meus (poucos) favoritos.

[]'s

[6] Comentário enviado por fernandoborges em 22/12/2009 - 17:43h

Muito bom o artigo. Parabéns.

[7] Comentário enviado por marcrock em 25/12/2009 - 13:37h

Realmente é um ótimo artigo. Parabéns!!!

[8] Comentário enviado por claudiotecnico em 27/12/2009 - 00:03h

Parabéns ao autor pelo artigo.

Acho que deveria ter sido explicado:

- Qual distro e versão do Linux está sendo usada?
- Qual o procedimento básico para instalação do módulo recent (ele foi instalado pelo gerenciador de pacotes da distro ou foi preciso baixar e compilar)?
- Onde baixar?
- Em quais locais posso obter mais informações e documentação sobre o módulo em questão?

No mais o artigo está perfeito.

Abraços,

Claudio

[9] Comentário enviado por tchello.mello em 27/12/2009 - 08:43h

Olá Claudio,

Obrigado pela comentário e respondendo suas perguntas:

- Qual distro e versão do Linux está sendo usada?
Fedora 12
- Qual o procedimento básico para instalação do módulo recent (ele foi instalado pelo gerenciador de pacotes da distro ou foi preciso baixar e compilar)?
Foi instalado diretamento com yum. O próprio iptables já estava com o suporte.

- Onde baixar?
http://netfilter.org/projects/iptables/downloads.html">http://netfilter.org/projects/iptables/downloads.html

- Em quais locais posso obter mais informações e documentação sobre o módulo em questão?
http://netfilter.org/projects/iptables

Grande abraço.


[10] Comentário enviado por danielrsj em 29/12/2009 - 11:37h

dá pra bloquear o ultrasurf (porta 443) com esse módulo?
Alguém já tentou?

[11] Comentário enviado por marcusburghardt em 06/01/2010 - 10:57h

Bom dia!

Legal seu artigo. Dei uma palestra sobre essa e mais algumas técnicas de Segurança em Firewalls no FISL 10.
Era um assunto bem interessante e pouco explorado no iptables.

Abraço!

[12] Comentário enviado por removido em 17/03/2010 - 14:00h

Show em Marcelo!

[]'s

[13] Comentário enviado por capitainkurn em 01/04/2010 - 17:02h

Ótimo artigo! Já está nos favoritos.

[14] Comentário enviado por removido em 03/11/2010 - 13:26h

Marcelão, muito bom o artigo!
Agora que tu tá com mais tempo, continue contribuindo... heheheh

Poderia ainda melhorar a segurança do Forewall utilizando outras técnicas e ferramentas, por exemplo o fail2ban.

Abração

Bruno Lima®
Brasília-DF-Brasil

[15] Comentário enviado por removido em 04/01/2011 - 10:52h

Otimo artigo, muito interessante esse modulo externo do netfilter,
meus parabens.

[16] Comentário enviado por rrossilva em 21/03/2011 - 10:42h

Otimo artigo!!! Funciona que é uma beleza.
Já implementei uma jaula com varias portas monitoradas, ficou show de bola.

[17] Comentário enviado por gilmar_gnu/slack em 01/06/2011 - 11:32h

Tem um tempo que não vejo nada novo de configuração de firewall.
Pois é necessário.
To ferrado em linux estes dias.
Virei um fanfarrão.
só não pedi para sair porquê tenho materiais.
Sinto falta do meu Slackware de Sempre.
hahahaha ^^
òtimo artigo man.

[18] Comentário enviado por felipetsi em 31/05/2012 - 14:20h

tchello.mello, excelente artigo. Eu não conhecia esse módulo do iptables.

Meus parabéns pelo artigo.

[19] Comentário enviado por hackerdubuntu em 27/07/2012 - 09:23h

ola amigo achei interesante esse artigo sera se teria problem em eu publicar para outros???

[20] Comentário enviado por pharaohgt em 03/10/2012 - 17:31h

Boa , obrigado pela contribuiçao!!!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts