forçar clientes a usar proxy

3

Aqui está minha configuração de rede:

Minha configuração de rede http://daveden.files.wordpress.com/2013/05/ network-configuration.png

O servidor proxy está executando o Ubuntu com o Squid na porta 3128 e o DansGuardian na porta 8080.

Eu gostaria de forçar todos os clientes a usar o servidor proxy - especificamente, a porta 8080 - para qualquer acesso HTTP / HTTPS.

No entanto, não quero redirecionar de forma transparente porque isso não funciona para HTTPS. Não me importo de configurar cada cliente, e não me importo que cada cliente saiba que está usando um servidor proxy. Eu só não quero que os clientes possam navegar na web sem as configurações de proxy.

Como faço isso? Posso apenas descartar pacotes se o cliente não estiver configurado para usar o servidor proxy na porta 8080?

Eu tentei usar o iptables para descartar pacotes que tinham um dport diferente de 8080, mas que rejeitava muito e eu não conseguia mais acessar nada.

EDITAR

Eu re-escrevi esta questão para que não seja específica do iptables, mas eu não sou contra o uso do iptables. Eu só quero atrair um leque mais amplo de possíveis soluções.

EDIT 2

Acho que posso ter dado uma impressão errada. Apenas para esclarecer, não estou interessado em filtrar o tráfego HTTPS (ou seja, observando os pacotes separados no proxy e inspecionando o conteúdo). Estou mais interessado em bloquear sites com o DansGuardian, seja por HTTP ou HTTPS (olhando o destino dos pacotes).

EDIT 3

Com base na sugestão de Alexandru-Florin Vintil abaixo, eis o que estou fazendo atualmente:

# Redirect HTTP traffic to port 8080 (DansGuardian)
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080

# Check TCP and UDP traffic against whitelist
iptables -A FORWARD -i eth1 -p tcp --dport 443 -j whitelist
iptables -A FORWARD -i eth1 -p udp --dport 443 -j whitelist

# Drop all other HTTPS traffic
iptables -A FORWARD -i eth1 -p tcp --dport 443 -j DROP
iptables -A FORWARD -i eth1 -p udp --dport 443 -j DROP

# Drop all traffic aimed straight at the proxy
iptables -A FORWARD -i eth1 -p tcp --dport 3128 -j DROP
iptables -A FORWARD -i eth1 -p udp --dport 3128 -j DROP
iptables -A FORWARD -i eth1 -p tcp --dport 8080 -j DROP
iptables -A FORWARD -i eth1 -p udp --dport 8080 -j DROP

Em poucas palavras, redirecione o tráfego HTTP para a porta 8080, elimine todo o tráfego HTTPS que não esteja na lista de permissões (em uma cadeia separada) e elimine todo o tráfego que use explicitamente o proxy. Sem a última regra, um cliente pode acessar qualquer site usando HTTPS, desde que eles configurem seu navegador para usar o proxy, porque a porta de destino é 8080 e não 443. Então, mesmo descartando todo o tráfego ligado a 443, ele não bloqueia totalmente o HTTPS. .

    
por davidkennedy85 29.05.2013 / 07:03

6 respostas

1

Meus 2 centavos:

Em relação ao HTTP: Ter um firewall transparente para encaminhar o tráfego da porta 80 para um proxy / filtro é a maneira mais simples de fazer as coisas. Não há necessidade de configuração do cliente, + você pode isentar qualquer host / sub-rede de usar o proxy sem a necessidade de reconfiguração do cliente. Esta é a única maneira de ter certeza de que tudo o que deve passar por proxy é.

Qualquer método diferente de bloquear todo o tráfego de saída de HTTPS 443 e permitir que apenas um subconjunto de sites com base no ip permitido para a porta de saída 443 não funcione como esperado. Protocolo seguro do HTTPS é projetado (algumas falhas de lado) para evitar ataques Man-In-The-Middle (proxies são MITM "legal"). Dessa forma, o HTTPS pode fazer o que foi projetado para fazer. Se, no entanto, você quiser IGNORE HTTPS, você deve configurar seu squid para usar DIRECT e não usar CONNECT (tocar), mas, mesmo se este for o caso, você ainda pode encontrar sites problemáticos com HTTP misto / HTTPS partes. Desta forma, o seu proxy Squid irá gerenciar HTTPS também. Isso também deve ser refletido na parte de encaminhamento transparente do seu firewall.

    
por 25.05.2013 / 00:46
3

Sempre que você vê que algo que deve funcionar não está funcionando, você precisa perguntar se há algum outro fator envolvido que você não está vendo. A regra

sudo iptables -A INPUT -p tcp ! --dport 8080 -j REJECT

Parece que deve funcionar, mas você adicionou à cadeia INPUT, então é provável que ela seja contornada por uma regra anterior na cadeia. Essa regra deve ser adequada por si só, já que a cadeia INPUT é a primeira cadeia que os pacotes recebidos atingem. Se eles são REJEITADOS na cadeia INPUT, eles nunca chegam às cadeias FORWARD ou OUTPUT. Claro, esta regra irá bloquear tudo TCP que não é destinado à porta 8080, o que provavelmente não é o que você realmente quer no final, a menos que o proxy 8080 seja o único serviço na máquina e você só faça o login no console.

Então, a primeira coisa a fazer é listar as regras e procurar o que pode estar causando a passagem dos pacotes:

sudo iptables -L

Se o seu firewall é o NAT reverso, você também deve listar a tabela NAT.

sudo iptables -L -t nat

Depois, tente colocar a mesma regra no início da cadeia:

sudo iptables -I INPUT -p tcp ! --dport 8080 -j REJECT

e veja se isso não resolve o problema, ou pelo menos lhe dá mais confiança de que você entende como o iptables funciona para que você possa concluir seu conjunto de regras. Se você estiver trabalhando com este host remoto, minha sugestão irá interrompê-lo, por isso você deve fazer isso apenas no console. Para trabalhar com segurança a partir do remoto, consulte meu colega Postagem de Eli Rosencruft sobre ajustes de firewalls do controle remoto .

    
por 20.05.2013 / 13:34
2

Padrão

Uma cadeia separada (definida pelo usuário) pode ajudar.

# create a chain just for user 100 (192.168.1.100)
iptables -N custom_user_100

# redirect all traffic FROM user 100 to custom chain
iptables -A INPUT -p tcp -s 192.168.1.100 -j custom_user_100

# return from user chain for valid traffic, drop all other
iptables -A custom_user_100 -p tcp --dport 8080 -j RETURN
iptables -A custom_user_100 -j DROP

Então - o que isso faz é redirecionar qualquer tráfego FROM 192.168.1.100 para uma cadeia personalizada. Essa cadeia personalizada (definida pelo usuário) retorna apenas se uma correspondência válida for encontrada (tráfego destinado à porta 8080). Todo o outro tráfego não correspondente que não resulta em um retorno da cadeia é descartado .

Mais tarde, você poderá visualizar as estatísticas das tabelas para verificar o que aconteceu:

iptables -L -v -n

Encaminhamento

Agora, se você estiver processando o encaminhamento de tráfego, haverá um conjunto diferente de regras, mas a ideia de usar uma cadeia personalizada (definida pelo usuário) é a mesma. Eu gostaria de me referir ao diagrama neste link: link ao tentar entender o fluxo de pacotes.

Nesse caso, você pode querer fazer algo como o seguinte:

# create a chain just for user 100 (192.168.1.100)
iptables -N custom_user_100

# redirect all traffic FROM user 100 to custom chain
iptables -A FORWARD -p tcp -s 192.168.1.100 -j custom_user_100

# return from user chain for valid traffic, drop all other
iptables -A custom_user_100 -p tcp --dport 8080 -j RETURN
iptables -A custom_user_100 -j DROP

Isso é idêntico ao primeiro, exceto que a regra que foi aplicada à cadeia INPUT é, em vez disso, aplicada à cadeia FORWARD.

Atualização 2013-05-24

Eu releio sua pergunta. Então vai começar de novo.

Vamos supor que seu "proxy" seja na verdade um roteador. Isto é - está passando todos os pacotes de uma interface para outra - talvez usando NAT. Isso significa que todos os pacotes de interesse estão fluindo pela cadeia FORWARD.

Próximo: você diz que irá configurar todos os clientes usando a porta 8080 para acessar o próprio proxy. Bem. Isso significa que todos os pacotes aqueles entrarão no "proxy" através da cadeia INPUT.

Então: você só quer impedir que alguém saia da porta 8080 na cadeia FORWARD.

iptables -A FORWARD -p tcp --dport 8080 -j REJECT

Esta regra irá garantir que qualquer coisa que deva ser encaminhada para uma porta de destino 8080 será rejeitada (um pacote ICMP será enviado para o cliente que tentou passar o pacote através do proxy).

Depois de implementar esta regra, é VITAL que você teste isso tentando fazer uma conexão proibida - então, você lista as regras digitando:

iptables -L -v -n |grep 8080

e garanta que o contador tenha aumentado. Se não, então algo está errado com a configuração do roteador.

    
por 20.05.2013 / 13:23
1

Primeiro, leia um pouco da documentação de iptables - especificamente, pelo menos você precisa saber em quais cadeias em que tabelas um pacote entrará (dê uma olhada aqui: link ).

Você terá que equilibrar entre duas coisas: sua meta de forçar todos a usar o proxy e a conveniência de todos. Por um lado, você pode impedir o encaminhamento de quaisquer pacotes (você pode até desabilitar ip_forwarding flag no kernel). Desta forma, os computadores locais poderão acessar a Internet apenas pelo seu servidor proxy. Mas mesmo isso não impedirá que todos usem uma conexão via túnel através de seu proxy http (e é ainda mais fácil com os https). Portanto, você não poderá monitorar nem limitar totalmente o uso da Internet.

Por outro lado, você pode adotar uma abordagem ainda mais simples: limitar o tráfego de saída à porta 80. Nesse caso, o software que não usa http (por exemplo, skype) não terá que encapsular o tráfego em http e o bom -como clientes terão todos os benefícios de um cache http local (acesso mais rápido aos sites).

Sua configuração atual parece a primeira opção acima. Mas você tem as regras de ACEITAR desnecessárias na cadeia FORWARD. Você não quer que o roteador encaminhe nenhum pacote. Os computadores locais se conectam ao seu proxy (os pacotes passam pela cadeia INPUT) e não aos hosts remotos. Com sua configuração atual, alguém poderia encontrar um proxy escutando na porta 8080 em qualquer lugar da Internet e usá-lo em vez de seu proxy.

    
por 23.05.2013 / 19:39
1

Se você não quiser que seus clientes acessem apenas sites http {s} sem o proxy, então você pode apenas DROP ou REJECT encaminhar pacotes para as portas 80 e 443:

IPTABLES -I FORWARD -i eth1 -p tcp -m multiport --dports 80,443 -j REJECT

Onde eth1 é sua interface interna. Fazendo assim você não terá que mexer com outras portas / acesso.

    
por 23.05.2013 / 20:28
0

Pessoalmente, gosto de definir as políticas padrão para a cadeia INPUT e FORWARD para DROP

iptables -P INOUT DROP
iptables -P FORWARD DROP

Em seguida, permita apenas o tráfego que quero - assim, encontro menos surpresas e tenho muita certeza de que apenas o que eu autorizo está indo para onde o direciono.

    
por 20.05.2013 / 19:58