1 votes

Comment configurer le mode transparent de sslh dans un environnement docker ?

Je veux mettre en place sslh sur le port 443 pour transférer vers https et openvpn qui résident dans deux conteneurs docker. Comme je veux fournir des ACL basées sur l'IP sur https à long terme, je veux que sslh fournisse la véritable IP du client au serveur web (c'est-à-dire le mode "transparent" de sslh).

Si je comprends bien documentation y cette réponse Dans ce cas, sslh simulera des demandes extérieures sur le réseau interne et la réponse du serveur devra être renvoyée pour traduire le port de communication avec le client.

Mon problème est la configuration d'iptables. Il y a deux possibilités pour exécuter sslh : sur l'hôte ou dans un conteneur à l'intérieur du réseau Docker.

J'ai réussi à faire fonctionner la configuration "par défaut" telle que décrite dans la documentation, c'est-à-dire que sslh sur l'hôte pouvait transférer de manière transparente vers un service sur l'hôte.

Cependant, je ne parviens pas à faire fonctionner transparent sslh, que ce soit sur l'hôte ou dans un conteneur, avec les serveurs conteneurisés. Plus précisément, mes règles iptables pour marquer le trafic qui doit être acheminé vers sslh ne correspondent jamais à un paquet.

Par exemple, pour un serveur web https, je le ferais :

iptables -t mangle -A OUTPUT -p tcp --sport 443 --source 172.25.0.2 --jump SSLH

Utilisation de ce tableau J'ai essayé de discerner comment les périphériques ethernet virtuels du conteneur, le pont docker, le NAT docker et iptables fonctionnent ensemble mais je n'arrive pas à m'y retrouver.

Pour mieux discuter de cette question, supposons ce qui suit :

  • hôte (eth0) : 1.1.1.1
  • docker-bridge (br0) : 172.25.0.0/16
    • serveur web (veth1) : 172.25.0.2:443 (exposé sur l'hôte comme 8443 si nécessaire)
    • openvpn (veth2) : 172.25.0.3:1194 (transféré à l'hôte si nécessaire)
    • sslh dans le conteneur (mutuellement exclusif avec host sslh) : 172.25.0.4:443 (transmis à l'hôte)
  • sslh sur l'hôte (mutuellement exclusif avec le conteneur sslh) : port 443
  • client : 8.8.8.8.8

Voici mon modèle défaillant de ce qui devrait se passer lorsqu'un navigateur se connecte à host:443 et que sslh est sur l'hôte en mode transparent.

  • sslh se connecte à 172.25.0.2:8443 en se faisant passer pour le client original 8.8.8.8
  • le serveur web répond pour le handshake TCP à 8.8.8.8 via veth1
  • le paquet va sur br0
  • le routage décide de l'envoyer via ent0
  • la chaîne de sortie mangle d'iptables le marque comme trafic pour sslh (c'est ce qui ne fonctionne pas pour moi)
  • la marque indique qu'il faut acheminer le paquet vers le périphérique local lo à la place.
  • sslh le récupère, traduit le port et le renvoie au client.

Mon problème dans la liste ci-dessus est que je ne connais pas les critères de filtrage pour le trafic sortant des serveurs web : Dois-je utiliser le port interne de docker 443 ou le port mappé 8443 ? L'IP du docker 172.25.0.2 ou une autre ? En résumé, la règle de sortie de mangle s'exécutera-t-elle avant ou après le NAT de docker ?

J'ai pensé que je pourrais mettre sslh dans le réseau docker pour éviter de penser au NAT mais je n'arrive toujours pas à faire correspondre les règles iptables.

Je ne sais pas comment procéder.

0voto

systemofapwne Points 1

Je sais que ce fil de discussion est plutôt "vieux", mais je viens de me retrouver dans la même situation et j'étais littéralement perdu au début. Mais j'ai réussi à faire en sorte que ça marche. Ce n'est peut-être pas la solution la plus élégante (n'hésitez pas à faire des suggestions !).

Mon installation est très similaire à la vôtre :

  • hôte (1.1.1.1)
    • sslh:443
    • ssh:2222
    • docker
      • container1 (container:443 -> hôte:4443)
      • conteneur2 (conteneur:443 -> hôte:1194)

En utilisant la documentation de sslh, j'ai réussi à utiliser le mode transparent pour ssh:443. Donc apparemment, le routage vers les processus hôtes en mode transparent fonctionne.

Voici mon ensemble actuel de règles (d'accueil)

iptables -t mangle -N SSLH
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j SSLH
#The next line routes ssh@host via sslh back to the client. Add more rules like this for other services running on the host (with their respective port)
iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 2222 -j SSLH
iptables -t mangle -A SSLH -j MARK --set-mark 0x1 
iptables -t mangle -A SSLH -j ACCEPT
ip rule add fwmark 0x1 lookup 100 
ip route add local 0.0.0.0/0 dev lo table 100

Cela achemine le trafic ssh de manière transparente entre l'hôte (port 2222) et le client via sshl. Mais l'ajout d'une règle similaire pour les conteneurs docker n'a pas fonctionné pour moi (probablement en raison des règles iptables/réseaux étendus des dockers).

Ma solution est maintenant la suivante : Attribuer une ip fixe (interne au conteneur) aux conteneurs docker et laisser sslh accéder aux conteneurs via cette ip et le port interne de ce conteneur au lieu de via 1.1.1.1:4443 ou 1.1.1.1:1194.

  • conteneur1 : 10.1.0.100
  • conteneur2 : 10.2.0.100

Mon fichier /etc/default/sslh contient maintenant cette entrée

DAEMON_OPTS="-n --user sslh --transparent --timeout 5 --listen 0.0.0.0:443 --ssh 1.1.1.1:2222 --ssl 10.1.0.100:443 --openvpn 10.2.0.100:443 --pidfile /var/run/sslh/sslh.pid"

Afin d'attribuer une IP fixe à un conteneur, il suffit de créer un nouveau réseau, par exemple via cli ou via docker-compose.

Comme j'utilise docker-compose, j'ai procédé comme suit :

version: '2.4'
services:
  nginx:
    image: nginx
    ports:
      - "80:80"
      - "4443:443"
    networks:
      static-network:
          ipv4_address: 10.1.0.100
      default: null

  static-network:
    ipam:
      config:
        - subnet: 10.1.0.0/16

Cette solution ajoutera le conteneur "nginx" à deux réseaux : Tout d'abord le nouveau "static-network" avec un ip fixe 10.1.0.100 et aussi au réseau par défaut (pratique si vous voulez par exemple lier deux conteneurs dans le même fichier docker-compose via le réseau par défaut généré automatiquement).

Je dois cependant admettre que cette solution n'est qu'une solution de rechange. Je ne comprends tout simplement pas la magie du routage et d'iptables à ce point, que je peux tout simplement écrire de meilleures règles de routage. Pourtant, cette solution de contournement fait l'affaire pour moi : Proxys sslh transparents vers l'hôte et les conteneurs docker.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X