Iptables - Segurança total para sua rede

O objetivo aqui neste artigo não é realizar um estudo profundo do iptables, mas sim aprendermos sobre algumas regras do mesmo e criarmos um script simples, porém seguro, para que a partir daí você possa melhorá-lo à sua maneira.

[ Hits: 83.062 ]

Por: Phillip Vieira em 17/01/2012


Exemplo de script



Vamos ao nosso exemplo de script, ele é muito simples, porém seguro, e aos poucos você pode ir incrementando o mesmo.

Lembre-se, o script aqui é apenas um exemplo, estude o script (e o iptables é claro). Leia os comentários e modifique-o de acordo com sua necessidade. Lembrando novamente que este exemplo é apenas para fins de aprendizagem.

Crie um arquivo com o seu editor de texto preferido com o nome de 'firewall' dentro de "/etc/init.d/" (para sistemas baseados em Debian). No meu caso, estarei utilizando o editor VIM.

# vi /etc/init.d/firewall

Daqui para baixo, é o script de 'firewall' (mencionado acima):

#!/bin/bash
 
# A linha acima é conhecida como shebang e server para chamar o interpretador do script
# poderia-se trocar o bash pelo sh ou outro shell de sua preferência
 
########################################################
# EXEMPLO DE SCRIPT DE FIREWALL PARA ARTIGO NO SITE www.vivaolinux.com.br
# CRIADO POR phrich                    
# Data da última alteração: 11/01/2012         
# ######################################################
 
######################
# DECLARANDO AS VARIÁVEIS #
######################
 
# Interface de rede ligada a internet
IFACE_WEB="eth0"
 
# Interface de rede ligada a rede interna
IFACE_REDE="eth1"
 
# Rede interna
REDE_INTERNA="10.0.0.0/24"
 
# Portas liberadas TCP
PORTAS_TCP="20,21,53,80,443"
 
# Portas liberadas UDP
PORTAS_UDP="53"
 
# Portas liberadas para a rede interna
PORTAS_REDE_INTERNA="25,110"
 
############################################################
# FUNÇÃO START                           #
# Esta função limpa as regras criadas anteriormente, e insere as regras listadas na função
###########################################################
 
function start () {
 
#++++++++++++++++++++++
# LIMPA AS REGRAS EXISTENTES #
#+++++++++++++++++++++#
 
# Limpa as regras da tabela filter
iptables -F
 
# Limpa as regras da tabela nat
iptables -t nat -F
 
# DEFINE AS POLÍTICAS PADRÕES DO IPTABLES COMO DROP #
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
 
# HABILITA O ROTEAMENTO NO KERNEL #
echo 1 > /proc/sys/net/ipv4/ip_forward
 
# CRIA A IDA E VOLTA DO ACESSO NAS CHAINS INPUT, OUTPUT E FORWARD, ASSIM NÃO PRECISAMOS CRIAR A IDA E VOLTA NAS REGRAS
# Não vamos nos aprofundar neste assunto, mas vale a pena dar uma estudada no módulo state ;-)
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
 
##############
# REGRAS DE NAT #
#############
 
# COMPARTILHA A INTERNET #
iptables -t nat -A POSTROUTING -s $REDE_INTERNA -o $IFACE_WEB -j MASQUERADE
 
# REDIRECIONA O ACESSO RDP PARA OUTRO SERVIDOR DENTRO DA REDE INTERNA#
iptables -t nat -A PREROUTING -p tcp --dport 3389 -j REDIRECT --to 10.0.0.2:3389
 
###############
# REGRAS DE INPUT #
###############
 
# Libera o acesso SSH de qualquer origem
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
 
# Libera o squid a partir da rede interna
iptables -A INPUT -p tcp --dport 3128 -j ACCEPT
 
# Aceita ping apenas da rede interna
iptables -A INPUT -s $REDE_INTERNA -p icmp --icmp-type 8 -j ACCEPT
 
################
# REGRAS DE OUTPUT #
################
 
# Libera as portas constantes na variável $PORTAS_TCP (para liberar mais portas, basta inserir as mesmas na variável citada)
iptables -A OUTPUT -p tcp -m multiport --dports $PORTAS_TCP -j ACCEPT
 
# Libera ping para qualquer lugar
iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
 
##################
# REGRAS DE FORWARD #
#################
 
# Libera as portas constantes em na variável $PORTAS_REDE_INTERNA (para liberar mais portas, basta inserir as mesmas na variável citada)
iptables -A FORWARD -p tcp -m multiport --dports $PORTAS_REDE_INTERNA -j ACCEPT
 
# Libera RDP citado na regra de NAT
iptables -A FORWARD -p tcp --dport 3389 -d 10.0.0.2 -j ACCEPT
# FINAL DA FUNÇÃO START #
}
 
############################################################################
# CRIA FUNÇÃO STOP                                     #
# Esta função limpa todas as regras, deixa as políticas padrões com ACCEPT e deixa todo e qualquer acesso liberado
############################################################################
 
functio stop () {
 
# LIMPA AS REGRAS EXISTENTES #
iptables -F
iptables -t nat -F
 
# DEFINE AS POLÍTICAS PADRÕES DO IPTABLES COMO DROP #
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
 
# HABILITA O ROTEAMENTO NO KERNEL #
echo 1 > /proc/sys/net/ipv4/ip_forward
 
# COMPARTILHA A INTERNET #
iptables -t nat -A POSTROUTING -s $REDE_INTERNA -o $IFACE_WEB -j MASQUERADE
 
# Caso queira manter as regras de NAT favor copiar as regras de nat
# e as correspondentes as mesmas de forward aqui
 
# FINAL DA FUNÇÃO STOP #
}
 
# Criando os parâmetros para o script, esses parâmetros serão start, stop e restart vejamos:
# start - chama a função start (Regras inseridas e política padrão como DROP)
# stop - chama a função stop (Sem regras e com a política padrão como ACCEPT, util para realizar testes)
# restart - chama a função stop e depois a função start (Carrega as novas regras que venha a ser inseridas na função start)
 
# Qualquer parâmetro que não seja start, stop ou restart não será válido e nada será alterado.
 
case $1 in
 
start)
start
;;
 
stop)
stop
;;
 
restart)
stop
start
;;
 
*)
echo "Insira um parâmetro para /etc/init.d/firewall... start | stop | restart
exit 0
;;
 
esac
# FIM DO SCRIPT DE FIREWALL #


Comentários

- A linha:

iptables -A OUTPUT -p tcp -m multiport --dports $PORTAS_TCP -j ACCEPT

- Pode ser substituída por estas:

iptables -A OUTPUT -p tcp --dport 20 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT


O exemplo foi usado para que você conheça o módulo Multiport e aprenda a trabalhar com variáveis, que dependendo do caso, pode facilitar sua vida, mas nada impede que você crie uma regra para cada porta.

- Caso você não utilize o Squid para controle de acesso, comente a linha:

iptables -A INPUT -p tcp --dport 3128 -j ACCEPT

- E adicione nas regras no bloco 'REGRAS DE FORWARD' dentro da função 'start':

iptables -A FORWARD -p tcp --dport 53 -j ACCEPT
iptables -A FORWARD -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -p tcp --dport 443 -j ACCEPT


- Ou:

iptables -A FORWARD -p tcp -m multiport --dports $PORTAS_TCP -j ACCEPT
iptables -A FORWARD -p tcp -m multiport --dports $PORTAS_UDP -j ACCEPT


Conclusão

No script exemplificado anteriormente, vimos como manter um firewall mais seguro usando as políticas padrões do iptables como 'DROP'. Com este exemplo, podemos bloquear todo e qualquer acesso e liberar apenas o necessário.

Sendo assim, no nosso exemplo, já estamos com internet compartilhada com ou sem 'Squid'.

Até o próximo!
Página anterior    

Páginas do artigo
   1. Introdução
   2. Políticas do iptables
   3. Exemplo de script
Outros artigos deste autor

Samba - Dançando conforme a música

Linux e Windows - Prós e Contras

Instalando o Linux Fedora 8 no Notebook Positivo v53

Squid + Iptables - Combinação Infalível

Recuperando dados do Windows usando um live-CD

Leitura recomendada

Fusion Firewall - Uma alternativa para Firewall-Proxy gerenciado via web

Desvendando as regras de Firewall Linux Iptables

Firewall funcional de fácil manipulação

Criando cluster com o PFSense

Iptables em modo gráfico

  
Comentários
[1] Comentário enviado por eldermarco em 17/01/2012 - 17:22h

Legal o seu artigo. Não trate o assunto de maneira mais detalhada, mas de forma bastante didática. Acho que já passei da hora de estudar esse assunto e o seu artigo me motivou a fazê-lo.

[2] Comentário enviado por phrich em 17/01/2012 - 18:08h

Fico feliz em saber que pude ajudar.

Estudar é sempre bom, seja em qual assunto for, eu por exemplo, sempre releio alguns livros, tutoriais, dicas, etc, assim posso me lembrar sempre de algo que eu tenha esquecido.

[3] Comentário enviado por danniel-lara em 17/01/2012 - 18:52h

Parabens pelo artigo
ficou muito bom mesmo

[4] Comentário enviado por phrich em 17/01/2012 - 19:31h

Obrigado, espero que tenha lhe ajudado em algo.

[5] Comentário enviado por arc em 17/01/2012 - 22:17h

Ótimo artigo

Mas tem um erro na linha que libera o squid para rede interna, da forma que esta libera para qualquer origem.

Mas ressaltando ficou ótimo e será de grande ajuda para muitos aqui do site.

[6] Comentário enviado por darcanjo em 17/01/2012 - 23:30h

O artigo ficou ótimo, mas existem dois erros nas regras da chain NAT:

#####ORIGINAL:

# COMPARTILHA A INTERNET #
iptables -t nat -A PREROUTING -s $REDE_INTERNA -o $IFACE_WEB -j MASQUERADE

# REDIRECIONA O ACESSO RDP PARA OUTRO SERVIDOR DENTRO DA REDE INTERNA#
iptables -t nat -A POSTROUTING -p tcp --dport 3389 -j REDIRECT --to 10.0.0.2:33

#####CORRETO:

# COMPARTILHA A INTERNET #
iptables -t nat -A POSTROUTING -s $REDE_INTERNA -o $IFACE_WEB -j MASQUERADE

# REDIRECIONA O ACESSO RDP PARA OUTRO SERVIDOR DENTRO DA REDE INTERNA#
iptables -t nat -A PREROUTING -p tcp --dport 3389 -j REDIRECT --to 10.0.0.2:33

[7] Comentário enviado por phrich em 17/01/2012 - 23:53h

Pessoal, se houver correções a fazer, por favor fiquem a vontade.

Isto não é um livro e sim um artigo para compartilhar os meus conhecimentos com todos os usuários do vivaolinux.com.br

darcanjo sua colocação está certíssima!

arc vc está certo, eu deveria ter colocado o acesso apenas para a rede interna (falha no erro kkk), mas tudo bem, sinta-se a vontade para corrigir.

Abraços!

[8] Comentário enviado por ecbr em 18/01/2012 - 08:01h

Tem certeza que isso esta correto?

##############
# REGRAS DE NAT #
#############

# COMPARTILHA A INTERNET #
iptables -t nat -A PREROUTING -s $REDE_INTERNA -o $IFACE_WEB -j MASQUERADE

# REDIRECIONA O ACESSO RDP PARA OUTRO SERVIDOR DENTRO DA REDE INTERNA#
iptables -t nat -A POSTROUTING -p tcp --dport 3389 -j REDIRECT --to 10.0.0.2:3389

[9] Comentário enviado por phrich em 18/01/2012 - 08:40h

Caro ecbr, o correto seria:

iptables -t nat -A PREROUTING -i $IFACE_WEB -p tcp --dport 3389 -j DNAT --to 192.168.0.2:3389

iptables -t nat -A PREROUTING -o $REDE_INTERNA -o $IFACE_WEB -j MASQUERADE

Obrigado por ter visto o erro.

Eu estava escrevendo o artigo e ao mesmo tempo trabalhando e escrevendo um outro artigo, talvez eu tenha me embolado nas regras ;-)

Mais tarde, postarei novamente o script com as devidas correções ok?

Mais uma vez obrigado a todos!

[10] Comentário enviado por levi linux em 18/01/2012 - 09:55h

Parabéns phrich, excelente artigo, bastante didático. Assim como o eldermarco fiquei motivado a estudar o iptables. 10, favoritado!

[11] Comentário enviado por removido em 18/01/2012 - 12:06h

Phillip,

Assim que preparar todas as modificações, descreva a página, o trecho sobre como está e como quer deixar. OK?
Envie tudo para este e-mail: izac.cf@gmail.com

É bem melhor efetuarmos as correções no próprio artigo do que postá-las nos comentários.
Os trabalhos devem estar corretos para quem faz a leitura, e fora que tem pessoas que nem leem os comentários.

Agradecemos também ao pessoal que está colaborando com as correções.

Esta é a melhor comunidade que existe!

Um abraço a todos.

[12] Comentário enviado por phrich em 18/01/2012 - 12:24h

Perfeito izaias, vou realizar as correções e lhe enviar.

[13] Comentário enviado por phrich em 21/01/2012 - 11:06h

Prezados, já foi enviado ao moderador as correções do script, agora ele está certinho ok?

Mais uma vez obrigado a todos!

[14] Comentário enviado por dalveson em 02/02/2012 - 15:29h

Otimo artigo, para mim ja esta sendo bastante util a tempos que queria organizar um script aqui e nao tinha muito noção de como fazer, este artigo clareu bastante!
tenho algumas duvidas:
1-em outros artigos aqui do viva o linux mesmo, os autores nos orientam a colocar os parametos iptables - F, iptables - Z e iptables - X vc coloca apenas o F para limpar, na sua opniao os demais nao seriam muito uteis ou depende de cada um?
2-Na variavel das Portas UDP e TCP eu posso colocar quantas portas que quiser sem dar problema na regras, ou tenho um limite sei lá tipo 30 portas?


abraços

[15] Comentário enviado por [gregory] em 03/02/2012 - 15:50h

Boa tarde amigos... gostei muito do post só queria deixar uma dica caso vocês estejam tendo muitas dificuldades com iptables que nem eu.. Uso como regra de firewall o ipfw no freebsd. Ele é muito bom e muito, mas absurdamente simples... Fica a dica pra quem quizer pesquisar sobre o assunto.

[16] Comentário enviado por phrich em 03/02/2012 - 19:29h

Caro dalveson vamos a suas dúvidas:

O parâmetro -Z é para zerar os contadores.

O parâmetro -X é para deletar uma chain.

O parâmetro -F é para limpar as regras que estão atualmente carregadas.

O módulo multiport suporta até 15 portas em sequência, ou vc pode especificar um intervalo de portas, por exemplo:


A linha abaixo libera as portas especificadas:
iptables -A INPUT -p tcp -m multiport --dports "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15" -j ACCEPT

A linha abaixo substitui a linha acima:
iptables -A INPUT -p tcp -m multiport --dports "1:15" -j ACCEPT

Qualquer dúvida basta consultar o manual, ele é bem detalhado.

#man iptables

Até a próxima!

[17] Comentário enviado por phrich em 03/02/2012 - 19:31h

Gregory, eu já tive a oportunidade de trabalhar com o ipfw, acho que a maior diferença está na sintaxe mesmo, acho mais uma questão de costume.

Eu particularmente, acostumei com o iptables, qdo usei o ipfw, fiquei meio perdido, mas é muito bom também. :-)

Obrigado por compartilhar com esta dica, afinal somos livres!

[18] Comentário enviado por dalveson em 04/02/2012 - 17:21h

Boa tarde phrich, obrigado pela atenção dada a minha duvida.
Estou aplicando o exemplo em um ambiente virtual, afinal não tenho muito conhecimento sobre iptables.
Porem estou com uma duvida, quando eu dou um start no firewall não consigo acessar nada na estação, qdo eu dou um stop tudo funciona de boa porem com tudo ACCEPT conforme descrito no script, então fui ate a parte "# CRIA A IDA E VOLTA DO ACESSO NAS CHAINS INPUT, OUTPUT E FORWARD, ASSIM NÃO PRECISAMOS CRIAR A IDA E VOLTA NAS REGRAS" , e adicione NEW ao state ficando assim:

iptables -A INPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

Funcionou de boa porem ta permitindo toda nova conexão sem restrição de portas, por mais que as politicas estejam DROP, se eu retirar o NEW as estação não acessam, vc tem ideia do que estaria acontecendo?

[19] Comentário enviado por phrich em 15/02/2012 - 08:59h

Caro dalveson teriamos que ver seu script de firewall....

Depois me envie por email ok?

[20] Comentário enviado por beyraq em 16/02/2012 - 14:52h

Olá, me ajude aqui http://www.vivaolinux.com.br/topico/Redes/iptables-bloqueia-tudo

Obrigado desde já.

[21] Comentário enviado por dalveson em 23/03/2012 - 19:54h

Boa noite phrich,
Acabei de enviar um e-mail para vc com o script, obrigado pela atenção dedicada.
att

[22] Comentário enviado por xanddydf em 08/05/2012 - 22:32h

Boa Noite phrich

Estou com o mesmo problema que o dalveson está passando.
Qual foi a solução? você pode me ajudar?
Meu e-mail é carlosalexandre@crtisolutions.com.br
Estou usando Debian Squeeze

Obrigado pela atenção

[23] Comentário enviado por phrich em 08/05/2012 - 22:58h

Caro xanddydf, já enviei ao seu email, pedi no email que vc abrisse um tópico na comunidade http://www.vivaolinux.com.br/comunidade/Squid-Iptables pois assim teriamos até mais pessoas para lhe ajudar ok?

Assim se eu estiver sem tempo, outras pessoas lhe ajudarão. ;-)

[24] Comentário enviado por embura em 06/07/2012 - 16:28h

Essa regra esta liberando INPUT na 3128 para todo.

# Libera o squid a partir da rede interna
iptables -A INPUT -p tcp --dport 3128 -j ACCEPT


assim só libera para a rede interna
iptables -A INPUT -s $REDE_INTERNA -p tcp --dport 3128 -j ACCEPT

[25] Comentário enviado por phrich em 08/07/2012 - 09:45h

Caro embura, eu já havia realizado algumas correções no script, porém outras não foram corrigidas devido a falta de atenção e falta de tempo, de qualquer forma obrigado pela correção.

[26] Comentário enviado por cpa83 em 11/12/2013 - 08:52h

Muito bom realmente seu artigo, queria saber se vc pode me enviar por email esse seu script corrigido.

Desde já queria te agradecer.

Meu email:cristiano.paiva@gmail.com

[27] Comentário enviado por Cesar29 em 31/03/2014 - 15:09h

Muito bom seu artigo, acabei tirando varias dúvidas com ele em meu ambiente teste, so encontrei dois detalhes que precisam ser corrigidos.

-----------------------------------------------------
# CRIA FUNÇÃO STOP #
# Esta função limpa todas as regras, deixa as políticas padrões com ACCEPT e deixa todo e qualquer acesso liberado
############################################################################

functio stop () { <------- Falta um "n" no final da palavra function.

# LIMPA AS REGRAS EXISTENTES #
-----------------------------------------------------
-----------------------------------------------------
*)
echo "Insira um parâmetro para /etc/init.d/firewall... start | stop | restart <-------- Falta uma " após restart.
exit 0
;;
-----------------------------------------------------

Mais uma vez muito obrigado pela contribuição.

[28] Comentário enviado por GonzalezRS em 19/07/2014 - 20:09h

Queria saber como libero um ip para não passar pelo proxy nem pelo iptables.

Estou usando esse script, meu professor me indicou pois está muito didático e fácil compreensão.

desde já agradeço.

[29] Comentário enviado por phrich em 22/07/2014 - 11:48h


[28] Comentário enviado por GonzalezRS em 19/07/2014 - 20:09h:

Queria saber como libero um ip para não passar pelo proxy nem pelo iptables.

Estou usando esse script, meu professor me indicou pois está muito didático e fácil compreensão.

desde já agradeço.


Se o seu firewall está na "borda" da rede, os hosts obrigatoriamente terão que passar pelo firewall, agora se algum host não precisa passar pelo proxy é outra história...

Pesquise sobre excessões de proxy.

[30] Comentário enviado por HeitorMiranda em 09/12/2015 - 18:34h

Boa tarde, estou tentando entender comando a comando, porém estou com uma dúvida, o que de fato efetua "--icmp-type 8", tem algo relacionado com o TOS?

[31] Comentário enviado por thiagosc em 21/12/2016 - 16:22h

Muito bom o artigo, parabéns.

Uma dúvida, esse script bloqueia utilização de torrents?

[32] Comentário enviado por phrich em 29/12/2016 - 10:16h

Caro thiagosc, em tese sim, tudo vai depender de como vc for configurar o script, com as políticas padrões como DROP ele bloqueia tudo e libera só o que vc especificar, aí vc terá que ver como o seu programa de torrent se conecta.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts