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.localhost
y 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.localhost
devuelve el 403 Forbidden
error, 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 mongo
servicio. Lo probé con el programa Robo 3T . Después de seleccionar la conexión SSL, proporcionar el host encendido example.localhost
y 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
- Instale mkcert (ejecute también
mkcert -install
para CA) - Clona mi código
- En la
certs
carpeta ejecutadamkcert example.localhost
- Iniciar contenedor por
docker-compose up -d
- Abra la página https: //example.localhost/ y verifique si es una conexión segura
- Si no se puede acceder a la dirección http: //example.localhost/ , agregue
127.0.0.1 example.localhost
a/etc/hosts
Certs:
- Público:
./certs/example.localhost.pem
- Privado:
./certs/example.localhost-key.pem
- CALIFORNIA:
~/.local/share/mkcert/rootCA.pem
Prueba MongoDB
- Instalar Robo 3T
- Crear nueva conexión:
- Habla a:
example.localhost
- Usar protocolo SSL
- Certificado CA:
rootCA.pem
(o certificado autofirmado)
- Habla a:
- Herramienta de prueba:
Prueba Redis
- Instalar RedisDesktopManager
- Crear nueva conexión:
- Habla a:
example.localhost
- SSL
- Llave pública:
example.localhost.pem
- Llave privada:
example.localhost-key.pem
- Autoridad:
rootCA.pem
- Habla a:
- Herramienta de prueba:
Hasta aquí:
- Puede conectarse a Postgres a través de IP (información de Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable
jdbc:postgresql://172.21.0.4:5432/postgres?sslfactory=org.postgresql.ssl.NonValidatingFactory
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.
I can't connect to them
-> ¿cómo lo probaste y cuál fue el error?Connections to redis (Redis Desktop Manager) ... do not work
, pero la captura de pantalla muestraSuccessful connection
-? ¿Por qué no estás probando a bajo nivel concurl, openssl, telnet, ...
? ¿Por qué no está probandonetstat
si esos puertos de aplicaciones están realmente vinculados para traefik en la127.0.0.1
interfaz?Respuestas:
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.
fuente