В предыдущей статье мы с вами установили непривилегированный LXC контейнер на базе Debian, скачали бинарный файл Traefik и с помощью самой простой статической конфигурации потестировали работоспособность нашего обратного прокси.
В этой статье проведем уже полноценную настройку обратного прокси Traefik.
Что нам нужно для полноценной работы обратного прокси.#
- Нам нужно квалифицированное доменное имя. При покупке доменного имени рекомендую обратить внимание не на стоимость покупки (они плюс, минус всегда одинаковые), а на стоимость продления. Потому что процентное соотношение между стоимость покупки и стоимостью продления может неприятно удивидить.
Сам я пользуюсь услугами smartape. Стоимость продления домена в зоне .ру у них 200р. Можете перейти по реферальной ссылке и посмотреть актуальную стоимость. Не реклама.
Дальше нам нужно разместить наше доменное имя на внешних днс серверах. Я сам пользуюсь услугами cloudflare, но из-за блокировок РКН доступ к их днс может не работать. И хотя я продолжаю пользоваться cloudflare, с учетом существующих на данный момент ограничений советовать их я не могу. Хотя в данной статье я покажу настройку именно с cloudflare. Список днс провайдеров можно посмотреть в документации Traefik. Там есть и отечественные сервисы, нужно просто учитывать код провайдера и переменные окружения при настройке.
Желательно иметь белый ip адрес, который вы можете приобрести у вашего интернет-провайдера.
Настройть split dns, чтобы запросы по поддоменному имени внутри локальной сети не выходили за ее пределы. Более подробно можете посмотреть в моем ролике, посвященному именно этой теме.
Настройки DNS с помощью Cloudflare#
Я предполагаю, что у вас уже зарегистрированно доменное имя и оно уже перенесено на dns сервера соответствующего провайдера. Я показываю все на примере Cloudflare. В этом гайде я использую доменное имя stilicho.ru Картинки не мои, а взяты из интернета
Переходите в ваш профайл
Переходим в меню для создания токена
Начинаем создавать кастомный токен
Задаем конкретные настройки токена
Создаем токен
Скопируйте значения вашего токена и сохраните в безопасном месте, так как посмотреть еще раз значения токена в профиле cloudflare у вас не получится. Полученный токен мы с вами будем использоваться на настройки нашего прокси как сервиса, и он позволяет управлять нашими сертификатами с помощью Cloudflare. Если вы потеряете токен, то единственным выходом будет только его пересоздание с нуля.
Можете посмотреть все токены, которые вы создали с помощью cloudflare
Настройка статической конфигурации обратного прокси Traefik#
Traefik поддерживает статическую и динамическую конфигурацию. Все изменения в статическом конфиге предполагают ручную перезагрузку Treafik. Изменения в динамической конфигурации 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которая будет включать в себя два сервиса: непосредственно дэшборд и популярный сервис по менеджементу видеофайлов 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 "my-pass"
где my-pass - это пароль, который мы хотим захэщировать.
Deafualt-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
- ручной запуск юнита