terça-feira, 2 de setembro de 2008

Iptables - compartilhando seu link de internet com SNAT ou MASQUERADE (Atualizado)

Como temos visto nos artigos anteriores o iptables é uma ferramenta muito poderosa e com conhecimento é possível criar regras melhores com o intuito de melhorar a segurança de sua rede interna. O que vou descrever aqui neste artigo não é muita novidade para pessoas que já estão acostumadas com seu uso, porém para aqueles que estão iniciando nesta poderosa ferramenta podem se sentir um pouco perdidos na hora de ter que implementar um firewall para compartilhar a internet. Espero que com este artigo possa abrir um pouco mais o horizonte dessas pessoas e mostrar que não é difícil criar seus próprios scripts de iptables que possam cumprir com todos os requisitos que necessitem!

Antes de tudo gostaria de mostrar aqui que existe um padrão para os endereços que podem ser utilizados dentro de uma rede interna! Já vi pessoas que usaram redes destinadas a uso na internet em suas redes locais. Pode ser que no inicio não tenha problema, mas pode ser que em um determinado momento você necessite de um recurso da internet que está presente nesta rede que esta sendo usada em sua lan, e como resultado, não irá conseguir acessa-lo! O documento guia para isto é a RFC1918 (procure por Private Address Space) e esta disponível para pesquisas. Para aqueles que querem saber de uma vez, o padrão é este:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
Com isto podemos nos guiar para criar nossa rede interna e saber que fora deste escopo estaremos usando uma rede que está disponível para uso na internet!

Se estamos falando aqui de compartilhar uma conexão de internet estamos falando de NAT (Network Address Translation), ou seja, queremos que endereços privados possam acessar recursos que geralmente estão fora da nossa rede local. Neste link está uma animação feita pela cisco onde descreve todo o processo! Bem interessante de se ver!

No iptables existe uma tabela específica para fazer este tipo de trabalho e ela tem um nome bem sugestivo que é nat! Nela é possível utilizar uma chain para fazer o serviço que é a POSTROUTING com dois possíveis alvos: SNAT e MASQUERADE! Cada um destes alvos pode ser utilizado para uma determinada necessidade.

O SNAT é muito útil para quando você tem por exemplo um ip público fixo ou ainda uma classe de ips públicos que foi dado a você pelo seu provedor! Por exemplo:
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 200.200.200.200
Desta forma estamos dizendo que a rede de origem 192.168.0/24 terá o ip público 200.200.200.200! Com isso é possível ter vários ips válidos na interface externa de seu Linux (eth0:1, eth0:2) e poder escolher por onde sairá algum pacote que você possa enquadrar em uma regra de iptables! Como por exemplo, você poderia ter seus servidores (web, ftp, e-mail) saindo por um ip válido enquanto que sua rede local usaria outro! As regras ficariam mais ou menos assim:
# Servidores usam este ip 200.200.200.200
iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.0.2-192.168.0.5 -j SNAT --to 200.200.200.200

# A lan usa este 200.200.200.201
iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.0.20-192.168.0.80 -j SNAT --to 200.200.200.201
Este exemplo funciona muito bem no caso de você ter mais de um endereço ip publico e não usar um proxy, como o Squid. Se você estiver usando o squid, é necessário acrescentar umas linhas ao seu arquivo de configuração. No meu caso eu fiz o seguinte:
acl MinhaLAN src 10.10.10.0/255.255.255.0
acl Cliente1 src 10.10.11.0/255.255.255.0
acl Cliente2 src 10.10.12.0/255.255.255.248
http_access allow MinhaLAN
http_access allow Cliente1
http_access allow Cliente2
tcp_outgoing_address seuIpPublico MinhaLAN
tcp_outgoing_address seuOutroIpPublico Cliente1 Cliente2
O que faz o trabalho de usar diferentes endereços ip para as requisições http são as linhas tcp_outgoing_address. Este é um exemplo totalmente funcional e estou usando aqui em minha empresa! O funcionamento do MASQUERADE por outro lado é útil para quando você não sabe seu endereço ip público, como por exemplo, em uma rede onde a atribuição seja automática (DHCP)! Por exemplo:
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
Com esta regra você não precisa se preocupar com o endereço ip externo do seu Linux. O iptables se encarregará de fazer o trabalho de NAT! Lendo no tutorial do IpSysctl eles fazem uma recomendação para que o parâmetro ip_dynaddr esteja habilitado evitando problemas em uma possível troca de ip de origem (por terminar o tempo de aluguel de um endereço)! Muito importante também não esquecer de habilitar o encaminhamento de ips no seu linux em ambos os casos:
echo "1" > /proc/sys/net/ipv4/ip_forward
É muito importante saber qual dessas opções melhor satisfaz seus requerimentos! Com essas instruções em mente podemos criar um script de iptables para compartilhar a internet:

#!/bin/bash
#
# Um firewall statefull com MASQUERADE
#

#=========================
# variaveis
#-------------------------
cmd=iptables
lan=eth1
wan=eth0

#=========================
# 1 - limpando iptables
# 2 - politica padrao
#-------------------------
$cmd -t filter -F
$cmd -t nat -F
$cmd -t mangle -F

$cmd -t filter -P INPUT DROP
$cmd -t filter -P FORWARD DROP
$cmd -t filter -P OUTPUT DROP

#=========================
# conexões filter - input
#-------------------------
$cmd -t filter -A INPUT -i $wan -m state --state RELATED,ESTABLISHED -j ACCEPT
$cmd -t filter -A INPUT -i lo -j ACCEPT
$cmd -t filter -A INPUT -i $lan -j ACCEPT

#==========================
# conexões filter - forward
#--------------------------
$cmd -t filter -A FORWARD -i $wan -m state --state RELATED,ESTABLISHED -j ACCEPT
$cmd -t filter -A FORWARD -i $lan -o $wan -j ACCEPT

#==========================
# conexões filter - output
#--------------------------
$cmd -t filter -A OUTPUT -i lo -j ACCEPT

#===========================
# conexões nat - postrouting
#---------------------------
$cmd -t nat -A POSTROUTING -o $wan -j MASQUERADE

Caso você tenha ficado em dúvida sobre algum conceito do iptables aqui aprensentado não deixe de visitar os outros artigos neste mesmo blog que estão nos seguintes links:

Iptables - Descrição das chains e seu uso na prática
Iptables - Um firewall statefull

Se tiverem dúvidas, críticas ou sugestões não hesitem em posta-las!

2 comentários:

Valcir Borges disse...

Parabéns pelo tutorial, muito didático até mesmo para que é experiente com netfilter/iptables mas que não aprofunda nos detalhes técnicos dos comandos e funcionalidades. De uma forma simples vc explicou a diferença entre SNAT e MASQUERADE, o que eu já busquei em outras documentações e não encontrei de forma clara.
Valcir Borges.

André Zenun disse...

Olá Valcir! Muito obrigado por seu comentário! Fico feliz que ele tenha cooperado para um melhor entendimento!