Estou tentando configurar o Traefik para ter acesso aos serviços através de nomes de domínio e para não precisar definir portas diferentes. Por exemplo, dois serviços MongoDB, ambos na porta padrão, mas em domínios diferentes example.localhost
e example2.localhost
. Somente este exemplo funciona. Quero dizer, outros casos provavelmente funcionam, mas não consigo me conectar a eles e não entendo qual é o problema. Provavelmente isso nem é um problema com o Traefik.
Eu preparei um repositório com um exemplo que funciona. Você só precisa gerar seu próprio certificado com o mkcert . A página em example.localhost
retorna o 403 Forbidden
erro, mas você não deve se preocupar com isso, porque o objetivo desta configuração é mostrar que o SSL está funcionando (cadeado, status verde). Portanto, não se concentre 403
.
Somente a conexão SSL com o mongo
serviço funciona. Eu testei com o programa Robo 3T . Depois de selecionar a conexão SSL, fornecer o host example.localhost
e selecionar o certificado para uma conexão autoassinada (ou própria) funciona. E essa é a única coisa que funciona dessa maneira. As conexões com redis
( Redis Desktop Manager ) e com pgsql
( PhpStorm , DBeaver , DbVisualizer ) não funcionam, independentemente de eu fornecer certificados ou não. Não encaminho SSL para serviços, apenas conecto ao Traefik. Passei longas horas nisso. Eu procurei na internet. Ainda não encontrei a resposta. Alguém resolveu isso?
PS. Como trabalho no Linux Mint, minha configuração deve funcionar neste ambiente sem nenhum problema. Eu pediria soluções para Linux.
Se você não deseja navegar no repositório , anexe os arquivos mais 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"
Construir e executar
mkcert example.localhost # in ./certs/
docker-compose up -d
Prepare passo a passo
- Instale o mkcert (execute também
mkcert -install
para a CA) - Clonar meu código
- Na
certs
pasta executarmkcert example.localhost
- Iniciar contêiner por
docker-compose up -d
- Abra a página https: //example.localhost/ e verifique se é uma conexão segura
- Se o endereço http: //example.localhost/ não estiver acessível, adicione
127.0.0.1 example.localhost
a/etc/hosts
Certos:
- Público:
./certs/example.localhost.pem
- Privado:
./certs/example.localhost-key.pem
- CA:
~/.local/share/mkcert/rootCA.pem
Teste do MongoDB
- Instale o Robo 3T
- Crie uma nova conexão:
- Endereço:
example.localhost
- Usar protocolo SSL
- Certificado da CA:
rootCA.pem
(ou certificado autoassinado)
- Endereço:
- Ferramenta de teste:
Teste Redis
- Instale o RedisDesktopManager
- Crie uma nova conexão:
- Endereço:
example.localhost
- SSL
- Chave pública:
example.localhost.pem
- Chave privada:
example.localhost-key.pem
- Autoridade:
rootCA.pem
- Endereço:
- Ferramenta de teste:
Tão longe:
- Pode se conectar ao Postgres via IP (informações do Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable
jdbc:postgresql://172.21.0.4:5432/postgres?sslfactory=org.postgresql.ssl.NonValidatingFactory
Experimente o telet (o IP muda a cada reinicialização do 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.
Se eu me conectar diretamente ao postgres, os dados serão bons. Se eu conectar através do Traefik, tenho uma solicitação incorreta ao fechar a conexão. Não faço ideia do que isso significa e se deve significar alguma coisa.
I can't connect to them
-> como você testou e qual foi o erro?Connections to redis (Redis Desktop Manager) ... do not work
, mas a captura de tela mostraSuccessful connection
-? Por que você não está testando em nível baixo comcurl, openssl, telnet, ...
? Por que você não está testandonetstat
se essas portas de aplicativos estão realmente ligadas ao traefik na127.0.0.1
interface?Respostas:
Pelo menos para a questão do PostgreSQL, parece que a conexão é iniciada em texto não criptografado e depois atualizada para o TLS:
Portanto, é basicamente impossível usar a terminação TLS com um proxy se esse proxy não suportar esse handshake de texto não criptografado + atualizar para a função TLS do protocolo.
fonte