В предыдущей статье мы с вами установили непривилегированный LXC контейнер на базе Debian, скачали бинарный файл Traefik и с помощью самой простой статической конфигурации протестировали работоспособность нашего обратного прокси.
В этой статье проведем уже полноценную настройку обратного прокси Traefik.
Если вам понравилась настоящая статья, то можете поддержать меня став спонсором на бусти (ссылка в разделе контакты).
Что нам нужно для полноценной работы обратного прокси.#
- Нам нужно квалифицированное доменное имя. При покупке доменного имени рекомендую обратить внимание не на стоимость покупки (они плюс, минус всегда одинаковые), а на стоимость продления. Потому что процентное соотношение между стоимость покупки и стоимостью продления может неприятно удивить.
Сам я пользуюсь услугами smartape. Стоимость продления домена в зоне .ру у них 200р. Можете перейти по реферальной ссылке в описании к ролику на ютуб и посмотреть актуальную стоимость. Не реклама.
Дальше нам нужно разместить наше доменное имя на внешних днс серверах. Я сам пользуюсь услугами cloudflare, но из-за блокировок РКН доступ к их днс может не работать. Хотя я продолжаю пользоваться cloudflare, с учетом существующих на данный момент ограничений, советовать их я не могу, решайте сами. В данной статье я все-таки покажу настройку именно с cloudflare. Список днс провайдеров можно посмотреть в документации Traefik. Там есть и отечественные сервисы, нужно просто указать при настройке Traefik код провайдера и переменные окружения при настройке, как у меня в статье.
Желательно иметь белый ip адрес, который вы можете приобрести у вашего интернет-провайдера.
Настроить split dns, чтобы запросы по поддоменному имени внутри локальной сети не выходили за ее пределы. Более подробно можете посмотреть в моем ролике, посвященному именно этой теме.
Настройки DNS с помощью Cloudflare#
Я предполагаю, что у вас уже зарегистрировано доменное имя и оно перенесено на dns сервера соответствующего провайдера. Я показываю все на примере Cloudflare. В этом гайде я использую доменное имя stilicho.ru Картинки про настройку cloudflare в статье не мои, взяты из интернета.
Переходите в ваш профайл
Переходим в меню для создания токена
Начинаем создавать кастомный токен
Задаем конкретные настройки токена
Создаем токен
Скопируйте значения вашего токена и сохраните в безопасном месте, так как посмотреть еще раз значения токена в профиле у cloudflare не получится. Полученный токен мы с вами будем использовать для настройки нашего обратного прокси как сервиса, он позволяет управлять нашими сертификатами с помощью Cloudflare. Если вы потеряете токен, то единственным выходом будет его пересоздание с нуля.
Можете посмотреть все токены, которые вы создали с помощью cloudflare
Настройка статической конфигурации обратного прокси Traefik#
Traefik поддерживает статическую и динамическую конфигурацию. Все изменения в статическом конфиге предполагают ручной перезапуск Traefik. Изменения в динамической конфигурации Traefik применяются налету и перезапуск обратного прокси не требуется.
В предыдущей статье мы с вами создали простой статический конфиг исключительно для проверки работоспособности Traefik. Сейчас мы с вами уже будем все делать по взрослому. В любом случае этот конфиг можно и нужно изменять или дополнять под ваши конкретные нужды.
nano /etc/traefik/traefik.yaml`
# Traefik global configuration
#-https://doc.traefik.io/traefik/contributing/data-collection/
global:
checkNewVersion: true
sendAnonymousUsage: true
# Enable traefik ui dashboard
#-https://doc.traefik.io/traefik/operations/api/
api:
dashboard: true
insecure: false # access to http://traefikIP:8080/dashboard/ is disabled
debug: true
disableDashboardAd: true
entryPoints:
web:
address: ":80"
http:
redirections: #https://doc.traefik.io/traefik/routing/entrypoints/#redirection
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
metrics:
address: :8082
#https://doc.traefik.io/traefik/observability/metrics/prometheus/
metrics:
prometheus:
entryPoint: metrics
# https://doc.traefik.io/traefik/routing/services/#serverstransport_1
# https://www.cloudflare.com/en-gb/learning/ssl/what-is-sni/
serversTransport:
insecureSkipVerify: true
#-https://doc.traefik.io/traefik/providers/overview/
providers:
#-https://doc.traefik.io/traefik/providers/file/
file:
directory: /etc/traefik/dynamic
watch: true
#filename: /etc/traefik/config.yml # when a specific file is desired
#-https://doc.traefik.io/traefik/https/acme/
certificatesResolvers:
cloudflare:
acme:
caServer: https://acme-v02.api.letsencrypt.org/directory # prod #https://letsencrypt.org/docs/rate-limits/
# caServer: https://acme-staging-v02.api.letsencrypt.org/directory # test
email: email@gmail.com # valid Cloudflare-account email
storage: /etc/traefik/acme.json
dnsChallenge:
provider: cloudflare
#disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
log: #- https://doc.traefik.io/traefik/observability/logs/
level: "INFO"
filePath: "/var/log/traefik/traefik.log"
noColor: false # Recommended to be true when using common. When using the 'common' format, disables the colorized output
maxSize: 100 # In megabytes. Maximum size in megabytes of the log file before it gets rotated.
compress: true # gzip compression when rotating. Determines if the rotated log files should be compressed using gzip.
#
#-https://doc.traefik.io/traefik/observability/access-logs/
accessLog:
addInternals: true #Enables access logs for internal resources (e.g.: ping@internal)
filePath: "/var/log/traefik/access.log"
bufferingSize: 100 # number of log lines Traefik will keep in memory before writing them to the selected output
fields:
names:
StartUTC: drop # Write logs in Container Local Time instead of UTC. The time at which request processing started. The time at which request processing started.
filters:
statusCodes:
- "204-299"
- "400-599"
#
experimental:
plugins:
bouncer:
moduleName: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
version: "v1.4.4"
#
cloudflarewarp:
moduleName: github.com/BetterCorp/cloudflarewarp
version: v1.3.3
В этом файле мы определяем следующие основные параметры:
- Traefik будет проверять выход свежих версий
- запрещаем передачу анонимной статистики использования, но подумайте над тем, чтобы разрешить передачу. Это поможет разработчикам в развитии продукта.
- разрешаем доступ к дэшборду Traefik только по доменному имени.
- определяем три точки входа для http, https трафика на соответствующих порта и называем эти точки web, и websecure соответственно.
- определяем еще одну точку для снятия метрик по порту 8082 и называем ее metrics
- говорим, что метрики мы будем передавать в сервис prometheus и говорим прокси на каком порту это можно сделать
- разрешаем доступ к сервисам, которые имеют встроенные самоподписанные ssl сертификаты. Например - Proxmox. Можно задавать эти параметры для конкретного сервиса в файле динамической конфигурации, но я считаю что проще один раз это сделать в статике.
- говорим Traefik, что ему надо мониторить соответствующую директорию для применения динамической конфигурации.
- указываем кто у нас будет служить резолвером наших ssl сертификатов и указываем соответствующие значения. Мы говорим, что будет использовать production сертификаты, но лучше конечно сначала потренироваться на staging сертификатах.
- указываем, что выпускать ssl сертификаты мы будем с помощью dns challenge.
- указываем, что у нас будет два варианта логов: traefik.log - лог настроек непосредственно traefik; access.log - файл, где будут записи обо всех запросах поступивших на наш Traefik. Также мы задаем соответствующие настройки непосредственно лог файлов.
- в разделе experimental у меня указаны два плагина, но их настройка выходит за рамки темы настоящей статьи.
Настройка динамической конфигурации обратного прокси Traefik#
В данной статье создадим достаточно простую динамическую конфигурацию обратного прокси Traefik, которая будет включать в себя два сервиса: непосредственно дэшборд Traefik и популярный сервис по менеджменту видеофайлов Radarr.
Создаем файл динамической конфигурации командой
nano /etc/traefik/dynamic/config.yaml
Теперь укажем там следующую конфигурацию
http:
# https://doc.traefik.io/traefik/routing/routers/
routers:
# harden dashboard access: can only be accessed with a username/password
dashboard:
entryPoints:
- websecure
rule: "Host(`traefik-dashboard.domain.ru`)"
service: api@internal
middlewares:
- auth
tls:
certResolver: cloudflare
radarr:
entryPoints:
- "websecure"
rule: "Host(`radarr.domain.ru`)"
middlewares:
- default-headers
- https-redirect
tls:
certResolver: cloudflare
service: radarr
# https://doc.traefik.io/traefik/routing/services/
services:
radarr:
loadBalancer:
servers:
- url: "http://192.168.x.x:7878" # Change IP Address to your radarr instance
passHostHeader: true
# https://doc.traefik.io/traefik/middlewares/http/overview/
middlewares:
# Middleware for Redirection
# This can be used instead of global redirection
#
auth:
basicAuth:
users: # users and their MD5 hashed passwords, granted access to the traefik dashboard
- "admin:hashedpassword" # openssl passwd -1 "hashedpassword"
#
https-redirect:
redirectScheme:
scheme: https
permanent: true
#
default-headers:
headers:
frameDeny: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https
# https://doc.traefik.io/traefik/https/tls/
tls:
options:
default:
minVersion: VersionTLS12 # change to a lower version if you expect to service Internet traffic from around the world
curvePreferences: # below priority sequence can be changed
- X25519 # the most commonly used 128-bit
- CurveP256 # the next most commonly used 128-bit
- CurveP384 # 192-bit
- CurveP521 # 256-bit
sniStrict: true # true if our own certificates should be enforced
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# certificates:
# - certFile: /etc/traefik/domain.cert
# keyFile: /etc/traefik/domain.key
# - certFile: /etc/traefik/certificate.pem
# keyFile: /etc/traefik/private_key.pem
#### Traefik uses its own default certificate for connections without SNI, or without a matching domain.
#### However, we can provide our own default certificate, instead of using the Traefik default.
# stores:
# default:
# defaultCertificate:
# certFile: /etc/traefik/cert.crt
# keyFile: /etc/traefik/cert.key
#### Alternatively, we can use an ACME generated default certificate.
stores:
default:
defaultGeneratedCert:
resolver: cloudflare
domain:
main: domain.ru
sans:
- "*.domain.ru"
Давайте опишу все по порядку.
Сначала поговорим о настройках routers.
Мы указываем каким образом можем получить доступ к дэшборду Traefik. Задаем описание маршрута, описание сервиса, поддоменное имя, по которому будет доступен наш дэшборд, а также тип middleware, которым мы зададим механизм авторизации для доступа к нашему дэшборду. Далее мы указываем второй маршрут к нашему сервису Radarr, а также типы middlewares, которые должны быть применены к данному сервису.
В разделе сервисы мы даем описание нашего сервиса Radarr. В отношении дэшборда нет необходимости задавать описание в разделе сервисы, мы это уже сделали в разделе routers, в связи с тем, что это внутренний сервис.
В разделе middlewares у нас три разных middleware:
- Auth - так мы с вами обозначаем middleware, которая отвечает за базовую аутентификацию в Traefik (так называемая basicauth). В качестве логина мы указываем admin, а пароль должен быть в захешированном виде. Сделать это можно с помощью команды
openssl passwd -1 "мой секретный пароль"
где мой секретный пароль - пароль, который мы хотим захэшировать.
Default-headers - стандартные заголовки для браузера
Https-redirect - тип редиректа
Но самое интересное - это раздел tls, где мы задаем параметры выпуска и хранения ssl сертификатов, устанавливаем минимальный уровень протокола tls, а также параметры шифрования. Далее мы указываем на какой домен мы будем выпускать ssl сертификат и также определяем выпуск wildcard сертификата на любое поддоменное имя третьего уровня по нашему доменному имени.
Теперь нам надо интегрировать полученный ранее токен от cloudflare. Сделать это можно простой bash командой
export CLOUDFLARE_DNS_API_TOKEN="твой-токен"
После этого запускаем наш обратный proxy командой traefik
.
Мы можем следить за ходом выпуска сертификатов и работы Traefik в его логах с помощью команд:
cat /var/log/traefik/traefik.log
cat /var/log//traefik/access.log
После того как в traefik.log
вы увидите, что сертификаты выпущены (также можно проверить файл acme.json) мы можем перейти по поддоменным именам для доступа к нашим сервисам.
В принципе начальная настройка обратного прокси завершена. Однако надо сделать еще одну вещь. Мы хотим чтобы наш обратный прокси теперь работал к сервис, чтобы мы могли использовать команды systemctl
Создадим простой файл
nano /etc/systemd/system/traefik-proxy.service
Укажем там следующие значения
[Unit]
Description=Start Traefik Proxy
Documentation=https://go-acme.github.io/lego/dns/cloudflare/
[Service]
# declare the Cloudflare API token so Let's Encrypt can verify the domain name
Environment="CLOUDFLARE_DNS_API_TOKEN=ваш-токен"
ExecStart=/usr/local/bin/traefik
Restart=always
[Install]
# installs a hook to use this unit file when the system boots or shuts down
WantedBy=multi-user.target
Теперь мы можем с вами использоваться обычные команды:
systemctl status traefik-proxy
- статус юнита
systemctl disable traefik-proxy
- отключить автоматическую загрузку юнита
systemctl start traefik-proxy
- ручной запуск юнита