Let’sEncryptも今年3月に入りようやくワイルドカード証明書に対応しましたが、 一方でワイルドカード取得にはACMEv2のDNS-01 Challengeによるドメイン所有権確認が必須となりました。

頻繁に証明書更新が必要(最長でも90日)な上、DNSレコードの編集までとなるとあまりカジュアルじゃないですよね。 そこで今回はDNS-01に対応したACME Clientがないかと調べlegoを見つけたので紹介いたします。

なお、本日(2018/5/31)にリリースされたv1.0.0よりACMEv2対応になっています。

legoのいいところ

legoはGo言語で作られた、Let’sEncrypt用のACME Clientです。 Goで書かれただけあって、軽量なバイナリーファイルでリリースページより最新版を取得できます。

また、以下のDNSサービスに対応しており、--dnsオプションで指定したDNSサービスに対し、 自動で認証用のTXTレコードを追加し証明書を取得することができます。

# ./lego dnshelp
Credentials for DNS providers must be passed through environment variables.

Here is an example bash command using the CloudFlare DNS provider:

 $ CLOUDFLARE_EMAIL=foo@bar.com \
   CLOUDFLARE_API_KEY=b9841238feb177a84330febba8a83208921177bffe733 \
   lego --dns cloudflare --domains www.example.com --email me@bar.com run

Valid providers and their associated credential environment variables:

 azure:		AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_RESOURCE_GROUP
 auroradns:	AURORA_USER_ID, AURORA_KEY, AURORA_ENDPOINT
 bluecat:	BLUECAT_SERVER_URL, BLUECAT_USER_NAME, BLUECAT_PASSWORD, BLUECAT_CONFIG_NAME, BLUECAT_DNS_VIEW
 cloudxns:	CLOUDXNS_API_KEY, CLOUDXNS_SECRET_KEY
 cloudflare:	CLOUDFLARE_EMAIL, CLOUDFLARE_API_KEY
 digitalocean:	DO_AUTH_TOKEN
 dnsimple:	DNSIMPLE_EMAIL, DNSIMPLE_OAUTH_TOKEN
 dnsmadeeasy:	DNSMADEEASY_API_KEY, DNSMADEEASY_API_SECRET
 duckdns:	DUCKDNS_TOKEN
 exoscale:	EXOSCALE_API_KEY, EXOSCALE_API_SECRET, EXOSCALE_ENDPOINT
 gandi:		GANDI_API_KEY
 gandiv5:	GANDIV5_API_KEY
 gcloud:		GCE_PROJECT, GCE_SERVICE_ACCOUNT_FILE
 glesys:		GLESYS_API_USER, GLESYS_API_KEY
 linode:		LINODE_API_KEY
 lightsail:	AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, DNS_ZONE
 manual:		none
 namecheap:	NAMECHEAP_API_USER, NAMECHEAP_API_KEY
 namedotcom:	NAMECOM_USERNAME, NAMECOM_API_TOKEN
 rackspace:	RACKSPACE_USER, RACKSPACE_API_KEY
 rfc2136:	RFC2136_TSIG_KEY, RFC2136_TSIG_SECRET,
     RFC2136_TSIG_ALGORITHM, RFC2136_NAMESERVER
 route53:	AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_HOSTED_ZONE_ID
 dyn:		DYN_CUSTOMER_NAME, DYN_USER_NAME, DYN_PASSWORD
 vultr:		VULTR_API_KEY
 ovh:		OVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY
 pdns:		PDNS_API_KEY, PDNS_API_URL
 dnspod:		DNSPOD_API_KEY
 otc:		OTC_USER_NAME, OTC_PASSWORD, OTC_PROJECT_NAME, OTC_DOMAIN_NAME, OTC_IDENTITY_ENDPOINT
 exec:		EXEC_PATH

For a more detailed explanation of a DNS provider's credential variables,
please consult their online documentation.

使い方

ここでは私の環境がroute53なので、route53を利用した例を記述していきます。
なお、DNS-01の認証は認証用のTXTレコードを参照するため、クライアントPCなどからでも証明書の作成が可能です。

route53の操作ができるIAMユーザを作成する

作業詳細は記述しませんが、route53に対して承認用TXTレコードの追加・削除ができるユーザが必要になります。 なお、readme上では環境変数としてAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGIONを 指定していますが、aws configureで作成したcredentialsでも問題なく動作します。

実行コマンド

新規作成

lego --accept-tos \
     --path=/etc/letsencrypt \
     --server="https://acme-v02.api.letsencrypt.org/directory" \
     --email="admin@eksy.tokyo" \
     --dns="route53" \
     --domains="*.eksy.tokyo" \
     --domains="eksy.tokyo" \
     run

少し説明を付け加えると、--pathオプションで指定したディレクトリに証明書や鍵ファイルを出力します。 なお、デフォルトだとカレントディレクトリの.lego/配下に出力されます。
また、--server="https://acme-v02.api.letsencrypt.org/directory"にてACMEv2を利用するように指定します。

※2018/6/1(の朝)にリリースされたv1.0.1ではACMEv2がデフォルトになったようです

更新

lego --accept-tos \
     --path=/etc/letsencrypt \
     --server="https://acme-v02.api.letsencrypt.org/directory" \
     --email="admin@eksy.tokyo" \
     --dns="route53" \
     --domains="*.eksy.tokyo" \
     --domains="eksy.tokyo" \
     renew

更新時はrenewでコマンドを実行します。上記コマンドには記載しませんでしたが、--daysオプションを指定することで 有効期限残忍数が指定の日数以下になった時に実行するようにすることもできます。

感想

legoにいきあたる前に、certbotのプラグインでroute53対応もできるようなネタがあったのですが、pip installしてとか Pythonのバージョンとか色々面倒だったのですが、さすがはGo言語で書かれているだけのことはあるなぁと。

なお、使い方の詳細については プロジェクトページ の方をご覧ください。

参考

以上。