3 pontos por GN⁺ 2024-10-06 | 1 comentários | Compartilhar no WhatsApp
  • Com a participação de tráfego QUIC e HTTP/3 aumentando, o mitmproxy 11 habilita HTTP/3 por padrão, ampliando o alcance da análise de tráfego web moderno
  • Além de proxy transparente e proxy reverso, o HTTP/3 também funciona com WireGuard e local mode, podendo ser aplicado a diversos ambientes de captura
  • No QUIC, o Chrome não confia em uma Certificate Authority adicionada pelo usuário, então é preciso escolher entre um certificado publicamente confiável, switches de linha de comando ou fallback para HTTP/2
  • A implementação de DNS passa a ser baseada no Hickory DNS e cobre consultas além de A/AAAA, HTTPS records, DNS-over-TCP, controle do arquivo hosts e remoção de chaves ECH
  • Recursos de privacidade como ECH dificultam o fluxo de geração de certificados de um proxy man-in-the-middle, mas o mitmproxy mantém a possibilidade de funcionamento ajustando respostas DNS

Escopo do suporte a HTTP/3

  • O mitmproxy 11 oferece suporte a HTTP/3 nos modos de proxy transparente e proxy reverso
  • No proxy reverso, uma única instância do mitmproxy recebe pacotes TCP e UDP e processa a versão de HTTP encaminhada
  • WireGuard e local mode também podem usar HTTP/3
    • Comandos de exemplo:
      mitmproxy --mode wireguard
      mitmproxy --mode local
      
  • Foram feitos testes com Firefox, Chrome, várias builds do cURL e outros clientes para reduzir problemas de compatibilidade
  • O trabalho de suporte a HTTP/3 foi iniciado em 2022 por Manuel Meitinger e Maximilian Hils, e foi habilitado por padrão no mitmproxy 11

Restrições de certificado QUIC no Chrome

  • A principal limitação conhecida hoje é que, no QUIC, o Chrome não confia em uma Certificate Authority adicionada pelo usuário
  • Para lidar com tráfego HTTP/3 no Chrome, é necessário um dos seguintes caminhos
    • Fornecer um certificado publicamente confiável, como os da Let’s Encrypt
    • Executar o Chrome com os switches de linha de comando relacionados
    • Aceitar o comportamento de fallback para HTTP/2
  • O Firefox não apresenta esse comportamento
  • Dicas para solucionar problemas de HTTP/3 podem ser encontradas em #7025

Reimplementação baseada no Hickory DNS

  • Com o surgimento de recursos de privacidade como DNS HTTPS records e Encrypted Client Hello(ECH), o processamento de DNS no mitmproxy ganhou mais importância
  • A implementação anterior de DNS usava getaddrinfo, por isso tinha limitações
    • Suportava apenas consultas A/AAAA para endereços IPv4 e IPv6
    • Não conseguia responder a consultas como HTTPS records, que indicam suporte a HTTP/3
  • O mitmproxy 11 reimplementa o suporte a DNS sobre a biblioteca DNS em Rust Hickory DNS
  • Com o Hickory, ele obtém os nameservers padrão do sistema operacional no Windows, Linux e macOS, e encaminha consultas que não sejam A/AAAA para esses nameservers
  • A nova opção dns_name_servers permite especificar os nameservers de destino para encaminhamento
    mitmdump --mode dns --set dns_name_servers=8.8.8.8
    

Controle do arquivo hosts e DNS-over-TCP

  • Com a migração para o Hickory, foi adicionada uma opção para ignorar o arquivo hosts do sistema
  • A nova opção dns_use_hosts_file permite controlar se arquivos hosts, como /etc/hosts no Linux, devem ser considerados
  • A resolução interna de DNS do mitmproxy também deve ser movida para o Hickory; depois disso, esse recurso será útil ao redirecionar transparentemente domínios específicos na mesma máquina
    • Atualmente, como o arquivo hosts é sempre considerado, em uma configuração de redirecionamento na mesma máquina o mitmproxy pode acabar se conectando recursivamente a si mesmo
  • Comportamento de exemplo:
    echo "192.0.2.1 mitmproxy.org" >> /etc/hosts
    mitmdump --mode dns
    dig @127.0.0.1 +short mitmproxy.org
    192.0.2.1
    mitmdump --mode dns --set dns_use_hosts_file=false
    dig @127.0.0.1 +short mitmproxy.org
    3.161.82.13
    
  • DNS usa UDP por padrão, mas TCP pode ser necessário ao lidar com registros que não cabem em um único pacote UDP
  • Como o mitmproxy 11 passou a dar suporte a tipos arbitrários de consulta, o tamanho das mensagens e o tratamento de TCP ganharam importância, e DNS-over-TCP também funciona

Remoção de chaves ECH e geração de certificados

  • Quando não há um certificado personalizado, o mitmproxy usa o Server Name Indication(SNI) do TLS ClientHello para montar um certificado válido
  • Sem SNI, talvez não seja possível gerar um certificado em que o cliente confie
  • Encrypted Client Hello(ECH) é um mecanismo em que o cliente obtém uma chave ECH via DNS HTTPS records e então criptografa a mensagem inicial de handshake ClientHello com essa chave
  • Se tanto a consulta DNS quanto o handshake estiverem criptografados, um intermediário passivo não consegue saber o domínio de destino, apenas o endereço IP de destino
    • Em hospedagem compartilhada e Content Delivery Networks, é difícil determinar o domínio de destino apenas pelo endereço IP
  • Essa melhoria de privacidade entra em conflito com a forma como o mitmproxy gera certificados
  • O mitmproxy 11 remove as chaves ECH dos HTTPS records para obter as informações de domínio necessárias à geração do certificado
    • O cliente não obtém a chave para criptografar a mensagem inicial de handshake
    • O mitmproxy consegue identificar o domínio de destino e montar um certificado correspondente
  • ECH pode tornar o uso do mitmproxy mais difícil, mas pode ser visto como uma mudança que aumenta a privacidade na web como um todo

1 comentários

 
GN⁺ 2024-10-06
Opiniões no Hacker News
  • Fico feliz em ver que o Mitmproxy ainda está sendo desenvolvido. Essa ferramenta, indiretamente, construiu minha carreira
    Em 2011, enquanto eu aprendia desenvolvimento de APIs interceptando requisições de apps móveis, descobri que a API do Airbnb estava exposta a uma vulnerabilidade de atribuição em massa do Rails (https://github.com/rails/rails/issues/5228). Depois de mudar algumas propriedades inofensivas, entrei em contato com a empresa, isso levou a uma entrevista, e o resto é literalmente história

    • A quantidade de desenvolvedores centrais naquele issue se opondo à mudança era realmente absurda
    • Ainda hoje ele é extremamente útil para mim, mas surpreende como até pessoas que deveriam conhecer muitas vezes não conhecem bem o Mitmproxy
      Às vezes é mais fácil plugar o mitmproxy em uma implementação existente do que ler a documentação
  • É interessante que o Chrome não confie em autoridades certificadoras adicionadas pelo usuário no QUIC
    No issue relacionado, a equipe do Chrome diz: “não permitimos explicitamente certificados que não sejam publicamente confiáveis para impedir a implantação de software/hardware de interceptação de QUIC. Caso contrário, isso prejudicaria a possibilidade de evolução do protocolo QUIC no longo prazo. Casos de uso que dependem de certificados que não sejam de confiança pública podem usar TLS+TCP em vez de QUIC”
    Não acompanho a evolução do protocolo, mas não entendo bem como bloquear certificados personalizados se conecta à capacidade de evolução. Fico curioso se alguém sabe o motivo

    • Meu palpite é que, como o Google controla tanto o cliente quanto grandes endpoints de servidor (Google Search, Youtube etc.), ele quer ter liberdade para fazer experimentos com mudanças no QUIC
      Eles podem colocar uma versão levemente modificada do QUIC no Chrome e dar suporte a ela em lugares como o Youtube, depois usar essas métricas para propor uma mudança “de verdade” no padrão ou continuar rodando uma versão especial só nos próprios serviços
      Se certificados personalizados fossem permitidos, empresas que inspecionam o tráfego dos funcionários com man-in-the-middle, usando coisas como ZScaler ZIA, correriam o risco de quebrar quando o protocolo mudasse. Se o fluxo de dados estiver totalmente criptografado e opaco para equipamentos intermediários, o Google pode fazer praticamente o que quiser
      Conceito relacionado: https://en.wikipedia.org/wiki/Protocol_ossification
    • Equipamentos intermediários (https://en.m.wikipedia.org/wiki/Middlebox) são uma causa bem conhecida de estagnação de protocolos
      Em geral, protocolos extensíveis exigem apenas a atualização do cliente e do servidor, mas, com middleboxes no caminho, potencialmente N equipamentos também precisam ser atualizados. Usuários e provedores de serviço têm incentivo para adotar novos recursos, mas os donos dos equipamentos intermediários podem não ter. Como resultado, fica difícil para o protocolo evoluir
    • Pode ser uma referência ao caso famoso em que instituições financeiras foram contra o TLS 1.3. A motivação era não querer atualizar o software de man-in-the-middle necessário para conformidade regulatória: https://mailarchive.ietf.org/arch/msg/tls/CzjJB1g0uFypY8UDdr6P9SCQBqA/
    • Um dos motivos para criar HTTP/2 e HTTP/3 também foi o fato de ser difícil demais fazer mudanças no HTTP 1.1
      Havia muito middleware que dependia fortemente de detalhes de implementação, então mudar qualquer coisinha podia quebrar a experiência do usuário sem querer. Parece que estão tentando evitar uma situação parecida nas novas versões
    • O QUIC existe para aumentar a taxa de entrega de anúncios, então dar liberdade ao usuário entra em conflito com esse objetivo
  • Fico curioso se há benefício quando HTTP/2 ou HTTP/3 são suportados apenas no proxy reverso, e não no servidor web real
    A maioria dos frameworks populares em JS/Python/Ruby não oferece suporte aos novos padrões HTTP. Nesse caso, o servidor web não viraria o gargalo da conexão com o proxy reverso?

    • Há, sim. HTTP/2 e HTTP/3 aumentam a confiabilidade da conexão entre o cliente e o proxy reverso
      A conexão entre o proxy reverso e o servidor web real geralmente é muito mais rápida e estável, então o ganho de elevar esse trecho para HTTP/2 ou HTTP/3 é bem menor
    • O transporte entre o proxy reverso e o backend nem sempre é HTTP. Por exemplo, Python às vezes usa uWSGI, e PHP usa FastCGI
      Mesmo quando se usa HTTP, o proxy reverso consegue estabelecer conexões com o backend muito mais rápido do que com o cliente remoto real. Por isso, ainda é vantajoso usar streams HTTP/2 no trecho lento
    • Talvez não faça muita diferença, mas o mitmproxy não é um proxy reverso para ambiente de produção
      É uma ferramenta que você roda na máquina local para testar protocolos de baixo nível ou segurança web
    • Há um ponto que ficou faltando. Navegadores web limitam o número de conexões por domínio a 6
      No HTTP/2 e acima, várias requisições simultâneas são tratadas em uma única conexão
    • Há, sim. Além de outros benefícios de desempenho, o HTTP/3 combina os handshakes de TCP e TLS e reduz uma ida e volta na conexão
  • O problema de fingerprinting ainda permanece. Até que seja possível imitar o handshake TLS de um navegador comum, em cerca de 80% da web você verá páginas como “Just a quick check...” ou “Sorry, it looks like you're a bot”
    https://github.com/mitmproxy/mitmproxy/issues/4575

    • Então parece que o Firefox não é mais um navegador comum
  • Obrigado por mencionar o Hickory. É sempre divertido ver o que as pessoas constroem com ele, e é um trabalho bem feito

    • Agradeço pelo trabalho no Hickory. É realmente interessante que a interoperabilidade Python↔Rust do PyO3 tenha permitido usar, em Python, uma biblioteca DNS de nível operacional como o Hickory e uma pilha de rede em espaço de usuário robusta como o smoltcp
      Essas coisas originalmente seriam difíceis de obter só com Python
  • Fico curioso se dá para usar o Mitmproxy como Privoxy/Proxomitron/Yarip
    Por exemplo, ao navegar no Ungoogled Chromium, eu poderia colocar o Mitmproxy como proxy e remover tags script de determinados sites? Qual seria o impacto no desempenho?

    • Em teoria, sim. Na prática, como o mitmproxy é escrito em Python, haverá latência, já que a linguagem não é muito rápida
      Ao visualizar uma página web, pequenos atrasos se acumulam centenas de vezes e podem ser perceptíveis
      Ainda assim, para quem se interessa por esse uso, pode ser uma opção. Tecnicamente, nada impede
      Ao reescrever arquivos JavaScript, há um pequeno risco de mexer na verificação de integridade de sub-recursos, mas, se isso de fato causar problema, acho que seria possível resolver reescrevendo também os hashes
  • O mitmproxy pode ser uma alternativa ao Fiddler?

  • Hmm: https://github.com/mitmproxy/mitmproxy/issues/4170