3 points par GN⁺ 2023-12-25 | 1 commentaires | Partager sur WhatsApp
  • Même si le port SSH est bloqué sur un réseau restrictif, il est possible de créer un chemin d’accès distant via le port HTTPS 443 et la méthode CONNECT
  • Côté serveur, apache2 ouvre CONNECT avec mod_proxy_connect, tout en limitant la portée du proxy pour n’autoriser que la cible ssh-server:22
  • Côté client, on relie ProxyCommand d’OpenSSH à socat, et pour HTTPS, le script envoie lui-même les en-têtes CONNECT
  • Certains pare-feu ou httpd peuvent fermer les connexions inactives ; ServerAliveInterval 30 aide donc à maintenir la session
  • Cette méthode encapsule SSH dans TLS, ce qui facilite l’évitement des blocages, mais laisse le coût du double chiffrement et la contrainte de configuration côté client

Créer un chemin d’accès SSH sur un réseau restreint

  • Dans l’environnement Wi‑Fi d’un hôpital, la plupart des types de connexion étaient bloqués, et seuls HTTP sur TCP 80 et HTTPS sur TCP 443 étaient principalement autorisés
  • DNS sur UDP 53 et DoT sur TCP 853 semblaient fonctionner avec des fournisseurs DNS bien connus
  • SSH sur TCP 22 ainsi que la plupart des ports personnalisés étaient totalement bloqués
  • Une connexion de secours GSM permettant de reconfigurer le serveur distant était disponible, ce qui a permis de tester plusieurs méthodes de contournement

Partage de port et encapsulation de protocole

  • Il existe une méthode pour recevoir à la fois SSH et HTTPS sur un même port et les aiguiller de façon transparente
    • Le projet sslh project estime le protocole de manière heuristique puis redirige vers le backend réel SSH, HTTPS ou un autre protocole pris en charge
    • L’avantage est qu’aucune configuration particulière n’est nécessaire côté client ssh, hormis l’indication d’un port non standard
    • Les inconvénients sont qu’il faut configurer un service supplémentaire, que HTTPS doit lui aussi passer par sslh, et que l’adresse source de la connexion peut être masquée côté backend, ce qui complique la journalisation
  • Une autre option consiste à encapsuler entièrement un protocole dans un autre
    • ProxyCommand d’OpenSSH permet à l’utilisateur de choisir le moyen de transport utilisé par le protocole ssh
    • Comme SSH est enveloppé dans un autre flux sans heuristique, il peut être plus difficile à bloquer pour un logiciel de DPI
    • HTTPS lui-même n’est ni redirigé ni affecté
    • En contrepartie, le double chiffrement peut dégrader les performances et une configuration côté client est nécessaire

Configuration de SSH over HTTP

  • La première tentative a consisté à faire passer SSH par HTTP
  • Côté serveur, la configuration apache2 charge mod_proxy_connect et autorise le CONNECT vers le port 22 avec AllowCONNECT 22
  • <Proxy *> refuse tout par défaut, et seul <Proxy ssh-server> est autorisé afin de limiter la cible à ssh-server:22
  • Côté client, .ssh/config utilise dans ProxyCommand PROXY:http-server:%h:%p,proxyport=80 de socat
  • Avec cette configuration, l’exécution de $ ssh ssh-via-http permet d’accéder à SSH via le port 80
  • ServerAliveInterval 30 envoie périodiquement des sondes pour éviter qu’une connexion HTTP inactive ne soit silencieusement fermée en chemin
  • Le httpd par défaut utilise TimeOut 60, qui ferme le tunnel après 60 secondes sans entrée ni sortie

Configuration de SSH over HTTPS

  • Il semble que socat ne prenne pas en charge les proxys HTTPS via la méthode CONNECT, mais seulement HTTP
  • À la place, la fonctionnalité d’encapsulation TLS de socat est utilisée, et la requête basée sur CONNECT est implémentée directement dans un script
  • ~/.ssh/https-tunnel.bash fonctionne selon le flux suivant
    • Il affiche d’abord les en-têtes CONNECT ssh-server:22 HTTP/1.1 et Host: ssh-server
    • Il enchaîne ensuite directement avec l’entrée standard
    • Le flux complet est transmis à socat - "SSL:$3:$4" afin de créer une connexion TLS
  • Dans .ssh/config, ProxyCommand ~/.ssh/https-tunnel.bash est défini pour Host ssh-via-https
  • En exécutant $ ssh ssh-via-https, la connexion à ssh-server s’établit bien via le tunnel HTTPS, comme prévu

Points d’attention en exploitation

  • Dans les environnements où HTTPS est largement autorisé, cette méthode permet de faire transiter des données à travers des équipements intermédiaires très restrictifs
  • La méthode CONNECT peut sembler être un vestige ancien, mais elle reste utile pour encapsuler un flux arbitraire de charge utile TCP dans un flux hôte TLS
  • ServerAliveInterval aide à maintenir une connexion OpenSSH lorsque la couche de transport sous-jacente n’est pas favorable aux connexions inactives
  • Une variante de configuration nginx est disponible ici : CONNECT passthrough on nginx

1 commentaires

 
GN⁺ 2023-12-25
Avis sur Hacker News
  • Le passage de l’article disant que « HTTPS est partout, si bien que même des équipements intermédiaires très restrictifs peuvent laisser passer les données » est précisément la raison pour laquelle presque tous les protocoles VPN propriétaires, les soi-disant « SSL VPN », implémentent un mode qui ouvre un tunnel via HTTPS.
    Même quand ce n’est pas le comportement par défaut, ils le gardent au moins comme solution de repli, afin de disposer d’un mode qui fonctionne sur quasiment n’importe quelle connexion Internet dans le monde.
    Je suis l’un des principaux développeurs de https://gitlab.com/openconnect/openconnect, qui implémente plusieurs protocoles VPN basés sur TLS, et j’ai aussi créé https://github.com/dlenski/what-vpn, qui détecte et identifie davantage de types de serveurs VPN basés sur TLS.

    • C’est dommage que les tentatives visant à limiter grossièrement l’utilité d’une connexion rendent difficile l’usage des ports selon leur fonction d’origine.
  • Il y a longtemps, le fournisseur d’accès Internet néerlandais XS4ALL proposait exactement cette fonctionnalité.
    Il ouvrait l’accès SSH sur le port 80, et cela m’a dépanné plusieurs fois en voyage, quand le WiFi d’un hôtel bloquait tout sauf le port 80.

    • XS4ALL était excellent, et c’est vraiment dommage que KPN ait décidé de faire disparaître cette marque.
      Cela dit, du point de vue de KPN, la culture hacker de XS4ALL ne devait probablement pas être très confortable dès le départ.
    • J’étais utilisateur de XS4ALL, c’était vraiment formidable, et l’esprit des débuts d’Internet y était encore vivant.
      On avait l’impression de revivre la culture des radios pirates des années 1960.
      https://en.wikipedia.org/wiki/Pirate_radio_in_Europe
    • Parmi les ports non standard pour SSH, le port 443 figure parmi les plus utilisés.
      https://www.shodan.io/search/facet?query=ssh&facet=port
      https://www.shodan.io/search/facet.png?query=ssh&facet=port
      En revanche, le port 80 est beaucoup moins courant.
    • Je ne savais pas que XS4ALL était un fournisseur d’accès Internet complet.
      Je me souviens l’avoir utilisé autrefois uniquement comme fournisseur de newsgroups.
    • XS4ALL se prolonge dans une certaine mesure sous la forme de Freedom : https://freedom.nl/en
  • Il existe souvent une troisième option : faire tourner SSH sur le port 80 ou 443 d’un autre hôte, puis utiliser ProxyJump depuis celui-ci vers la destination.
    Ou bien ouvrir SOCKS vers cet hôte afin d’obtenir une connexion Internet globalement moins filtrée.
    J’utilise SOCKS, et je fais aussi passer du DNS basé sur TLS via le port forwarding de la connexion SSH.
    Il y a quelques années, quand j’ai configuré un proxy SOCKS pour la première fois et beaucoup utilisé le WiFi, je n’ai pas vu d’endroit qui allait au-delà d’une simple vérification des ports, mais ce genre d’équipement existe et il est peut-être plus courant aujourd’hui.

    • En première année de lycée, je venais de commencer l’auto-hébergement, et l’école bloquait des sites web, mais ne faisait absolument aucun blocage de ports.
      Je me connectais donc simplement en SSH à mon serveur et je l’utilisais comme d’habitude.
      Plus tard, en constituant une archive de fichiers .iso Windows, je les ai téléchargés sur mon ordinateur portable puis envoyés sur le serveur avec scp ; apparemment, plusieurs dizaines de Go cumulés en upload et download sur un port autre que 80/443 ont suffi à déclencher une inspection du trafic, car vers midi l’IT a bloqué le port 22.
      Mais comme les autres ports n’étaient pas bloqués, j’ai déplacé SSH sur le 443 avec du port forwarding et j’ai continué à l’utiliser.
      Ensuite, l’IT de l’école a remarqué que j’utilisais SSH sur le 443 et a ajouté une analyse de trafic basique pour bloquer SSH sur 80/443, mais tous les autres ports restaient ouverts.
      Ils ont fini par bloquer mon serveur au niveau de l’IP, mais toutes les autres IP restaient accessibles.
      On pourrait contourner ça avec ProxyJump via un VPS, mais comme c’était un cursus lycée en early college, je ne suis presque plus allé à l’école après la deuxième année, donc cela ne valait pas vraiment l’effort.
      La prochaine fois que j’y retournerai, j’essaierai pour prouver que c’est possible, et s’ils bloquent SSH sur tous les ports, il suffira de mettre du SSH sur HTTPS sur le VPS.
      Après l’obtention du diplôme, je compte regarder à nouveau jusqu’où on peut aller depuis le WiFi invité.
  • C’est un peu de promotion assumée, mais chez Adaptive [1], nous construisons une infrastructure de sécurité des données.
    Dans l’un de nos produits, nous faisons passer SSH et plusieurs autres protocoles au-dessus de HTTP/3, afin que les utilisateurs puissent se connecter à des bases de données, serveurs et autres ressources via un unique port sortant.
    C’est similaire aux solutions de type Ngrok, mais auto-hébergeable, avec la possibilité d’un accès sans mot de passe ou d’ajouter des identifiants temporaires et une protection maker-checker.
    [1] https://adaptive.live/

  • En pratique, il suffisait de faire écouter openssh sur le port 443 pour contourner la plupart des pare-feu.

  • Intéressant. Curieusement, je n’avais jamais envisagé la méthode CONNECT comme une sorte de reverse proxy plutôt que comme un proxy forward.
    Dans mon cas, toutefois, CONNECT seul ne suffisait pas, donc j’ai utilisé SSH au-dessus de WebSocket pour passer à travers le proxy de l’entreprise.
    Ce proxy inspectait les connexions HTTPS avec une CA personnalisée.
    J’ai modifié socat pour exposer mon serveur SSH via WebSocket à travers Apache, et côté client je l’utilisais avec le ProxyCommand d’OpenSSH.
    Je me dis toujours qu’il faudrait que je publie ce patch, mais il existe aussi d’autres options comme websocat.

    • C’est probablement pour ça que beaucoup de proxys ou pare-feu d’entreprise bloquent WebSocket par défaut.
    • On dirait que tu as involontairement recréé huproxy.
  • Il y a presque 20 ans, pour percer un trou dans le pare-feu de l’entreprise, j’utilisais un outil qui faisait exactement ça, corkscrew[0]
    L’implémentation autonome et l’article sont propres
    0: https://github.com/bryanpkc/corkscrew

    • Si j’ai bien compris, corkscrew ne fonctionne que dans certaines conditions : il faut être derrière un proxy HTTP, et ce proxy HTTP doit prendre en charge la méthode CONNECT
      Lors d’une courte mission en contrat il y a environ 20 ans, la première condition était remplie, mais pas la seconde
      Heureusement, il existe un outil utilisable même dans ce cas, avec bien sûr une configuration nécessaire côté serveur
      https://github.com/larsbrinkhoff/httptunnel
  • Dans l’ensemble, le tunneling via HTTP/2 s’est révélé être un bon choix
    Il existe gRPC[1], un protocole d’appel de procédure distante construit au-dessus de HTTP/2
    C’est parce que HTTP/2 exploite une seule connexion TCP et excelle dans le multiplexage, en envoyant et recevant simultanément plusieurs structures de données
    Cela dit, comme QUIC fournit lui-même le multiplexage, il n’y a peut-être pas de raison d’utiliser HTTP/3
    À l’avenir, comme les fabricants d’équipements intermédiaires ne pourront pas s’empêcher de discriminer le trafic, la plupart des communications passeront probablement sur HTTP/2 chiffré et QUIC
    Pour atténuer la détection active[2], il faudra peut-être servir du contenu HTTP/2·HTTP/3 aléatoire, peut-être généré par IA
    [1] <https://grpc.io>
    [2] <https://blog.torproject.org/learning-more-about-gfws-active-...>

    • Je ne comprends pas très bien l’intérêt d’ajouter encore un protocole d’appel de procédure distante au-dessus de HTTP
      HTTP est déjà en soi un protocole requête/réponse, et peut essentiellement servir aux appels de procédure distante
      Que ce soit HTTP 1, 2 ou 3, je ne vois pas une grande différence
      L’évolution même de ce protocole me paraît aussi assez discutable, et il a été conçu pour exploiter des choses qui ne sont pas nécessaires dans un contexte d’appel de procédure distante
      Fondamentalement, il est plutôt conçu pour l’Internet public que pour des services locaux
    • Dans le cas de SSH, il n’y a qu’une seule connexion et, en pratique, SSH implémente son propre multiplexage, donc l’avantage de HTTP/2 n’est pas très évident
    • HTTP/2 reste basé sur TCP, donc il subit le blocage en tête de ligne de TCP
      HTTP/3 fonctionne au-dessus de QUIC
  • À l’inverse, je préfère plutôt HTTP au-dessus de SSH
    C’est à moitié une plaisanterie, mais j’aimerais que les navigateurs intègrent une gestion d’identité équivalente à celle de SSH
    La première fois que j’ai lu hobo, une proposition d’authentification HTTP par clé publique, j’étais enthousiaste, puis j’ai découvert qu’il n’y avait ni implémentation serveur ni implémentation client dans les navigateurs
    Il existe une implémentation JavaScript, mais ce n’était pas la forme que je voulais

    • ssh -D “*:8080” host
      Cette commande lance un proxy SOCKS sur le port 8080
      Je l’utilise tout le temps dans Firefox, et ça fonctionne comme une sorte de VPN originel
      C’est pratique pour des usages douteux, mais je m’en sers aussi pour accéder au tableau de bord rmq sur le réseau privé d’AWS
    • Et les certificats client HTTPS ?
      https://techcommunity.microsoft.com/t5/iis-support-blog/clie...
      Je ne connais pas le sujet assez en détail pour savoir si ça répond aux besoins, mais je m’en suis déjà servi à l’université pour l’authentification serveur
    • Tu ne parles pas des passkeys ?
    • Ça aurait été bien si ssh://google.com avait été possible dans le navigateur
    • Si vous l’avez manqué la semaine dernière, il y avait un article dans une direction similaire : SSH3, SSHv2 utilisant HTTP/3 et QUIC
      https://news.ycombinator.com/item?id=38664729
  • Pourquoi sslh ne reçoit-il pas plus d’amour ?
    Il détecte HTTP, TLS/SSL (y compris SNI et ALPN), SSH, OpenVPN, tinc, XMPP, SOCKS5, et peut aussi reconnaître d’autres protocoles inspectables par expression régulière
    L’usage typique consiste à servir plusieurs services sur le port 443
    Par exemple, on peut se connecter en SSH depuis derrière un pare-feu d’entreprise tout en continuant à servir du HTTPS sur le même port
    https://www.rutschle.net/tech/sslh/README.html

    • La première moitié de l’article portait sur le choix entre sslh et l’encapsulation complète
      La raison du choix de l’encapsulation complète semble être qu’il y a un service de moins à configurer, que le serveur HTTP gère la connexion et que l’adresse distante dans les logs est donc correcte, et probablement aussi que, dans l’esprit hacker, une nouvelle solution est plus attirante qu’une solution existante