- httptap ist ein Tool, das Linux-Programme in der Form
httptap -- <command>ausführt und die HTTP/HTTPS-Anfragen sowie eine Zusammenfassung der Antworten, die das Programm erzeugt, im Terminal anzeigt - Es funktioniert ohne Root-Rechte, Daemon, systemweite Änderungen,
iptables-Regeln oder Änderungen an der Routing-Tabelle; die ausführbare Datei ist ein abhängigkeitfreies statisches Go-Binary - Derzeit ist es nur für Linux verfügbar und erklärt, dass eine Portierung auf andere Betriebssysteme schwierig ist, weil Linux-spezifische Systemaufrufe wie network namespace verwendet werden
- HTTPS-Traffic wird entschlüsselt, indem beim Start eine spontan erzeugte Zertifizierungsstelle in die Umgebung des Subprozesses injiziert wird; intern arbeitet es als transparenter TCP-Proxy, der rohe IP/TCP/UDP-Pakete verarbeitet
- Unter Ubuntu 23.10 oder neuer sowie auf Distributionen, bei denen unprivilegierte User-Namespaces standardmäßig deaktiviert sind, kann eine
sysctl-Konfiguration nötig sein; außerdem gibt es Einschränkungen wie das Annehmen eingehender Verbindungen und den Zugriff auf/dev/net/tun
Was httptap macht
- httptap führt einen beliebigen Linux-Befehl umhüllt aus und zeigt die HTTP/HTTPS-Anfragen an, die dieser Befehl erzeugt
- Die grundlegende Verwendung ist
httptap -- <command> - Im Beispiel mit
curl https://monasticacademy.orgwird die AnfrageGET https://monasticacademy.org/und die Antwort308angezeigt
- Die grundlegende Verwendung ist
- Im Beispiel mit Python
requests.get('https://monasticacademy.org')werden beim Folgen von Redirects zwei Anfragen angezeigt- Die erste Anfrage erhält für
https://monasticacademy.org/ein308 - Die nächste Anfrage erhält für
https://www.monasticacademy.org/ein200
- Die erste Anfrage erhält für
Installation und Ausführungsbedingungen
- Vorab gebaute Binaries können durch Herunterladen des neuesten Release-Tarballs installiert werden
- Alle Versionen und CPU-Architekturen sind unter releases verfügbar
- Es gibt auch eine Installationsmethode über Go
go install github.com/monasticacademy/httptap@latest
- Für die Ausführung sind in der Regel weder Root-Rechte noch ein Daemon oder systemweite Konfigurationen erforderlich
- Es werden keine
iptables-Regeln angelegt - Die Routing-Tabelle wird nicht verändert
- Andere Prozesse auf demselben System werden normalerweise nicht beeinflusst
- Es werden keine
- Unter Ubuntu 23.10 oder neuer sind die folgenden Einstellungen erforderlich
sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- Diese Einstellungen deaktivieren aktuelle Kernel-Funktionen, die unprivilegierte user namespace einschränken
- Sie können auch auf anderen Distributionen nötig sein, bei denen unprivilegierte User-Namespaces standardmäßig deaktiviert sind
- Es wird untersucht, ob ein mitgeliefertes AppArmor-Profil für httptap diese Anforderung überflüssig machen kann
Anwendungsbeispiele
- Das Beispiel mit
curl -s https://buddhismforai.sutra.co -o /dev/nullzeigt, dass der Server einen302-Redirect zurückgegeben hat - Wenn man Redirects wie mit
curl -sLfolgt, werden auch zusätzliche Anfragen angezeigt- Die erste Anfrage ergibt
302 - Die zweite Anfrage ergibt
200für die Ziel-URL des Redirects
- Die erste Anfrage ergibt
- Im Beispiel
gcloud compute instances listlassen sich die HTTP-Endpunkte sehen, die die Google Cloud CLI intern verwendetPOST https://oauth2.googleapis.com/tokenGET https://compute.googleapis.com/compute/v1/.../aggregated/instances?...- Die normale
gcloud-Ausgabe erscheint zusammen mit dem Anfrage-Log von httptap
- Im Beispiel
kubectl get allwerden die Anfragen an den Kubernetes-API-Server angezeigt--https 443 6443behandelt TCP-Verbindungen auf Port 443 und 6443 als HTTPS--insecure-skip-tls-verifyist nötig, weilkubectldie von httptap erzeugte Zertifizierungsstelle nicht verwendet
- Das Beispiel
curl --doh-url https://cloudflare-dns.com/dns-queryzeigt einen DNS-over-HTTP-Ablauf- Die ersten beiden Anfragen sind DNS-Abfragen
- Die nächsten beiden Anfragen sind normale HTTP-Anfragen an die Zielseite
- Werden die Optionen
--headund--bodyzusammen verwendet, gibt das Tool HTTP-Header und rohe Payloads aus
HAR-Ausgabe
- Mit der Option
--dump-har out.harkönnen HTTP-Anfragen und -Antworten in eine HAR-Datei geschrieben werden - Die erzeugte HAR-Datei kann in verschiedenen HAR-Viewern visualisiert werden
- Als Beispiel wird Google HAR Analyzer genannt
- Die Beispiel-HAR enthält eine Anfrage an
https://monasticacademy.orgmit308 Redirectund eine Anfrage anhttps://www.monasticacademy.orgmit200 OK
Zugriff auf localhost
- Um innerhalb von httptap auf einen localhost-Port des Hosts zuzugreifen, verwendet man statt
localhostentwederhost.httptap.localoder169.254.77.65 - Jeder network namespace unter Linux besitzt ein eigenes Loopback-Gerät
127.0.0.1; deshalb ist127.0.0.1:1234innerhalb von httptap nicht dieselbe Adresse und derselbe Port wie auf dem Host - httptap umgeht dieses Problem, indem es hartkodiert
169.254.77.65auf127.0.0.1routet
Als Daemon weiterlaufende Subprozesse
- Unter Linux können Subprozesse erzeugt werden, die auch nach dem Ende des ursprünglichen Prozesses weiterlaufen
- Das ist ein übliches Muster bei Daemons und GUI-Apps, die über die Kommandozeile gestartet werden
- Werden solche Prozesse unter httptap gestartet, bleiben die daemonisierten Prozesse weiterhin im network namespace von httptap
- Mit der Option
--no-exitlässt sich erreichen, dass httptap Proxying und Logging fortsetzt, auch nachdem der direkt gestartete Subprozess beendet ist- Im Beispiel mit Visual Studio Code wird
httptap --no-exit -- code --ignore-certificate-errors .verwendet - Zum Beenden muss man nach dem Schließen von VS Code httptap mit
Ctrl+Cbeenden
- Im Beispiel mit Visual Studio Code wird
- Wenn httptap ohne
--no-exitzuerst endet, bleibt der Network Namespace zwar bestehen, aber da kein Prozess mehr Pakete vom TUN-Gerät liest, brechen die Netzwerkverbindungen der App ab - Auch in den Beispielen mit
setsid setsid curl http://httpbin.org/getsowie Python mitfork,setsid,forktritt ohne--no-exitder FehlerCould not resolve hostauf
Funktionsweise
httptap -- <command>führt<command>in einem isolierten network namespace aus und injiziert eine spontan erzeugte Zertifizierungsstelle, um HTTPS-Traffic zu entschlüsseln- Es erstellt ein Linux-TUN-Gerät und konfiguriert die Umgebung des Subprozesses so, dass sämtlicher Netzwerk-Traffic durch dieses Gerät läuft
- Traffic, der an das TUN-Gerät geschrieben wird, wird an den Dateideskriptor des Prozesses geliefert, der das Gerät erstellt hat
- Würde man den Root-Network-Namespace verändern, hätte das Auswirkungen auf den gesamten System-Traffic; deshalb erstellt httptap einen separaten Network Namespace
- Dieser Namespace enthält nur ein Loopback-Gerät und das TUN-Gerät
- Der Subprozess wird innerhalb dieses Namespace ausgeführt
- Der vom TUN-Gerät empfangene Traffic besteht aus rohen IP-Paketen
- httptap parst die IP-Pakete und die darin enthaltenen TCP/UDP-Pakete
- Es muss anschließend wieder rohe IP-Pakete an den Subprozess zurückschreiben
- Die eigene TCP/IP-Implementierung lässt zwar viele Teile des vollständigen TCP-Protokolls aus, funktioniert für den vorgesehenen Zweck aber ausreichend gut
- Wenn der Subprozess eine Anfrage an
www.example.comstellt, empfängt httptap ein TCP-SYN an die Ziel-IP und antwortet mit SYN+ACK- Separat baut es über die normale Socket-API des Linux-Kernels eine echte TCP-Verbindung zur Ziel-IP auf
- Danach werden Daten in beide Richtungen weitergeleitet
- Diese Struktur ist ein klassischer transparenter TCP-Proxy
- Die HTTPS-Entschlüsselung erfolgt über die Injektion einer Zertifizierungsstelle
- Beim Start wird eine Zertifizierungsstelle erzeugt, die aus Private Key und x509 certificate besteht
- Das Zertifikat wird in ein Dateisystem geschrieben, das nur für den Subprozess sichtbar ist
- Es werden Umgebungsvariablen gesetzt, die nur für den Subprozess sichtbar sind, damit diese Zertifizierungsstelle zur Vertrauensliste hinzugefügt wird
- Da httptap den Private Key der Zertifizierungsstelle besitzt, kann es sich gegenüber dem Subprozess als der Server ausgeben, mit dem kommuniziert werden soll, und die HTTP-Anfragen im Klartext lesen
Einschränkungen
- Derzeit nur für Linux, da es von Linux-spezifischen Systemaufrufen wie network namespace abhängt
- Prozesse können keine eingehenden Netzwerkverbindungen annehmen
- Zugriffsrechte auf
/dev/net/tunsind erforderlich - Alle ICMP-Echo-Anfragen werden lediglich zurückgespiegelt, statt echte ICMP-Pakete ins Netzwerk zu senden
2 Kommentare
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.
Meinungen auf Hacker News
Der Abschnitt „How it was made“ im README war fast so interessant wie das Tool selbst.
Dort heißt es, sie lebten und praktizierten gemeinsam auf etwas mehr als 100 Acres Land, chanteten und meditierten morgens und abends zusammen und organisierten bzw. besuchten etwa eine Woche pro Monat Meditations-Retreats. In der übrigen Zeit kümmerten sie sich gemeinsam um Landpflege, Gebäudeinstandhaltung, Kochen, Putzen, Planung, Fundraising und in den letzten Jahren auch um Softwareentwicklung.
In einer Zeit, in der Mikrocode und Logik Probleme im Nanosekundenbereich verursachten, soll ein überarbeiteter Ingenieur bei seinem Abschied am Terminal als Kündigungsschreiben diese Notiz hinterlassen haben: „Ich gehe in eine Kommune in Vermont und werde mich nicht mehr mit Zeiteinheiten befassen, die kürzer sind als Jahreszeiten.“
Ob das eine gute Idee ist oder zu den Ergebnissen führt, die sie sich vorstellen, ist eine andere Frage.
Die Kombination aus Technik und Meditation spricht mich an. Die Idee selbst ist attraktiv, aber sie tatsächlich umzusetzen, dürfte wohl schwierig sein. Es wirkt wie eine Art buddhistisches Recurse.
httptap ist ein HTTP-Tracer auf Prozessebene, der ohne Root-Rechte ausgeführt werden kann.
Wenn man ein Linux-Programm wie
httptap <Programm>startet, sieht man auf der Standardausgabe Traces der HTTP/HTTPS-Requests und -Responses.httptap -- 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)Es läuft in einem isolierten Network Namespace und nutzt gVisor als eigenen TCP/IP-Stack. Da es kein HTTP-Proxy ist, hängt es nicht von Proxy-Einstellungen ab. TLS-Traffic wird durch das spontane Erzeugen einer CA entschlüsselt; es installiert keine
iptables-Regeln und nimmt keine globalen Systemänderungen vor.netstack-Bibliothek.Besonders nützlich wäre es, wenn keine Proxy-Einstellungen nötig sind.
https://blog.wireshark.org/2010/02/running-wireshark-as-you/
Die Idee, einen Prozess in einem isolierten Network Namespace auszuführen, ist genial.
Der HTTPS-Teil ist noch interessanter. Es sieht so aus, als würden gemeinsame Umgebungsvariablen[1] gesetzt, damit das Programm ein CA-Bundle in einem temporären Verzeichnis verwendet; dabei gibt es aber, ähnlich wie bei den
http_proxy-Varianten, das Problem, dass ein Programm diese Variablen einfach ignorieren kann.Außerdem scheint ein Overlay-Dateisystem auf
/etc/resolv.confgemountet zu werden[2]. Ich frage mich, ob es helfen würde, wenn httptap das Verzeichnis/etc/ca-certificatesals temporäres CA-Bundle mounten würde.[1] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
[2] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
Dass httptap ein Overlay auf
/etc/resolv.confmountet, liegt daran, dass es bei der DNS-Auflösung ähnlich wie bei CA-Roots keine wirklich sichere Möglichkeit gibt, einem beliebigen Prozess mitzuteilen, welchen DNS-Server er verwenden soll. Trotzdem ist/etc/resolv.confeine ziemlich verlässliche Option. Sobald man einen Prozess in einen Network Namespace steckt, kann er auf dem Desktop-Linux-Standardsetup, den systemd-Resolverlocalhost:53, nicht mehr zugreifen, also muss man DNS-Auflösung bereitstellen.Ein Overlay-Mount von
/etc/ca-certificateskönnte ebenfalls helfen. Als ich mir die Verzeichnisstruktur angesehen habe, war ich allerdings erstaunt, wie inkonsistent sie je nach Distribution ist. Möglich ist es aber. Wenn jemand weiß, wie man dort Zertifikate so hinzufügt, dass zumindest einige TLS-Implementierungen sie erkennen, würde ich das gern hören.Als Gegenbeispiel kann man sich Malware vorstellen, die über TLS kommuniziert und deren kompilierter Code stark obfuskiert ist. Es könnte ein Programm sein, das ein festes Bündel von CA-Zertifikaten in die Binary einbettet und das Dateisystem überhaupt nicht öffnet. Trotzdem könnte es noch etwa zehn Jahre lang, bis die meisten Root-CA-Zertifikate ablaufen, gültige und sichere TLS-Verbindungen aufbauen. TLS läuft vollständig im Userspace, und es gibt keine Garantie, dass OpenSSL oder eine andere gemeinsame Bibliothek verwendet wird; daher kann man auch nicht darauf setzen, bestimmte OpenSSL-Funktionen zu hooken. Noch schlimmer wird es, wenn der Server ein selbstsigniertes Zertifikat verwendet und der Client es aus irgendeinem Grund akzeptiert.
Trotzdem ist es mit etwas Arbeit sicher möglich, 99 % der Fälle zuverlässig abzudecken. Das ist besser als nichts.
Hier eine TUN-Schnittstelle zu verwenden, ist wirklich eine großartige Idee. Auch der Abschnitt „How it was made“ im README gehört zu den besten, die ich je in einem GitHub-README gelesen habe.
Ich baue gerade etwas namens Subtrace[1], das sowohl eingehende als auch ausgehende Requests automatisch abfangen kann. Witzig ist, dass sich offenbar auch das Interface zum Starten von Programmen in dieselbe Form entwickelt hat[2]. Der Zweck von Subtrace unterscheidet sich allerdings etwas von httptap und liegt eher bei Observability/Monitoring für Cloud-Backend-Services, weshalb bidirektionale Requests betont werden. Auch der Ansatz ist anders: Mit Seccomp BPF werden etwa zehn Systemaufrufe wie
socket,connect,listen,acceptusw. abgefangen, sodass alle TCP-Verbindungen über Subtrace geproxyt werden. Anschließend werden HTTP-Requests aus dem TCP-Stream geparst, und der Network-Tab der Chrome DevTools wird so wiederverwendet, dass er wie eine normale Web-App im Browser läuft und dem Nutzer angezeigt wird.Ich frage mich, ob es interessante Anekdoten vom Ausführen von Programmen unter httptap gibt. Außerdem wäre spannend, welches Programm am häufigsten nach Hause telefoniert.
[1] https://github.com/subtrace/subtrace
[2] https://docs.subtrace.dev/quickstart
https://github.com/M66B/NetGuard
Kaum zu glauben, aber im Verzeichnis
networktabdes Repos liegt ein halb fertiger Versuch, dasselbe für den Firefox-Network-Tab zu machen. Ein sehr cooles Projekt; ich würde gern mehr darüber lernen und mich auch weiter darüber austauschen.Als weiteres Tool, mit dem unprivilegierte Nutzer Netzwerk-Traffic analysieren können, lassen sich rootless Podman und Pasta verwenden.
Man muss den Optionen von
podman runFolgendes hinzufügen:--network=pasta:--pcap,myfile.pcapDann zeichnet Pasta den Netzwerk-Traffic in eine PCAP-Datei auf, die man später analysieren kann. Ich habe auch ein einfaches Beispiel geschrieben, das die aufgezeichnete PCAP-Datei mit
tsharkanalysiert.https://github.com/eriksjolund/podman-networking-docs?tab=re...
Ziemlich interessant. Ich habe einmal eine Library geschrieben, die eine ähnliche „Tap“-Funktion für Go-Anwendungen bietet: https://github.com/henvic/httpretty
https://asciinema.org/a/297429
Ich hatte auch darüber nachgedacht, so etwas für beliebige Programme zu machen, bin aber nie tief in die tatsächliche Umsetzung eingestiegen. Schön zu sehen, dass jemand es gebaut hat.
Ich frage mich, warum nicht eBPF verwendet wird. Damit könnte man HTTP-Requests aller Prozesse auf einmal sehen, einschließlich solcher, die bereits laufen. Außerdem müsste man sich wohl nicht einmal um TLS kümmern, wenn man zum Beispiel
write(2)hookt.write(2)TLS lösen soll. Man könnte zwar Ciphertext lesen und verändern, aber der Prozess ruftwrite(2)nicht mit Klartext-Bytes auf, daher kann man den tatsächlichen HTTP-Request nicht lesen. Am Ende sieht man nur die verschlüsselten Bytes, die aufs Netzwerk gehen, und die kann auch die NSA sehen.Man braucht einen CA-Zertifikat-Trick wie den, den httptap offenbar verwendet. Natürlich gibt es dabei Fallstricke wie Certificate Pinning, aber in den meisten praktischen Szenarien lässt sich das zuverlässig zum Laufen bringen.
Beim Bau von Subtrace[1] habe ich über genau dieses Problem absurd viel nachgedacht; falls es einen einfacheren oder eleganteren Ansatz gibt, interessiert mich das wirklich sehr.
[1] https://github.com/subtrace/subtrace
writemit eBPF nicht bei der TLS-Entschlüsselung.Wie auch immer: Je mehr Optionen, desto besser.
Cool. Ich werde es wahrscheinlich direkt zum Debuggen von nginx-Konfigurationen ausprobieren.
Im Moment nutze ich
curl -vund muss die Ausgabe manuell danach durchsuchen, was schiefläuft; mit diesem Tool dürften Dinge wie Redirect-Loops sofort sichtbar werden.Sieht sehr nützlich aus, wenn man schnell und grob den HTTP/S-Call-Stack einer App untersuchen muss.
Persönlich bevorzuge ich eBPF, wenn ich alles sehen will, aber dieses Utility könnte dabei helfen, den wichtigen Teil bei eBPF-Tracing einzugrenzen.
Sieht gut aus
Das GitHub-Profil verweist auf https://www.monasticacademy.org/about; dazu habe ich an sich keine besondere Meinung, aber ich habe mich gefragt, wie ihre klösterlichen Trainings-Retreats mit dem GitHub-Projekt zusammenhängen.
Ganz unten im README wurde die Verbindung erklärt: https://github.com/monasticacademy/httptap?tab=readme-ov-fil...
Das bedeutet, dass Menschen auf einem 123 Acre großen Grundstück in Vermont gemeinsam nach einer vergleichsweise traditionellen buddhistischen Klosterstruktur leben, allerdings ohne formell ordinierte Mönche oder Nonnen zu sein. Tagsüber arbeiten sie gemeinsam an verschiedenen technischen und nichttechnischen Projekten. Der oben verlinkte README-Abschnitt gibt einen guten Überblick.
https://github.com/monasticacademy/httptap?tab=readme-ov-fil...