Httptap - veja as requisições HTTP/HTTPS de qualquer programa Linux
(github.com/monasticacademy)- httptap é uma ferramenta que executa programas Linux no formato
httptap -- <command>e mostra no terminal um resumo das requisições e respostas HTTP/HTTPS geradas por esse programa - Funciona sem privilégios de root, sem daemon, sem mudanças globais no sistema, sem regras de
iptablese sem alterar a tabela de roteamento; o executável é um binário Go estático sem dependências - No momento, é exclusivo para Linux e informa que é difícil portar para outros sistemas operacionais por usar chamadas de sistema específicas do Linux, como network namespace
- O tráfego HTTPS é descriptografado injetando em tempo de execução uma autoridade certificadora criada na hora no ambiente do subprocesso, e o funcionamento é baseado em um proxy TCP transparente que processa pacotes IP/TCP/UDP brutos
- Em Ubuntu 23.10 ou superior, ou em distribuições que desativam por padrão user namespace sem privilégios, pode ser necessária configuração de
sysctl; também há limitações como não aceitar conexões de entrada e exigir acesso a/dev/net/tun
O que o httptap faz
- httptap envolve e executa qualquer comando Linux, mostrando as requisições HTTP/HTTPS feitas por esse comando
- A forma básica de uso é
httptap -- <command> - O exemplo com
curl https://monasticacademy.orgmostra a requisiçãoGET https://monasticacademy.org/e a resposta308
- A forma básica de uso é
- No exemplo com Python
requests.get('https://monasticacademy.org'), ele segue os redirecionamentos e mostra duas requisições- A primeira requisição recebe
308parahttps://monasticacademy.org/ - A seguinte recebe
200parahttps://www.monasticacademy.org/
- A primeira requisição recebe
Instalação e requisitos de execução
- O binário pré-compilado pode ser instalado baixando o tarball da release mais recente
- Todas as versões e arquiteturas de CPU podem ser consultadas em releases
- Também há a opção de instalação com Go
go install github.com/monasticacademy/httptap@latest
- Em geral, a execução não exige privilégios de root, nem daemon, nem configuração global do sistema
- Não cria regras de
iptables - Não altera a tabela de roteamento
- Em geral, não afeta outros processos no mesmo sistema
- Não cria regras de
- No Ubuntu 23.10 ou superior, são necessárias as seguintes configurações
sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- Essas configurações desativam recursos recentes do kernel que restringem user namespace sem privilégios
- Também podem ser necessárias em outras distribuições que desativam por padrão user namespace sem privilégios
- O projeto está investigando uma forma de eliminar essa necessidade fornecendo junto um perfil AppArmor para o httptap
Exemplos de uso
- O exemplo com
curl -s https://buddhismforai.sutra.co -o /dev/nullmostra que o servidor retornou um redirecionamento302 - Se você seguir os redirecionamentos com
curl -sL, as requisições adicionais também serão exibidas- A primeira requisição retorna
302 - A segunda retorna
200para a URL de destino do redirecionamento
- A primeira requisição retorna
- No exemplo com
gcloud compute instances list, é possível ver os endpoints HTTP usados internamente pela Google Cloud CLIPOST https://oauth2.googleapis.com/tokenGET https://compute.googleapis.com/compute/v1/.../aggregated/instances?...- A saída normal do
gcloudaparece junto com o log de requisições do httptap
- No exemplo com
kubectl get all, ele mostra as requisições ao servidor de API do Kubernetes--https 443 6443faz com que conexões TCP nas portas 443 e 6443 sejam tratadas como HTTPS--insecure-skip-tls-verifyé necessário porque o kubectl não usa a autoridade certificadora gerada pelo httptap
- O exemplo com
curl --doh-url https://cloudflare-dns.com/dns-querymostra o fluxo de DNS-over-HTTP- As duas primeiras requisições são consultas DNS
- As duas seguintes são requisições HTTP normais ao site de destino
- Usando as opções
--heade--bodyjuntas, ele imprime os cabeçalhos HTTP e a carga útil bruta
Saída HAR
- Com a opção
--dump-har out.har, é possível exportar as requisições e respostas HTTP para um arquivo HAR - O arquivo HAR gerado pode ser visualizado em vários visualizadores HAR
- Um exemplo citado é o Google HAR Analyzer
- O HAR de exemplo inclui uma requisição
308 Redirectparahttps://monasticacademy.orge uma requisição200 OKparahttps://www.monasticacademy.org
Acesso a localhost
- Para acessar uma porta localhost do host a partir de dentro do httptap, use
host.httptap.localou169.254.77.65em vez delocalhost - Cada network namespace no Linux tem seu próprio dispositivo loopback
127.0.0.1, então127.0.0.1:1234dentro do httptap não é o mesmo endereço e porta do host - O httptap contorna isso roteando de forma fixa
169.254.77.65para127.0.0.1
Subprocessos que viram daemon
- No Linux, é possível criar subprocessos que continuam existindo mesmo depois que o processo original termina
- Isso é comum em daemons e em aplicativos GUI executados pela linha de comando
- Ao executar esses processos sob o httptap, o processo daemonizado continua dentro do network namespace do httptap
- A opção
--no-exitfaz o httptap continuar com o proxy e o registro mesmo depois que o subprocesso executado diretamente termina- No exemplo com Visual Studio Code, usa-se
httptap --no-exit -- code --ignore-certificate-errors . - Para encerrar, é preciso fechar o VS Code e depois finalizar o httptap com
Ctrl+C
- No exemplo com Visual Studio Code, usa-se
- Se o httptap terminar primeiro sem
--no-exit, o network namespace pode continuar existindo, mas como não haverá processo lendo os pacotes do dispositivo TUN, a conexão de rede do app será interrompida - Nos exemplos com
setsid setsid curl http://httpbin.org/gete comfork,setsid,forkem Python, sem--no-exitocorre o erroCould not resolve host
Como funciona
httptap -- <command>executa o<command>em um network namespace isolado e injeta uma autoridade certificadora criada na hora para descriptografar o tráfego HTTPS- Ele cria um dispositivo TUN no Linux e configura o ambiente do subprocesso para que todo o tráfego de rede passe por esse dispositivo
- O tráfego escrito no dispositivo TUN é entregue ao descritor de arquivo mantido pelo processo que criou esse dispositivo
- Como alterar o network namespace raiz afetaria o tráfego do sistema inteiro, o httptap cria um network namespace separado
- Nesse namespace existem apenas o dispositivo loopback e o dispositivo TUN
- O subprocesso é executado dentro desse namespace
- O tráfego recebido pelo dispositivo TUN consiste em pacotes IP brutos
- O httptap faz o parse dos pacotes IP e dos pacotes TCP/UDP internos
- Depois precisa escrever de volta pacotes IP brutos para o subprocesso
- Sua implementação própria de TCP/IP não cobre muitas partes do protocolo TCP completo, mas funciona de forma razoável para esse objetivo
- Quando o subprocesso faz uma requisição para
www.example.com, o httptap recebe um TCP SYN destinado ao IP de destino e responde com SYN+ACK- Em separado, ele usa a API normal de sockets do kernel Linux para abrir uma conexão TCP real com o IP de destino
- Depois retransmite os dados nos dois sentidos
- Essa estrutura é um proxy TCP transparente tradicional
- A descriptografia HTTPS é feita por meio da injeção da autoridade certificadora
- Na inicialização, ele gera uma autoridade certificadora correspondente a uma private key e a um x509 certificate
- Grava o certificado em um sistema de arquivos visível apenas para o subprocesso
- Define variáveis de ambiente visíveis apenas para o subprocesso para adicionar essa autoridade certificadora à lista de confiança
- Como o httptap possui a private key da autoridade certificadora, ele consegue se apresentar como se fosse o servidor com o qual o subprocesso quer se comunicar e ler a requisição HTTP em texto puro
Limitações
- Atualmente é exclusivo para Linux e depende de chamadas de sistema específicas do Linux, como network namespace
- O processo não pode aceitar conexões de rede de entrada
- É necessário ter permissão de acesso a
/dev/net/tun - Todas as requisições ICMP echo são simplesmente respondidas em eco, sem enviar pacotes ICMP para a rede real
2 comentários
it was developed at the Monastic Academy in Vermont in the US. We believe that a monastic schedule, and the practice of the Buddhist spiritual path more generally, provide ideal conditions for technological development.
Opiniões do Hacker News
A seção “How it was made” do README foi tão interessante quanto a própria ferramenta
Diz que eles vivem e praticam juntos em uma propriedade de pouco mais de 100 acres, recitam cânticos e meditam juntos de manhã e à noite, e, todo mês, por cerca de uma semana, organizam e participam de retiros de meditação. No restante do tempo, trabalham juntos no cuidado da terra, manutenção dos prédios, cozinha, limpeza, planejamento, captação de recursos e, nos últimos anos, também no desenvolvimento de software
Numa época em que microcódigo e lógica causavam problemas em escala de nanossegundos, um engenheiro exausto, ao pedir demissão, teria deixado no terminal uma nota como carta de renúncia: “Vou para uma comuna em Vermont e não vou lidar com nenhuma unidade de tempo menor que uma estação do ano”
Se é uma boa ideia, ou se levará ao resultado que eles imaginam, é outra questão
A combinação de tecnologia e meditação é atraente. A ideia em si é interessante, mas colocá-la em prática provavelmente deve ser difícil. Parece uma espécie de Recurse budista
httptap é um rastreador HTTP no escopo do processo que pode ser executado sem privilégios de root
Ao executar um programa Linux como
httptap <programa>, você vê no stdout o rastreamento das requisições e respostas HTTP/HTTPShttptap -- python -c "import requests; requests.get('https://monasticacademy.org')"---> GET https://monasticacademy.org/<--- 308 https://monasticacademy.org/ (15 bytes)---> GET https://www.monasticacademy.org/<--- 200 https://www.monasticacademy.org/ (5796 bytes)Ele funciona executando o processo dentro de um namespace de rede isolado e usa o gVisor como sua própria pilha TCP/IP. Como não é um proxy HTTP, não depende de configurações de proxy. O tráfego TLS é descriptografado com a criação de uma CA em tempo real, sem instalar regras de
iptablesnem fazer alterações globais no sistemanetstackem alguns recursos do macOSEspecialmente se não exigir configuração de proxy, fica ainda mais útil
https://blog.wireshark.org/2010/02/running-wireshark-as-you/
A ideia de executar o processo em um namespace de rede isolado é genial
A parte de HTTPS é ainda mais interessante. Parece que ele define variáveis de ambiente comuns[1] para que o programa use o bundle de CA em um diretório temporário, mas há o problema de que, assim como nas variantes de
http_proxy, o programa pode simplesmente ignorar essas variáveisTambém vi que ele monta um sistema de arquivos overlay em
/etc/resolv.conf[2]. Fico imaginando se ajudaria o httptap montar o diretório/etc/ca-certificatescom o bundle temporário de CA[1] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
[2] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
O motivo de o httptap montar um overlay em
/etc/resolv.confé que, de modo parecido com as CAs raiz, também não há uma forma confiável de dizer a um processo arbitrário qual servidor DNS usar. Ainda assim,/etc/resolv.confé uma opção bastante confiável. No momento em que você coloca o processo em um namespace de rede, ele não consegue mais acessarlocalhost:53, o resolvedor do systemd, que é a configuração mais comum em desktops Linux, então é preciso fornecer resolução DNSMontar
/etc/ca-certificatescomo overlay também poderia ajudar. Porém, ao olhar a estrutura desse diretório, fiquei surpreso com a falta de consistência entre distribuições. Ainda assim, é possível. Se alguém souber como adicionar certificados a esse diretório de um modo que pelo menos algumas implementações de TLS reconheçam, eu gostaria de ouvirComo contraexemplo, dá para imaginar um malware que se comunica por TLS e tem o código compilado fortemente ofuscado. Poderia ser um programa que inclui no binário um conjunto fixo de certificados de CA e nunca abre o sistema de arquivos. Mesmo assim, ele conseguiria criar conexões TLS seguras e válidas por cerca de 10 anos, até a maioria dos certificados de CA raiz expirar. TLS é todo tratado em espaço de usuário, e não há garantia de que use OpenSSL ou alguma outra biblioteca comum, então também não dá para contar com hooks em funções específicas do OpenSSL. Se o servidor usar um certificado autoassinado e o cliente, por qualquer motivo, aceitá-lo, fica ainda pior
Ainda assim, com um pouco de trabalho, certamente é possível lidar de forma confiável com 99% dos casos. É melhor do que não ter nada
Usar um dispositivo TUN aqui é uma ideia realmente genial. A seção “How it was made” do README também é uma das melhores que já li em um README do GitHub
Estou criando algo chamado Subtrace[1], que consegue interceptar automaticamente tanto requisições de entrada quanto de saída. É engraçado que a interface para iniciar programas parece ter convergido para o mesmo formato[2]. Mas o objetivo do Subtrace é um pouco diferente do httptap, mais voltado para observabilidade/monitoramento de serviços de backend em nuvem, por isso ele enfatiza requisições nos dois sentidos. A abordagem também é diferente. Com Seccomp BPF, ele intercepta cerca de 10 chamadas de sistema, como
socket,connect,listen,acceptetc., e faz proxy de todas as conexões TCP por meio do Subtrace. Depois, faz o parsing das requisições HTTP no stream TCP e reaproveita a aba Network do Chrome DevTools para rodar no navegador como um webapp comum e mostrar isso ao usuárioFico curioso se há alguma história interessante surgida ao executar programas sob o httptap. Também queria saber qual programa é o que mais “liga para casa”
[1] https://github.com/subtrace/subtrace
[2] https://docs.subtrace.dev/quickstart
https://github.com/M66B/NetGuard
Pode ser difícil de acreditar, mas há uma tentativa meio pronta de fazer a mesma coisa com a aba de rede do Firefox no diretório
networktabdo repositório. É um projeto muito bacana; quero aprender mais e também ficaria feliz em conversar mais sobre eleOutra ferramenta para um usuário sem privilégios analisar tráfego de rede é usar rootless Podman com Pasta
Basta adicionar o seguinte às opções de
podman run--network=pasta:--pcap,myfile.pcapEntão o Pasta registra o tráfego de rede em um arquivo PCAP, que pode ser analisado depois. Também escrevi um exemplo simples de análise de um arquivo PCAP gravado usando
tsharkhttps://github.com/eriksjolund/podman-networking-docs?tab=re...
Bem interessante. Já escrevi uma biblioteca que faz uma função parecida de “tap” em aplicações Go: https://github.com/henvic/httpretty
https://asciinema.org/a/297429
Também pensei em fazer algo assim para programas arbitrários, mas nunca fui muito a fundo em como implementar de fato. Fico contente em ver que alguém criou isso
Fico me perguntando por que não usar eBPF. Assim daria para ver de uma vez as requisições HTTP de todos os processos, inclusive os que já estão em execução. Além disso, talvez nem fosse preciso se preocupar com TLS; bastaria, por exemplo, fazer hook em
write(2)write(2)resolveria TLS. Você até poderia ler e modificar o texto cifrado, mas como o processo não chamawrite(2)com bytes em texto puro, não conseguiria ler a requisição HTTP real. No fim, você só veria os bytes criptografados que vão para a rede, e isso até a NSA consegue verÉ preciso um truque de certificado CA como o que o httptap usa. Claro que há ressalvas como certificate pinning, mas na maioria dos cenários práticos dá para fazer isso funcionar de forma confiável
Ao criar o Subtrace[1], pensei absurdamente muito sobre esse problema específico, então tenho interesse genuíno se houver uma abordagem mais simples ou elegante
[1] https://github.com/subtrace/subtrace
writecom eBPF não ajuda na descriptografia TLSDe qualquer forma, quanto mais opções, melhor
Legal. Acho que vou usar imediatamente para debugar configurações do nginx
Hoje uso
curl -ve preciso vasculhar manualmente a saída para descobrir o que deu errado; com essa ferramenta, coisas como loops de redirecionamento devem aparecer na horaParece muito bom para dar uma olhada rápida e grosseira na pilha de chamadas HTTP/S de um app
Pessoalmente, prefiro eBPF para ver tudo, mas esse utilitário pode ajudar a restringir as partes importantes em um tracing com eBPF
Parece bom
O perfil no GitHub aponta para https://www.monasticacademy.org/about; não tenho uma opinião específica sobre isso em si, mas fiquei curioso para entender como os retiros de treinamento monástico deles se conectam ao projeto no GitHub
No fim do README, a conexão estava explicada: https://github.com/monasticacademy/httptap?tab=readme-ov-fil...
Isso significa que, em uma propriedade de 123 acres em Vermont, as pessoas vivem juntas seguindo uma estrutura relativamente tradicional de mosteiro budista. Só que não são monges formalmente ordenados. Durante o dia, trabalham juntos em vários projetos técnicos e não técnicos. O link do README acima dá uma boa visão geral
https://github.com/monasticacademy/httptap?tab=readme-ov-fil...