В данной статье вы найдете всю необходимую информация по настройке, установке и примерах использования обратного прокси-сервера (реверс-прокси) Traefik.
Reverse proxy служит для ретрансляции запросов из внешней сети к каким-либо сервервисам либо серверам внутренней сети.
Реверс-прокси используется для:
- Сокрытия структуры внутренней сети и сервисах которые в ней находятся
- Балансировать нагрузку между серверами либо сервисами выполняемые одинаковые задачи
- Организовать контроль доступа к сервисам в виде дополнительной авторизации либо файрвола
Мы разберем установка Traefik 2 в Docker в качестве реверс-прокси. Реверс-прокси будет использоваться как для сервисов которые будут установлены в Docker контейнере так им для сторонних сервисов располагаемых на удаленных серверах.
Установка Traefik 2 в Docker
Предполагается, что перед началом установки Traefik 2 у вас уже установлен docker и docker-compose, если нет то краткую инструкцию по установки вы можете найти в данной статье.
Создадим папку в которой будут находиться файлы конфигурации traefik
mkdir traefik
cd traefik
Создадим файл docker-compose.yml
со следующим содержимым
version: '3'
services:
traefik:
image: traefik:v2.8
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./ssl:/ssl
В данной конфигурации у нас будут доступны два порта 80 и 443 для HTTP и HTTPS. Последней строкой мы подключаем файл конфигурации который будет находится в подпапке data и называться traefik.yml. Создадим директорию data и создадим в ней файл traefik.yml
mkdir data
cd data
touch traefik.yml
Откроем файл traefik.yml в редакторе и внесем в него базовую конфигурацию
nano traefik.yml
entryPoints:
http:
address: ":80"
https:
address: ":443"
http:
routers:
http-catchall:
rule: hostregexp(`{host:.+}`)
entrypoints:
- http
middlewares:
- redirect-to-https
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
permanent: false
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
letsEncrypt:
acme:
email: [email protected]
storage: /ssl/acme.json
caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: http
В entryPoints описываются все доступные входящие порты, у нас это 80 и 433 порт, название портов может быть любым, для простоты восприятия я дал портам название http и https.
В providers мы указываем нашего первого провайдера Docker и указываем, что Traefik не должен подгружать все доступные контейнеры.
Код который указан ниже отвечает за перенаправление всего http трафика в https
http:
routers:
http-catchall:
rule: HostRegexp(`{host:.+}`)
entrypoints:
- http
middlewares:
- redirect-to-https
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
permanent: false
В конфиг файле у нас есть отдельный блок который отвечает за получение сертификата Let’s Encrypt. В поле caServer указан тестовый сервер для того чтобы не получить лимит обращений к основному серверу. После того как вы все настроите необходимо будет закомментировать данную строку.
certificatesResolvers:
letsEncrypt:
acme:
email: [email protected]
storage: /ssl/acme.json
caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: http
Таким образом у нас полностью готов файл конфигурации traefik.yml и файл docker-compose.yml
и мы можем приступать к установки Traefik. Вернемся в директорию traefik и выполним следующую команду
sudo docker-compose up -d
Для того чтобы убедиться что установка и запуск контейнера прошел без ошибок, выполним команду которая покажет логи нашего контейнера
sudo docker-compose logs -f
На этом установка и запуск Traefik завершена и можно переходить к настройке
Настройка Traefik 2 и добавление провайдеров
Для описания конфигурации в Docker Traefik использует метки контейнеров(labels) . Отредактируем файл docker-compose.yml
и добавим в него следующий текст
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=https"
- "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
Подробнее разберем каждую из добавленных строк.
traefik.enable=true
— сообщает что Traefik должен обеспечить доступ к этому контейнеру
traefik.http.routers.traefik.entrypoints=https
— создаем новый роутер с точной входа https
traefik.http.routers.traefik.rule=Host(traefik.yourdomain.com)
— роутеру назначен адрес traefik.yourdomain.comtraefik.http.routers.traefik.tls=true
— указываем что будет использоваться TLStraefik.http.routers.traefik.tls.certresolver=letsEncrypt
— указывает что будет получаться сертификат через letsEncrypttraefik.http.routers.traefik.service=api@internal
— указываем, что сервер за этим роутером — api@internal
, это специальный сервис, созданный по умолчанию, это наш дашборд который у нас и будет доступен по адресу traefik.yourdomain.comtraefik.http.services.traefik-traefik.loadbalancer.server.port=888
— порт на котором будет вебинтерфейс
Для того чтобы активировать дашборд необходимо в конфиг файл traefik.yml добавить
api:
dashboard: true
Таким образом наш полный файл docker-compose.yml
будет иметь следующий вид
version: '3'
services:
traefik:
image: traefik:v2.8
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./ssl:/ssl
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=https"
- "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
А файл traefik.yml
entryPoints:
http:
address: ":80"
https:
address: ":443"
http:
routers:
http-catchall:
rule: hostregexp(`{host:.+}`)
entrypoints:
- http
middlewares:
- redirect-to-https
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
permanent: false
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
letsEncrypt:
acme:
email: [email protected]
storage: /ssl/acme.json
caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: http
api:
dashboard: true
Теперь чтобы все наши правки применились нам необходимо пересоздать контейнер
sudo docker-compose down && sudo docker-compose up -d
И теперь после перехода по адресу который мы указали выше в конфиге в моем случаи это traefik.yourdomain.com мы попадаем в панель управления Traefik.
Базовая защита с BasicAuth
Для дополнительной защиты сервисов можно использовать BasicAuth. В примере выше мы создали поддомен на котором у нас находится панель управления Traefik, как вы заметили у данной панели нет защиты по авторизации и каждый кто знает адрес может получить к ней доступ. Для того чтобы предоставить доступ к панели только тем у кого будет логин и пароль мы будем использовать BasicAuth.
Для генерации зашифрованного пароля в терминале выполним команду
htpasswd -nb unixhost password
В качестве ответа мы получим строку которую будет содержать имя пользователя и зашифрованный пароль.
unixhost:$apr1$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/
Теперь отредактируем файл docker-compose.yml
и добавим в labels следующий текст заменив значение auth.basicauth.users на строку которую мы получили ранее и дополнительно продублируем каждый символ $ . Вместо $apr1$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/
мы должны указать $$apr1$$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/
- "traefik.http.middlewares.traefik-auth.basicauth.users=unixhost:$$apr1$$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/"
- "traefik.http.routers.traefik.middlewares=traefik-auth"
И теперь после пересоздания контейнера при переходе по адресу traefik.yourdomain.com у нас запросит логин и пароль для доступа в панели.
Добавление File провайдеров в Traefik 2
Добавление провайдеров которые разворачиваются в docker мы рассмотрели, но в Traefik реализована возможность автоматического добавления провайдеров из отдельных файлов конфигурации. Данный способ удобен тем, что вам нет необходимости каждый раз перезапускать контейнер.
Допустим, нам необходимо добавить службу мониторинга Grafana которая находится на сервере с IP 192.168.100.100, порт который использует сервис 3000. Доступ к данному сервису необходимо сделать через HTTPS. О том как установить Grafana мы подробно разбирали в данной статье.
Отредактируем файл docker-compose.yml
в volumes добавим следующее
- ./data/custom/:/custom/:ro
Создадим новую директорию custom в директории data. А в файл конфигурации traefik.yml в providers добавим следующее
providers:
file:
directory: /custom
watch: true
watch: true говорит о том, что traefik будет следить за изменением в данной директории и после внесения добавления новых файлов с конфигурациями они автоматически будет применены.
Секция providers в конфигурационном файле traefik.yml в рамках данной статьи у нас будет выглядеть следующим образом
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: /custom
watch: true
Пересоздадим контейнер, создадим файл grafana.yml в директории custom и добавим в него первый провайдер
http:
routers:
grafana:
entryPoints:
- https
service: grafana-host
rule: Host(`grafana.yourdomain.com`)
tls:
certResolver: letsEncrypt
services:
grafana-host:
loadBalancer:
servers:
- url: http://192.168.100.100:3000/
passHostHeader: true
И теперь если мы перейдем по адресу grafana.yourdomain.com у нас откроется система мониторинга Grafana.
Подобным образом вы можете добавлять новые сервисы.