8 Punkte von GN⁺ 2025-02-04 | 2 Kommentare | Auf WhatsApp teilen
  • 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

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
  • Unter Ubuntu 23.10 oder neuer sind die folgenden Einstellungen erforderlich
    • sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0
    • sudo 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/null zeigt, dass der Server einen 302-Redirect zurückgegeben hat
  • Wenn man Redirects wie mit curl -sL folgt, werden auch zusätzliche Anfragen angezeigt
    • Die erste Anfrage ergibt 302
    • Die zweite Anfrage ergibt 200 für die Ziel-URL des Redirects
  • Im Beispiel gcloud compute instances list lassen sich die HTTP-Endpunkte sehen, die die Google Cloud CLI intern verwendet
  • Im Beispiel kubectl get all werden die Anfragen an den Kubernetes-API-Server angezeigt
    • --https 443 6443 behandelt TCP-Verbindungen auf Port 443 und 6443 als HTTPS
    • --insecure-skip-tls-verify ist nötig, weil kubectl die von httptap erzeugte Zertifizierungsstelle nicht verwendet
  • Das Beispiel curl --doh-url https://cloudflare-dns.com/dns-query zeigt 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 --head und --body zusammen verwendet, gibt das Tool HTTP-Header und rohe Payloads aus

HAR-Ausgabe

Zugriff auf localhost

  • Um innerhalb von httptap auf einen localhost-Port des Hosts zuzugreifen, verwendet man statt localhost entweder host.httptap.local oder 169.254.77.65
  • Jeder network namespace unter Linux besitzt ein eigenes Loopback-Gerät 127.0.0.1; deshalb ist 127.0.0.1:1234 innerhalb von httptap nicht dieselbe Adresse und derselbe Port wie auf dem Host
  • httptap umgeht dieses Problem, indem es hartkodiert 169.254.77.65 auf 127.0.0.1 routet

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-exit lä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+C beenden
  • Wenn httptap ohne --no-exit zuerst 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/get sowie Python mit fork, setsid, fork tritt ohne --no-exit der Fehler Could not resolve host auf

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.com stellt, 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/tun sind erforderlich
  • Alle ICMP-Echo-Anfragen werden lediglich zurückgespiegelt, statt echte ICMP-Pakete ins Netzwerk zu senden

2 Kommentare

 
halfenif 2025-02-06

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.

Beim Testen habe ich mir GitHub angesehen. Es wirkt, als hätten Menschen in klösterlicher Praxis (?) es als Teil ihres spirituellen Wegs entwickelt.

 
GN⁺ 2025-02-04
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.

    • Das erinnert an eine Passage aus „Soul of a New Machine“.
      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.“
    • Ehrlich gesagt klingt das wie einer der vielen Yoga-/Spiritualitätskulte, die es im Westen schon überall gibt.
    • Die Passage „In den letzten Jahren haben wir eine Vortragsreihe namens Buddhism for AI aufgezeichnet. Darin geht es um den Versuch, eine auf dem Buddhismus basierende Religion, ja, Religion, zu entwerfen, die direkt von KI-Systemen konsumiert werden kann. Angesichts der Weltlage halten wir diese Arbeit für sehr wichtig“ wirkt wie ein Indikator dafür, wie seltsam die Zeit ist, in der wir leben.
      Ob das eine gute Idee ist oder zu den Ergebnissen führt, die sie sich vorstellen, ist eine andere Frage.
    • Beim ersten Foto vom Land dachte ich, es sei ein generiertes Bild, aber inzwischen wirkt es auf mich wie ein echtes Foto.
      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.

    • Ich frage mich, ob man das auch unter macOS zum Laufen bringen könnte. Soweit ich weiß, verwendet Tailscale für einige macOS-Funktionen die TCP/IP-Bibliothek von gVisor als netstack-Bibliothek.
    • Ich frage mich, ob man Requests oder Responses verändern kann. Da das Web den Nutzern gegenüber immer feindseliger wird, ist der Bedarf an solchen Tools größer denn je.
      Besonders nützlich wäre es, wenn keine Proxy-Einstellungen nötig sind.
    • Haben alle Wireshark vergessen, das man auch ohne Root ausführen kann?
      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.conf gemountet zu werden[2]. Ich frage mich, ob es helfen würde, wenn httptap das Verzeichnis /etc/ca-certificates als temporäres CA-Bundle mounten würde.

    [1] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
    [2] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...

    • Ich stimme zu, dass es frustrierend ist, dass es praktisch keine vereinbarte oder vom System erzwungene Methode gibt, einem beliebigen Prozess CA-Roots vorzugeben.
      Dass httptap ein Overlay auf /etc/resolv.conf mountet, 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.conf eine ziemlich verlässliche Option. Sobald man einen Prozess in einen Network Namespace steckt, kann er auf dem Desktop-Linux-Standardsetup, den systemd-Resolver localhost:53, nicht mehr zugreifen, also muss man DNS-Auflösung bereitstellen.
      Ein Overlay-Mount von /etc/ca-certificates kö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.
    • Für den HTTPS-Teil gibt es meiner Meinung nach keine allgemeine Lösung, die alle Arten von Programmen und den Long Tail an Certificate-Pinning-Implementierungen abdeckt.
      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, accept usw. 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

    • Das erinnert an NetGuard, das den VPN-Dienst von Android zur Paketfilterung nutzt. Es verwendet statt eines rohen TUN-Devices den Android-VPN-Dienst.
      https://github.com/M66B/NetGuard
    • Interessant ist auch, die erfassten Inhalte an Chrome DevTools anzubinden, und ebenso der Einsatz von eBPF. Sehr gut ist auch, dass die Developer Tools als eigenständige Web-App ausführbar gemacht wurden.
      Kaum zu glauben, aber im Verzeichnis networktab des 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 run Folgendes hinzufügen:

    --network=pasta:--pcap,myfile.pcap

    Dann 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 tshark analysiert.
    https://github.com/eriksjolund/podman-networking-docs?tab=re...

    • Sehr gut zu wissen, aber es bleibt weiterhin das Problem der Entschlüsselung von TLS-Traffic.
  • 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.

    • Mir ist nicht klar, wie ein Hook auf write(2) TLS lösen soll. Man könnte zwar Ciphertext lesen und verändern, aber der Prozess ruft write(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
    • Leider findet TLS innerhalb der Anwendung statt und nicht im Kernel; daher hilft ein Hook auf den Systemaufruf write mit eBPF nicht bei der TLS-Entschlüsselung.
    • Ich frage mich, ob man mit einer uprobe auf die SSL-Library Inhalte wie entschlüsselte HTTP-Responses untersuchen und verändern könnte, um Content zu filtern.
    • eBPF benötigt vermutlich Root-Rechte, denke ich.
    • Braucht dieser Ansatz nicht Root? Der große „Selling Point“ von httptap scheint genau zu sein, dass keine Root-Rechte nötig sind.
      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 -v und muss die Ausgabe manuell danach durchsuchen, was schiefläuft; mit diesem Tool dürften Dinge wie Redirect-Loops sofort sichtbar werden.

    • Ich würde gern hören, wie es in echten Nutzungskontexten funktioniert, insbesondere welche Funktionen hilfreich sind.
  • 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...

    • Für alle, die diesen Thread lesen: Der Zusammenhang ist einfach, dass httptap ein Projekt der Monastic Academy ist.
      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...