Value DomainでLet’s encryptのワイルドカード証明書を発行する

Posted on

今北三行

現状

公式では対応してなかったので、対応させるプルリクを投げてる最中です。

そのかわり、使えるようにしたDockerイメージを用意しました。マージされるまでのつなぎにどうぞ。

Dockerイメージの使い方

使うには、こんな感じのdocker-compose.yml書いて:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
---
version: '3.7'
services:
certbot:
# つくった
image: 'ghcr.io/ledyba/certbot-with-dns_valuedomain:latest'
network_mode: 'host'
volumes:
- ./data:/etc/letsencrypt
- ./conf:/etc/certbot
networks: {}
--- version: '3.7' services: certbot: # つくった image: 'ghcr.io/ledyba/certbot-with-dns_valuedomain:latest' network_mode: 'host' volumes: - ./data:/etc/letsencrypt - ./conf:/etc/certbot networks: {}
---
version: '3.7'

services:
  certbot:
    # つくった
    image: 'ghcr.io/ledyba/certbot-with-dns_valuedomain:latest'
    network_mode: 'host'
    volumes:
      - ./data:/etc/letsencrypt
      - ./conf:/etc/certbot

networks: {}

conf/valuedomain.ini

  • 所有者root:root
  • パーミッション0600

で作成して、Value Domain APIのページから持ってきたトークンをこんな感じでコピペして:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
dns_valuedomain_api_token=(your-token)
dns_valuedomain_api_token=(your-token)
dns_valuedomain_api_token=(your-token)

最後にこんな感じでコマンド打って証明書を発行してもらう:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
docker-compose run \
--rm certbot \
certonly \
-vvv \
--agree-tos \
--email <your-email-addr> \
--non-interactive \
--preferred-challenges dns-01 \
--dns-valuedomain \
--dns-valuedomain-propagation-seconds=90 \
--dns-valuedomain-credentials=/etc/certbot/valuedomain.ini \
--keep \
-d example.com *.example.com *.foo.example.com
docker-compose run \ --rm certbot \ certonly \ -vvv \ --agree-tos \ --email <your-email-addr> \ --non-interactive \ --preferred-challenges dns-01 \ --dns-valuedomain \ --dns-valuedomain-propagation-seconds=90 \ --dns-valuedomain-credentials=/etc/certbot/valuedomain.ini \ --keep \ -d example.com *.example.com *.foo.example.com
docker-compose run \
  --rm certbot \
    certonly \
      -vvv \
      --agree-tos \
      --email <your-email-addr> \
      --non-interactive \
      --preferred-challenges dns-01 \
      --dns-valuedomain \
      --dns-valuedomain-propagation-seconds=90 \
      --dns-valuedomain-credentials=/etc/certbot/valuedomain.ini \
      --keep \
      -d example.com *.example.com *.foo.example.com

renewするには:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
docker-compose run --rm certbot renew -vvv
docker-compose run --rm certbot renew -vvv
docker-compose run --rm certbot renew -vvv

無料でワイルドカード証明書が欲しい!

TLSで暗号化せざるをえない(?)昨今、どうせ証明書を作るならワイルドカード証明書が欲しくなります。

実験で新しいウェブアプリを書いてドメイン名が必要になった時、通常のHTTP認証を使った証明書を使う場合は、実験用のドメイン用にlet’s encryptのコマンドを追加でたくさんたくさん叩かないといけません。

一方、ワイルドカード証明書ならA/AAAA/CNAMEレコードを1つか2つ追加すればすぐに使えます。

楽です。楽であることは正義です。

certbotが対応していない

certbotにはDNSプラグインなる仕組みがあり、Route53などの有名どころにはすでにプラグインが存在し、各サービスのパスワード的なものを用意すればプラグインを使ってワイルドカード証明書が発行できるとのこと。

じゃあ我らがValue Domainはどうなのかというと…

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
% certbot --help certonly
usage:
certbot certonly [options] [-d DOMAIN] [-d DOMAIN] ...
....
--dns-cloudflare Obtain certificates using a DNS TXT record (if you are using Cloudflare for DNS). (default: False)
--dns-cloudxns Obtain certificates using a DNS TXT record (if you are using CloudXNS for DNS). (default: False)
--dns-digitalocean Obtain certificates using a DNS TXT record (if you are using DigitalOcean for DNS). (default: False)
--dns-dnsimple Obtain certificates using a DNS TXT record (if you are using DNSimple for DNS). (default: False)
--dns-dnsmadeeasy Obtain certificates using a DNS TXT record (if you are using DNS Made Easy for DNS). (default: False)
--dns-gehirn Obtain certificates using a DNS TXT record (if you are using Gehirn Infrastructure Service for DNS). (default: False)
--dns-google Obtain certificates using a DNS TXT record (if you are using Google Cloud DNS). (default: False)
--dns-linode Obtain certificates using a DNS TXT record (if you are using Linode for DNS). (default: False)
--dns-luadns Obtain certificates using a DNS TXT record (if you are using LuaDNS for DNS). (default: False)
--dns-nsone Obtain certificates using a DNS TXT record (if you are using NS1 for DNS). (default: False)
--dns-ovh Obtain certificates using a DNS TXT record (if you are using OVH for DNS). (default: False)
--dns-rfc2136 Obtain certificates using a DNS TXT record (if you are using BIND for DNS). (default: False)
--dns-route53 Obtain certificates using a DNS TXT record (if you are using Route53 for DNS). (default: False)
--dns-sakuracloud Obtain certificates using a DNS TXT record (if you are using Sakura Cloud for DNS). (default: False)
% certbot --help certonly usage: certbot certonly [options] [-d DOMAIN] [-d DOMAIN] ... .... --dns-cloudflare Obtain certificates using a DNS TXT record (if you are using Cloudflare for DNS). (default: False) --dns-cloudxns Obtain certificates using a DNS TXT record (if you are using CloudXNS for DNS). (default: False) --dns-digitalocean Obtain certificates using a DNS TXT record (if you are using DigitalOcean for DNS). (default: False) --dns-dnsimple Obtain certificates using a DNS TXT record (if you are using DNSimple for DNS). (default: False) --dns-dnsmadeeasy Obtain certificates using a DNS TXT record (if you are using DNS Made Easy for DNS). (default: False) --dns-gehirn Obtain certificates using a DNS TXT record (if you are using Gehirn Infrastructure Service for DNS). (default: False) --dns-google Obtain certificates using a DNS TXT record (if you are using Google Cloud DNS). (default: False) --dns-linode Obtain certificates using a DNS TXT record (if you are using Linode for DNS). (default: False) --dns-luadns Obtain certificates using a DNS TXT record (if you are using LuaDNS for DNS). (default: False) --dns-nsone Obtain certificates using a DNS TXT record (if you are using NS1 for DNS). (default: False) --dns-ovh Obtain certificates using a DNS TXT record (if you are using OVH for DNS). (default: False) --dns-rfc2136 Obtain certificates using a DNS TXT record (if you are using BIND for DNS). (default: False) --dns-route53 Obtain certificates using a DNS TXT record (if you are using Route53 for DNS). (default: False) --dns-sakuracloud Obtain certificates using a DNS TXT record (if you are using Sakura Cloud for DNS). (default: False)
% certbot --help certonly
usage: 

  certbot certonly [options] [-d DOMAIN] [-d DOMAIN] ...

....

  --dns-cloudflare      Obtain certificates using a DNS TXT record (if you are using Cloudflare for DNS). (default: False)
  --dns-cloudxns        Obtain certificates using a DNS TXT record (if you are using CloudXNS for DNS). (default: False)
  --dns-digitalocean    Obtain certificates using a DNS TXT record (if you are using DigitalOcean for DNS). (default: False)
  --dns-dnsimple        Obtain certificates using a DNS TXT record (if you are using DNSimple for DNS). (default: False)
  --dns-dnsmadeeasy     Obtain certificates using a DNS TXT record (if you are using DNS Made Easy for DNS). (default: False)
  --dns-gehirn          Obtain certificates using a DNS TXT record (if you are using Gehirn Infrastructure Service for DNS). (default: False)
  --dns-google          Obtain certificates using a DNS TXT record (if you are using Google Cloud DNS). (default: False)
  --dns-linode          Obtain certificates using a DNS TXT record (if you are using Linode for DNS). (default: False)
  --dns-luadns          Obtain certificates using a DNS TXT record (if you are using LuaDNS for DNS). (default: False)
  --dns-nsone           Obtain certificates using a DNS TXT record (if you are using NS1 for DNS). (default: False)
  --dns-ovh             Obtain certificates using a DNS TXT record (if you are using OVH for DNS). (default: False)
  --dns-rfc2136         Obtain certificates using a DNS TXT record (if you are using BIND for DNS). (default: False)
  --dns-route53         Obtain certificates using a DNS TXT record (if you are using Route53 for DNS). (default: False)
  --dns-sakuracloud     Obtain certificates using a DNS TXT record (if you are using Sakura Cloud for DNS). (default: False)

してなーい!

じゃあさせるぞ!

Certbotが依存しているlexiconを対応させる

一番最後の行に出てるsakuracloudが一番近そうなので、これを適当に模倣します(プルリク)。

仕組みがどうなってるのかよくわかんないんですが(笑)、実装であるlexicon/providers/valuedomain.pyと、そのテストlexicon/tests/providers/test_valuedomain.pyを用意すれば基本的には終わりです。

あとはこのコードが正しいかどうか調べるためのユニットテストを通すために、tests/fixtures/cassettes以下にテスト用に通信を記録したファイルを配置しないといけないんですすが、これはルートフォルダにあるtox.ini

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
setenv =
PYTEST_ADDOPTS = {env:PYTEST_ADDOPTS:--numprocesses auto}
PYTHONHASHSEED = 0
LEXICON_VALUEDOMAIN_AUTH_TOKEN = <token>
LEXICON_LIVE_TESTS = true
setenv = PYTEST_ADDOPTS = {env:PYTEST_ADDOPTS:--numprocesses auto} PYTHONHASHSEED = 0 LEXICON_VALUEDOMAIN_AUTH_TOKEN = <token> LEXICON_LIVE_TESTS = true
setenv =
    PYTEST_ADDOPTS = {env:PYTEST_ADDOPTS:--numprocesses auto}
    PYTHONHASHSEED = 0
    LEXICON_VALUEDOMAIN_AUTH_TOKEN = <token>
    LEXICON_LIVE_TESTS = true

みたいな感じで書いとくと勝手に生成されるようになります(どこにも書いてなかったのでメモ)。ただし、結構ユニットテストの数が多くてレートリミットが掛かってしまうので気をつけて…。その時はレートリミットのせいでエラーになったテストのファイルだけ削除してテストを再実行すればOKです。ファイルを削除したテストだけ、実際のHTTPリクエストが発生するのでレートリミットが掛からなくなります。

toxがオールグリーンになったのでおしまい。次いこう次。

Certbotはほとんどlexiconに丸投げ

certbotに関してもほぼSakuraCloudプラグインをコピペしてvaluedomainにrenameしているだけです。正直いうとgrepしてsakuracloudの文字列がないか調べて片っ端からvaluedomainに書き換えてるだけに近しい。

びっくりするぐらいとくに何も言うことがない。おしまい。

Dockerがあるから自分で改造したコードを使うのが楽になった

コードを変更したら、それが取り入れられる前に自分の手元で簡単に動かして実際に使えるようになったので、楽な時代になったなぁと思いました(こなみかん)。Docker imageを作ってしまえば、冒頭に書いたように公式の用意したdockerイメージの名前を自前のものに書き換えるだけであとは同じように使えます。

昔だったら…そうさね、Virtualenvみたいなので済めばいいけど、サーバに色々細工して環境を汚しまくらないとダメだったかもわからんね…。