3 Punkte von GN⁺ 2023-12-25 | 1 Kommentare | Auf WhatsApp teilen
  • In eingeschränkten Netzwerken lässt sich auch bei gesperrtem SSH-Port über den HTTPS-Port 443 und die CONNECT-Methode ein Pfad für den Remote-Zugriff aufbauen
  • Der Server öffnet CONNECT über mod_proxy_connect von apache2, erlaubt aber nur das Ziel ssh-server:22, um den Proxy-Umfang einzugrenzen
  • Auf dem Client werden OpenSSHs ProxyCommand und socat kombiniert; bei HTTPS sendet ein Skript die CONNECT-Header direkt
  • Manche Firewalls oder httpd können inaktive Verbindungen schließen; ServerAliveInterval 30 hilft daher, die Sitzung aufrechtzuerhalten
  • Diese Methode kapselt SSH in TLS und macht Blockaden leichter umgehbar, bringt aber weiterhin doppelte Verschlüsselung und zusätzlichen Konfigurationsaufwand auf Client-Seite mit sich

Einen SSH-Zugangsweg in eingeschränkten Netzwerken schaffen

  • In einem Krankenhaus-WLAN waren die meisten Verbindungstypen blockiert; hauptsächlich waren nur TCP 80 für HTTP und TCP 443 für HTTPS erlaubt
  • UDP 53 für DNS und TCP 853 für DoT schienen bei bekannten DNS-Anbietern zu funktionieren
  • SSH war auf TCP 22 und auf den meisten benutzerdefinierten Ports vollständig blockiert
  • Es gab eine alternative GSM-Verbindung, über die der Remote-Server neu konfiguriert werden konnte, sodass mehrere Umgehungsansätze getestet werden konnten

Einen Port teilen und Protokolle kapseln

  • Es gibt die Möglichkeit, SSH und HTTPS auf einem einzigen Port gemeinsam anzunehmen und transparent zu verzweigen
    • Das sslh project schätzt das Protokoll heuristisch ein und leitet zur tatsächlichen Backend-Komponente SSH, HTTPS oder einem unterstützten Protokoll weiter
    • Der Vorteil ist, dass im ssh-Client keine besondere Konfiguration nötig ist; es muss nur ein nicht standardmäßiger Port angegeben werden
    • Der Nachteil ist, dass ein zusätzlicher Dienst eingerichtet werden muss, auch HTTPS über sslh laufen muss und im Backend die Quelladresse der Verbindung verborgen wird, was Logging unpraktischer machen kann
  • Eine andere Option ist, ein Protokoll vollständig in ein anderes Protokoll zu kapseln
    • Mit OpenSSHs ProxyCommand lässt sich das Transportmittel festlegen, das das ssh-Protokoll verwenden soll
    • Da SSH ohne Heuristik in einen anderen Stream eingepackt wird, kann es für DPI-Software schwieriger zu blockieren sein
    • HTTPS selbst wird dabei nicht umgeleitet oder beeinträchtigt
    • Dafür kann die doppelte Verschlüsselung die Performance verringern, und es ist eine Client-Konfiguration nötig

SSH over HTTP konfigurieren

  • Zunächst wurde versucht, SSH über HTTP zu tunneln
  • Die apache2-Konfiguration auf Serverseite lädt mod_proxy_connect und erlaubt mit AllowCONNECT 22 CONNECT auf Port 22
  • <Proxy *> verweigert standardmäßig alles; nur <Proxy ssh-server> wird erlaubt, um das Ziel auf ssh-server:22 zu beschränken
  • Die clientseitige .ssh/config verwendet in ProxyCommand PROXY:http-server:%h:%p,proxyport=80 von socat
  • Mit dieser Konfiguration kann man durch Ausführen von $ ssh ssh-via-http über Port 80 eine Verbindung zu SSH herstellen
  • ServerAliveInterval 30 sendet regelmäßig Probes, um zu verhindern, dass eine inaktive HTTP-Verbindung auf dem Zwischenweg stillschweigend geschlossen wird
  • Der standardmäßige httpd nutzt TimeOut 60 und schließt den Tunnel, wenn 60 Sekunden lang keine Ein- oder Ausgabe erfolgt

SSH over HTTPS konfigurieren

  • Es stellte sich heraus, dass socat keine HTTPS-Proxys über die CONNECT-Methode unterstützt, sondern nur HTTP
  • Stattdessen wird die TLS-Kapselung von socat genutzt, während die CONNECT-basierte Anfrage direkt im Skript implementiert wird
  • ~/.ssh/https-tunnel.bash arbeitet nach folgendem Ablauf
    • Zunächst gibt es den Header CONNECT ssh-server:22 HTTP/1.1 und Host: ssh-server aus
    • Danach hängt es die Standardeingabe unverändert an
    • Der gesamte Stream wird an socat - "SSL:$3:$4" übergeben, um eine TLS-Verbindung zu erzeugen
  • In .ssh/config wird für Host ssh-via-https ProxyCommand ~/.ssh/https-tunnel.bash festgelegt
  • Beim Ausführen von $ ssh ssh-via-https wird wie erwartet über den HTTPS-Tunnel eine Verbindung zu ssh-server hergestellt

Hinweise für den Betrieb

  • In Umgebungen, in denen HTTPS breit erlaubt ist, können Daten über sehr restriktive Zwischengeräte hinweg übertragen werden
  • Die CONNECT-Methode wirkt wie ein Relikt, ist aber nützlich, um beliebige TCP-Payload-Streams in einen TLS-Host-Stream einzubetten
  • ServerAliveInterval hilft, OpenSSH-Verbindungen aufrechtzuerhalten, wenn die darunterliegende Transportschicht inaktive Verbindungen nicht gut behandelt
  • Eine nginx-Konfigurationsvariante gibt es unter CONNECT passthrough on nginx

1 Kommentare

 
GN⁺ 2023-12-25
Hacker-News-Kommentare
  • Die Stelle im Artikel, dass „HTTPS überall vorhanden ist, sodass selbst stark eingeschränkte Zwischenkomponenten Daten durchlassen können“, ist genau der Grund, warum fast alle proprietären VPN-Protokolle, die sogenannten „SSL VPNs“, einen Modus implementieren, der einen Tunnel über HTTPS öffnet.
    Selbst wenn es nicht der Standardmodus ist, gibt es ihn zumindest als Ausweichpfad, um einen Modus zu haben, der bei fast jeder Internetverbindung weltweit funktioniert.
    Ich bin einer der Hauptentwickler von https://gitlab.com/openconnect/openconnect, das verschiedene TLS-basierte VPN-Protokolle implementiert, und habe außerdem https://github.com/dlenski/what-vpn entwickelt, das weitere Arten TLS-basierter VPN-Server erkennt und identifiziert.

    • Es ist schade, dass Versuche, die Nützlichkeit von Verbindungen grob einzuschränken, es erschweren, Ports für ihren eigentlichen Zweck zu verwenden.
  • Der niederländische Internetanbieter XS4ALL bot früher genau so eine Funktion an.
    Er öffnete SSH-Zugänge über Port 80, und das hat mir auf Reisen mehrfach geholfen, wenn Hotel-WLANs alles außer Port 80 blockiert haben.

  • Oft gibt es noch eine dritte Option: SSH auf Port 80 oder 443 eines anderen Hosts laufen zu lassen und von dort mit ProxyJump zum eigentlichen Ziel zu gehen.
    Oder man öffnet über diesen Host SOCKS und erhält so insgesamt eine weniger gefilterte Internetverbindung.
    Ich nutze SOCKS und leite per Port-Forwarding meiner SSH-Verbindung auch TLS-basiertes DNS durch.
    Als ich vor ein paar Jahren erstmals einen SOCKS-Proxy eingerichtet und recht viel WLAN genutzt habe, ist mir kein Ort begegnet, der über bloße Port-Prüfung hinausging, aber solche Geräte existieren, und heute könnten sie verbreiteter sein.

    • Als ich in der 10. Klasse gerade mit Self-Hosting angefangen hatte, blockierte meine Schule zwar Websites, aber Port-Sperren gab es überhaupt nicht.
      Also habe ich mich einfach per SSH auf meinen Server eingeloggt und ihn wie gewohnt genutzt.
      Später habe ich ein Archiv mit Windows-.iso-Dateien angelegt, sie auf den Laptop heruntergeladen und dann per scp auf den Server hochgeladen; offenbar reichte es aus, auf einem anderen Port als 80/443 beim Up- und Download zusammen einige Dutzend GB zu übertragen, um eine Traffic-Prüfung auszulösen, denn gegen Mittag blockierte die IT Port 22.
      Da andere Ports aber nicht blockiert waren, habe ich SSH im Port-Forwarding einfach auf 443 verlegt und weitergemacht.
      Danach merkte die Schul-IT, dass ich SSH über 443 nutzte, und führte eine einfache Traffic-Analyse ein, die SSH auf 80/443 blockierte, aber alle anderen Ports waren weiterhin offen.
      Schließlich blockierten sie meinen Server auf IP-Basis, aber alle anderen IPs waren weiterhin erreichbar.
      Mit einem VPS und ProxyJump könnte ich das umgehen, aber da es ein Early-College-Highschool-Programm war, war ich ab der 11. Klasse kaum noch in der Schule, daher lohnte sich der Aufwand nicht besonders.
      Beim nächsten Mal will ich es vielleicht ausprobieren, nur um zu beweisen, dass es geht; und falls sie SSH auf allen Ports blockieren, kann man auf dem VPS immer noch SSH über HTTPS betreiben.
      Nach dem Abschluss will ich mir noch einmal ansehen, wie weit man im Gäste-WLAN kommt.
  • Etwas unverhohlene Eigenwerbung, aber bei Adaptive [1] bauen wir Infrastruktur für Datensicherheit.
    Eines unserer Produkte transportiert SSH und mehrere andere Protokolle über HTTP/3, sodass Nutzer über einen einzigen ausgehenden Port auf Datenbanken, Server und andere Ressourcen zugreifen können.
    Es ist ähnlich wie Ngrok und ähnliche Dienste, aber selbst hostbar, und man kann passwortlosen Zugriff oder temporäre Zugangsdaten mit Maker-Checker-Schutz hinzufügen.
    [1] https://adaptive.live/

  • In der Praxis reichte es oft schon aus, openssh einfach auf Port 443 lauschen zu lassen, um die meisten Firewalls zu umgehen.

  • Schön. Merkwürdigerweise habe ich die Methode CONNECT nie als eine Art Reverse Proxy statt als Forward Proxy betrachtet.
    Für meinen Fall reichte CONNECT allein allerdings nicht aus, daher habe ich SSH über WebSocket verwendet, um den Firmen-Proxy zu umgehen.
    Dieser Proxy untersuchte HTTPS-Verbindungen mit einer benutzerdefinierten CA.
    Ich habe socat angepasst, damit mein SSH-Server über Apache per WebSocket bereitgestellt wird, und auf Client-Seite zusammen mit OpenSSHs ProxyCommand verwendet.
    Ich nehme mir schon länger vor, den Patch zu veröffentlichen, aber es gibt auch andere Optionen wie websocat.

    • Deshalb blockieren viele Firmen-Proxys oder Firewalls offenbar standardmäßig WebSocket.
    • Das klingt so, als hättest du unbeabsichtigt huproxy neu erfunden.
  • Vor fast 20 Jahren habe ich corkscrew[0] benutzt, ein Tool, das genau das macht, um ein Loch durch die Firmen-Firewall zu bohren
    Die Standalone-Implementierung und der Artikel sind sauber
    0: https://github.com/bryanpkc/corkscrew

    • So wie ich es verstehe, funktioniert corkscrew nur unter bestimmten Bedingungen: Man muss hinter einem HTTP-Proxy sitzen, und dieser HTTP-Proxy muss die Methode CONNECT unterstützen
      Als ich vor etwa 20 Jahren einen kurzen Vertragsjob hatte, war die erste Bedingung erfüllt, die zweite aber nicht
      Glücklicherweise gibt es auch für solche Fälle ein Tool, natürlich mit notwendiger Konfiguration auf der Serverseite
      https://github.com/larsbrinkhoff/httptunnel
  • Insgesamt scheint sich Tunneling über HTTP/2 als eine gute Wahl herauszustellen
    Mit gRPC[1] gibt es ein Remote-Procedure-Call-Protokoll, das auf HTTP/2 aufbaut
    HTTP/2 ist stark bei der Multiplexing, weil es mehrere Datenstrukturen gleichzeitig über eine einzige TCP-Verbindung senden und empfangen kann
    Allerdings bietet QUIC selbst bereits Multiplexing, daher gibt es möglicherweise keinen Grund, HTTP/3 zu verwenden
    Künftig wird der Großteil der Kommunikation wohl über verschlüsseltes HTTP/2 und QUIC laufen, weil Hersteller von Middleboxes nicht aufhören werden, zu diskriminieren
    Um aktive Erkennung[2] abzumildern, muss man möglicherweise zufällige, vielleicht sogar von KI erzeugte HTTP/2- bzw. HTTP/3-Inhalte bereitstellen
    [1] <https://grpc.io>
    [2] <https://blog.torproject.org/learning-more-about-gfws-active-...>

    • Ich verstehe nicht ganz, warum man noch ein Remote-Procedure-Call-Protokoll auf HTTP aufsetzen sollte
      HTTP selbst ist bereits ein Request/Response-Protokoll und kann grundsätzlich für Remote Procedure Calls genutzt werden
      Ob es nun HTTP 1, 2 oder 3 ist, scheint keinen großen Unterschied zu machen
      Auch die Weiterentwicklung dieses Protokolls wirkt etwas fragwürdig; es scheint so entworfen zu sein, dass es Dinge nutzt, die man in einer Remote-Procedure-Call-Umgebung nicht braucht
      Im Kern ist es eher für das öffentliche Internet als für lokale Dienste entworfen
    • Bei SSH gibt es nur eine einzelne Verbindung, und SSH implementiert tatsächlich selbst Multiplexing, daher ist der Vorteil von HTTP/2 nicht wirklich ersichtlich
    • HTTP/2 ist weiterhin TCP und leidet daher unter TCP Head-of-Line Blocking
      HTTP/3 läuft auf QUIC
  • Ich bevorzuge umgekehrt eher HTTP über SSH
    Halb im Scherz, aber ich wünschte, Browser hätten eine eingebaute Identitätsverwaltung auf dem Niveau von SSH
    Als ich zum ersten Mal von hobo, einem Vorschlag für Public-Key-HTTP-Authentifizierung, las, war ich begeistert, stellte dann aber fest, dass es weder eine Server- noch eine Browser-Client-Implementierung gibt
    Es gibt zwar eine JavaScript-Implementierung, aber nicht in der Form, die ich mir gewünscht hatte

    • ssh -D “*:8080” host
      Dieser Befehl startet einen SOCKS-Proxy auf Port 8080
      Ich nutze das ständig in Firefox, und es funktioniert wie eine ursprüngliche Art VPN
      Praktisch auch für dubiose Zwecke, aber ich verwende es ebenso, um auf das rmq-Dashboard in einem privaten AWS-Netzwerk zuzugreifen
    • Wie wäre es mit HTTPS-Client-Zertifikaten?
      https://techcommunity.microsoft.com/t5/iis-support-blog/clie...
      Ich kenne mich damit nicht gut genug aus, um zu sagen, ob das die Anforderungen erfüllt, aber ich habe es im Studium einmal zur Server-Authentifizierung verwendet
    • Ist das nicht einfach das, was man heute Passkeys nennt?
    • Es wäre schön gewesen, wenn im Browser ssh://google.com möglich wäre
    • Falls du es letzte Woche verpasst hast: Es gab einen Artikel in eine ähnliche Richtung: SSH3, SSHv2 unter Verwendung von HTTP/3 und QUIC
      https://news.ycombinator.com/item?id=38664729
  • Warum bekommt sslh keine Liebe?
    Es erkennt HTTP, TLS/SSL (einschließlich SNI und ALPN), SSH, OpenVPN, tinc, XMPP, SOCKS5 und kann auch andere Protokolle erkennen, die sich per regulärem Ausdruck prüfen lassen
    Der typische Einsatzzweck ist, mehrere Dienste gemeinsam auf Port 443 bereitzustellen
    So kann man zum Beispiel innerhalb einer Firmen-Firewall per SSH verbinden und gleichzeitig auf demselben Port weiterhin HTTPS anbieten
    https://www.rutschle.net/tech/sslh/README.html

    • In der ersten Hälfte des Artikels ging es darum, ob man sslh oder vollständige Kapselung wählen sollte
      Die Entscheidung für vollständige Kapselung scheint darauf zu beruhen, dass ein zu konfigurierender Dienst weniger anfällt, der HTTP-Server die Verbindungen verarbeitet und dadurch die Remote-Adressen in den Logs korrekt sind, und vielleicht auch darauf, dass man aus Hackergeist eine neue Lösung lieber mag als eine bestehende