Configurando um Proxy SSL Transparente

14

Eu tenho uma caixa Linux configurada com 2 placas de rede para inspecionar o tráfego que passa pela porta 80. Uma placa é usada para acessar a Internet, a outra é conectada a um comutador de rede. O objetivo é poder inspecionar todo o tráfego HTTP e HTTPS em dispositivos conectados a esse comutador para fins de depuração.

Eu escrevi as seguintes regras para o iptables:

nat

-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.2.1:1337
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1337

-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

Em 192.168.2.1:1337, eu tenho um proxy http transparente usando Charles ( http://www.charlesproxy.com/ ) para gravação.

Está tudo bem para a porta 80, mas quando adiciono regras semelhantes para a porta 443 (SSL) apontando para a porta 1337, recebo um erro sobre mensagens inválidas por Charles.

Eu usei o proxy SSL no mesmo computador antes com Charles ( http://www.charlesproxy.com/documentation/proxying/ssl-proxying/ ), mas não obtive êxito ao fazê-lo de forma transparente por algum motivo. Alguns recursos que pesquisei no Google dizem que não é possível - estou disposto a aceitar isso como resposta, se alguém puder explicar o porquê.

Como observação, tenho acesso total à configuração descrita, incluindo todos os clientes conectados à sub-rede - para que eu possa aceitar certificados autoassinados por Charles. A solução não precisa ser específica de Charles, já que, em teoria, qualquer proxy transparente servirá.

Obrigado!

Edit: Depois de brincar um pouco, consegui fazê-lo funcionar para um host específico. Quando modifico minhas tabelas de ip para o seguinte (e abro 1338 em charles para proxy reverso):

nat

-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.2.1:1337
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1337

-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j DNAT --to-destination 192.168.2.1:1338
-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1338

-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

Consigo obter uma resposta, mas sem host de destino. No proxy reverso, se eu apenas especificar que tudo, desde 1338, vai para um host específico que eu gostaria de acessar, ele executa o aperto de mão corretamente e eu posso ativar o proxy SSL para inspecionar a comunicação.

A configuração é inferior ao ideal, porque não quero assumir que tudo, desde 1338, vá para esse host - alguma idéia de por que o host de destino está sendo removido?

obrigado novamente

badunk
fonte
Quais problemas específicos você está tendo? É possível, já que você confia nos certificados que estão gerando dinamicamente - pode ser um MITM e capturar o texto sem formatação da comunicação e ter a conexão ainda confiável pelo cliente.
Shane Madden
Eu editei o meu post - Eu acredito que o host de destino fica retirados
badunk

Respostas:

10

Os problemas que você vê são os mesmos que impedem o uso de vários certificados em um único endereço IP / porta (sem usar a Indicação do nome do servidor) .

No HTTP simples, seu proxy transparente pode dizer a qual host o cliente deseja se conectar, olhando para o Hostcabeçalho.

Quando o proxy transparente HTTPS MITM obtém a solicitação, ele não pode saber qual nome do host o cliente estava solicitando em primeiro lugar. (Eu nem tenho certeza de que ele pode obter o endereço IP com essas regras, o que pode pelo menos ter permitido adivinhar usando uma pesquisa DNS reversa, mesmo que seja improvável que funcione no caso geral.)

  • Para obter o nome do host esperado, o proxy MITM precisaria ler o Hostcabeçalho na mensagem HTTP, que só pode ocorrer após um handshake bem-sucedido.
  • Para ter um handshake bem-sucedido, o proxy MITM precisa gerar um certificado de spoof correspondente ao nome do host esperado.

Como resultado, o proxy MITM não pode saber qual certificado gerar antes do handshake.

Isso pode funcionar com um proxy MITM não transparente, porque você obteria pelo menos o nome do host pretendido por meio do CONNECTmétodo HTTP .

Bruno
fonte
Isso me explicou muito obrigado! Sinto que posso começar a fazer as perguntas certas. Como é possível configurar um proxy SSL transparente? Como é o aperto de mão?
badunk
1
@badunk, acho que não, a menos que desative todas as verificações de certificado no lado do cliente.
de Bruno
Outra maneira de o proxy obter o nome do host correto seria fazer uma solicitação ao endereço IP de destino para obter seu certificado, antes de prosseguir com o handshake entre o cliente e o proxy.
Bruno
mitmproxy é um proxy HTTPS. Você não precisa desativar toda a verificação de certificado, mas precisa instalar o certificado mitmproxy, pois ele será usado para todas as conexões https.
Tyler
3

Apenas algumas informações básicas sobre este tópico.

Existem apenas alguns dispositivos que eu conheço que podem executar com êxito essa ação. No entanto, eles não estão realmente disponíveis ao público em geral. Eu mesmo estou usando um Fortinet Fortigate com SSL Offloading.

O que basicamente faz é; ele intercepta a conexão SSL feita com o host e descriptografa a conexão no hardware, depois inspeciona para onde deseja ir e toma uma decisão de firewall com base nessas informações.

Depois, configura sua própria conexão com o host para recuperar os dados e assinar novamente a solicitação original ao cliente usando uma CA fornecida pelo usuário. Para que isso funcione sem problemas, é necessário ter a autoridade de certificação na autoridade de certificação raiz confiável no cliente.

Esse tipo de configuração é usado nas organizações para impor políticas da empresa com relação ao uso da Internet. Como o uso do Active Directory é fácil de instalar a autoridade de certificação da empresa nos clientes, isso não é problema para grandes organizações.

Essa é a única maneira de fazer isso sem criar um proxy manual, pois o tráfego SSL é criptografado. Basicamente, é um MITM, portanto, é importante ter quaisquer questões legais cobertas.

Jochen Oonincx
fonte
1

Há mais algumas sugestões sobre essa outra questão que você já deve ter visto: mitos e fatos transparentes sobre proxy SSL . E existe esse link que explica exatamente como configurar o Squid para se tornar um proxy SSL transparente. Não é o que você está procurando, mas pelo menos pode lhe dar uma idéia do que pode estar errado.

As regras do iptables parecem boas, mas não faço ideia se o software proxy que você está usando é capaz de fazer o que você está tentando fazer. A documentação certamente afirma que esse é o caso.

chutz
fonte
0

Para adicionar à solução de Bruno, investiguei um pouco e queria compartilhar como consegui mais uma solução rápida abaixo do ideal.

Depois de definir essas tabelas de ip, posso colocar um proxy reverso na porta 1338 e encaminhar para localhost na porta 1337. Como a porta 1337 é um proxy http transparente e os dados foram descriptografados, ele pega o cabeçalho do host e o torna o destino hospedeiro.

A principal desvantagem é que eu converti essencialmente uma conexão https para http - que nem sempre funciona com todos os servidores (para não mencionar a falha de segurança que estou expondo disso).

Eu estava trabalhando dentro dos limites do meu software. Acredito que uma solução mais limpa, de acordo com Bruno, seria assumir que todo o tráfego de 1338 deveria ser descriptografado. Após a descriptografia, inspecione o host de destino e faça proxy da solicitação usando SSL.

badunk
fonte
Não sabe ao certo, certamente, você não está fazendo uma https://conexão adequada do ponto de vista do cliente com isso?
de Bruno