Firewall rápido e seguro com iptables

Neste artigo mostrarei um script de firewall utilizando iptables com regras que julgo necessárias para a segurança da sua rede, além de opções de NATs, proxy transparente, logs, etc.

[ Hits: 91.365 ]

Por: Ricardo Jacomel em 27/07/2004


Introdução



Neste artigo mostrarei um script de firewall utilizando iptables com regras que julgo necessárias para a segurança da sua rede, além de opções de NATs, proxy transparente, logs, etc.

A configuração do meu servidor é a seguinte:

Ambiente testado:
  • Distro: Fedora Core 2

A máquina possui 2 interfaces de rede:
  • Intranet: eth1 - 10.0.0.0/24
  • ADSL: eth0 - 192.168.200.1/24 - GW: 192.168.200.254

Neste exemplo todo o tráfego da minha rede sai para a internet através do gateway (roteador) 192.168.200.254, passando antes pelo meu firewall.

Abaixo segue o script detalhado e comentado. Provavelmente você só precisará alterar o conteúdo das variáveis IF_EXTERNA e IF_INTERNA, correspondente às interfaces do seu firewall e mais no final do script as regras que tratam de possíveis NATs, proxy transparente, etc. Estas regras estão comentadas:

#!/bin/sh

# Variáveis
# -------------------------------------------------------
iptables=/sbin/iptables
IF_EXTERNA=eth0
IF_INTERNA=eth1


# Ativa módulos
# -------------------------------------------------------

/sbin/modprobe iptable_nat
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_REJECT
/sbin/modprobe ipt_MASQUERADE


# Ativa roteamento no kernel
# -------------------------------------------------------
echo "1" > /proc/sys/net/ipv4/ip_forward


# Proteção contra IP spoofing
# -------------------------------------------------------
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter


# Zera regras
# -------------------------------------------------------
$iptables -F
$iptables -X
$iptables -F -t nat
$iptables -X -t nat
$iptables -F -t mangle
$iptables -X -t mangle


# Determina a política padrão
# -------------------------------------------------------
$iptables -P INPUT DROP
$iptables -P OUTPUT DROP
$iptables -P FORWARD DROP


#################################################
# Tabela FILTER
#################################################


# Dropa pacotes TCP indesejáveis
# -------------------------------------------------------
$iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j LOG --log-level 6 --log-prefix "FIREWALL: NEW sem syn: "
$iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j DROP


# Dropa pacotes mal formados
# -------------------------------------------------------
$iptables -A INPUT -i $IF_EXTERNA -m unclean -j LOG --log-level 6 --log-prefix "FIREWALL: pacote mal formado: "
$iptables -A INPUT -i $IF_EXTERNA -m unclean -j DROP


# Aceita os pacotes que realmente devem entrar
# -------------------------------------------------------
$iptables -A INPUT -i ! $IF_EXTERNA -j ACCEPT
$iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$iptables -A OUTPUT -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
$iptables -A FORWARD -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT


# Proteção contra trinoo
# -------------------------------------------------------
$iptables -N TRINOO
$iptables -A TRINOO -m limit --limit 15/m -j LOG --log-level 6 --log-prefix "FIREWALL: trinoo: "
$iptables -A TRINOO -j DROP
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 27444 -j TRINOO
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 27665 -j TRINOO
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 31335 -j TRINOO
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 34555 -j TRINOO
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 35555 -j TRINOO


# Proteção contra tronjans
# -------------------------------------------------------
$iptables -N TROJAN
$iptables -A TROJAN -m limit --limit 15/m -j LOG --log-level 6 --log-prefix "FIREWALL: trojan: "
$iptables -A TROJAN -j DROP
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 666 -j TROJAN
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 666 -j TROJAN
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 4000 -j TROJAN
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 6000 -j TROJAN
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 6006 -j TROJAN
$iptables -A INPUT -p TCP -i $IF_EXTERNA --dport 16660 -j TROJAN


# Proteção contra worms
# -------------------------------------------------------
$iptables -A FORWARD -p tcp --dport 135 -i $IF_INTERNA -j REJECT


# Proteção contra syn-flood
# -------------------------------------------------------
$iptables -A FORWARD -p tcp --syn -m limit --limit 2/s -j ACCEPT


# Proteção contra ping da morte
# -------------------------------------------------------
$iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT


# Proteção contra port scanners
# -------------------------------------------------------
$iptables -N SCANNER
$iptables -A SCANNER -m limit --limit 15/m -j LOG --log-level 6 --log-prefix "FIREWALL: port scanner: "
$iptables -A SCANNER -j DROP
$iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -i $IF_EXTERNA -j SCANNER
$iptables -A INPUT -p tcp --tcp-flags ALL NONE -i $IF_EXTERNA -j SCANNER
$iptables -A INPUT -p tcp --tcp-flags ALL ALL -i $IF_EXTERNA -j SCANNER
$iptables -A INPUT -p tcp --tcp-flags ALL FIN,SYN -i $IF_EXTERNA -j SCANNER
$iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -i $IF_EXTERNA -j SCANNER
$iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -i $IF_EXTERNA -j SCANNER
$iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -i $IF_EXTERNA -j SCANNER


# Loga tentativa de acesso a determinadas portas
# -------------------------------------------------------
$iptables -A INPUT -p tcp --dport 21 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: ftp: "
$iptables -A INPUT -p tcp --dport 23 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: telnet: "
$iptables -A INPUT -p tcp --dport 25 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: smtp: "
$iptables -A INPUT -p tcp --dport 80 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: http: "
$iptables -A INPUT -p tcp --dport 110 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: pop3: "
$iptables -A INPUT -p udp --dport 111 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: rpc: "
$iptables -A INPUT -p tcp --dport 113 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: identd: "
$iptables -A INPUT -p tcp --dport 137:139 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: samba: "
$iptables -A INPUT -p udp --dport 137:139 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: samba: "
$iptables -A INPUT -p tcp --dport 161:162 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: snmp: "
$iptables -A INPUT -p tcp --dport 6667:6668 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: irc: "
$iptables -A INPUT -p tcp --dport 3128 -i $IF_EXTERNA -j LOG --log-level 6 --log-prefix "FIREWALL: squid: "


# Libera acesso externo a determinadas portas
# -------------------------------------------------------
$iptables -A INPUT -p tcp --dport 22 -i $IF_EXTERNA -j ACCEPT


# Libera acesso de smtp para fora apenas para o IP XXX.XXX.XXX.XXX
# -------------------------------------------------------
#$iptables -A FORWARD -p tcp -d ! XXX.XXX.XXX.XXX --dport 25 -j LOG --log-level 6 --log-prefix "FIREWALL: SMTP proibido: "
#$iptables -A FORWARD -p tcp -d ! XXX.XXX.XXX.XXX --dport 25 -j REJECT


#################################################
# Tabela NAT
#################################################


# Ativa mascaramento de saída
# -------------------------------------------------------
$iptables -A POSTROUTING -t nat -o $IF_EXTERNA -j MASQUERADE


# Proxy transparente
# -------------------------------------------------------
#$iptables -t nat -A PREROUTING -i $IF_INTERNA -p tcp --dport 80 -j REDIRECT --to-port 3128
#$iptables -t nat -A PREROUTING -i $IF_INTERNA -p tcp --dport 8080 -j REDIRECT --to-port 3128


# Redireciona portas para outros servidores
# -------------------------------------------------------
#$iptables -t nat -A PREROUTING -d 192.168.200.1 -p tcp --dport 22 -j DNAT --to-destination 10.0.0.1


# Redireciona portas na própria máquina
# -------------------------------------------------------
#$iptables -A PREROUTING -t nat -d 192.168.200.1 -p tcp --dport 5922 -j REDIRECT --to-ports 22

Links relacionados e consultados:
Dúvidas, mail me: ricardo@jacomel.com.br

Ricardo Jacomel
http://www.jacomel.com.br
ricardo@jacomel.com.br

   

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

Monitoramento de MSN com imsniff

Dois links de ADSL em um mesmo servidor

Leitura recomendada

Como construir um firewall de baixo custo para sua empresa (parte 3)

Shorewall, uma excelente opção para firewall Linux

Firewall invisível com Proxy ARP

Migrando do ipchains para o iptables

Dominando o iptables (parte 1)

  
Comentários
[1] Comentário enviado por y2h4ck em 28/07/2004 - 10:00h

Bom ... apesar dos metodos citados acima ja serem bem batidões e tal ... achei legal a maneira que vc disponibilizou as infos dentro das tabelas ... separando cada determinado grupo em chains com os nomes separados ... oq a ajuda na hora de uma futura auditoria ...

isso ae []s

[2] Comentário enviado por cmarcelo em 28/07/2004 - 16:25h

Achei muito bom o artigo, parabéns!

Aproveitando-o vou fazer um pargunta sobre um porblema q tenho a tempo...
Eu tenho um servidor FTP em um PC aqui em casa, sem firewall funciona perfeito, mas quando levando as regras, o tempo até apareceer a tela de login para o servidor é mt grande..
Abaixo fragmentos do meu script de firewall..

---(cut)---
...
$IPTABLES -F
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
...
$IPTABLES -A INPUT -p tcp --dport 20 -j ACCEPT
$IPTABLES -A INPUT -p udp --dport 20 -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 21 -j ACCEPT
$IPTABLES -A INPUT -p udp --dport 21 -j ACCEPT
...
---(cut)---

Obrigado!

[3] Comentário enviado por diogojp em 30/07/2004 - 13:53h

Muito bacana no script.
:)

[4] Comentário enviado por nhlj em 02/08/2004 - 08:37h

Muito bom o artigo, bem explicado e organizado. Parabéns !
Só uma pergunta, se você configurou a policy de input como drop, porque criar regras para bloquear as portas para trinoo e trojan ?

um abraço,
nilo.

[5] Comentário enviado por rjacomel em 02/08/2004 - 11:01h

Na verdade não haveria mesmo a necessidade de "dropar" nada nas regras de proteção contra trinoo e trojan. A minha intenção principal para estas regras é apenas de "logar" as tentativas de acesso.

Como você disse, a política padrão já é de negar tudo.

Abraços,

Ricardo Jacomel

[6] Comentário enviado por engos em 02/08/2004 - 15:09h

Achei um pouco pobre de informação o artigo, mas gostei dele, principalmente pelo fato de ser bem prático e bem comentado.

Parabéns!

[7] Comentário enviado por brekaus em 11/08/2004 - 13:23h

sou novato no mundo do linux, mais adorei suas regras de firewall, e acho que se alguem souber algum melhor que esse ao inves de criticar, monta um artigo igual o Ricardo montou, pq pra min foi mto util!!

valews

[]s

[8] Comentário enviado por reimassupilami em 17/11/2004 - 15:19h

cara, muito bom seu artigo... estou estudando o uso de iptables e isso está sendo muito útil para mim...

algumas dúvidas: nas sessões:

Loga tentativa de acesso a determinadas portas
Libera acesso externo a determinadas portas

vc está bloqueando e liberando todas as portas necessarias, ou são apenas alguns exmplos pra q a gente faça conforme nossas necessidades?

[9] Comentário enviado por reimassupilami em 17/11/2004 - 15:31h

ah, outra dúvida... quanto aos logs que algumas regras geram, onde ele são gravados, e quais os nomes dos arquivos?

[10] Comentário enviado por reimassupilami em 17/11/2004 - 15:57h

quando executei o script deu os seguintes erros:

WARNING: Error inserting ipfwadm (/lib/modules/2.6.9/kernel/net/ipv4/netfilter/ipfwadm.ko): Device or resource busy
WARNING: Error inserting ipfwadm (/lib/modules/2.6.9/kernel/net/ipv4/netfilter/ipfwadm.ko): Device or resource busy
WARNING: Error inserting ipfwadm (/lib/modules/2.6.9/kernel/net/ipv4/netfilter/ipfwadm.ko): Device or resource busy
iptables v1.2.9: Maximum prefix length 29 for --log-prefix
Try `iptables -h' or 'iptables --help' for more information.
iptables: No chain/target/match by that name

vc poderia me ajudar sobre isso?

[11] Comentário enviado por reimassupilami em 18/11/2004 - 13:54h

rodei linha por linha do script de firewall e identifiquei que o q tava dando o primeiro erro, tres vezes, eram as seguintes linha que usava pra ativas os modulos:

/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_MASQUERADE

depois comentei essas linhas e naum deu mais aquele erro... agora vem a questão: pq ta dando o esso nessas linhas, e será vai funcionar se naum tiver essas linhas?

mesmo assim o segundo erro ainda persiste... o q mais pode ser?

[12] Comentário enviado por reimassupilami em 18/11/2004 - 16:09h

bom cheguei a conclusao de q as linhas

/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_MASQUERADE

sao desnecessarias pois esses modulos ja estao carregados, por isso dava os erros...

quanto ao outro erro econtrei onde ele esta ocorrendo, é nas linhas:

$iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j LOG --log-level 6 --log-prefix "FIREWALL: NEW sem syn: "
$iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j DROP

e o erro:

iptables: No chain/target/match by that name

sera q tem algo errado nas regras?

[13] Comentário enviado por reimassupilami em 19/11/2004 - 09:14h

bom, ja que ninguem comentou nada, deixa eu postar aki a solução:

muito bem, depois de tanta luta, um colega do underlinux deu a seguinte solução para o segundo erro:

depois do tcp coloca um -m.

$iptables -A FORWARD -p tcp -m tcp! --syn -m state --state NEW -j LOG --log-level 6 --log-prefix "FIREWALL: NEW sem syn: "
$iptables -A FORWARD -p tcp -m tcp ! --syn -m state --state NEW -j DROP

agora ficou legal...

falow...

[14] Comentário enviado por reimassupilami em 19/11/2004 - 09:15h

ah, e quanto ao primeiro erro:

bom cheguei a conclusao de q as linhas

/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_MASQUERADE

sao desnecessarias pois esses modulos ja estao carregados, por isso dava os erros...

[15] Comentário enviado por newton_portobr em 29/11/2004 - 13:57h

Parabens pelo Artigo,

Estou testando ele num RedHat 9.0, so que quando execulto o firewall, esta apresentando a seguinte mensagem;

iptables v1.2.7a: Maximum prefix length 29 for --log-prefix
Try `iptables -h' or 'iptables --help' for more information.

Como resolver isso.?.....

[16] Comentário enviado por rjacomel em 29/11/2004 - 16:37h

Este erro que dá no Red Hat 9 é porque a regra que dropa pacotes mal formatos está excedendo o limite de caracteres em seu comentário:

$iptables -A INPUT -i $IF_EXTERNA -m unclean -j LOG --log-level 6 --log-prefix "FIREWALL: pacote mal formado: "

Basta diminuir o número de caracteres. Ex.:

$iptables -A INPUT -i $IF_EXTERNA -m unclean -j LOG --log-level 6 --log-prefix "FIREWALL: pcte mal formado: "

Ricardo Jacomel

[17] Comentário enviado por johntop3 em 07/02/2005 - 02:42h

Exelente script, associei a um já existente e esta funcionando perfeitamente

[18] Comentário enviado por 4driano em 14/03/2005 - 19:18h

Legal esse script..... eu vi um pessoal reclamando sobre ele falando que estava fraco e tudo mais, o que mais é preciso como firewall de uma rede?
A única coisa que eu faço além disso é realmente olhar os logs e analisá-los, pois não tem outro jeito..... se alguém preferir, põe o snort para ajudar....mas esse firewall tá muito legal, fecha tudo e abre o que precisa.

Não tem muito erro não é isso aí...parabéns

[19] Comentário enviado por Bique em 07/04/2005 - 15:39h

Bem fixe...Tenho uma duvida como posso bloquear os spywares a partir do iptables?Alguem me sabe explicar com fazer tal manobra?

[20] Comentário enviado por Bique em 07/04/2005 - 15:42h

Mais uma pequena duvida...Onde posso ver os logs que vao sendo gerados?

[21] Comentário enviado por macgyver_rp em 18/10/2005 - 10:28h

retornou essa menssagem no meu shell alguem sabe sé é algum erro de regra?


iptables: No chain/target/match by that name
iptables: No chain/target/match by that name

[22] Comentário enviado por macgyver_rp em 19/10/2005 - 14:00h

Achei o erro do script no meu Debian Sarge....

São essas duas linhas depois de comentadas parou o erro
Alguem pode dar olhada nas linhas e achar o problema eu achei que era o nome e diminui o nome como sujeriram acima...mas não deu certo.

# Dropa pacotes mal formados
# -------------------------------------------------------
$iptables -A INPUT -i $IF_EXTERNA -m unclean -j LOG --log-level 6 --log-prefix "FIREWALL: pac mal formado: "
$iptables -A INPUT -i $IF_EXTERNA -m unclean -j DROP

[23] Comentário enviado por removido em 04/11/2005 - 11:20h

Sinceramente nao sei se entendi direito este link, mas parece que o ipt_unclean foi retirado do kernel 2.6. Provavelmente é o seu caso.

https://lists.netfilter.org/pipermail/netfilter-devel/2003-August/012199.html

[24] Comentário enviado por madsonsander em 07/04/2006 - 20:54h

olá tentei usar o seu firewall, porém não consegui navegar, a minha saída para a internet não é pelo meu gateway, saio por um dns válido do meu provedor, o que preciso fazer, uso red hat 9....

[25] Comentário enviado por terranova em 30/10/2006 - 12:46h

Respondendo a pergunta de alguns amigos, os logs são gravados no /var/log/messages
Espero ter ajudado.

[26] Comentário enviado por gusfreire em 05/03/2007 - 11:49h

Realmente muito bom o scrip mas quando eu executo ele no meu servidor da o seguinte erro: iptables v1.2.11: Maximum prefix length 29 for --log-prefix Try `iptables -h' or 'iptables --help' for more information.
A minha distribuição é o Debian 3.1 Sarge.
Se alguém souber o porque está dando este erro.

[27] Comentário enviado por gusfreire em 05/03/2007 - 11:51h

Cara me desculpe malndei a dúvida e não li direito o que o pcclinica escreveu eu vi que o meu problema era parecido com o dele mas não li a resolução foi mal mesmo.
Foi só comentar as duas linhas que o pcclinica havia comentado acima que funcionou. Valew

[28] Comentário enviado por marceloespindola em 07/07/2007 - 15:28h

Pessoal estou escrevendo um artigo aqui para o viva o linux sobre scrippt de firewall, ele está completo pois levei muito tempo para desenvolve-lo e tinha objetivo de reunir as principais soluções e dúvidas sobre firewall para este artigo, mas como quero construir um bom artigo ainda está em fase de construção para o vivaolinux, entretanto estou disponibilizando no endereço

http://marcelolinux.blogspot.com/2007/07/meu-primeiro-artigo-do-vivaolinux.html

os arquivos e o artigo referente a script de firewall completo.

[29] Comentário enviado por conhe em 24/07/2007 - 10:29h

como eu faço para liberar a radio uol nesse scrip?ja tentei de algumas formas mas nao estou conseguindo nao.vlw

[30] Comentário enviado por conhe em 24/07/2007 - 10:51h

consegui galera.
com a seguinte regra.
$iptables -t nat -I PREROUTING -i $IF_INTERNA -m tcp -p tcp -d 200.221.5.71/16 --dport 80 -j ACCEPT

[31] Comentário enviado por conhe em 25/07/2007 - 11:41h

quero saber como eu faço pra rede 192.168.0.0/24 conseguir enxergar a rede 192.168.1.0/24?

[32] Comentário enviado por overond em 22/09/2007 - 17:49h

quando executo a linha iptables -A INPUT -i eth0 -m unclean -j DROP me retorna a mensagem No chain/target/match by that name, vcs sabem o que pode estar errado?

[33] Comentário enviado por beowulf em 19/11/2007 - 22:34h

Como que eu faco para liberar as portas do servidor de DNS e email?

[34] Comentário enviado por celsof2 em 26/03/2008 - 05:33h

bom o artigo

[35] Comentário enviado por educlj em 18/04/2008 - 17:30h

Excelente artigo. Trabalho com segurança há alguns anos e posso dizer que o artigo está muito bem elaborado. 10 em organização.

[]'
Eduardo

[36] Comentário enviado por moacircostajr em 01/10/2008 - 14:05h

se eu suprimisse o argumento -i $IF_EXTERNA (ou $IF_INTERNA), todas as regras se aplicariam a qualquer interface (eth0, ath0) sem problemas?

[37] Comentário enviado por removido em 20/05/2009 - 21:30h

Parabens, Muito bom o Firewall!
So fiz modificacoes mas estou usando.

Flw

[38] Comentário enviado por cooperrj em 08/06/2009 - 10:23h

Muito show o script, parabéns mesmo, mas tenho uma duvida...

Eu removi desse script a parte de dropar trinoo, trojan e dos pacotes mal formados... Também removi os logs, pois pra mim não seria interessante e é bom que usa menos hardware... Agi certo em fazer isso?

[39] Comentário enviado por thiagosc em 27/09/2010 - 20:28h

Bom script!!! Ele se aplica ao debian?


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts