Seedbox

Ubuntu 20.04 / Debian 10 – Installation d’une seedbox anonyme et sécurisée – (Partie 2) Accès de l’extérieur avec Traefik

blank

Debian

Un reverse proxy est le récepteur frontal de toutes les requêtes HTTP venant de l’extérieur. Celui-ci les redirigera vers les bonnes instances des conteneurs Docker. Dans notre cas, nous disposons d’une multitude de containers Docker et nous ne pouvons pas toutes les faire écouter sur le port 80 ou 443, d’où l’utilisation d’un reverse proxy. Ajoutez à cela un joli nom de domaine à votre seedbox en sécurisant le tout avec le protocole SSL/TLS et un certificat Let’s Encrypt.

5 – Traefik

Traefik est un reverse-proxy et un load-balancer moderne conçu (par un Français) pour faciliter le déploiement des microservices (Docker, Kubernetes, AWS, etc.). Traefik est extrêmement simple à configurer et gère automatiquement vos certificats délivrés par Let’s Encrypt. De plus, il est capable de charger vos containers dynamiquement sans interruption de service et dispose d’un dashboard affichant l’ensemble de vos routes configurées.

Traefik avec Docker

Nous détaillerons ici la procédure avec l’image Deluge AirVPN mais celle-ci reste bien sûr compatible avec les images PIA et sans VPN si elle est suivie consciencieusement.

5.1 – Création de l’utilisateur traefik

Si vous avez plusieurs docker-compose.yml ou si vous avez pour projet d’en créer par la suite, il est préférable d’isoler et de dédier un docker-compose.yml à Traefik. Il est recommandé de ne pas le lancer sous votre super-utilisateur et de créer un utilisateur dédié.

  1. Créez un utilisateur traefik :

    sudo adduser traefik
  2. Ajoutez-le au groupe docker :

    sudo adduser traefik docker

5.2 – Le réseau Traefik

Dans la première partie de ce tutoriel, chaque container Docker partage le réseau de votre machine pour être accessible en local avec la propriété network_mode: "host". Avec un reverse proxy, cette configuration n’a plus lieu d’être et nous allons en profiter pour ajouter un peu plus de sécurité en isolant vos containers dans un réseau uniquement accessible par Traefik et vos containers.

  1. Connectez-vous sous l’utilisateur traefik :

    su traefik
  2. Déplacez-vous dans le répertoire personnel de cet utilisateur :

    cd
  3. Créez le réseau dédié à Traefik et à l’ensemble de vos containers :

    docker network create traefik_network

5.3 – L’image Traefik

Créez le fichier /home/traefik/docker-compose.yml en ajoutant le contenu suivant :

version: '3.7'
services:
  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    restart: unless-stopped
    networks:
      - traefik_network
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /home/traefik/traefik.toml:/traefik.toml:ro
      - /home/traefik/acme.json:/acme.json

networks:
  traefik_network:
    external: true
  • /var/run/docker.sock:/var/run/docker.sock:ro : précise le socket Unix de votre docker. Laissez cette valeur par défaut.
  • /home/traefik/traefik.toml:/traefik.toml:ro : précise le chemin du fichier de configuration de Traefik. Nous le créerons à l’étape suivante.
  • /home/traefik/acme.json:/acme.json : précise le chemin du fichier contenant les informations relatives à vos certificats.
  • traefik_network : ici nous spécifions le réseau créé précédemment et dédié à Traefik. Nous ajouterons les différents containers dans ce réseau par la suite.

5.4 – Configuration Traefik

Traefik peut être configuré de différentes manières, nous allons détailler ici, la configuration recommandée par Traefik, à savoir par un fichier statique au format TOML.

  1. Traefik stocke les informations liées au certificat dans un fichier acme.json. Vous devez au préalable créer le fichier et lui attribuer un minimum de permissions :

    touch /home/traefik/acme.json && chmod 600 /home/traefik/acme.json
  2. Créez le fichier de configuration Traefik /home/traefik/traefik.toml en ajoutant les lignes suivantes. L’unique propriété à modifier est l’email :

    [providers.docker]
      endpoint = "unix:///var/run/docker.sock"
      watch = true
      exposedByDefault = false
    
    [entryPoints.web]
      address = ":80"
      [entryPoints.web.http.redirections.entryPoint]
        to = "websecure"
        scheme = "https"
    
    [entryPoints.websecure]
      address = ":443"
    
    [certificatesResolvers.leresolver.acme]
      email = "votre-adresse@email.com"
      storage = "acme.json"
      [certificatesResolvers.leresolver.acme.httpChallenge]
        entryPoint = "web"
    • [providers.docker] : cette directive permet tout simplement d’activer le support Docker.
    • endpoint = « unix:///var/run/docker.sock » : précise le socket Unix de votre Docker à Traefik. Laissez la valeur par défaut.
    • watch = true : permet de déployer à chaud les containers dès qu’un changement dans la configuration est détectée.
    • exposedByDefault = false : n’expose pas par défaut les containers au monde extérieur. Il est préférable d’activer cette option dans le docker-compose.yml pour chacun des containers dans le cas où, si pour une raison ou une autre, vous ne souhaiteriez plus rendre accessible un container de l’extérieur.
    • [entryPoints.web] et [entryPoints.websecure] : ces directives définissent les points d’entrée de votre Traefik. web et websecure sont purement indicatifs, vous pouvez les nommer autrement mais ils doivent correspondre aux labels que nous définirons plus tard dans le docker-compose.yml. Les propriétés adress précisent les ports sur lesquels Traefik « écoute » en fonction du point d’entrée.
    • [entryPoints.web.http.redirections.entryPoint] : force la redirection du port 80 vers le port 443 donc force le HTTP en HTTPS.
    • [certificatesResolvers.[NOM_RESOLVEUR].acme] : nous indiquons ici que nous souhaitons utiliser le protocole ACME (donc le service Let’s Encrypt) pour obtenir un certificat. Le nom du résolveur est purement indicatif, il doit simplement correspondre aux labels que nous définirons plus tard dans le docker-compose.yml.
    • storage = « acme.json » : la propriété storage précise à Traefik le fichier (que nous avons créé précédemment) où seront stockées les informations relatives aux certificats. L’erreur commune est d’indiquer le chemin absolu (dans notre cas /home/traefik/acme.json), ici le chemin à renseigner est celui au sein du container Traefik, il faut donc laisser cette valeur par défaut.
    • [certificatesResolvers.[NOM_RESOLVEUR].acme.httpChallenge] : cette directive précise tout simplement par quel point d’entrée (dans notre cas le port 80) Traefik peut obtenir un certificat.
  3. Déplacez-vous dans le répertoire personnel de l’utilisateur traefik et démarrez le container :

    cd
    docker-compose up -d

5.5 – Labels et réseau Traefik


N’oubliez pas d’ajouter des règles DNS pour chacun des sous-domaines dans l’interface administrateur du fournisseur de votre nom de domaine pour pointer vers l’IP de votre serveur. Les règles à ajouter dont de type « A ».

Si votre serveur est hébergé chez vous, il sera aussi nécessaire de créer une redirection du port 80 et 443 vers votre serveur dans l’interface de configuration de votre box internet (ou routeur).


  1. Connectez-vous sous l’utilisateur media :

    su media
  2. Déplacez-vous dans son répertoire personnel :

    cd
  3. Modifiez votre /home/media/.env en ajoutant les lignes suivantes en fin de fichier. Remplacez mondomaine.com par le vôtre. Attention ici à renseigner uniquement la base de votre domaine (aucun sous-domaine ni même les www) :

    [...]
    NETWORK=traefik_network
    BASE_HOST=mondomaine.com
  4. Dans votre fichier /home/media/docker-compose.yml, remplacez toutes les directives network_mode: "host" par votre nouveau réseau. Attention, l’image Deluge sans VPN possède aussi cette directive. De plus, toutes les expositions de ports sont inutiles, vous pouvez supprimer toutes les directives ports: avec les ports associés.

    Ensuite, ajoutez les labels permettant de communiquer avec Traefik et terminez par ajouter le réseau traefik_network en fin de fichier :

    version: '3.7'
    services:
      deluge:
        image: binhex/arch-delugevpn:latest
        container_name: deluge
        restart: unless-stopped
        networks:
          - ${NETWORK}
        cap_add:
          - NET_ADMIN
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - VPN_ENABLED=yes
          - VPN_PROV=airvpn
          - ENABLE_PRIVOXY=yes
          - LAN_NETWORK=${LAN_NETWORK}
          - NAME_SERVERS=209.222.18.222,37.235.1.174,8.8.8.8,209.222.18.218,37.235.1.177,8.8.4.4
          - UMASK=000
          - DEBUG=false
        volumes:
          - /home/deluge/config:/config
          - /etc/localtime:/etc/localtime:ro
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.deluge.entrypoints=web,websecure"
          - "traefik.http.routers.deluge.rule=Host(`deluge.${BASE_HOST}`)"
          - "traefik.http.services.deluge.loadbalancer.server.port=8112"
          - "traefik.http.routers.deluge.tls=true"
          - "traefik.http.routers.deluge.tls.certresolver=leresolver"
    
      jackett:
        image: linuxserver/jackett:latest
        container_name: jackett
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/jackett/config:/config
          - /etc/localtime:/etc/localtime:ro
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.jackett.entrypoints=web,websecure"
          - "traefik.http.routers.jackett.rule=Host(`jackett.${BASE_HOST}`)"
          - "traefik.http.services.jackett.loadbalancer.server.port=9117"
          - "traefik.http.routers.jackett.tls=true"
          - "traefik.http.routers.jackett.tls.certresolver=leresolver"
    
      sonarr:
        image: linuxserver/sonarr:latest
        container_name: sonarr
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/sonarr/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.sonarr.entrypoints=web,websecure"
          - "traefik.http.routers.sonarr.rule=Host(`sonarr.${BASE_HOST}`)"
          - "traefik.http.services.sonarr.loadbalancer.server.port=8989"
          - "traefik.http.routers.sonarr.tls=true"
          - "traefik.http.routers.sonarr.tls.certresolver=leresolver"
    
      radarr:
        image: linuxserver/radarr:latest
        container_name: radarr
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/radarr/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.radarr.entrypoints=web,websecure"
          - "traefik.http.routers.radarr.rule=Host(`radarr.${BASE_HOST}`)"
          - "traefik.http.services.radarr.loadbalancer.server.port=7878"
          - "traefik.http.routers.radarr.tls=true"
          - "traefik.http.routers.radarr.tls.certresolver=leresolver"
    
      lidarr:
        image: linuxserver/lidarr:latest
        container_name: lidarr
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/lidarr/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.lidarr.entrypoints=web,websecure"
          - "traefik.http.routers.lidarr.rule=Host(`lidarr.${BASE_HOST}`)"
          - "traefik.http.services.lidarr.loadbalancer.server.port=8686"
          - "traefik.http.routers.lidarr.tls=true"
          - "traefik.http.routers.lidarr.tls.certresolver=leresolver"
    
      plex:
        image: linuxserver/plex:latest
        container_name: plex
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - VERSION=latest
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/plex/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.plex.entrypoints=web,websecure"
          - "traefik.http.routers.plex.rule=Host(`plex.${BASE_HOST}`)"
          - "traefik.http.services.plex.loadbalancer.server.port=32400"
          - "traefik.http.routers.plex.tls=true"
          - "traefik.http.routers.plex.tls.certresolver=leresolver"
    
    networks:
      traefik_network:
        external: true
    • traefik.enable=true : ce label expose le container au monde extérieur. Il surchage la propriété exposedByDefault de votre fichier /home/traefik/traefik.toml.
    • traefik.docker.network=traefik_network : ce label précise à Traefik quel réseau utilise le container.
    • traefik.http.routers.[NOM_DU_CONTAINER].entrypoints : chaque règle de routage spécifique à un container doit être spécifiée par un nom, ici nous utilisons tout simplement le nom du container. Le label entrypoints précise que les requêtes entrantes sur les points d’entrée web (port 80) et websecure (port 443) seront transmises au container.
    • traefik.http.routers.[NOM_DU_CONTAINER].rule=Host(`[SERVICE].${BASE_HOST}`) : ici nous précisons une règle, toute requête arrivant sur http://SERVICE.mondomaine.com sera transmise au container Docker associé.
    • traefik.http.services.[NOM_DU_CONTAINER].loadbalancer.server.port=[PORT] : ici nous précisons le port du container sur lequel les requêtes doivent être transmises.
    • traefik.http.routers.[NOM_DU_CONTAINER].tls : active le support SSL/TLS.
    • traefik.http.routers.[NOM_DU_CONTAINER].tls.certresolver : précise le résolveur et donc les certificats à utiliser.
  5. Déplacez-vous dans le répertoire personnel de l’utilisateur media et redémarrez l’ensemble des containers :

    cd
    docker-compose up -d

5.6 – Configuration des services

Plex

Pour un accès à distance, il est nécessaire d’associer l’interface web Plex à votre serveur. Pour cela, vous devez préciser l’URL et un code d’association dont la validité est de 4 minutes.
  1. Demandez le code d’association à l’adresse suivante : https://www.plex.tv/claim/

  2. Modifiez votre fichier /home/media/docker-compose.yml et ajoutez les lignes suivantes en spécifiant le code obtenu précédemment :

    version: '3.7'
    services:
      [...]
    
      plex:
        image: linuxserver/plex:latest
        container_name: plex
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - VERSION=latest
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
          - PLEX_CLAIM=claim-424242424242
          - ADVERTISE_IP=plex.${BASE_HOST}:443
        volumes:
          - /home/media/plex/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.plex.entrypoints=web,websecure"
          - "traefik.http.routers.plex.rule=Host(`plex.${BASE_HOST}`)"
          - "traefik.http.services.plex.loadbalancer.server.port=32400"
          - "traefik.http.routers.plex.tls=true"
          - "traefik.http.routers.plex.tls.certresolver=leresolver"
    
    [...]
  3. Redémarrez le container Plex avec la commande :

    docker-compose up -d
Les services sont désormais disponibles aux adresses suivantes :
  • Deluge : http://deluge.mondomaine.com
  • Jackett : http://jackett.mondomaine.com
  • Sonarr : http://sonarr.mondomaine.com
  • Radarr : http://radarr.mondomaine.com
  • Lidarr : http://lidarr.mondomaine.com
  • Plex : http://plex.mondomaine.com

6 – Configuration

Nous allons maintenant configurer les applications pour qu’elles puissent communiquer entre elles et que chacune d’elles dispose d’un minimum de sécurité.

Suite du tutoriel (configuration et problèmes rencontrés)



Debian

Debian 10 BlusterDocker 19.03.8
Docker Compose 1.26.2
Traefik 2.2
Deluge 2.0.4
Jackett 0.16.105.0
Sonarr 2.0.0.5344
Radarr 0.2.0.1480
Lidarr 0.7.1.1381


blank

5/5 - (4 votes)
22 réponses
  1. Jeremy
    Jeremy dit :

    Bonjour,

    J’espère que vous allez bien.

    Lors de l’ajout de la balise network dans le fichier docker-composer.yml, je fait un docker-compose up -d

    J’ai un message d’erreur qui m’indique mapping values are not allowed here line 161, en gros la dernière ligne du fichier ..

    networks:
    seedbox_network:
    name: ${NETWORK}:

    Pouvez-vous me dire pourquoi ? J’ai fait sans copier coller et avec copier coller car j’ai vu que l’espace était sensible..

    Répondre
          • Quentin
            Quentin dit :

            Bonjour,

            Avez-vous corriger le problème ?
            Je suis en train de suivre votre tutoriel et je reçois aussi la même erreur à la dernière ligne…

          • Edouard WATTECAMPS
            Edouard WATTECAMPS dit :

            Bonjour Quentin, j’ai repris entièrement la procédure de Traefik en la simplifiant. Le mieux est de reprendre la procédure depuis le début. N’hésitez pas si vous avez des retours.

          • denis
            denis dit :

            Bonjour, Merci pour le tuto, j’ai malheureusement le même problème ligne 155.
            Je n’utilises pas encore assez docker pour comprendre ou est l’erreur de syntaxe.
            J’ai fait et refait tellement de modif que je ne sais même plus si mes fichiers sont correcte, le fichier est disponible quelque part en download ?
            Ou avez-vous une autre idée ?
            par avance merci
            Denis

          • Edouard WATTECAMPS
            Edouard WATTECAMPS dit :

            Bonjour Denis, j’ai repris entièrement la procédure de Traefik en la simplifiant. Le mieux, dans votre cas, est de supprimer vos docker-compose.yml et de reprendre la procédure depuis le début. N’hésitez pas si vous avez des retours.

  2. Golgfag
    Golgfag dit :

    Bonjour,

    J’ai décidé de passer le pas et de prendre un vpn (PIA) sur mon serveur kimsufi.
    Vous donnez la méthode sur la première partie mais je me demande sur traefik permet l’utilisation du vpn? Dans votre configuration la partie vpn n’est plus présente sur deluge.
    Est-il possible de jumeler les deux? De plus est-il possible d’intégrer jackett dans le vpn? (je souhaite faire un get sous une autre ip).
    Merci

    Répondre
    • Edouard WATTECAMPS
      Edouard WATTECAMPS dit :

      Bonjour,

      Oui je confirme que Traefik est compatible avec les deux images avec VPN et sans VPN, mais effectivement j’ai du faire un choix d’image lors de la procédure pour Traefik. Je vais clarifier tout ça. Non il n’est pas possible d’intégrer Jackett dans le VPN, mais quel serait l’intérêt ? De cacher votre IP lors d’une recherche sur un tracker ?

      Répondre
      • Golgfag
        Golgfag dit :

        Merci pour la réponse l idée était effectivement de faire des get de jacket via d autre ip pour éviter le ban des trackers. Mais finalement je fais autrement ! J ai une autre question à laquelle je n arrive pas à trouver de solution.
        Je souhaite ajouter organizr, celui-ci fonctionne sans problème. Sauf que je suis obligé de faire mes requête sur mon domaine extérieur ( xxx.fr/radarr) hors il serait plus logique de les faires directement sur le network des docker. Mais impossible, je pong bien les docker dans leurs network (172.18.0.x) mais j ai l impression qu’ils ne répondent pas aux requêtes sur les ports spécifiques entre eux… seul traefik peut contacter un container où les containers peuvent communiquer entre eux?

        J espere que je suis compréhensible dans mes explication.

        Merci

        Répondre
  3. Ludo
    Ludo dit :

    Bonjour et merci pour ce tuto de qualité et au goût du jour.
    Je suis bloqué à l’étape 5.5.4, sûrement un problème d’indentation, je ne suis pas à l’aise avec le yaml.
    Le shell me retourne :

    media@xxxxxx:~$ docker-compose up -d
    WARNING: The BASE_HOST variable is not set. Defaulting to a blank string.
    ERROR: The Compose file ‘./docker-compose.yml’ is invalid because:
    Unsupported config option for services.networks: ‘traefik_network’

    Merci par avance de votre aide ! bonne journée

    Répondre
    • Edouard WATTECAMPS
      Edouard WATTECAMPS dit :

      Bonjour Ludo,

      Pouvez-vous me montrer le contenu de votre fichier /home/media/.env, /home/traefik/docker-compose.yml et /home/media/docker-compose.yml ? Sur quel OS êtes-vous et quelle est la version de votre docker-compose (docker-compose -v) ?

      Merci

      Répondre
  4. El BoDe
    El BoDe dit :

    Bonjour et merci pour le tutoriel, j’ai tout suivi à la lettre et ça fonctionne.

    J’aurai juste aimé rajouter la possibilité d’accéder à la GUI de traefik de l’extérieur en passant par traefik.nomdedomaine.com et donc de l’auto référencer.
    j’ai rajouté des labels comme pour les autres services mais cela n’a pas l’air de suffir, une idée de comment faire?

    Merci

    Répondre
      • El BoDe
        El BoDe dit :

        Merci pour la réponse, j’ai pu retrouver dans la doc en plus d’ajouter « traefik.http.routers.traefik.service=api@internal » ça fonctionne nickel.
        J’ai un autre petit soucis, peut être que tu as une idée, sinon je vais continuer à creuser: pour l’accès à Plex, je perds l’accès à distance, comme si le port 32400 n’était pas naté à l’intérieur du réseau (et pourtant il l’est!). Quand je lui demande de « réessayer » dans le menu réglages puis accès à distance, il me dit que tout est ok pendant 2secondes puis il se remet en « non disponible », une idée d’à quoi pourrait être dû ce soucis?

        Merci pour ta réponse plus tôt, bonne continuation

        Répondre

Laisser un commentaire

Rejoindre la discussion?
N’hésitez pas à contribuer !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *