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.388 ]

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

Dois links de ADSL em um mesmo servidor

Monitoramento de MSN com imsniff

Leitura recomendada

Firewall e NAT em FreeBSD com controle de banda e redirecionamento de portas e IPs

Conexões de entrada e saída com 2 links em um servidor

Segurança com iptables

Firewall iptables com NAT

Entendendo TCP/IP (Parte 5) - Portas TCP/UDP

  
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