Как я могу заставить Traefik запросить один сертификат 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-серверов уже настроен, пропуская filename=proxmox.yaml providerName=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 providerName=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 providerName=stepca.acme
2024-12-17T21:52:17+01:00 ERR Ошибка при создании хранилища сертификатов error="не удалось найти сертификат для доменов \"*.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 Регистрация... providerName=letsEncrypt.acme
2024-12-17T21:52:24+01:00 INF Регистрация... providerName=stepca.acme
2024-12-17T21:52:37+01:00 ERR Ошибка при создании хранилища сертификатов error="не удалось найти сертификат для доменов \"*.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 Ошибка при создании хранилища сертификатов error="не удалось найти сертификат для доменов \"*.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 сертификат для домена error="не удалось сгенерировать сертификат для доменов [mydomain.com *.mydomain.com]: ошибка: одна или несколько доменов имели проблему:\n[*.mydomain.com] распространение: превышено время: последняя ошибка: авторитетные серверы имен: ошибка DNS-запроса: dial udp: lookup technitiumdns. on 192.168.2.113:53: нет такого хоста [ns=technitiumdns.:53, вопрос='_acme-challenge.mydomain.com. IN  TXT']\n[mydomain.com] распространение: превышено время: последняя ошибка: авторитетные серверы имен: ошибка 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"] providerName=letsEncrypt.acme tlsStoreName=default
2024-12-17T22:10:03+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:03+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:12+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:12+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:12+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:19+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:19+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:19+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:19+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:22+01:00 WRN Транспорт HTTP-серверов уже настроен, пропуская filename=proxmox.yaml providerName=file serversTransport=insecureTransport
2024-12-17T22:10:23+01:00 ERR Ошибка при создании хранилища сертификатов error="не удалось найти сертификат для доменов \"*.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?

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

Чтобы Traefik запросил единственный подстановочный сертификат Let’s Encrypt, необходимо выполнить несколько шагов и внести изменения в вашу текущую конфигурацию. Ниже приведены инструкции и рекомендации, учитывающие предоставленную вами информацию.

1. Проверка конфигурации для использования подстановочного сертификата

Для получения подстановочного сертификата от Let’s Encrypt требуется наличие правильно настроенного DNS и поддержка подстановочных сертификатов на уровне домена. Убедитесь, что ваш DNS-провайдер поддерживает автоматическую проверку DNS-указателей.

2. Обновление конфигурации Traefik

В конфигурационном файле /etc/traefik/traefik.yaml вам нужно настроить certificatesResolvers, чтобы указать на использование подстановочного сертификата. Ваша часть конфигурации для certificatesResolvers выглядит корректно, но необходимо убедиться, что указаны правильные DNS-поставщики.

certificatesResolvers:
  letsEncrypt:
    acme:
      email: [email protected] # Укажите свой действующий адрес электронной почты
      storage: /etc/traefik/acme/letsencrypt-acme.json
      caServer: https://acme-staging-v02.api.letsencrypt.org/directory # Используйте основную директорию для продакшн
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 10

Обратите внимание, что у вас два решения для получения сертификата: letsEncrypt и stepca. Убедитесь, что вы используете только один Resolver (в данном случае letsEncrypt) для получения подстановочного сертификата.

3. Устранение конфликта между Let’s Encrypt и Technitium

Ваша конфигурация показывает, что вы используете два провайдера ACME — letsEncrypt и stepca. Это может вызвать путаницу и конфликты при запросе сертификатов. Вам нужно удалить или закомментировать блок stepca в разделе certificatesResolvers, если вы хотите использовать только Let’s Encrypt.

4. Общение с вашим DNS-поставщиком

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

5. Убедитесь, что все поддомены корректно настроены

Вы также хотите убедиться, что все ваши поддомены (например, jellyfin.mydomain.com, jellyseerr.mydomain.com) правильно настроены и что DNS-записи для них действительные. Все поддомены должны указывать на ваш сервер с Traefik.

6. Примеры изменения конфигурации

Если вы хотите включить подстановочный сертификат для всех ваших поддоменов, измените конфигурацию в вашем файле /etc/traefik/dynamic/core.yaml, чтобы включить tls для глобальных маршрутизаторов:

http:
  routers:
    jellyseerr:
      rule: "Host(`jellyseerr.mydomain.com`)"
      service: jellyseerr-service
      entryPoints:
        - http
        - https
      tls:
        certResolver: letsEncrypt
    jellyfin:
      rule: "Host(`jellyfin.mydomain.com`)"
      service: jellyfin-service
      entryPoints:
        - https
      tls:
        certResolver: letsEncrypt  # Использование общей конфигурации для всех маршрутизаторов

Это обеспечит использование одного и того же резолвера сертификатов для всех маршрутов.

Заключение

Таким образом, для успешного получения единого подстановочного сертификата от Let’s Encrypt вам необходимо скорректировать конфигурацию Traefik, убедиться в корректной настройке DNS и устранить конфликты с другими провайдерами сертификатов. После внесения необходимых изменений перезапустите Traefik и проверьте логи на наличие ошибок.

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

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