Как подключиться к Traefik TCP Services с включенной конфигурацией TLS?

13

Я пытаюсь настроить Traefik так, чтобы у меня был доступ к сервисам через доменные имена, и чтобы мне не приходилось устанавливать разные порты. Например, две службы MongoDB, оба на порте по умолчанию, но в разных доменах, example.localhostи example2.localhost. Только этот пример работает. Я имею в виду, что другие случаи, вероятно, работают, но я не могу подключиться к ним, и я не понимаю, в чем проблема. Это, вероятно, даже не проблема с Traefik.

Я подготовил хранилище с примером, который работает. Вам просто нужно сгенерировать свой собственный сертификат с помощью mkcert . Страница at example.localhostвозвращает 403 Forbiddenошибку, но вы не должны беспокоиться об этом, потому что цель этой конфигурации - показать, что SSL работает (замок, зеленый статус). Так что не зацикливайтесь на 403.

mongoРаботает только SSL-соединение с сервисом. Я проверил это с программой Robo 3T . После выбора SSL-соединения работает предоставление хоста example.localhostи выбор сертификата для самоподписанного (или собственного) соединения. И это единственное, что работает таким образом. Соединения с redis( Redis Desktop Manager ) и с pgsql( PhpStorm , DBeaver , DbVisualizer ) не работают, независимо от того, предоставляю я сертификаты или нет. Я не пересылаю SSL на сервисы, я только подключаюсь к Traefik. Я провел долгие часы на этом. Я искал в интернете. Я еще не нашел ответ. Кто-нибудь решил это?

PS. Я работаю на Linux Mint, поэтому моя конфигурация должна работать в этой среде без каких-либо проблем. Я бы попросил решения для Linux.


Если вы не хотите просматривать репозиторий , я прилагаю самые важные файлы:

докер-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"

Построить и запустить

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

Подготовить шаг за шагом

  1. Установите mkcert (запустите также mkcert -installдля CA)
  2. Клонировать мой код
  3. В certsпапке запуститьmkcert example.localhost
  4. Начать контейнер с docker-compose up -d
  5. Откройте страницу https: //example.localhost/ и убедитесь, что это безопасное соединение
  6. Если адрес http: //example.localhost/ недоступен, добавьте 127.0.0.1 example.localhostв/etc/hosts

Certs:

  • Общественность: ./certs/example.localhost.pem
  • Частный: ./certs/example.localhost-key.pem
  • CA: ~/.local/share/mkcert/rootCA.pem

Тест MongoDB

  1. Установить Robo 3T
  2. Создать новое соединение:
    • Адрес: example.localhost
    • Использовать протокол SSL
    • Сертификат CA: rootCA.pem(или самоподписанный сертификат)
  3. Тестовый инструмент:

тестовое задание

Тест Redis

  1. Установите RedisDesktopManager
  2. Создать новое соединение:
    • Адрес: example.localhost
    • SSL
    • Открытый ключ: example.localhost.pem
    • Закрытый ключ: example.localhost-key.pem
    • Орган власти: rootCA.pem
  3. Тестовый инструмент:

тестовое задание


Уже:

  1. Можно подключиться к Postgres через IP (информация от Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable

введите описание изображения здесь

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

введите описание изображения здесь


Попробуйте telet (IP изменяет каждый перезапуск докера):

> 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.

Если я подключаюсь напрямую к postgres, данные хороши. Если я подключаюсь через Traefik, то при закрытии соединения появляется Bad Request. Я понятия не имею, что это значит и должно ли это что-то значить.

гусак
источник
I can't connect to them-> как ты это проверял и в чем была ошибка?
Ян Гарадж
@JanGaraj Я добавил пошаговую инструкцию
Гандер
Connections to redis (Redis Desktop Manager) ... do not work, но скриншот показывает Successful connection-? Почему вы не тестируете на низком уровне curl, openssl, telnet, ...? Почему вы не проверяете netstat, действительно ли эти порты приложений привязаны к traefik на 127.0.0.1интерфейсе?
Ян Гарадж
Контейнер с трафиком и базами данных работает на одном хосте?
Рябченко Александр
@RyabchenkoAlexander да, в докер-контейнерах
Гандер

Ответы:

2

По крайней мере, для проблемы PostgreSQL, кажется, что соединение запускается открытым текстом, а затем обновляется до TLS:

Таким образом, в принципе невозможно использовать завершение TLS с прокси, если указанный прокси не поддерживает это рукопожатие открытым текстом + обновление до функции TLS протокола.

Хосе Либер
источник