web-dev-qa-db-fra.com

Comment se connecter à Traefik TCP Services avec la configuration TLS activée?

J'essaie de configurer Traefik afin d'avoir accès aux services via des noms de domaine, et que je n'aurais pas à définir de ports différents. Par exemple, deux services MongoDB, tous deux sur le port par défaut, mais dans des domaines différents, example.localhost et example2.localhost. Seul cet exemple fonctionne. Je veux dire, d'autres cas fonctionnent probablement, mais je ne peux pas me connecter à eux et je ne comprends pas quel est le problème. Ce n'est probablement même pas un problème avec Traefik.

J'ai préparé un référentiel avec un exemple qui fonctionne. Vous avez juste besoin de générer votre propre certificat avec mkcert . La page sur example.localhost renvoie le 403 Forbidden erreur mais ne vous en faites pas, car le but de cette configuration est de montrer que SSL fonctionne (cadenas, état vert). Alors ne vous concentrez pas sur 403.

Seule la connexion SSL au service mongo fonctionne. Je l'ai testé avec le programme Robo 3T. Après avoir sélectionné la connexion SSL, fournir l'hôte sur example.localhost et en sélectionnant le certificat pour une connexion auto-signée (ou propre). Et c'est la seule chose qui fonctionne de cette façon. Connexions à redis ( Redis Desktop Manager) et à pgsql ( PhpStorm, DBeaver, DbVisualizer) ne fonctionne pas, que je fournisse des certificats ou non. Je ne transfère pas SSL aux services, je me connecte uniquement à Traefik. J'y ai passé de longues heures. J'ai cherché sur internet. Je n'ai pas encore trouvé la réponse. Quelqu'un a-t-il résolu cela?

PS. Je travaille sur Linux Mint, donc ma configuration devrait fonctionner dans cet environnement sans aucun problème. Je demanderais des solutions pour Linux.


Si vous ne souhaitez pas parcourir le référentiel , je joins les fichiers les plus importants:

docker-compose.yml

version: "3.7"

services:
    traefik:
        image: traefik:v2.0
        ports:
            - 80:80
            - 443:443
            - 8080:8080
            - 6379:6379
            - 5432:5432
            - 27017:27017
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock:ro
            - ./config.toml:/etc/traefik/traefik.config.toml:ro
            - ./certs:/etc/certs:ro
        command:
            - --api.insecure
            - --accesslog
            - --log.level=INFO
            - --entrypoints.http.address=:80
            - --entrypoints.https.address=:443
            - --entrypoints.traefik.address=:8080
            - --entrypoints.mongo.address=:27017
            - --entrypoints.postgres.address=:5432
            - --entrypoints.redis.address=:6379
            - --providers.file.filename=/etc/traefik/traefik.config.toml
            - --providers.docker
            - --providers.docker.exposedByDefault=false
            - --providers.docker.useBindPortIP=false

    Apache:
        image: php:7.2-Apache
        labels:
            - traefik.enable=true
            - traefik.http.routers.http-dev.entrypoints=http
            - traefik.http.routers.http-dev.rule=Host(`example.localhost`)
            - traefik.http.routers.https-dev.entrypoints=https
            - traefik.http.routers.https-dev.rule=Host(`example.localhost`)
            - traefik.http.routers.https-dev.tls=true
            - traefik.http.services.dev.loadbalancer.server.port=80
    pgsql:
        image: postgres:10
        environment:
            POSTGRES_DB: postgres
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: password
        labels:
            - traefik.enable=true
            - traefik.tcp.routers.pgsql.rule=HostSNI(`example.localhost`)
            - traefik.tcp.routers.pgsql.tls=true
            - traefik.tcp.routers.pgsql.service=pgsql
            - traefik.tcp.routers.pgsql.entrypoints=postgres
            - traefik.tcp.services.pgsql.loadbalancer.server.port=5432
    mongo:
        image: mongo:3
        labels:
            - traefik.enable=true
            - traefik.tcp.routers.mongo.rule=HostSNI(`example.localhost`)
            - traefik.tcp.routers.mongo.tls=true
            - traefik.tcp.routers.mongo.service=mongo
            - traefik.tcp.routers.mongo.entrypoints=mongo
            - traefik.tcp.services.mongo.loadbalancer.server.port=27017
    redis:
        image: redis:3
        labels:
            - traefik.enable=true
            - traefik.tcp.routers.redis.rule=HostSNI(`example.localhost`)
            - traefik.tcp.routers.redis.tls=true
            - traefik.tcp.routers.redis.service=redis
            - traefik.tcp.routers.redis.entrypoints=redis
            - traefik.tcp.services.redis.loadbalancer.server.port=6379

config.toml

[tls]
[[tls.certificates]]
certFile = "/etc/certs/example.localhost.pem"
keyFile = "/etc/certs/example.localhost-key.pem"

Build & Run

mkcert example.localhost # in ./certs/
docker-compose up -d

Préparez-vous étape par étape

  1. Installer mkcert (exécuter également mkcert -install pour CA)
  2. Cloner mon code
  3. Dans le dossier certs, exécutez mkcert example.localhost
  4. Démarrer le conteneur par docker-compose up -d
  5. Ouvrez la page https: //example.localhost/ et vérifiez s'il s'agit d'une connexion sécurisée
  6. Si l'adresse http: //example.localhost/ n'est pas accessible, ajoutez 127.0.0.1 example.localhost à /etc/hosts

Certs:

  • Publique: ./certs/example.localhost.pem
  • Privé: ./certs/example.localhost-key.pem
  • CALIFORNIE: ~/.local/share/mkcert/rootCA.pem

Testez MongoDB

  1. Installer Robo 3T
  2. Créer une nouvelle connexion:
    • Adresse: example.localhost
    • Utiliser le protocole SSL
    • Certificat CA: rootCA.pem (ou certificat auto-signé)
  3. Outil de test:

test

Test Redis

  1. Installer RedisDesktopManager
  2. Créer une nouvelle connexion:
    • Adresse: example.localhost
    • SSL
    • Clé publique: example.localhost.pem
    • Clé privée: example.localhost-key.pem
    • Autorité: rootCA.pem
  3. Outil de test:

test


Jusque là:

  1. Peut se connecter à Postgres via IP (informations de Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable

enter image description here

jdbc:postgresql://172.21.0.4:5432/postgres?sslfactory=org.postgresql.ssl.NonValidatingFactory

enter image description here


Essayez telet (l'IP change à chaque redémarrage du docker):

> telnet 172.27.0.5 5432
Trying 172.27.0.5...
Connected to 172.27.0.5.
Escape character is '^]'.
^]
Connection closed by foreign Host.
> telnet example.localhost 5432
Trying ::1...
Connected to example.localhost.
Escape character is '^]'.
^]
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad RequestConnection closed by foreign Host.

Si je me connecte directement à postgres, les données sont sympas. Si je me connecte via Traefik, j'ai une mauvaise demande lors de la fermeture de la connexion. Je n'ai aucune idée de ce que cela signifie et si cela doit signifier quelque chose.

11
Gander

Au moins pour le problème PostgreSQL, il semble que la connexion soit démarrée en texte clair puis mise à niveau vers TLS:

Il est donc fondamentalement impossible d'utiliser la terminaison TLS avec un proxy si ledit proxy ne prend pas en charge cette prise de contact en texte clair + la mise à niveau vers la fonction TLS du protocole.

2
Jose Liber