Docker swarm + Traefik v1.7(Let’s Encrypt)でワイルドカード証明書を利用する方法

Docker

Traefik v1.7を使用して、Let’s Encryptのワイルドカード証明書を利用する方法の覚書です。

Docker Swarmによるオーケストレーション環境での設定方法です。(Docker-composeの場合は、たぶんdeployあたりを書き換えればOKだと思う)

ワイルドカード証明書を使用するよう設定したところ、dnsChallengeが必要というエラーログが出力されました。dnsChallengeとは、DNSのTXTレコードに確認用のデータを書き込んで認証を行う方法です。つまり、外部からDNSの書き換えが可能なDNSプロバイダを利用する必要があります。

幸い僕が利用しているLinodeのDNSサーバは、APIを叩くことでDNSの書き換えが可能であり、Traefikが対応しているプロバイダのひとつであったため、設定することが出来そうです。

Linodeの管理画面から、DNS情報の読み書きが可能なAPIキーを発行して、Traefikコンテナの環境変数に設定します。

※対応しているDNSプロバイダは以下のページにリストアップされています。
https://doc.traefik.io/traefik/v1.7/configuration/acme/#provider

version: '3.4'
services:
  traefik:
    image: traefik:1.7-alpine
    command:
      - "--logLevel=error"
      - "--entryPoints=Name:http Address::80 Redirect.EntryPoint:https"
      - "--entryPoints=Name:https Address::443 TLS TLS.minVersion:VersionTLS12 TLS.cipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA Compress:true"
      - "--defaultentrypoints=http,https"
      - "--web"
      - "--web.address=:8080"
      - "--acme"
      - "--acme.storage=certs.json"
      - "--acme.email=あなたのメールアドレス"
      - "--acme.entrypoint=https"
      - "--acme.httpchallenge=true"
      - "--acme.httpchallenge.entrypoint=http"
      - "--acme.tlsChallenge=true"
      - "--acme.dnschallenge=true"
      # ▼DNSプロバイダを指定する
      - "--acme.dnschallenge.provider=linodev4"
      # ▼ドメインを指定する(カンマで区切る main,sans1,sans2,...と解釈される)
      - "--acme.domains=*.hogehoge.com,hogehoge.com"
      - "--docker"
      - "--docker.endpoint=unix:///var/run/docker.sock"
      # ▼Docker swarmに追加したオーバーレイネットワークを指定する
      - "--docker.network=overlay"
      - "--docker.swarmMode"
      - "--docker.watch"
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80
      - mode: host
        protocol: tcp
        published: 443
        target: 443
    networks:
      - overlay
    environment:
      # ▼環境変数にDNSプロバイダーで発行したAPIキーを設定する
      LINODE_TOKEN: << Linodeの管理画面で発行したAPIキー >>
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/web/traefik/certs.json:/certs.json
    deploy:
      restart_policy:
        condition: on-failure

networks:
  # ▼Docker swarmに追加したオーバーレイネットワークを指定する
  overlay:
    external: true

さらに、サブドメインにワイルドカードを指定したドメイン用のコンテナには、以下のように指定します。

version: '3.4'
services:
  sample:
    image: tutum/hello-world
    networks:
      - overlay
    deploy:
      labels:
        - traefik.enable=true
        - traefik.backend=sample
        - traefik.frontend.rule=HostRegexp:{catchall:.*}
        - traefik.frontend.priority=1
        - traefik.frontend.entryPoints=https
        - traefik.port=80
        - traefik.protocol=http

networks:
  overlay:
    external: true

traefik.frontend.rule にキャッチオールの設定をします。
例1)HostRegexp:{catchall:.*}
例2)HostRegexp:{subdomain:[a-z0-9]+}.hogehoge.com

さらに traefik.frontend.priority に 1 を指定します。priority の設定をしない場合、サブドメインを明示的に指定した他のコンテナにルーティングされず、すべてのアクセスがこのコンテナにルーティングされてしまう可能性があります。

以上です。

【おまけ】
Traefikの2系でなくv1.7を使用する理由は、Traefikコンテナを複数起動する負荷分散が無料で出来るためですw
https://doc.traefik.io/traefik/v1.7/user-guide/cluster-docker-consul/

コメント

タイトルとURLをコピーしました