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: 19.642 ]

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

Firewall iptables com NAT

Endian Firewall - Solução completa para um servidor de internet

Revisão atualizada de instalação do Iptables com Layer7

Criando um Firewall transparente com Bridges no Debian Etch

Script de Firewall com redirecionamento de portas em Linux Debian

  
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




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts