Comment rendre accessible les services que l’on héberge à la maison sans se prendre la tête et sans ouvrir de port ? C’est ce que nous allons voir dans cet article dédié à Cloudflare Tunnel. L’objectif est simple : ouvrir une application sur internet, en quelques minutes et sans avoir à toucher à la moindre configuration sur notre box.

État des lieux de mes accès externes

J’autohéberge des services depuis aussi longtemps que je m’en souvienne (ou depuis aussi longtemps qu’une connexion internet est à ma disposition). J’ai toujours choisi la facilité pour l’accès externe de ces services : ouvrir les ports sur ma box opérateur. Avec un reverse proxy derrière, ça fait le boulot, mais ça ouvre la porte à tout le monde pour tenter de s’introduire sur mon réseau local.

J’ai récemment installé CrowdSec sur la VM qui porte mon reverse proxy. Cela m’a permis de me rendre compte du nombre de tentatives d’accès ou de compromission que reçoit mon pauvre serveur web. J’ai donc décidé de me pencher sérieusement sur un moyen de sécuriser un peu plus l’accès à mes ressources locales, afin d’ouvrir uniquement le strict nécessaire et surtout sans affecter le fonctionnement de mes services.

Par ailleurs, j’utilisais déjà Wireguard comme VPN pour me permettre d’accéder de façon sécurisée à l’entièreté de mon LAN. Cependant, j’ai des services que je souhaite rendre accessibles plus largement et sans nécessiter de configuration « complexe » pour mes utilisateurs. On parle ici de Home Assistant, Immich, Paperless ou encore Synology Drive… Une solution s’est donc imposée : les Cloudflare Tunnels.

La solution Cloudflare Tunnel

Les Cloudflare Tunnels répondent parfaitement à ce besoin. L’idée est simple : on installe un « connecteur » sur notre réseau local (via un conteneur Docker dans mon cas) qui permet de monter un tunnel chiffré vers l’infrastructure Cloudflare. Le tout, sans avoir à ouvrir le moindre port sur la box de l’opérateur. Jusqu’ici, le fonctionnement est semblable à ce que proposerait un simple VPN.

Mais les Tunnels ne s’arrêtent pas là puisqu’ils s’adossent à un nom de domaine (qu’il faudra impérativement rattacher à votre compte Cloudflare). Une fois le tunnel monté, il est alors possible de définir un domaine, un sous-domaine et pourquoi pas une URI et d’indiquer sur quelle IP locale et quel port le trafic doit être redirigé. Cloudflare porte ensuite la gestion du SSL en frontal, puis tunnelise le trafic jusqu’à l’application sur le réseau local.

Schéma de principe - Cloudflare Tunnel
Schéma de principe d’un Cloudflare Tunnel

Pour résumer, les Cloudflare Tunnels sont de pseudo-VPN applicatifs et permettent de rendre accessible un service local sur internet en quelques clics et sans avoir à ouvrir le moindre port. On ouvre ainsi un domaine ou un sous-domaine sur internet, et on le fait pointer sur une IP et un port sur notre réseau local. J’attire votre attention sur le fait que le trafic dans le tunnel, bien que chiffré pour le commun des mortels, est accessible pour Cloudflare puisqu’ils portent le SSL en frontal. Aussi, bien que Cloudflare garantisse un tier gratuit sur ce service, il présente quelques limitations techniques comme l’impossibilité d’y faire transiter des fichiers de plus de 100 Mo.

Comment mettre en place un Cloudflare Tunnel ?

L’interface d’administration de Cloudflare est… complexe. J’ai eu quelques difficultés à m’y retrouver au départ et vais donc tâcher d’être le plus clair possible dans mes explications. La première chose à faire est d’ajouter votre domaine à votre compte Cloudflare.

Il n’est pas nécessaire de transférer celui-ci chez Cloudflare, mais il faudra définir Cloudflare comme NS pour ce domaine. Cela se passe sous Domain registration > Transfer domains. Suivre juste les instructions pour ajouter votre domaine à Cloudflare. Attention, le service prendra la main sur tous vos services et vous pourriez donc en couper l’accès temporairement.

Une fois le domaine ajouté, on peut donc passer à la configuration de notre tunnel. Pour cela, direction Zero Trust (toujours dans le menu latéral). Puis, sous Networks > Connectors, on va créer un nouveau tunnel de type “Cloudflared”. Choisir un nom pour ce tunnel et installer le connecteur.

J’utilise personnellement cette configuration via Docker (en n’oubliant pas d’ajouter le token en variable d’environnement) :

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    environment:
      - TZ=Europe/Paris
      - TUNNEL_TOKEN=${TOKEN}
    restart: unless-stopped
    command: tunnel --no-autoupdate run

Si tout se passe bien, le tunnel nouvellement créé devrait apparaitre comme “Healthy” dans l’interface. En cliquant sur le nom du tunnel dans la liste, puis Edit, on accède à sa gestion sur laquelle nous allons pouvoir ouvrir l’accès à nos applications. Sur la page du tunnel, on se rend dans l’onglet « Published application routes » et on ajoute une nouvelle route.

Il ne reste plus qu’à remplir les informations sur l’application. Le sous-domaine sera automatiquement créé par Cloudflare, qui activera au passage le SSL (donc plus besoin de s’embêter avec Let’s Encrypt. Pensez à supprimer les éventuels records existants si vous avez un message d’erreur.

Sous « Service », il conviendra d’indiquer comment le connecteur doit accéder à l’application sur votre réseau local. En général, on choisira HTTP puis l’IP locale du service ainsi que son port. En résumé, il faut ici sélectionner ce que vous utilisez en local pour accéder au service en question. On sauvegarde, on teste l’accès via l’URL de l’application et… ça marche.

Conserver l’accès local sans utiliser le tunnel

Maintenant qu’on a créé notre première application publiée, tout le trafic à destination du sous-domaine configuré passera donc au travers du tunnel Cloudflare, sans avoir à ouvrir le moindre port sur la box de notre opérateur. C’est intéressant quand on n’est pas chez nous, mais l’intérêt est relativement limité lorsqu’on est connecté à la maison.

Cloudflare Tunnel - Adguard

De mon côté, pour résoudre cette problématique, j’ai laissé en place mon Nginx Proxy Manager historique, qui encadre également le SSL pour mon domaine. Associé à AdGuard, qui tourne lui aussi sur une VM sur mon réseau local, j’ai ajouté des résolutions DNS locales qui pointent directement sur les IP privées de mes applications. Ainsi, les personnes connectées au sein du domicile ne sont pas dépendantes de Cloudflare pour accéder aux ressources locales.

Nous avons donc mis en place un tunnel Cloudflare vers un service hébergé sur le réseau local. On peut désormais refermer les éventuels ports ouverts sur notre box. Vous remarquerez qu’en l’état, en dehors d’avoir limité la surface d’attaque, nous n’avons pas mis en place de sécurité particulière sur ces tunnels. Cela sera l’objet d’un prochain article, où nous verrons comment ajouter une authentification côté Cloudflare et comment bloquer, par défaut, certaines sources.

Catégorisé dans :

Homelab,

Tagué dans :

, , ,