Pular para o conteúdo

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.
Ricardo Jacomel rjacomel
Hits: 92.157 Categoria: Linux Subcategoria: Firewall
  • Indicar
  • Impressora
  • Denunciar

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

   1. Introdução

Dois links de ADSL em um mesmo servidor

Monitoramento de MSN com imsniff

Firewall bridge + iptables + layer7 + ipp2p

Firewalls redundantes utilizando VRRP

Firewall invisível com Proxy ARP

IpCop - Um firewall personalizado

IPFire - Um Firewall Open Source

#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
#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

Entre na sua conta para comentar.