From f3539231c2b6a2e1d76643009ff1235a66830602 Mon Sep 17 00:00:00 2001 From: LecygneNoir Date: Thu, 11 May 2023 16:10:27 +0200 Subject: [PATCH] Nouvel article sur haproxy et ssh --- content/2019/rudder-outil-conformite.rst | 6 +- content/2023/ssh_over_haproxy.rst | 153 ++++++++++++++++++ .../ssh-openssl-haproxy/ssh_over_ssl.png | Bin 0 -> 30167 bytes .../images/ssh-openssl-haproxy/ssh_simple.png | Bin 0 -> 17391 bytes 4 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 content/2023/ssh_over_haproxy.rst create mode 100644 content/images/ssh-openssl-haproxy/ssh_over_ssl.png create mode 100644 content/images/ssh-openssl-haproxy/ssh_simple.png diff --git a/content/2019/rudder-outil-conformite.rst b/content/2019/rudder-outil-conformite.rst index c18bd6b..08ceecc 100644 --- a/content/2019/rudder-outil-conformite.rst +++ b/content/2019/rudder-outil-conformite.rst @@ -1,6 +1,6 @@ Suivre vos serveurs avec rudder ############################### -:subtitle: - conformité et maîtrise opérationnelle +:subtitle: \- conformité et maîtrise opérationnelle :date: 2019-07-28 18:32 :authors: Victor :slug: rudder-outil-conformite @@ -8,7 +8,7 @@ Suivre vos serveurs avec rudder :tags: rudder, mco, conformité, ansible :keywords: rudder, mco, conformité, ansible :status: published -:summary: - conformité et maîtrise opérationnelle +:summary: conformité et maîtrise opérationnelle .. contents:: @@ -218,4 +218,4 @@ C'est un outil vraiment très pratique et qui laisse une grande part à l'imagin Avoir un pool de serveurs à gérer n'a jamais été aussi agréable ! -Si cet article vous a plu, ou si vous souhaitez que j'aborde plus en détails certains points de rudder, n'hésitez pas à laisser un commentaire ! \ No newline at end of file +Si cet article vous a plu, ou si vous souhaitez que j'aborde plus en détails certains points de rudder, n'hésitez pas à laisser un commentaire ! diff --git a/content/2023/ssh_over_haproxy.rst b/content/2023/ssh_over_haproxy.rst new file mode 100644 index 0000000..23bdaa6 --- /dev/null +++ b/content/2023/ssh_over_haproxy.rst @@ -0,0 +1,153 @@ +SSH over Openssl over Haproxy +############################### +:subtitle: \- contourner les blocages +:date: 2023-06-20 10:22 +:authors: Victor +:slug: ssh-openssl-haproxy +:category: Réseaux +:tags: ssh, astuces, openssl, haproxy +:keywords: ssh, astuces, openssl, haproxy +:status: published +:summary: contourner les blocages + +.. contents:: + +Contexte +======================= + +Parfois, en entreprise ou dans les hôtels, des règles de sécurité sont mises en place pour empêcher les employés de sortir sur d'autres ports que l'http⋅s (ports 80 et 443) + +Selon l'intelligence du matériel utilisé, il sera capable de détecter si le flux est de l'http, du ssh, ou un autre protocole interdit et en conséquence, contourner ce genre de protection peut s'avérer complexe. + +Bien entendu, jamais je ne conseillerai de contourner les protections mises en place par votre entreprise 😇 +Par contre, rien n'empêche de donner un coup de main à votre SI en pointant les failles du système qu'une personne mal intentionnée pourrait utiliser. + +Je vous invite à consulter votre charte informatique quand aux éventuelles conséquences, mais sachez que **si protection il y a, vous devez légalement en être informé par écrit**. + +Cela étant posé, je vais ici vous proposer d'utiliser Haproxy pour passer outre 2 types de protections : + +1. Un blocage des ports autres que 80/443 sans vérification du type de protocole +2. Un blocage des ports autres que 80/443, avec vérification du type de protocole + +L'objectif sera de faire passer **un flux ssh** sur le port 443 (étape 1), puis de **l'encapsuler dans du SSL** (étape 2). + +Je partirai du principe que vous avez un serveur avec Haproxy installé et fonctionnel, par exemple pour servir vos sites habituels. + +**Disclaimer 1 :** Cette technique vous permettra d'utiliser toutes les fonctionnalités de SSH. J'écris cet article depuis le boulot en committant via un tunnel SSH sur openssl vers mon repo git. Toujours dans l'optique d'entretenir la forme de l'équipe sécurité bien sûr. 🤫 + +**Disclaimer 2 :** Retrouvez à la fin de l'article les configurations complètes si vous êtes pressés ^^ + +PS: Dans le cas où le filtrage se ferait avec un système de `Deep Packet Inspection +`_ qui désencapsule les flux SSL pour les analyser, cela ne fonctionnera pas. Mais si vous avez une protection de ce genre, ça sous-entends que l'entreprise peut (et le fait) voir absolument tout ce que vous faites en https, que ça soit les mots de passe de votre banque ou les messages privés envoyés sur votre discord. Je vous invite à insulter votre DSI (Avec virulence) puis à changer de boite 😄 + +Étape 1 : SSH sur 443 +===================== + +La première étape va consister à assez simplement faire passer votre flux SSH sur le port 443. Si vous rencontrez un simple pare-feu qui bloque tous les ports sauf le 443, cela permettra de contourner le blocage sans problème. + +Côté serveur on pourrait simplement faire écouter sshd sur ce port, ou utiliser iptables pour NATer le port 443 vers le port 22 de votre serveur **mais** c'est moins fun, et puis si vous avez déjà des sites web votre port 443 est déjà utilisé. + +C'est là qu'Haproxy va intervenir car il est capable de détecter si le flux entrant est du SSH ou de l'http ! +Cette étape est assez simple, on va demander à Haproxy de rediriger le flux http (plus précisément, ssl) vers votre frontend habituel, et le flux ssh **vers un serveur particulier**. On verra ensuite une technique pour dire à Haproxy quel serveur ssh on souhaite joindre 😄 + +.. figure:: {static}/images/ssh-openssl-haproxy/ssh_simple.png + :width: 500px + :alt: Description de l'objectif à atteindre : Un frontend Public 443 redistribue les flux vers un backend SSH et un backend SSL, ce dernier renvoyant ensuite vers le fronted HTTP SSL habituel + + Première étape : séparer SSH et SSL + +Frontend TCP SSL/SSH +-------------------- + +Tout d'abord on va modifier votre frontend qui écoute sur le port 443. En toute logique, il devrait écouter sur l'adresse IP exposée vers l'extérieur, mais on va lui dire d'écouter plutôt sur l'adresse localhost, afin de créer ensuite un nouveau frontend qui s'occupera des accès entrants. + +Modifiez donc votre frontend existant : + +.. code-block:: bash + + frontend ft_tcpssl + # Local frontend + bind 127.0.0.1:1443 ssl crt /etc/your/certs accept-proxy + +Modifiez bien sûr le chemin ``/etc/your/certs`` par votre répertoire habituel pour stocker vos certificats. + +L'option `accept-proxy +`_ indique de n'accepter que les connexions de type PROXY, ce qui sera le cas via notre chaine de frontend/backend Haproxy et assure de garder un maximum d'information sur la connexion d'origine. + +Ensuite, on va configurer un nouveau frontend qui se chargera de recevoir le flux sur 443 et de filtrer le flux chiffré en SSL (typiquement de l'https) de celui chiffré via SSH + +Pour cela : + +.. code-block:: bash + + frontend 443-in + bind YOUR_IP:443 + mode tcp # On est bien sûr en TCP ici et pas encore en http + + # On verifie les types de trafics parmi tcp over ssl, http et SSH + tcp-request inspect-delay 5s # Une connexion ssh peut être longuette à s'étblir, on prends le temps d'inspecter le flux + acl trafic_ssl req.ssl_ver gt 0 + acl trafic_ssh_raw req.payload(0,7) -m str SSH-2.0 + +Ici on définit **deux ACLs** : + - L'acl ``trafic_ssl`` se base simplement sur le fait que le flux est chiffré avec ssl + - l'acl ``trafic_ssh_raw`` quand à elle, vérifie les 7 premiers bits de payload de la connexion TCP, qui contiennent ``SSH-2.0`` dans le cas d'une transaction SSH ! + + Sur la base de ces ACL, on peut facilement rediriger vers les backends qui vont bien + +.. code-block:: bash + + # Si SSL on envoie au backend TCP pour dechiffrement + use_backend bk_tcpssl if trafic_ssl + # Si ssh direct on envoie au backend ssh + use_backend bk_ssh if trafic_ssh_raw + +Backends SSL et SSH +------------------- + +On va pouvoir établir les backends : + +.. code-block:: bash + + backend bk_tcpssl + mode tcp + timeout server 2h + server ft_tcpssl 127.0.0.1:1443 send-proxy + + backend bk_ssh + mode tcp + timeout server 2h + + server ssh SSH_IP_SERVER:22 + +On retrouve ici le frontend ``ft_tcpssl``, votre frontend habituel qui gère l'https, avec le mot clef ``send-proxy`` pour transmettre le flux sur localhost en mode PROXY. + +Le bk_ssh quand à lui reste très simple, vous indiquez l'adresse IP du serveur sur lequel vous souhaitez vous connecter en ssh comme cible du backend. +(Rappel, on verra ensuite comment se connecter à plusieurs serveurs ssh sans devoir en indiquer un en dur 😜 ) + +Cette première configuration est assez simple, et vous permettra simplement en lançant une connexion SSH sur le port 443 de vous retrouver sur votre serveur habituel. + +Les connexions pourront se faire par clef ou par mot de passe, de la manière dont vous fonctionnez en général ! + +.. code-block:: bash + + ssh -p 443 YOUR_IP + + +Étape 2 : SSH sur SSL +===================== + +Dans cette 2eme étape, on va ajouter une brique qui permettra d'injecter un flux SSH dans une connexion chiffrée avec SSL. + +Bien que techniquement plus complexe à utiliser et à configurer, on ajoute ici 2 gros avantages. + +1. Le fait qu'un pare-feu intelligent capable de faire la différence entre https et ssh sera par contre incapable de bloquer ce nouveau flux, qu'il ne pourra que considérer comme de l'https +2. La possibilité d'utiliser l'en-tête SNI des connexions SSL pour choisir dynamiquement la cible de notre connexion SSH + +On garde la configuration précédente, mais on va ajouter une nouvelle vérification de flux **une fois le SSL déchiffré**, pour voir si on à affaire à de l'http ou du SSH ! + +.. figure:: {static}/images/ssh-openssl-haproxy/ssh_over_ssl.png + :width: 700px + :alt: Description de l'objectif à atteindre : Un frontend Public 443 redistribue les flux vers un backend SSH et un backend SSL, ce dernier renvoyant ensuite vers un nouveau frontend SSL. Ce nouveau frontend va se charger de déchiffrer le flux SSL, puis de rediriger le flux final vers le frontend HTTP habituel ou vers le serveur SSH demandé. + + Deuxième étape : Séparer SSH et HTTP depuis le flux SSL diff --git a/content/images/ssh-openssl-haproxy/ssh_over_ssl.png b/content/images/ssh-openssl-haproxy/ssh_over_ssl.png new file mode 100644 index 0000000000000000000000000000000000000000..be9340b4f7a71646339abece0c99d9f06a6720f8 GIT binary patch literal 30167 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 C_SPc+ literal 0 HcmV?d00001 diff --git a/content/images/ssh-openssl-haproxy/ssh_simple.png b/content/images/ssh-openssl-haproxy/ssh_simple.png new file mode 100644 index 0000000000000000000000000000000000000000..38655ac4bf12a6adb806f2b8f59853b91c122142 GIT binary patch literal 17391 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 Q$OA=1QB$Ex&g#K`0~3AG8~^|S literal 0 HcmV?d00001