Как мне заставить Traefik запросить единственный wildcard сертификат Let’s Encrypt?

Вопрос или проблема

Я пытаюсь настроить Traefik, переходя с Nginx proxy manager.

Это /etc/traefik/traefik.yaml

# наблюдаемость

api: {}

global:
  checkNewVersion: true
  sendAnonymousUsage: true    # отправлять анонимные данные об использовании

accesslog:
 addInternals: true
 filePath: "/var/log/traefik-access.log"
 bufferingSize: 128

log:
 filePath: "/var/log/traefik.log"
 level: INFO    # TRACE DEBUG INFO WARN ERROR FATAL PANIC
 maxAge: 48

metrics:
 addInternals: true

# окружение

entryPoints:
 http:
   address: ":80"
   http:
     middlewares:
       - internal-hosts-endorsed
 https:
  address: ":443"
  http:
    middlewares:
       - internal-hosts-endorsed
    tls:
      certResolver: letsEncrypt
      domains:
        - main: "mydomain.com"
          sans:
            - "*.mydomain.com"
providers:
 file:
   directory: /etc/traefik/dynamic
   watch: true

certificatesResolvers:
  letsEncrypt:
    acme:
      email: [email protected]
      storage: /etc/traefik/acme/letsencrypt-acme.json
      #caServer: https://acme-v02.api.letsencrypt.org/directory # производство (по умолчанию)
      caServer: https://acme-staging-v02.api.letsencrypt.org/directory # тестирование
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 10 # Дополнительно, чтобы подождать x секунд перед проверкой с DNS-сервером
  stepca:
    acme:
      email: [email protected]
      storage: "/etc/traefik/acme/stepca-acme.json"
      caServer: "https://ca.mydomain.com:9000/acme/acme/directory"
      certificatesDuration: 2160
      dnsChallenge:
        provider: technitium
        disablePropagationCheck: true
        delayBeforeCheck: 5
        resolvers:
          - "192.168.2.113:53"

Это /etc/traefik/dynamic/core.yaml

http:

  routers:

    dashboard:
      rule: Host(`traefik.mydomain.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
      service: api@internal
      middlewares:
        - auth

    catchall:
      entryPoints:
        - http
        - https
      rule: PathPrefix(`/`)
      service: unavailable
      priority: 1

  services:

    unavailable:
      loadBalancer:
        servers: {}

  middlewares:

    auth:
      basicAuth:
        users:   
          - david:$1$bXGAceOu$1zRJMvh60HR5n6.q2B8io0

    internal-hosts-endorsed:
      ipAllowList:
        sourceRange:
          - 192.168.2.0/24
          - 10.0.0.0/24

    http-only:
      redirectScheme:
        scheme: http
        permanent: true

    internal-http-hosts:
      chain:
        middlewares:
          - internal-hosts-endorsed
          - http-only

    https-only:
      redirectScheme:
        scheme: https
        permanent: true

    internal-https-hosts:
      chain:
        middlewares:
          - internal-hosts-endorsed
          - https-only

tls:
  options:
    default:
      minVersion: VersionTLS13   
      curvePreferences:  
        - X25519    
        - CurveP256 
        - CurveP384 
        - CurveP521 
      sniStrict: true    

  stores:
    default:
      defaultGeneratedCert:
        resolver: letsEncrypt
        domain:
          main: mydomain.com
          sans:
            - '*.mydomain.com'

И у меня есть поддомены, такие как (/etc/traefik/dynamic/jellyseerr.yaml):

# Конфигурация Traefik для jellyseerr_mydomain_com
#jellyseerr.mydomain.com
http:
  routers:
    jellyseerr:
      rule: "Host(`jellyseerr.mydomain.com`)"
      service: jellyseerr-service
      entryPoints:
      - http
      - https
      tls:
        certResolver: letsEncrypt

  services:
    jellyseerr-service:
      loadBalancer:
        servers:
          - url: "http://192.168.2.102:5055"

И это /etc/traefik/dynamic/jellyfin.yaml

# Конфигурация Traefik для jellyfin_mydomain_com
#jellyfin.mydomain.com
http:
  routers:
    jellyfin:
      rule: "Host(`jellyfin.mydomain.com`)"
      service: jellyfin-service
      entryPoints:
        - https
      tls:
        certResolver: letsEncrypt

  services:
    jellyfin-service:
      loadBalancer:
        servers:
          - url: "http://192.168.2.101:8096"

Как мне сделать так, чтобы Traefik запрашивал один сертификат wildcard?

root@traefik:~# cat /var/log/traefik.log

2024-12-17T21:52:16+01:00 INF Версия Traefik 3.2.3 собрана 2024-12-16T10:31:50Z версия=3.2.3
2024-12-17T21:52:16+01:00 INF Сбор статистики включен.
2024-12-17T21:52:16+01:00 INF Большое спасибо за участие в улучшении Traefik, позволяя нам получать анонимную информацию из вашей конфигурации.
2024-12-17T21:52:16+01:00 INF Помогите нам улучшить Traefik, оставив эту функцию включенной :)
2024-12-17T21:52:16+01:00 INF Подробнее: https://doc.traefik.io/traefik/contributing/data-collection/
2024-12-17T21:52:16+01:00 INF Начинаем агрегатор провайдеров *aggregator.ProviderAggregator
2024-12-17T21:52:16+01:00 INF Начинаем провайдер *file.Provider
2024-12-17T21:52:16+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T21:52:16+01:00 INF Начинаем провайдер *traefik.Provider
2024-12-17T21:52:16+01:00 INF Начинаем провайдер *acme.ChallengeTLSALPN
2024-12-17T21:52:16+01:00 INF Начинаем провайдер *acme.Provider
2024-12-17T21:52:16+01:00 INF Тестируем обновление сертификата... acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory имя провайдера = letsEncrypt.acme
2024-12-17T21:52:16+01:00 INF Начинаем провайдер *acme.Provider
2024-12-17T21:52:16+01:00 INF Тестируем обновление сертификата... acmeCA=https://ca.mydomain.com:9000/acme/acme/directory имя провайдера = stepca.acme
2024-12-17T21:52:17+01:00 ERR Ошибка при создании хранилища сертификатов ошибка="не удалось найти сертификат для доменов \"*.mydomain.com,mydomain.com\": возвращение к внутреннему сгенерированному сертификату" tlsStoreName=default
2024-12-17T21:52:17+01:00 WRN Домен не найден в правиле PathPrefix(`/`), параметры TLS, применяемые для этого маршрутизатора, будут зависеть от SNI каждого запроса entryPointName=https routerName=https-catchall@file
2024-12-17T21:52:22+01:00 INF Регистрация... имя провайдера = letsEncrypt.acme
2024-12-17T21:52:24+01:00 INF Регистрация... имя провайдера = stepca.acme
2024-12-17T21:52:37+01:00 ERR Ошибка при создании хранилища сертификатов ошибка="не удалось найти сертификат для доменов \"*.mydomain.com,mydomain.com\": возвращение к внутреннему сгенерированному сертификату" tlsStoreName=default
2024-12-17T21:52:37+01:00 WRN Домен не найден в правиле PathPrefix(`/`), параметры TLS, применяемые для этого маршрутизатора, будут зависеть от SNI каждого запроса entryPointName=https routerName=https-catchall@file
2024-12-17T21:52:38+01:00 ERR Ошибка при создании хранилища сертификатов ошибка="не удалось найти сертификат для доменов \"*.mydomain.com,mydomain.com\": возвращение к внутреннему сгенерированному сертификату" tlsStoreName=default
2024-12-17T21:52:38+01:00 WRN Домен не найден в правиле PathPrefix(`/`), параметры TLS, применяемые для этого маршрутизатора, будут зависеть от SNI каждого запроса entryPointName=https routerName=https-catchall@file
2024-12-17T21:56:32+01:00 ERR Не удалось получить сертификат ACME для домена ошибка="не удалось сгенерировать сертификат для доменов [mydomain.com *.mydomain.com]: ошибка: одна или несколько доменов вызвали проблему:\n[*.mydomain.com] propagation: превышен лимит времени: последняя ошибка: авторитетные именовые серверы: ошибка вызова DNS: dial udp: lookup technitiumdns. on 192.168.2.113:53: нет такого хоста [ns=technitiumdns.:53, вопрос='_acme-challenge.mydomain.com. IN  TXT']\n[mydomain.com] propagation: превышен лимит времени: последняя ошибка: авторитетные именовые серверы: ошибка вызова DNS: dial udp: lookup technitiumdns. on 192.168.2.113:53: нет такого хоста [ns=technitiumdns.:53, вопрос='_acme-challenge.mydomain.com. IN  TXT']\n" ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory domains=["mydomain.com","*.mydomain.com"] имя провайдера = letsEncrypt.acme tlsStoreName=default
2024-12-17T22:10:03+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:03+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:12+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:12+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:12+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:19+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:19+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:19+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:19+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:22+01:00 WRN HTTP-серверы транспорт уже сконфигурированы, пропуск файла = proxmox.yaml имя провайдера = file serversTransport = insecureTransport
2024-12-17T22:10:23+01:00 ERR Ошибка при создании хранилища сертификатов ошибка="не удалось найти сертификат для доменов \"*.mydomain.com,mydomain.com\": возвращение к внутреннему сгенерированному сертификату" tlsStoreName=default
2024-12-17T22:10:26+01:00 WRN Домен не найден в правиле PathPrefix(`/`), параметры TLS, применяемые для этого маршрутизатора, будут зависеть от SNI каждого запроса entryPointName=https routerName=https-catchall@file
2024-12-17T22:10:49+01:00 WRN Домен не найден в правиле PathPrefix(`/`), параметры TLS, применяемые для этого маршрутизатора, будут зависеть от SNI каждого запроса entryPointName=https routerName=https-catchall@file

Почему кажется, что он смешивает Let’s Encrypt с Technitium?

Ответ или решение

Как получить единый сертификат Wildcard Let’s Encrypt с помощью Traefik?

Ваша конфигурация Traefik для управления HTTPS-трафиком и получения сертификатов Let’s Encrypt может потребовать некоторых корректировок, чтобы правильно запросить единый Wildcard сертификат для домена *.mydomain.com. Обратите внимание, что Wildcard сертификаты требуют подтверждения владения доменом, что делается через DNS. Ваша ошибка указывает на проблемы с проверкой DNS для _acme-challenge.

Что такое Wildcard сертификат?

Wildcard сертификат — это тип TLS/SSL сертификата, который позволяет вам защитить ваше основной домен и все его поддомены. Например, один сертификат для mydomain.com и *.mydomain.com будет достаточно для работы со всеми поддоменами, такими как jellyfin.mydomain.com, jellyseerr.mydomain.com, и т.д.

Шаги для получения Wildcard сертификата

  1. Проверьте настройки DNS:
    Убедитесь, что у вас настроены правильные DNS записи для домена mydomain.com и поддомена *.mydomain.com. Вам необходимо будет добавить запись TXT для проверки, так как именно через нее Let’s Encrypt будет проверять, что вы владеете доменом.

  2. Корректировка конфигурации Traefik:
    Убедитесь, что конфигурация для certificatesResolvers выглядит следующим образом:

    certificatesResolvers:
     letsEncrypt:
       acme:
         email: your-email@example.com
         storage: /etc/traefik/acme/letsencrypt-acme.json
         caServer: https://acme-v02.api.letsencrypt.org/directory # производственный сертификат
         dnsChallenge:
           provider: cloudflare # или другой DNS-провайдер
           delayBeforeCheck: 10
  3. Правильное направление для DNS Challenge:
    Запишите _acme-challenge.mydomain.com как TXT запись с токеном, который будет предоставлен Traefik. Это важно, так как он должен быть доступен для Let’s Encrypt для верификации.

  4. Координация с динамическими конфигурациями:
    Ваши динамические конфигурационные файлы для поддоменов должны также указывать на использование certResolver:

    http:
     routers:
       jellyseerr:
         rule: "Host(`jellyseerr.mydomain.com`)"
         service: jellyseerr-service
         entryPoints:
         - http
         - https
         tls:
           certResolver: letsEncrypt
  5. Удалите лишние провайдеры:
    Если вы не планируете использовать Technitium для сертификатов, удалите его настройки. Смешивание различных ACME-провайдеров может вызывать ошибки. Оставьте только конфигурацию для Let’s Encrypt.

  6. Проверка логов:
    Из вашей лог-файлы видно, что Traefik не может найти сертификат. Это может быть связано с проблемами DNS:

    ERR Error while creating certificate store error="unable to find certificate for domains \"*.mydomain.com,mydomain.com\": falling back to the internal generated certificate"

    Проверьте, чтобы DNS-серверы были настроены правильно и отвечали на запросы о _acme-challenge.

  7. Перезапустите Traefik:
    После внесения изменений обязательно перезапустите Traefik, чтобы новые настройки вступили в силу.

Заключение

Получение Wildcard сертификата с помощью Traefik требует корректной настройки DNS для проверки складаете на владение доменом. Убедитесь, что все параметры ACME и DNS установлены правильно, и вы сможете успешно получить и использовать Wildcard сертификат для защиты оформленных доменов и поддоменов.

Рекомендации по оптимизации

  • Обновляйте DNS-записи своевременно: Убедитесь, что любые изменения в конфигурации ваших доменов немедленно отражаются в DNS.
  • Мониторинг логов: Постоянно следите за логами Traefik для выявления проблем на ранней стадии.
  • Обратите внимание на уровни доступа: Поддерживайте безопасность ваших систем, включая надлежащие политики доступа и аутентификации.

Следуйте этим рекомендациям, и вы сможете успешно настроить Traefik для управления сертификатами Wildcard с Let’s Encrypt.

Оцените материал
Добавить комментарий

Капча загружается...