DNS-01を使ったワイルドカード証明書の取得

ワイルドカード証明書を利用できるようにDNS-01を利用した取得を試す。

現在利用しているMyDNS.jpではLet's Encrypt用API「DirectEdit/txtregist.php at master · disco-v8/DirectEdit · GitHub」を公開しているが、php環境を導入していない(導入したくない)ため利用できない。

見たところ、単にcertbotが送ってくるパラメータに応じて、MyDNS.jpへコマンドやパラメータをPOSTするだけで良いようなので、使い慣れたRubyで書き直す。

#!/usr/local/bin/ruby
# encoding: utf-8

require 'net/http'
require 'base64'

module DNS01
	def self.buildPostData(mode)
		data = {}
		[
			'CERTBOT_DOMAIN',
			'CERTBOT_VALIDATION',
			'CERTBOT_TOKEN',
			'CERTBOT_CERT_PATH',
			'CERTBOT_KEY_PATH',
			'CERTBOT_SNI_DOMAIN',
			'CERTBOT_AUTH_OUTPUT'
		].each {|env_name| data[env_name] = ENV[env_name]}
		data['EDIT_CMD'] = mode
		return data
	end

	def self.createSession(url, is_output = $false)
		uri = URI.parse(url)
		http = Net::HTTP.new(uri.host, uri.port)
		http.set_debug_output $stderr if is_output
		http.use_ssl = true
		http.start
		return http
	end

	def self.buildPostRequest(url, id, pwd, post_data)
		request = Net::HTTP::Post.new(url)
		request['Content-Type'] = 'application/x-www-form-urlencoded'
		request['Authorization'] = "Basic #{Base64.encode64(id+':'+pwd).strip}"
		request.body = URI.encode_www_form(post_data)
		return request
	end

	def done(mode, id, pwd)
		url = "https://www.mydns.jp/directedit.html"
		post_data = buildPostData(mode)
		http = createSession(url, $true)
		response = http.request(buildPostRequest(url, id, pwd, post_data))
		p response.body
		return response.code == 200
	end

	module_function :done
end

DNS01::done(ARGV[0], ARGV[1], ARGV[2])

これをdns01.rbとして保存し、同じディレクトリで以下のshell scriptも作成する。

※冒頭の変数は実行環境に応じて変更する。

#!/bin/sh

id=[your mydns master_id]
pwd=[your mydns master_password]
domain=[your domain]
email=[your e-mail]

hook_script=dns01.rb
certbot=/usr/local/bin/certbot
ruby=/usr/local/bin/ruby

cd `dirname $0`
${certbot} certonly --manual --preferred-challenges=dns \
--manual-auth-hook "${ruby} ${hook_script} REGIST ${id} ${pwd}" \
--manual-cleanup-hook "${ruby} ${hook_script} DELETE ${id} ${pwd}" \
-d ${domain} -d *.${domain} \
--server https://acme-v02.api.letsencrypt.org/directory \
--agree-tos -m ${email} \
--manual-public-ip-logging-ok

ここではregist_dns01.shとして保存し、これを実行すると実行状況がずらずらと表示される。

# sh ./regist_dns01.sh
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for [your domain]

:省略:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /usr/local/etc/letsencrypt/live/[your domain]/fullchain.pem
   Your key file has been saved at:
   /usr/local/etc/letsencrypt/live/[your domain]/privkey.pem
   Your cert will expire on ####-##-##. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

一応、確認。

# certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: [your domain]
    Serial Number: ###################################
    Domains: [your domain] *.[your domain]
    Expiry Date: ####-##-## ##:##:##+00:00 (VALID: ## days)
    Certificate Path: /usr/local/etc/letsencrypt/live/[your domain]/fullchain.pem
    Private Key Path: /usr/local/etc/letsencrypt/live/[your domain]/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

ワイルドカード対応の証明書が生成された。

あとはこれを良しなにする。