¿Cómo conectarse a Traefik TCP Services con la configuración TLS habilitada?

13

Estoy tratando de configurar Traefik para tener acceso a los servicios a través de nombres de dominio y no tener que configurar puertos diferentes. Por ejemplo, dos servicios MongoDB, ambos en el puerto predeterminado, pero en dominios diferentes, example.localhosty example2.localhost. Solo este ejemplo funciona. Quiero decir, otros casos probablemente funcionen, pero no puedo conectarme a ellos y no entiendo cuál es el problema. Esto probablemente ni siquiera sea un problema con Traefik.

He preparado un repositorio con un ejemplo que funciona. Solo necesita generar su propio certificado con mkcert . La página en example.localhostdevuelve el 403 Forbiddenerror, pero no debe preocuparse por ello, porque el propósito de esta configuración es mostrar que SSL está funcionando (candado, estado verde). Así que no te enfoques 403.

Solo funciona la conexión SSL al mongoservicio. Lo probé con el programa Robo 3T . Después de seleccionar la conexión SSL, proporcionar el host encendido example.localhosty seleccionar el certificado para una conexión autofirmada (o propia) funciona. Y eso es lo único que funciona de esa manera. Las conexiones a redis( Redis Desktop Manager ) y a pgsql( PhpStorm , DBeaver , DbVisualizer ) no funcionan, independientemente de si proporciono certificados o no. No reenvío SSL a los servicios, solo me conecto a Traefik. Pasé largas horas en eso. Busqué en internet. Aún no he encontrado la respuesta. ¿Alguien ha resuelto esto?

PD. Trabajo en Linux Mint, por lo que mi configuración debería funcionar en este entorno sin ningún problema. Yo pediría soluciones para Linux.


Si no desea explorar el repositorio , adjunto los archivos más importantes:

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"

Construye y corre

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

Preparar paso a paso

  1. Instale mkcert (ejecute también mkcert -installpara CA)
  2. Clona mi código
  3. En la certscarpeta ejecutadamkcert example.localhost
  4. Iniciar contenedor por docker-compose up -d
  5. Abra la página https: //example.localhost/ y verifique si es una conexión segura
  6. Si no se puede acceder a la dirección http: //example.localhost/ , agregue 127.0.0.1 example.localhosta/etc/hosts

Certs:

  • Público: ./certs/example.localhost.pem
  • Privado: ./certs/example.localhost-key.pem
  • CALIFORNIA: ~/.local/share/mkcert/rootCA.pem

Prueba MongoDB

  1. Instalar Robo 3T
  2. Crear nueva conexión:
    • Habla a: example.localhost
    • Usar protocolo SSL
    • Certificado CA: rootCA.pem(o certificado autofirmado)
  3. Herramienta de prueba:

prueba

Prueba Redis

  1. Instalar RedisDesktopManager
  2. Crear nueva conexión:
    • Habla a: example.localhost
    • SSL
    • Llave pública: example.localhost.pem
    • Llave privada: example.localhost-key.pem
    • Autoridad: rootCA.pem
  3. Herramienta de prueba:

prueba


Hasta aquí:

  1. Puede conectarse a Postgres a través de IP (información de Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí


Pruebe telet (IP cambia cada reinicio de la ventana acoplable):

> 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 me conecto directamente a postgres, los datos son buenos. Si me conecto a través de Traefik, tengo una solicitud incorrecta al cerrar la conexión. No tengo idea de lo que esto significa y si debe significar algo.

Vistazo
fuente
I can't connect to them-> ¿cómo lo probaste y cuál fue el error?
Jan Garaj
@ JanGaraj Agregué una instrucción paso a paso
Gander
Connections to redis (Redis Desktop Manager) ... do not work, pero la captura de pantalla muestra Successful connection-? ¿Por qué no estás probando a bajo nivel con curl, openssl, telnet, ...? ¿Por qué no está probando netstatsi esos puertos de aplicaciones están realmente vinculados para traefik en la 127.0.0.1interfaz?
Jan Garaj
¿El contenedor con traefik y bases de datos se ejecuta en el mismo host?
Ryabchenko Alexander
@RyabchenkoAlexander sí, en contenedores acoplables
Gander

Respuestas:

2

Al menos para el problema de PostgreSQL, parece que la conexión se inicia en texto sin formato y luego se actualiza a TLS:

Por lo tanto, es básicamente imposible usar la terminación TLS con un proxy si dicho proxy no admite este protocolo de enlace claro + actualización a la función TLS del protocolo.

Jose Liber
fuente