Обо мне Блог Контакты

Обратный прокси Traefik: статическая конфигурация

Продолжение статьи про обратный прокси Traefik. Для полного понимания рекомендую прочитать сначала предыдущую.

В этой статье мы разберем статическую конфигурацию Traefik. Она включает в себя такие настройки как entryPoints, providers, certificatesResolvers, logs. Файл статической конфигурации (traefik.yaml) является единым и содержит все базовые инструкции для запуска Traefik. Ниже я привожу свою конфигурацию, которую использую прямо сейчас у себя.


Статическая конфигурация Traefik

global:
  checkNewVersion: true
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: false
  debug: false

entryPoints:
  websecure:
    address: :443
    asDefault: true
    http:
      tls:
        certResolver: timewebcloud
    forwardedHeaders:
      trustedIPs:
        - 10.0.0.1/32
    proxyProtocol:
      trustedIPs:
        - 10.0.0.1/32

providers:
  file:
    directory: /etc/traefik/dynamic
    watch: true

certificatesResolvers:
  timewebcloud:
    acme:
      caServer: https://acme-v02.api.letsencrypt.org/directory
      email: roman.kvasnikov@gmail.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: timewebcloud
        resolvers:
          - 8.8.8.8:53
          - 8.8.4.4:53

log:
  filePath: /var/log/traefik/traefik.log
  level: WARN
  compress: true

accessLog:
  filePath: /var/log/traefik/access.log
  addInternals: true
  bufferingSize: 100
  fields:
    names:
      StartUTC: drop

Я не буду досконально расписывать каждый параметр в этой конфигурации потому что описание любого из них, можно найти за секунды в официальной документации обратного прокси Traefik. Затрону лишь некоторые важные из них, о чем хотелось бы рассказать.

1. entryPoints

В моей конфигурации определена единственная точка входа — websecure, которая прослушивает только порт 443 (HTTPS).

Это единственный открытый порт в LXC-контейнере с Traefik (не считая SSH порта). Все сервисы моего домашнего сервера доступны исключительно по HTTPS через поддомены. Другие порты не используются.

Note

В статье Организация внешнего доступа к домашней Homelab, я упоминал, что мы открываем два порта, - 80 (HTTP) и 443 (HTTPS). Но, если используется DNS-01 challenge (о нём ниже), то порт 80 не требуется вовсе. Весь трафик работает исключительно через HTTPS.

Указываем параметр asDefault: true делая эту точку входа по умолчанию, чтобы потом не нужно было ее указывать явно для каждого маршрута.

Тоже самое делаем и для certResolver. О его конфигураци написано чуть ниже. Тут просто указываем его также, по умолчанию.

Дополнительно я указал, что Traefik доверяет входящим подключениям только от нашего внешнего VPS, соединённого с ним через WireGuard-туннель. Поэтому в параметрах forwardedHeaders.trustedIPs и proxyProtocol.trustedIPs указан доверенный IP-адрес из подсети WireGuard10.0.0.1/32.

Параметр forwardedHeaders позволяет принимать и доверять заголовкам вида X-Forwarded-*, которые передаются проксирующей стороной (в данном случае VPS) и также используются для определения исходного IP-адреса и других параметров запроса.

Параметр proxyProtocol необходим для корректного определения реального IP-адреса клиента. Без его настройки Traefik видел бы все входящие подключения как поступающие только от IP-адреса VPS (10.0.0.1), а не от фактического клиента.

Note

proxyProtocol будет работать только если VPS действительно отправляет Proxy Protocol (например, через Nginx с proxy_protocol). В статье Организация внешнего доступа к домашней Homelab мы указали proxy_protocol, так что если вы делаете точно также - все будет работать.

2. providers

Здесь мы указываем путь до каталога с файлами динамической конфигурации. А также указываем флаг watch: true, чтобы изменения вступали в силу сразу же после изменения файлов без перезапуска Traefik.

3. certificatesResolvers

В данном фрагменте настраивается механизм автоматического получения SSL-сертификатов через протокол ACME от центра сертификации Let's Encrypt. Тут я создаю резолвер сертификатов и называю его timewebcloud. Имя произвольное, я назвал его по названию своего провайдера, через который я буду подтверждать факт владения доменом. Этот резолвер я указал чуть выше в конфигурации для точки входа websecure по умолчанию. Теперь этот резолвер применится ко всем нашим роутерам автоматически.

Настраиваем сам протокол ACME. Указываем:

  • Адрес ACME сервера Let's Encrypt.
  • Email адрес для регистрации ACME аккаунта и получения уведомлений об истечении действия сертификатов или проблемах с их продлением.
  • Файл для хранения сертификатов и ключей. Важно чтобы он имел права доступа 600, так как содержит приватные ключи.

Дальше указываем, что метод подтверждения владения доменом у нас будет DNS-01 challenge. Это означает, что при выпуске сертификата Traefik автоматически создаёт специальную TXT-запись в DNS-зоне домена. Let's Encrypt проверяет наличие этой записи и, если всё корректно, выпускает сертификат.

Преимущества DNS-challenge:

  • не требуется открытый порт 80 (HTTP);
  • можно выпускать wildcard-сертификаты (*.example.com), чтобы не выпускать несколько сертификатов для каждого сервиса;
  • не зависит от прямой доступности сервера из интернета.

Запись provider: timewebcloud означает, что Traefik будет работать с DNS-API провайдера Timeweb Cloud для автоматического создания и удаления TXT-записей. Для этой возможности в файле .env мы определяем переменную окружения TIMEWEBCLOUD_AUTH_TOKEN. Найти свой провайдер и посмотреть какие для него нужны переменные окружения можете здесь: https://go-acme.github.io/lego/dns/index.html

Ну и наконец я указал два публичных DNS резолвера от Google для проверки доступности TXT-записи во время ACME challenge.

Подытожим:

  • Traefik автоматически получает и продлевает сертификаты Let's Encrypt.
  • Подтверждение владения доменом происходит через DNS-01 challenge.
  • TXT-записи создаются через API Timeweb Cloud.
  • Сертификаты и ключи хранятся локально в acme.json.
  • Проверка доступности TXT-записи DNS выполняется через публичные DNS-резолверы Google.

4. log

В этом разделе настраиваются системные логи Traefik — ошибки, предупреждения и служебные сообщения. Здесь задаётся путь к файлу журнала, уровень логирования и автоматическое сжатие архивных логов.

Конфигурация интуитивно понятна. Подробное описание всех доступных параметров можно найти в официальной документации Traefik.

5. accessLog

В данном разделе настраивается журнал входящих HTTP-запросов — информация о том, кто обращался к серверу, к какому ресурсу и с каким результатом (статус ответа).

Access-лог особенно важен, если сервер доступен из интернета. Он позволяет:

  • анализировать входящий трафик;
  • выявлять подозрительную активность;
  • обнаруживать попытки перебора, сканирования и другие несанкционированные обращения.

Если сервер доступен исключительно из доверенной локальной сети, необходимость в подробном access-логе может быть не столь критичной. Однако при открытии внешнего доступа его ведение фактически становится обязательным. Именно на основе этих логов можно настраивать системы защиты и блокировать нежелательные источники (например, автоматические сканеры — подробнее об этом в отдельной статье).


Запуск Traefik как systemd сервиса

В предыдущей статье был рассмотрен процесс установки Traefik через бинарный файл. После создания статической конфигурации необходимо запустить сервис и добавить его в автозагрузку systemd.

systemctl daemon-reload   # Перечитываем unit-файлы systemd после создания traefik.service
systemctl start traefik   # Запускаем сервис Traefik
systemctl enable traefik  # Добавляем сервис в автозагрузку
systemctl status traefik  # Проверяем текущий статус сервиса
journalctl -u traefik -f  # Просмотр логов Traefik в реальном времени

После изменения статической конфигурации, нам нужно всегда перезапускать сервис Traefik, чтобы изменения вступили в силу:

systemctl restart traefik

В следующей статье мы затронем динамическую конфигурацию, настройку роутеров, сервисов и middlewares.