IPtables: Bloqueando portas de saída e domínios

Mais um uso importante para o firewall é bloquear portas de saída, ou seja, bloquear portas no sentido rede local > Internet. Isso permite bloquear o uso de determinados programas que utilizem estas portas.

O MSN, por exemplo, utiliza originalmente a porta 1863. Nas versões recentes ele é capaz de se conectar também através da porta 80 (ou através de sites como o meebo.com, que permitem acessar o MSN diretamente através do navegador). Por isso, ao bloquear a porta 1863, os clientes podem continuar conseguindo se conectar, porém, você obriga o tráfego a passar pela porta 80, onde tem a chance de fazê-lo passar por um servidor Squid, configurado como proxy transparente. Isso permite logar os acessos ou sabotar o sistema de autenticação do MSN, bloqueando os domínios “messenger.hotmail.com” e “webmessenger.msn.com”, além de outros sites que ofereçam clientes via web.

Hoje em dia, cada vez mais programas são capazes de acessar a Web através da porta 80, 443 ou via proxy, o que torna difícil bloqueá-los. Em muitos casos, é preciso usar uma combinação de portas fechadas no firewall, bloqueio a endereços IPs específicos e bloqueio de determinados domínios no Squid.

Ao criar as regras do Iptables, existem duas opções. Bloqueando a porta para “FORWARD”, você impede o acesso a partir dos micros da rede local, que acessam através da conexão compartilhada pelo servidor. Bloqueando para “OUTPUT”, a porta é bloqueada no próprio micro onde o firewall está ativo. Você pode bloquear as duas situações, duplicando a regra:

iptables -A OUTPUT -p tcp –dport 1863 -j REJECT
iptables -A FORWARD -p tcp –dport 1863 -j REJECT

Você pode ainda bloquear intervalos de portas, separando-as por “:”, como em:

iptables -A FORWARD -p tcp –dport 1025:65536 -j REJECT

Como estamos criando regras para os micros da rede local e não para possíveis invasores provenientes da Internet, é aconselhável usar a regra “REJECT” ao invés de “DROP”. Caso contrário, os programas nos clientes sempre ficarão muito tempo parados ao tentar acessar portas bloqueadas, o que vai gerar reclamações e um certo overhead de suporte.

Você pode descobrir facilmente quais portas de saída são utilizados por cada programa fazendo buscas no Google, mas tentar bloquear um a um todos os programas indesejados acaba sendo tedioso. Ao invés disso, você pode experimentar um solução mais radical: inverter a lógica da regra, bloqueando todas as portas de saída e abrindo apenas algumas portas “permitidas”.

O mínimo que você precisa abrir neste caso são as portas 80 e 53 (DNS). A partir daí, você pode abrir mais portas, como a 25 (SMTP), 110 (POP3), 443 (HTTPS) e assim por diante. Um exemplo de configuração neste caso seria:

iptables -A FORWARD -p udp -i eth0 –dport 53 -j ACCEPT
iptables -A FORWARD -p tcp -i eth0 –dport 80 -j ACCEPT
iptables -A FORWARD -p tcp -i eth0 –dport 443 -j ACCEPT
iptables -A FORWARD -p tcp -i eth0 -j LOG
iptables -A FORWARD -p tcp -i eth0 -j REJECT

Veja que todas as regras especificam a interface da rede local (eth0 no exemplo), de onde serão recebidas as conexões dos clientes. Note que não incluí nenhum bloqueio para forwarding de pacotes provenientes da interface eth1 (da Internet), pois a idéia é bloquear diretamente as requisições dos clientes, e não as respostas. Em uma conexão TCP típica, o cliente envia a requisição na porta TCP usada pelo serviço, mas recebe a resposta em uma porta aleatória. Este é um exemplo de entrada no log do Iptables que mostra a resposta a uma conexão HTTP normal. Veja que ela está endereçada à porta 45159 do cliente:

IN=eth1 OUT=eth0 SRC=64.233.169.99 DST=192.168.0.10 LEN=40 TOS=0×00 PREC=0×00 TTL=239 ID=36813 PROTO=TCP SPT=80 DPT=45159 WINDOW=8190 RES=0×00 ACK FIN URGP=0

No caso da porta 53 (DNS), estou especificando o protocolo UDP ao invés de TCP, pois as requisições são feitas usando portas UDP para ganhar tempo. Embora os servidores DNS escutem tanto na porta 53 TCP, quanto UDP, a porta 53 TCP é utilizada apenas para transferência de zonas e não para resolução de nomes, já que ao usar UDP o tempo de resposta é menor. No UDP a requisição é simplesmente respondida da forma mais rápida possível, enquanto que no TCP é necessário abrir e encerrar a conexão.

A regra “iptables -A FORWARD -j LOG” é uma boa opção durante a fase de testes, pois ela faz com que o Iptables logue todos os pacotes que forem encaminhados (tanto envio, quanto resposta), permitindo que você verifique o que está ocorrendo quando algo não estiver funcionando. Você pode acompanhar o log usando o comando “dmesg”.

Colocado nesta posição (depois das regras que autorizam as conexões nas portas 53 e 80), ele vai mostrar apenas as requisições bloqueadas pelo firewall, dando-lhe a chance de acompanhar os acessos dos clientes e permitir portas adicionais sempre que necessário.

Por exemplo, esta estrada (no log) mostra uma tentativa de conexão de um cliente MSN rodando no micro “192.168.1.10” que foi bloqueada pelo firewall:

IN=eth0 OUT=eth1 SRC=192.168.1.10 DST=207.46.28.77 LEN=60 TOS=0×00 PREC=0×00 TTL=63 ID=21328 DF PROTO=TCP SPT=38119 DPT=1863 WINDOW=5840 RES=0×00 SYN URGP=0

A opção “DTP” indica a porta usada. Se quisesse autorizar o uso do programa, você adicionaria a regra “iptables -A FORWARD -p tcp -i eth1 –dport 1863 -j ACCEPT” em seu script.

Outra opção, para não precisar abrir tantas portas e ter um melhor controle sobre o tráfego de saída é usar um servidor Squid configurado como proxy transparente (interceptando o tráfego da porta 80) e rodar servidores locais para DNS e e-mail (você pode configurar um servidor Postfix como sistema satélite, de forma que ele envie os e-mails dos usuários da rede usando o SMTP do provedor), de forma que qualquer acesso precise necessariamente passar por algum dos serviços ativos no servidor, sujeito a log e aos bloqueios que configurar.

Neste caso, desabilite o compartilhamento da conexão (ou bloqueie o forward de todas as portas) e configure os clientes para utilizarem o IP do servidor como DNS, servidor SMTP, POP e outros serviços que tenha ativado. Mesmo ao ser configurado como proxy transparente, o Squid continua funcionando como um proxy tradicional, através da porta 3128. Você pode configurar clientes de FTP e outros programas com suporte a proxy para acessarem através dele. A vantagem sobre o acesso direto é que ao passar pelo proxy, tudo fica registrado e todo acesso precisa passar pelos filtros de domínios, formatos de arquivos, limitação de banda, etc. definidos por você.

Complementando o bloqueio de portas, você pode também bloquear o acesso de determinados endereços IP, como em:

# Bloqueia o acesso à web a partir de um determinado IP
iptables -A FORWARD -p tcp -s 192.168.1.67 -j REJECT

Esta regra deve ir logo no início do script, antes das regras que abrem as portas de saída, caso contrário não surtirá efeito. Lembre-se de que o Iptables processa as regras seqüencialmente: se uma compartilha a conexão com todos os micros da rede, não adianta tentar bloquear para determinados endereços depois. As regras com as exceções devem sempre vir antes da regra mais geral.

É possível ainda bloquear ou permitir com base no domínio, tanto para entrada quanto saída. Isso permite bloquear sites e programas diretamente a partir do firewall, sem precisar instalar um servidor Squid e configurá-lo como proxy transparente. Nesse caso, usamos o parâmetro “-d” (destiny) do Iptables, seguido do domínio desejado.

Para bloquear os acessos ao Orkut, por exemplo, você usaria as regras:

iptables -A OUTPUT -d http://www.orkut.com -j REJECT
iptables -A FORWARD -d http://www.orkut.com -j REJECT

A primeira linha bloqueia pacotes de saída destinados ao domínio, ou seja, impede que ele seja acessado a partir da própria máquina local. A segunda linha bloqueia o forward de pacotes destinados a ele (domínio), ou seja, impede que outras máquinas da rede local, que acessam através de uma conexão compartilhada, acessem o domínio.

Se for paranóico, você pode usar também a regra:

iptables -A INPUT -s http://www.orkut.com -j DROP

Esta regra impede também que qualquer pacote proveniente do orkut.com chegue até a sua máquina. Como disse, é apenas para paranóicos. ;)

Originalmente, o Iptables sabia trabalhar apenas com endereços IP. A possibilidade de criar regras baseadas em domínios é um recurso um pouco mais recente, onde o firewall faz um lookup do domínio, de forma a descobrir qual é o IP atual e assim poder bloqueá-lo. Você pode verificar o IP usado pelo servidor de um determinado domínio usando o comando “dig” (que no Debian faz parte do pacote “dnsutiuls”), como em:

$ dig orkut.com

A vantagem de criar as regras do firewall baseadas em domínios é que elas são automaticamente atualizadas caso o servidor do site mude de endereço.

Ao bloquear o “orkut.com” no Iptables, você automaticamente bloqueia o “www.orkut.com” ou qualquer outra variante do domínio que leve ao mesmo servidor. A principal limitação é que a regra não se aplica a subdomínios hospedados em diferentes servidores. Por exemplo, você pode bloquear o domínio “uol.com.br”, mas isso não bloqueará o “tvuol.uol.com.br”, que é hospedado em um servidor separado. Em casos como este, a única solução é bloquear ambos.

Assim como no caso do Squid, ao decidir bloquear o acesso a sites ou endereços diversos utilizando o Iptables, você vai logo acabar com uma lista relativamente grande de endereços a bloquear. Diferente do Squid, o Iptables não oferece uma opção para carregar a lista dos endereços que devem ser bloqueados a partir de um arquivo de texto, mas isso pode ser resolvido com um script simples, que leia o conteúdo do arquivo e gere as regras correspondentes.

Comece criando um arquivo de texto contendo os domínios ou endereços IP que deseja bloquear, um por linha, como em:

http://www.orkut.com
http://www.myspace.com
http://www.facebook.com

Em seguida, adicione esta função no início do seu script de firewall, especificando o arquivo de texto com os endereços:

for end in `cat /etc/bloqueados`
do
iptables -A OUTPUT -d $end -j REJECT
iptables -A FORWARD -d $end -j REJECT
done

Esta função usa o comando cat para ler o conteúdo do arquivo, gerando um par de regras do Iptables para cada um deles. O laço continua até gerar regras para todos os endereços incluídos no arquivo.

Fonte: Link

Anúncios

~ por 3c0linux em julho 28, 2010.

 
%d blogueiros gostam disto: