В статье по запуску Traefik мы использовали параметр, указанный в разделе command в docker-compose-traefik.yml
- "--api.insecure=true"
Для быстрого старта этого вполне достаточно, однако оставлять так traefik не стоит, особенно в production.
Чтобы обезопасить свой дашборд от несакционированного доступа, мы настроим для него basic authentification, то есть защиту с помощью логина и пароля.
Наш docker-compose-traefik.yml будет выглядеть вот так после изменений:
version: "3.7"
services:
traefik:
image: traefik:v2.10.7
ports:
- "80:80" # Оставляем открытыми только порт 80 для http
- "443:443" # и порт 443 для https запросов к нашим сервисам, спрятанным за reverse proxy (traefik)
command:
- "--api.insecure=false" # Меняем несекьюрный доступ к api traefik с true на false
- "--api.dashboard=true"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.exposedByDefault=false"
- "--entrypoints.http.address=:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# Весь раздел ниже добавлен для осуществления защиты dashboard traefik с помощью basic authentification, поэтому опишем его отдельно под конфигурацией
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard-http-router.entrypoints=http"
- "traefik.http.routers.traefik-dashboard-http-router.rule=Host(`dashboard.example.com`)"
- "traefik.http.routers.traefik-dashboard-http-router.service=api@internal"
- "traefik.http.middlewares.traefik-dashboard-auth.basicauth.users=admin:$TRAEFIK_DASHBOARD_PASSWORD"
- "traefik.http.routers.traefik-dashboard-http-router.middlewares=traefik-dashboard-auth"
Итак, чтобы закрыть доступ к дашборду с помощью пароля мы в первую очередь убираем проброс порта 8080 наружу, а заходить на него будем по адресу dashboard.example.com и 80 порту.
Мы хотим, чтобы доступ к дашборду осуществлялся через сам traefik, а для этого добавляем секцию labels и в первую очередь указываем, что traefik должен обслуживать этот контейнер и сервисы в нем:
- "traefik.enable=true"
Указываем, какую точку входа следует использовать (у нас их две - http и https; так как в этой статье мы не касаемся сертификатов и запросов https, то выбираем http):
- "traefik.http.routers.traefik-dashboard-http-router.entrypoints=http"
Обращаю внимание, что traefik-dashboard-http-router это произвольное название router, которое будет отображаться в traefik.
Говорим, что на наш сервис надо направлять только запросы, которые пришли на адрес dashboard.example.com:
- "traefik.http.routers.traefik-dashboard-http-router.rule=Host(`dashboard.example.com`)"
Так как дашборд это внутренний сервис traefik со своим api, сообщаем об этом таким образом:
- "traefik.http.routers.traefik-dashboard-http-router.service=api@internal"
Дальше нам надо создать middlewares, в которой мы затем опишем нашу аутентификацию по паролю
- "traefik.http.routers.traefik-dashboard-http-router.middlewares=traefik-dashboard-auth"
Обращаю внимание, что traefik-dashboard-auth это произвольное название middlewares, которое будет отображаться в traefik.
И, наконец, нам надо указать метод basicauth.users
для созданной middlewares.traefik-dashboard-auth
, который будет включать в себя логин и хешированный пароль (используется хеш MD5, SHA1, или BCrypt.):
- "traefik.http.middlewares.traefik-dashboard-auth.basicauth.users=admin:$TRAEFIK_DASHBOARD_PASSWORD"
Мы написали переменную $TRAEFIK_DASHBOARD_PASSWORD, чтобы не писать пароль в открытом виде в файле docker-composer-traefik.yml. Вместо этого мы создадим файл .env и запишем его туда.
Но сперва его надо сгенерировать.
Для этого нам понадобится утилита htpasswd из пакета apache-utils.
Ставим ее так:
sudo apt update && sudo apt install apache2-utils -y
Чтобы создать пару admin:PASSWORD
надо воспользоваться такой командой:
echo $(htpasswd -nB admin)
А затем дважды ввести пароль, который вы хотите захешировать.
На выходе у вас напечатается строка вроде этой:
admin:$2y$05$0SxAezpAD0EBGPpYQ3dJ8eWmQwGVt0/X8VkGYnZMPYPj7M5/KnHN.
Все, что идет после admin: мы копируем и вставляем в наш файл .env в таком виде:
TRAEFIK_DASHBOARD_PASSWORD=$$2y$$05$$0SxAezpAD0EBGPpYQ3dJ8eWmQwGVt0/X8VkGYnZMPYPj7M5/KnHN.
Сохраняем и выходим.
Если вы хотите ввести пароль в открытом виде в файл docker-compose-traefik.yml, вам надо воспользоваться командой:
echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g
В файле YAML символ $ используется для обозначения переменных окружения. Если вы хотите использовать символ $ как часть строки без интерпретации как переменной, вам нужно удвоить каждый $ (что и делает sed после пайплайна в команде).
Теперь если мы запустим контейнер командой:
docker-compose -f docker-compose-traefik.yml up -d
и зайдем на адрес dashboard.example.com, мы увидим запрос логина и пароля.
Вводим и оказываемся на странице дашборда traefik.
Защита других сервисов, спрятанных за traefik, с помощью basic authentification происходит аналогичным способом.
В статье про добавление сервисов за traefik мы использовали следующие labels в файле docker-compose-nginx.yml:
labels:
- "traefik.enable=true" # Говорим, что траефик должен обслуживать данный контейнер
- "traefik.http.routers.nginx_1.entrypoints=http" # Говорим, что наш сайт будет доступен через точку входа http (описание см. ниже)
- "traefik.http.routers.nginx_1.rule=Host(`site_1.example.com`)" # Говорим, что на этот контейнер траефику надо направлять запросы, которые приходят на адрес site_1.example.com
К нему надо добавить еще 2 параметра:
- "traefik.http.middlewares.nginx-1-auth.basicauth.users=admin:$TRAEFIK_NGINX_1_PASSWORD"
- "traefik.http.routers.nginx_1.middlewares=nginx-1-auth"
Обращаю внимание, что routers для nginx_1 у нас уже есть, поэтому middlewares мы добавляем к traefik.http.routers.nginx_1
. Также обращаю внимание, что nginx-1-auth
это произвольное название middlewares, которое будет отображаться в traefik.
Вы можете (и должны) использовать разные пароли для доступа к разным сервисам (если это вообще требуется), поэтому надо сгенерировать еще одну пару логин/пароль и добавить в файл .env на следующей строке в виде:
TRAEFIK_NGINX_1_PASSWORD=login:password