• Docker
  • reverse proxy pour services docker et autre

Bonsoir,

j'ai des services web (Webmail, serveur baikal,etc)qui tournes dans des containers docker et un nas syno (et bientôt une box domotique jeedom) et je souhaiterai pouvoir rendre tout ça accessible depuis l'extérieur et sécurisé avec lets encrypt.

j'ai utilisé un temps un reverse proxy apache mais c'est galère a chaque fois que je veux ajouter un service, sans parler de la gestion des certificat avec lets encrypt.

j'ai essayé traeffik c'est le pied pour les containers mais du coup (sauf erreur) pas possible de faire du reverse vers autre chose comme le nas par exemple.

avez vous une idée de ce que je pourrais utiliser pour répondre à mes besoins?

merci
jericho63

Bonjour,

non j'ai un serveur dédié à docker qui tourne sous debian.
j'ai oublié de préciser que j'héberge tout ça @ la maison.
j'avais un sous domaine pour le nas lorsque j'utilisais un container apache pour faire le reverse proxy, je suis passé sur trafeik par simplicité car le reverse proxy apache était lourd a gérer mais je n'ai pas pensé au nas...

La solution que tu proposes permet de faire reverse avec autre chose que les containers docker?
Va falloir que je me penche sur le fonctionnement de Nginx, je ne l'ai jamais utilisé.

Pas vraiment, non. Mais je pense que tu n'abordes pas le problème avec le bon angle. Je comprends que tu cherches une solution globale pour joindre plusieurs périphériques distincts.
Pour moi c'est pas le bon raisonnement, ça veut dire globaliser la sortie/entrée des flux de données pour faire des redirections : routeur/firewall homemade, VPN etc.
Il me semble que le plus simple est de te garantir l'accès à tous tes services via le même domaine. Ce qui te permet de gérer un/des sous-domaine.s pour ton NAS, d'autres (via le duo que je cite avant) pour tes Dockers etc.

En tous cas il ne me vient pas de solution plus simple dans l'immédiat.

pardon je ne suis pas vraiment sur d'avoir compris l'idée, j'ai l'esprit un peu embrouillé.
en fait je ne comprend pas trop en quoi a quel moment cela diffère de l'utilisation d'un reverse proxy?

a la base j'utilisais un reverse proxy apache qui permettait via des sous domaines distincts de joindre mes services dockers et mon nas.

je crois que j'ai besoin d'un éclaircissement, merci d'avance!

jericho63

    Salut jericho63 ,

    Pour faire ce que tu veux avec plusieurs sous-domaine du même domaine avec traefik (exemple: toto.domain.com, titi.domain.com, tata.domain.com ...), il faut que tu rapproche de la config "file" de celui-ci.
    C'est un peu chaud, mais je pense faisable :

    https://docs.traefik.io/configuration/backends/file/
    https://serverfault.com/questions/850095/simple-reverse-proxy-with-traefik

    Il faut que tu fasse un mix avec la balise file et la balise docker.

    A plus

      bonjour triptixx
      on est bien sur le cas : toto.domain.com et titi.domain.com qui pointent sur des applis docker et nas.domain.com qui pointerait sur le nas?

      j'ai vu la configuration file mais je n'étais pas sur d'avoir bien compris le fonctionnement et donc si ça pouvait répondre à mon besoin.

      En ce qui me concerne, je n utilise pas de reverse proxy Docker mais nginx sur l hôte qui gère tous les reverses aussi bien Docker que locaux (ton nas). Est ce que c est ce que tu souhaites faire ?

      Si c est le cas post ton docker-compose ainsi que les ports que tu utilises pour les services sur ton nas

        laster13

        oui c'est ça, je le faisais avec un apache dockerisé mais c'est lourd d'entretien et un peu pénible avec letsencrypt.

        tu gères letsencrypt aussi?

          jericho63 Oui bien sur. En fait j'ai la messagerie d'@Hardware en docker et tout le reste (sonarr, radarr, lidarr, plex etc ..) en local. Let'encrypt est également en local. Si tu peux poster ce que je t'ai demandé, je regarderai comment je peux t'aider.

            laster13
            mon nas est un synology
            les ports sont le 5000 en http 5001 en https pour le file station, il faut que je regarde pour le video et photo station.

            et mon docker-compose (j'ai pas trouvé comment faire la balise code)

            version: '3'
            networks:
            http_network:
            external: true
            mail_network:
            external: false
            services:
            reverse-proxy:
            image: traefik # The official Traefik docker image
            command: --api --docker # Enables the web UI and tells Træfik to listen to docker
            container_name: reverse-proxy
            ports:
            - "192.168.1.150:80:80" # The HTTP port
            #- "9090:8080" # The Web UI (enabled by --api)
            - "192.168.1.150:443:443"
            labels:
            - traefik.enable=true
            - traefik.frontend.rule=Host:mail.mondomaine.fr
            - traefik.port=8080
            - traefik.docker.network=http_network
            volumes:
            - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
            - /home/srv/traefik/traefik.toml:/traefik.toml:ro
            - /home/srv/traefik/acme:/etc/traefik/acme
            networks:
            - http_network
            mariadb:
            image: mariadb:latest
            container_name: mariadb
            ports:
            - "192.168.1.150:3306:3306"
            volumes:
            - /home/srv/mysql:/var/lib/mysql
            restart: always
            environment:
            - MYSQL_ROOT_PASSWORD=monpassword
            networks:
            - mail_network
            - http_network
            dovecot:
            build: ./dovecot/.
            container_name: mailserver
            ports:
            - "192.168.1.150:25:25"
            - "192.168.1.150:587:587"
            - "192.168.1.150:143:143"
            - "192.168.1.150:993:993"
            - "192.168.1.150:4190:4190"
            volumes:
            - /home/srv/logs:/var/log
            - /home/srv/vmail:/srv/vmail
            - /home/srv/ssl:/etc/ssl
            - /home/srv/dovecot:/var/lib/dovecot
            - /home/srv/letsencrypt:/etc/letsencrypt
            links:
            - mariadb:mysql
            restart: always
            privileged: true
            environment:
            - MYSQL_USERNAME=root
            - ADD_DOMAINS=mondomaine.fr,mondomaine2.eu,mondomaine3.fr
            hostname: mailserver
            domainname: mondomaine.fr
            depends_on:
            - mariadb
            labels:
            - traefik.enable=true
            - traefik.frontend.rule=Host:spam.mondomaine.fr
            - traefik.port=11334
            - traefik.docker.network=http_network
            networks:
            - mail_network
            - http_network
            postfixadmin:
            build: ./postfixadmin/.
            container_name: postfixadmin
            #ports:
            #- "192.168.1.150:33300:80"
            #- "192.168.1.150:33343:443"
            #volumes:
            #- /home/srv/wwwpostfixadmin:/var/www
            #- /home/srv/ssl:/etc/ssl
            links:
            - mariadb:mysql
            hostname: postfixadmin
            domainname: mondomaine.fr
            restart: always
            environment:
            - DBUSER=pfa
            - DBPASS=monpassword
            depends_on:
            - mariadb
            - dovecot
            labels:
            - traefik.enable=true
            - "traefik.frontend.rule=Host:postfixadmin.mondomaine.fr"
            - traefik.backend.port=8888
            - traefik.docker.network=http_network
            networks:
            - mail_network
            - http_network
            phpmyadmin:
            build: ./phpmyadmin/.
            container_name: phpmyadmin
            ports:
            - "192.168.1.150:33400:80"
            - "192.168.1.150:33443:443"
            volumes:
            - /home/srv/ssl:/etc/ssl
            links:
            - mariadb:mysql
            hostname: phpmyadmin
            domainname: mondomaine.fr
            restart: always
            environment:
            - MYSQL_USERNAME=root
            depends_on:
            - mariadb
            labels:
            - traefik.enable=true
            - "traefik.frontend.rule=Host:phpmyadmin.mondomaine.fr"
            - traefik.docker.network=http_network
            networks:
            - mail_network
            - http_network
            baikal:
            build: ./baikal/.
            container_name: baikal
            ports:
            - "192.168.1.150:33500:80"
            - "192.168.1.150:33543:443"
            volumes:
            - /home/srv/wwwbaikal:/var/www
            - /home/srv/ssl:/etc/ssl
            links:
            - mariadb:mysql
            hostname: baikal
            domainname: mondomaine.fr
            restart: always
            environment:
            - MYSQL_USERNAME=root
            - ADD_DOMAINS=mondomaine2.eu,mondomaine3.fr
            labels:
            - traefik.enable=true
            - "traefik.frontend.rule=Host:baikal.mondomaine.fr"
            - traefik.docker.network=http_network
            networks:
            - mail_network
            - http_network
            dokuwiki:
            build: ./dokuwiki/.
            container_name: dokuwiki
            ports:
            - "192.168.1.150:33800:80"
            - "192.168.1.150:33843:443"
            volumes:
            - /home/srv/wwwdokuwiki:/var/www
            - /home/srv/ssl:/etc/ssl
            links:
            - mariadb:mysql
            hostname: dokuwiki
            domainname: mondomaine.fr
            restart: always
            environment:
            - MYSQL_USERNAME=root
            labels:
            - traefik.enable=true
            - "traefik.frontend.rule=Host:dokuwiki.mondomaine.fr"
            networks:
            - http_network
            rainloop:
            build: ./rainloop/.
            container_name: rainloop

            ports:

            #- "192.168.1.150:33100:80"
            #- "192.168.1.150:33143:443"
            volumes:
            - /home/srv/wwwdata/data:/rainloop/data
            #- /home/srv/wwwdata:/var/www
            #- /home/srv/ssl:/etc/ssl
            links:
            - baikal:baikal.mondomaine.fr
            - mariadb:mysql
            - dovecot:mailserver.mondomaine.fr
            restart: always
            hostname: rainloop
            domainname: mondomaine.fr
            depends_on:
            - mariadb
            labels:
            - traefik.enable=true
            - traefik.backend.port=8888
            - "traefik.frontend.rule=Host:rainloop.mondomaine.fr"
            - traefik.docker.network=http_network
            networks:
            - mail_network
            - http_network
            unbound:
            build: ./unbound/.
            container_name: unbound
            restart: always
            ports:
            - "192.168.1.150:53:53"
            - "192.168.1.150:53:53/udp"
            volumes:
            - /srv/logdns:/logdns

              jericho63 Déja il faut virer traeffic, ensuite nettoyer docker avec :

              docker volume rm $(docker volume ls -qf "dangling=true")

              Ensuite je te conseille, plutôt que d’utiliser unbound de suivre le tuto de @Hardware pour la mise en place d'un serveur autoritaire avec nsd :
              https://blog.meshup.net/deploy-nsd-dnssec-with-docker/

              Et de procéder par étape. L'idée est d'abord de mettre en place le reverse sur le serveur mail d'@Hardware sans le reste. Une fois que cela fonctionne tu rajoutes tes services au fur et a mesure. Je te donne mon docker compose

              version: '2.1'
               services:
               mailserver:
                  image: hardware/mailserver:1.1-stable  # <- New tag
                  container_name: mailserver
                  domainname: domain.com
                  hostname: mail
                  restart: always
                  ports:
                    - "25:25"
                    - "143:143"
                    - "587:587"
                    - "993:993"
                    - "4190:4190"
                    - "11334:11334"                      # <- New port, not needed if the                         
                  environment:                           #    webserver is on the same host
                    - DBPASS=xxxxx
                    - RSPAMD_PASSWORD=xxxxx
                    - ENABLE_ENCRYPTION=true            # <- New required variable
                  volumes:
                    - /mnt/docker/mail:/var/mail
                    - /mnt/docker/ssl:/etc/letsencrypt
                  depends_on:
                    - mariadb
                    - redis                              # <- New dependency
              
              # Administration interface
                # https://github.com/hardware/postfixadmin
                # http://postfixadmin.sourceforge.net/
                # Configuration : https://github.com/hardware/mailserver/wiki/Postfixadmin-initial-configuration
                postfixadmin:
                  image: hardware/postfixadmin
                  container_name: postfixadmin
                  domainname: domain.com
                  hostname: mail
                  restart: always
                  environment:
                    - DBPASS=xxxxx
                  ports:
                    - "127.0.0.1:8888:8888"
                  depends_on:
                    - mailserver
                    - mariadb
              
                # Webmail (Optional)
                # https://github.com/hardware/rainloop
                # https://www.rainloop.net/
                # Configuration : https://github.com/hardware/mailserver/wiki/Rainloop-initial-configuration
                rainloop:
                  image: hardware/rainloop
                  container_name: rainloop
                  restart: always
                  volumes:
                    - /mnt/docker/rainloop:/rainloop/data
                  ports:
                    - "127.0.0.1:8889:8888"
                  depends_on:
                    - mailserver
                    - mariadb
              
                nsd:
                  image: hardware/nsd-dnssec
                  container_name: nsd
                  restart: always
                  ports:
                    - "xxxxx:53:53"
                    - "xxxxxx:53:53/udp"
                  volumes:
                    - /mnt/docker/nsd/conf:/etc/nsd
                    - /mnt/docker/nsd/zones:/zones
                    - /mnt/docker/nsd/db:/var/db/nsd
              
                redis:
                  image: redis:4.0-alpine
                  restart: always
                  container_name: redis
                  command: redis-server --appendonly yes
                  volumes:
                    - /mnt/docker/redis/db:/data
              
                mariadb:
                  restart: always
                  image: mariadb:10.2
                  container_name: mariadb
                  #restart: always
                  # Info : These variables are ignored when the volume already exists (databases created before).
                  environment:
                    - MYSQL_ROOT_PASSWORD=xxxxx
                    - MYSQL_DATABASE=postfix
                    - MYSQL_USER=postfix
                    - MYSQL_PASSWORD=xxxxx
                  volumes:
                    - /mnt/docker/mysql/db:/var/lib/mysql

              Mon vhost rainloop (tous mes vhosts sont sur le meme schéma) dans /etc/nginx/sites-enabled

              server {
                listen 80;
                server_name webmail.domain.com;
                return 301 https://$host$request_uri;
              }
              
              server {
                listen 443 ssl http2;
                server_name webmail.domain.com;
              
                 ssl_certificate /etc/letsencrypt/live/mail.domain.com/fullchain.pem;
                 ssl_certificate_key /etc/letsencrypt/live/mail.domain.com/privkey.pem;
                 include /etc/nginx/conf/*.conf;
                 
                 location / {
                  proxy_pass http://127.0.0.1:8889;
                  include /etc/nginx/conf/proxy_params;
                }
              }

              Mes paramètres ssl et header qui sont dans /etc/nginx/conf/ssl_params.conf

              ssl_protocols TLSv1.2;
              ssl_ecdh_curve X25519:P-521:P-384;
              ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM;
              ssl_prefer_server_ciphers on;
              
              ssl_session_cache shared:SSL:20m;
              ssl_session_timeout 15m;
              ssl_session_tickets off;
              
              ssl_dhparam /etc/nginx/ssl/dhparam.pem;
              
              add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
              add_header X-Content-Type-Options nosniff always;
              add_header X-XSS-Protection "1; mode=block" always;
              

              Ainsi que le fichier proxy dans /etc/nginx/conf/proxy_params

              proxy_set_header        Host                 $host;
              proxy_set_header        X-Real-IP            $remote_addr;
              proxy_set_header        X-Forwarded-For      $proxy_add_x_forwarded_for;
              proxy_set_header        X-Remote-Port        $remote_port;
              proxy_set_header        X-Forwarded-Proto    $scheme;
              proxy_redirect          off;

              Voila commence par ça, l’idée encore une fois est de faire fonctionner le reverse du serveur mail avec nginx en local.. Adaptes avec tes ip local, public et tes ports http et https

              Pour lets'encrypt tu suis le tuto de @Jedediah
              https://mondedie.fr/d/7414-Tuto-Certificat-SSL-signe-gratuit-avec-Let-s-Encrypt-et-nginx

                laster13

                mon mailserver docker n'est pas celui d'hardware, mais un dérivé que j'ai fait a l'aide du tuto présent sur ce forum il y a quelques années. Comme je suis hébergé chez moi, je ne peux pas utiliser sa version car elle ne permet pas (encore) le relais smtp (le port 25 étant bloqué je suis obligé de passé par le relais orange)

                j'avoue que j'attend avec impatience qu'il intégré le relais smpt , je manque de temps pour maintenir et mettre a jour mon container, bref ça c'est une autre histoire.

                j'utilise unbound uniquement en interne et pour bloquer toutes les régies publicitaires et avoir un surf sans pub 😁 et ça j'avoue c'est bien un truc dont je ne pourrai plus me passer!

                je vais étudier tes fichiers de configurations ce weekend et voir comment intégrer ça a mon installation.

                merci

                Dryusdan Salut,

                Je préfère a jwilder et xataz celui ci : https://hub.docker.com/r/neilpang/nginx-proxy/
                c'est un fork de celui de jwilder un peu plus large (notamment au niveau du timeout et de la taille des requêtes).
                il se marie comme son ancêtre jwilder très bien avec le compagnon let's encrypt

                Bonjour Jericho63, j'ai aussi un nas Synology, pourquoi tu n'utilise pas le reverse proxy intégré dans le dsm ?

                  dextou bonne question! comme a la base j'avais un serveur dédié pour mes containers je n'y ai pas pensé.

                  ceci dit j'ai réussi a comprendre le fonctionnement de traefik (parfois avec l'anglais ça veut pas )et maintenant a faire du reverse vers mon nas , j'arrive donc a atteindre file station, photos station, pour video station l'interface s'affiche mais impossible d'avoir le flux video. il faut que je continu à creuser la question.

                    A l'époque, j'utilisais Haproxy sur mon Syno pour gérer mes accès par reverse proxy et un simple script bash en cron pour le renouvellement de mes certificats LE.

                    9 mois plus tard

                    jericho63 Et du coup, comment as tu réussi ?? J'ai traefik sur Docker qui fonctionne bien avec les containers, mais j'aimerais aussi que mes NDD pointent vers le NAS. 🙂

                    Répondre…