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

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

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

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


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

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"

Создать и запустить

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/example.localhost.pem
  • Личное: ./certs/example.localhost-key.pem
  • КА: ~/.local/share/mkcert/rootCA.pem

Протестировать MongoDB

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

test

Протестируйте Redis

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

test


Слишком далеко:

  1. Может подключаться к Postgres по IP (информация от 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


Попробуйте телет (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 при закрытии соединения. Я понятия не имею, что это значит и должно ли это что-то означать.

15
Gander 10 Дек 2019 в 12:51
I can't connect to them -> как вы это проверяли и в чем была ошибка?
 – 
Jan Garaj
1 Янв 2020 в 02:22
Добавил пошаговую инструкцию
 – 
Gander
4 Янв 2020 в 03:40
Connections to redis (Redis Desktop Manager) ... do not work, но на снимке экрана показано Successful connection - ? Почему вы не тестируете на низком уровне с помощью curl, openssl, telnet, ...? Почему вы не тестируете netstat, если эти порты приложений действительно привязаны к traefik на интерфейсе 127.0.0.1?
 – 
Jan Garaj
4 Янв 2020 в 09:58
Работает ли контейнер с traefik и базами данных на одном хосте?
 – 
Ryabchenko Alexander
6 Янв 2020 в 13:08
Да, в докер-контейнерах
 – 
Gander
6 Янв 2020 в 14:18

1 ответ

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

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

4
SultanLegend 18 Мар 2020 в 19:54