Squid/IPtables - Bloqueando Facebook e personalizando IP de acesso irrestrito (definitivo)

Bloquear sites com protocolos HTTPS não é uma tarefa fácil para versões mais antigas do Squid. Neste artigo, vou demonstrar como desenvolvi uma solução, de apenas 4 linhas, que resolve totalmente este problema, com personalização de IPs de acesso.

[ Hits: 18.196 ]

Por: Claucilei B dos Santos em 30/07/2014


Entendendo o problema e resolvendo



Já, há algum tempo, o Squid sozinho sem ferramentas paralelas, não consegue ter uma boa eficiência para bloqueio de sites com o protocolo HTTPS, o fluxo de dados acaba passando por fora do Squid.

Isso já era uma dor de cabeça desde a época do velho Orkut, hoje, grande parte dos sites de relacionamentos, Facebook, Twiter, etc, utilizam o protocolo HTTPS e no mundo de hoje, com o nível altíssimo de acessos às redes sociais, causa um grande transtorno para os administradores de rede.

Alguns extremistas bloqueavam através do IPtables todo fluxo para a porta 443, porta usada pelo protocolo HTTPS, isso afetava acessos a bancos e outros sites seguros. Para determinados perfis de usuários até funciona, mas a Google resolveu utilizar todos os seus sites com o protocolo HTTPS.

Neste momento, caia por terra toda teoria que redirecionamento da porta 443 para outra, ou fechá-la seria uma opção, qualquer ação no sentido de bloquear a porta 443, seria um verdadeiro fiasco. Pois quem no mundo não usa um serviço, no mínimo, da gigante Google?

Esbarrei neste problema, fui obrigado a desenvolver uma solução prática e definitiva, sem grandes scripts, algumas poucas linhas e tudo se resolveu de maneira satisfatória, eficiente e personalizada. Sim, personalizada, pois você define o IP que terá acesso sem bloqueio.

Abaixo, as devidas explicações.

Vamos lá!

No firewall IPtables, vamos adicionar após todas as regras as seguintes linhas:

for t in `cat /etc/squid/ips_liberados` ; do
iptables -I FORWARD -i eth1 -m string --algo bm --string "facebook.com" -j DROP ! -s $t
iptables -I FORWARD -i eth1 -m string --algo bm --string "twitter.com" -j DROP ! -s $t
done

Explicação: Deve ser criado um arquivo na pasta desejada. Neste arquivo, os IPs liberados devem ser inseridos um a cada linha, se você tem um arquivo com os IPs liberados que o Squid usa, melhor ainda, pois você vai centralizar os IPs liberados tanto para Squid, quanto para o IPtables, este foi o meu caso.

Comando para criação do arquivo:

# vi /etc/squid/ips_liberados

Agora, vamos à explicação das linhas que bloquearão os sites HTTPS desejados, no meu caso, só bloqueei o Facebook e Twitter:

Usei um for para carregar todos os IPs do arquivo /etc/squid/ips_liberados na variável color="5C5C5C">t:

for t in `cat /etc/squid/ips_liberados` ; do

A linha abaixo, na interface eth1 (rede local), nela é determinado que todo fluxo com string facebook.com será dropada ou bloqueada, após o comando, utilizo o ! para fazer uma exceção aos IPs do arquivo /etc/squid/ips_liberados, que estão carregados na variável t.

Prontinho, todos os IPs que estiverem fora do arquivo color="5C5C5C">/etc/squid/ips_liberados, estarão com o Facebook bloqueado.

A linha seguinte mostra a mesma coisa, só muda o site para o twitter.com.

iptables -I FORWARD -i eth1 -m string --algo bm --string "facebook.com" -j DROP ! -s $t

Esta linha fecha o for:

done

Ponderações finais

A solução aqui apresentada foi fruto de muitas pesquisas, encontrei muitos conteúdos pela Internet, muitos com soluções complexas, muitas linhas nada eficientes, outros diziam que só usando o Squid 3 + SquidGuard, outros diziam que tinha que recompilar o kernel, enfim, muitas soluções com um nível complexo de implementação e pouca eficiência.

Eu mesmo cansei de implementar muitas regras baseadas nestas teorias que encontrei por aí, porém, depois de um tempo parava de funcionar, pois não eram flexíveis à mudanças.

A solução que cheguei foi algo simples e muito eficiente, resolvi os meus problemas com proxys que tinham GNU/Linux mais antigos, com Squid 2, por exemplo, pois existem clientes que não podem parar para atualizar o S.O., outros, não querem parar e muito menos implementar um novo S.O. do zero, então, os proxys vão ficando com sistemas antigos, sem atualizações, a manutenção a cada dia fica pior e mais arriscada.

A solução que propus resolve situações tanto para os S.Os novos, quanto para os antigos, pois todos os pacotes a serem usados já estão instalados.

Enfim, espero ter ajudado!

   

Páginas do artigo
   1. Entendendo o problema e resolvendo
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Port Scan Attack Detector (PSAD) com iptables

Dominando o Iptables (parte 2)

Ensinando seu servidor a ler emails e liberar acesso SSH

Implementando prioridade nos serviços com TOS no Iptables

Incremente o iptables com patch-o-matic

  
Comentários
[1] Comentário enviado por pvitorribeiro em 30/07/2014 - 08:39h

Claucilei, simples e objetivo, funfou de boa aqui !!

Obrigado !!

[2] Comentário enviado por ederpaulopereira em 30/07/2014 - 08:52h

Já tenho essa solução na minha empresa, funciona, entretanto, ao tentar acessar o facebook, ele fica carregando até dar o erro, seria bom se tivesse como mostrar uma página de erro, ou algo assim. No endian, dá pra cadastrar um host com o nome facebook.com, e com um ip da sua rede, aí aponta p/ um apache com uma página personalizada e tal. Mas isso é outra história.

[3] Comentário enviado por navegador_x11 em 30/07/2014 - 09:32h

Por nada pvitorribeiro, solução simples e direta!

[4] Comentário enviado por navegador_x11 em 30/07/2014 - 09:37h

Realmente é um inconveniente não apresentar uma msg de erro, mas para uma solução simples atende bem, nunca usei a distro ENdian, mas é interessante este recurso, estou tentando uma solução de redirecionamento para uma tela de erro, quando desenvolver posto aqui.

[5] Comentário enviado por px em 30/07/2014 - 18:32h


[2] Comentário enviado por ederpaulopereira em 30/07/2014 - 08:52h:

Já tenho essa solução na minha empresa, funciona, entretanto, ao tentar acessar o facebook, ele fica carregando até dar o erro, seria bom se tivesse como mostrar uma página de erro, ou algo assim. No endian, dá pra cadastrar um host com o nome facebook.com, e com um ip da sua rede, aí aponta p/ um apache com uma página personalizada e tal. Mas isso é outra história.


Sem querer me intrometer... mais seria melhor em uma rede local usar o -j REJECT ao invés do -j DROP, dê uma lida aqui nesta dica simples:

http://www.vivaolinux.com.br/dica/DROP-ou-REJECT-no-iptables/

[6] Comentário enviado por saitam em 31/07/2014 - 11:44h

No script firewall coloco assim que também bloqueia de forma efetiva o Facebook, Twitter e Youtube.

iptables -I FORWARD -i eth1 -m string --algo bm --string "facebook.com" -j DROP
iptables -I FORWARD -i eth1 -m string --algo bm --string "twitter.com" -j DROP
iptables -I FORWARD -i eth1 -m string --algo bm --string "youtube.com" -j DROP


[7] Comentário enviado por navegador_x11 em 31/07/2014 - 12:21h

Caro amigo px, eu prefiro o drop, por vários motivos, mas quem quiser usar o reject, tbm pode ser utilizado.

[8] Comentário enviado por navegador_x11 em 31/07/2014 - 12:24h

Caro amigo saitam, a sua regra funciona, porém bloqueia para a rede toda, no meu caso ñ é interessante, achei melhor personalizar o acesso e dar mais flexibilidade a regra.


Abs!

[9] Comentário enviado por navegador_x11 em 31/07/2014 - 13:48h

AMIGOS, peço desculpas ao excesso de vírgulas no texto acima, porém ao fazer o mesmo não o pontuei como está no artigo, não sei se alteraram durante a moderação, enfim, Desculpe-me!



[10] Comentário enviado por viniciuspedra em 31/07/2014 - 14:00h

existe a opção de bloquear pelo mac? e quem não estive na lista não consegue acesso?

[11] Comentário enviado por navegador_x11 em 31/07/2014 - 14:12h

Olá viniciuspedra, n testei com mac, pois se torna mais chatinho de administrar, pois queimam placas etc, etc, mas pela experiência que tenho, acredito que vai funcionar assim:

Aproveitando o meu exemplo, troque os ips que estão dentro do arquivo /etc/squid/ips_liberados e adicione os "macs", vc pode usar o meu exemplo totalmente, só altere os ips pelos macs.

Poste aqui o resultado.

Abs!

[12] Comentário enviado por px em 05/08/2014 - 18:26h


[7] Comentário enviado por navegador_x11 em 31/07/2014 - 12:21h:

Caro amigo px, eu prefiro o drop, por vários motivos, mas quem quiser usar o reject, tbm pode ser utilizado.


Entendo... você poderia me dizer quais motivos? gostaria de saber se possível pois assim vejo se cometi algum erro de minha parte.

[13] Comentário enviado por wagnerfs em 21/08/2014 - 13:31h

Parabéns pela contribuição na propagação do conhecimento.

[14] Comentário enviado por navegador_x11 em 21/08/2014 - 13:49h

Por nada K666. Abs!

[15] Comentário enviado por t3ch_security em 18/09/2014 - 22:43h

Olá navegador_x11 tentei adicionar o mac no arquivo como mencionado logo acima pelo colega viniciuspedra mas retornou o seguinte erro "host/network 'mac' not found.


[16] Comentário enviado por navegador_x11 em 19/09/2014 - 12:10h

Boa tarde t3ch_security !

Qual formtato de máscara de MAC vc está utilizando, esta "xx:xx:xx:xx:xx:xx" ou "xx-xx-xx-xx-xx-xx"? O linux utiliza "x:xx:xx:xx:xx:xx". Abs!

[17] Comentário enviado por t3ch_security em 19/09/2014 - 17:37h

Estou usando com os dois pontos mesmo.

[18] Comentário enviado por navegador_x11 em 22/09/2014 - 17:56h

Nunca testei com mac t3ch_security, assim q me sobrar um tempinho vou testar e reporto.

[19] Comentário enviado por t3ch_security em 23/09/2014 - 10:22h

ta bom obrigado

[20] Comentário enviado por navegador_x11 em 25/09/2014 - 16:08h

Olá t3ch_security, fiz uns testes aqui, veja se a linha abaixo te ajuda. Abs

iptables -I FORWARD -m string --algo bm --string "facebook" -m mac ! --mac-source 00:0F:EA:91:04:08 -j DROP

[21] Comentário enviado por navegador_x11 em 30/09/2014 - 17:47h

Também pode ser utilizado desta maneira:

iptables -I FORWARD -i eth1 -m mac --mac-source E0:CB:4E:BC:E1:B0 -m string --algo bm --string "twitter" -j REJECT

Obs: Esta eu testei e funciona perfeitamente


Criei uma outra forma de bloquear de maneira mais dinâmica, pois em alguns clientes a lista de sites estava começando a crescer, então fiz um arquivo com a lista de sites.


######### BLOQUEIA SITES HTTPS###########
for s in `cat /etc/squid/firewall/sites_https`; do
iptables -I FORWARD -i eth1 -m string --algo bm --string "$s" -j REJECT
done
########## FIM##################
########DESBLOQUEIA SITES HTTPS QUE ESTEJAM COM IPS LIBERADOS#######
for g in `cat /etc/squid/firewall/sites_https`; do
for t in `cat /etc/squid/ips_liberados`; do
iptables -I FORWARD -i eth1 -s $t -m string --algo bm --string "$g" -j ACCEPT
done
done
############ FIM ###########


[22] Comentário enviado por gnumoksha em 24/10/2014 - 17:14h

Gostaria de saber, daqueles que adotam este método, quantos hosts acessam à internet através do firewall.

Que eu saiba, o uso de comparação de strings é mais custoso. Além disso, é mais interessante criar uma chain com o a regra de bloqueio e jogar os hosts bloqueados dentro dela, ou algo do tipo. Mas, de qualquer maneira, creio que a solução mais adequada é definir o squid como proxy nas estações, assim todo o tráfego (http e https) passará por ele. Como fazer isso? Utilizando wpad, é fácil e efetivo.

[23] Comentário enviado por favera em 27/10/2014 - 12:57h

Ola, boa tarde.. eu implementei as linhas no meu script so que nao esta respeitando o listado de ips librados, to testando em uma maquina antes de implementar na empresa onde trabalho, e cuando vou trocando de ip entre os permitidos e nao permitidos, acho que cria algum conflicto. pos eu testo em todos os navegadores, e em algum abre e em otro nao, firefox abre chrome nao asim por diante.. deixarei meu script pra ver se nao tema alguma coisa errada.. desde ja agradeco a resposta.. pd: descupa a falta de ortografia, o portugues nao e minha lingua materna..


echo 1 > /procs/sys/net/ipv4/ip_forward
/sbin/iptables -N block
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128

for t in `cat /etc/squid/ips_liberados` ; do
ipatbles -I FORWARD -i eth0 -m string --algo bm --string "facebook.com" -j DROP ! -s $t
iptables -I FORWARD -i eth0 -m string --algo bm --string "youtube.com" -j DROP ! -s $t
done

as placas seriam asim
eth0: WAN
eth1: LAN


[24] Comentário enviado por tgcrypt em 06/07/2015 - 22:39h

Boa noite, estou com um pequeno problema na hora da leitura do aquivo de texto toda vez que rodo meu conf do firewall ele me da a seguinte mensagem
"Bad argument `/etc/squid3/whitelistHTTPS'
Try `iptables -h' or 'iptables --help' for more information. "

Obs: meu arquivo esta em /etc/squid3/whitelistHTTPS e o comando usado para leitura do arquivos foi


iptables -N HTTPS
iptables -A FORWARD -i $LAN -p tcp --dport 443 -j HTTPS
for SSL in 'cat /etc/squid3/whitelistHTTPS'; do
iptables -A HTTPS -d !$SSL -j DROP
done

Obs2: no meu caso estou bloqueando todo o trafego na porta 443 e liberando só o que está na lista, minha politica de FORWARD e DROP.

Obriagdo!


[25] Comentário enviado por schmeing_br em 08/11/2015 - 03:10h

Agradecendo a dica do colega e aproveitando a ideia para utilizar mais um arquivo ACL do SQUID:

echo "Liberando dominios indesejados somente aos ips livres"

for t in `cat /etc/squid3/ips_liberados` ; do
for u in `cat /etc/squid3/dominios_bloqueados` ; do
iptables -I FORWARD -i eth1 -m string --algo bm --string $u -j DROP ! -s $t
done
done



[26] Comentário enviado por janduy em 24/12/2015 - 11:57h

Valeu Brother, funcionou perfeito no meu ambiente!


Contribuir com comentário