Question réseau et connections

network
#1

Je me pose une question sur la faisabilité technique du cas que je décris ci-dessous.
Il y a peu de chance que ce soit faisable (avec mes connaissances ça ne l’est pas), mais je préfère demander aux experts qui traînent dans le coin histoire de ne pas passer à côté d’une solution potentielle.

Le setup:

Un file server derrière un firewall qui ne laisse passer que les connexions sortantes.
Un serveur central en open bar.
Un browser qui ne peut, par définition que faire des connexions sortantes vers le serveur central.

J’ai totalement la main sur les deux serveurs (y compris le code).

Est-ce qu’il est possible, le serveur central étant le seul à pouvoir accepter des connections entrantes, d’initier un transfert de fichier du serveur de fichier vers le browser sans que le serveur central ne fasse proxy et se tappe tout le traffic ?

En gros je veux du peer to peer avec une connection initiée par un serveur central.

Bon j’y crois pas trop mais sait-on jamais…

#2

C’est tout à fait possible. Ce que tu appelles “central server” en réseau on appelle ça un reverse proxy. C’est-à-dire que c’est un serveur intermédiaire qui “se fait passer pour le client auprès d’un serveur”. Dans le domaine HAProxy est ce qui se fait de mieux à mon goût (il fait reverse proxy HTTP mais aussi TCP si tu utilises des protocoles non-HTTP).

En revanche là où ça se complique, c’est si la connexion est sécurisée. N’importe quel protocole qui chiffre la communication (HTTPS par exemple), va te poser souci. Tu as trois possibilités :

  1. transmettre le flux sans le déchiffrer, mais dans ce cas selon le protocole le “destinataire” indiqué dans le flux reste ton reverse proxy et ça peut provoquer des problèmes pour ton serveur qui ne comprendra pas pourquoi il reçoit des choses adressée au nom de quelqu’un d’autre
    Usage : le contenu des échanges ne se base pas du tout sur qui est l’émetteur et qui est le destinataire
  2. le reverse proxy déchiffre tout flux qui vient du client, en réécrivant les infos du flux qui indiquent qui est l’émetteur et qui est le destinataire afin de “se faire passer pour le client”, et l’envoie en clair au serveur qui n’y voit que du feu (de son point de vue le protocole n’est pas sécurisé)
    Usage : le contenu des échanges se base sur qui émet et qui reçoit, mais tu as la main sur tout ce qui est entre ton reverse proxy et ton backend et tu considère que c’est une zone sécurisée
  3. le reverse proxy déchiffre le flux qui vient du client, toujours en réécrivant les infos, mais ensuite il rechiffre le flux pour le donner chiffré au serveur
    Usage : le contenu des échanges se base sur qui émet et qui reçoit, et en plus tu considère que le réseau entre ton reverse proxy et ton backend n’est pas sûr, par exemple parce que d’autres services/personnes pourraient essayer d’intercepter le flux

Dans les cas 2 et 3 c’est ce qu’on appelle une rupture protocolaire.

Quand c’est du HTTP(S), c’est très facile à faire :

  • pour “se faire passer pour le client” il suffit de regarder du côté des headers X-Forwared-For / X-Forwarded-Port / X-Forwarded-Proto etc. ;
  • pour déchiffrer/rechiffrer il suffit que ton reverse proxy porte un certificat X.509 (que tu peux auto-générer si tu ne fait pas un truc pro et que tu n’as pas peur d’avoir une alerte dans ton navigateur).

En revanche, si c’est autre chose que du HTTP, tu vas un peu plus galérer. Pour la partie déchiffrer/rechiffrer, tu peux utiliser un outil comme stunnel. Mais pour le côté “se faire passer pour le client” il y a de grandes chances que tu doives trouver un soft adapté à ton protocole, ou le recoder toi-même.

Je vais partir du principe que tu pensais à mettre à dispo des fichiers de type vidéo/musique à dispo via un simple serveur HTTP qui sert un répertoire rempli de fichiers. Dans ce cas ta stack va ressembler à :

  • un serveur “backend” qui sert les fichiers (typiquement un nginx ou un apache)
  • un firewall qui laisse passer les nouveaux flux entrants HTTP (port 80) vers le “backend”, et tous les flux sortants en réponse, et qui fait du NAT (càd qu’il se fait passer pour le reverse proxy auprès du “backend”)
  • un reverse proxy “frontal” qui réécrit les requêtes du navigateur client entrantes en remplaçant le header Host par l’adresse du “backend”, et en ajoutant un header X-Forwarded-For avec sa propre adresse avant de transmettre le flux au “backend”

Doc :

Et quelques slides que j’ai écrit pour une formation sur le sujet pour ma boîte :

4 Likes
#3

Psss, connection, c’est en anglais. En français, c’est connexion, avec un zix !

#4

Tu remarqueras que j’y ai pensé en début de post, et qu’ensuite les réflexes on repris le dessus. :stuck_out_tongue:

1 Like
#5

Alors déjà merci beaucoup pour les explications détaillées, je garde ça sous le coude. :ok_hand:

Maintenant je pense que mon problème n’est pas soluble avec un reverse proxy (ou alors j’ai zappé un truc).

Pour prendre un exemple plus précis, imagine un serveur S qui tourne sur un PC perso ou un NAS (donc derrière un firewall Windows et une box ou un routeur). Un peu comme une instance de Plex.
Le “serveur central” est sur un hébergeur quelconque.
Le client C est un browser de PC ou de téléphone mobile (pas le même PC que celui qui hoste le serveur évidemment).

A cause du firewall et du routeur, le client C ne peux pas attaquer le serveur S directement (je ne veux pas avoir à toucher au firewall et au routeur pour forwarder des ports). C’est ce problème que je cherche à résoudre .

#6

Encore une fois ça va dépendre de ton protocole. Si c’est du flux TCP ça va marcher.

La contrainte si ton Firewall est ton routeur Internet fourni par ton FAI (ou à ta main) c’est qu’il ait une IP fixe. S’il a une IP dynamique il faut que tu redémarres ton reverse proxy avec la nouvelle IP quand ta box change d’IP. Ou que tu utilises un service de type DynDNS.

Note que si ton protocole est non chiffré (genre HTTP en clair), alors ton flux va passer en clair sur Internet.

Si c’est un problème, parce que les données sont confidentielles, et que ton serveur ne gère pas lui-même le fait de chiffrer ses communications, c’est là que tu peux faire entrer en jeu, en plus, stunnel. Si tu veux plus d’infos, n’hésite pas.

Quelques ressources :

#7

En l’occurence il s’agit bêtement de servir des fichiers sur HTTP(S), en se débrouillant pour pouvoir le faire sans avoir à configurer quoi que ce soit niveau réseau, ni firewall, ni redirection de port.
(dans ton exemple il y a bien une redirection de port faite au niveau du firewall, ce que je cherchais à éviter)

En gros faire un serveur qui fonctionne sans écouter de connection entrante (oui ça a l’air con dit comme ça, ce qui veut probablement dire que ce n’est pas possible).

Use case: le user downloade un exe, le lance sur sa machine (en saisisant des credentials). Puis il pointe sont téléphone sur un site web tiers, et hop, magie, il a accès au contenu servi par l’exe qu’il a lancé sur son poste local.

#8

C’est antinomique. Un serveur est défini par le fait qu’il écoute des connexions entrantes et y répond.

C’est le principe d’un reverse proxy d’être le site tiers qui fait que jamais ton client ne saura quelle est l’IP de ta box internet. Que tu veuilles un serveur HTTP, FTP, p2p.

C’est en contradiction avec le fait d’héberger quelque chose.

Mais avec ces infos je commence à voir ce que tu cherches. Je pense que le plus proche que tu puisses avoir de ce que tu es en train de demander c’est un logiciel du style Gigatribe :

https://www.gigatribe.com/fr/accueil

Mais avec Gigatribe les gens se connectent à ton IP publique. Tu pourrais donc essayer de mettre en place un reverse proxy devant Gigatribe, mais là sans connaître les détails du protocole, je ne peux pas savoir ce que ça implique comme complications. Peut-être qu’un simple HAProxy en reverse proxy TCP ça fonctionnerait. Tout comme ça pourrait ne pas marcher du tout parce que l’IP du serveur distant est vérifiée au niveau du protocole côté client par rapport à l’IP contenu dans le flux… Il n’y a qu’en testant que tu peux savoir.

#9

Merci pour les pistes et les explication ! :slight_smile: