【Let’s Encrypt / KUSANAGI】SSL証明書の自動更新ができず、苦労した話

こんにちはー、ニアです。

本サイトでは、Let’s Encryptを使用しており、自動更新をしていたのですが、その自動更新に問題があったようで、本日未明から、朝方にかけて本サイトで証明書エラー(有効期限切れ)が発生する状態になっていました。

現在は、本サイトのSSL証明書を更新が完了し、正常にアクセスできるようになりました。

1. 自動更新に失敗していた

Let’s Encryptのログ(/var/log/letsencrypt/letsencrypt.log)を見てみると、証明書の更新中にエラーが発生して失敗していたことが分かりました。

2016-10-25 21:49:16,089:DEBUG:certbot.main:certbot version: 0.9.3
2016-10-25 21:49:16,089:DEBUG:certbot.main:Arguments: ['--noninteractive', '--webroot', '-w', '/home/kusanagi/chronoir_kusanagi/DocumentRoot', '-d', 'chronoir.net', '-d', 'www.chronoir.net', '-m', '[メールアドレス]', '--agree-tos']
 中略
2016-10-25 21:49:16,438:DEBUG:certbot.main:Exiting abnormally:
Traceback (most recent call last):
  中略
MissingCommandlineFlag: Missing command line flag or config entry for this setting:
You have an existing certificate that contains a portion of the domains you requested (ref: /etc/letsencrypt/renewal/chronoir.net.conf)

It contains these names: chronoir.net

You requested these names for the new certificate: chronoir.net, www.chronoir.net.

Do you want to expand and replace this existing certificate with the new certificate?

(You can set this with the --expand flag)

こちらは、7月28日の自動更新した時のログです。

2016-07-27 18:07:37,298:DEBUG:certbot.main:certbot version: 0.8.1
2016-07-27 18:07:37,298:DEBUG:certbot.main:Arguments: ['--webroot', '-w', '/home/kusanagi/chronoir_kusanagi/DocumentRoot', '-d', 'chronoir.net', '--renew-by-default']
 中略
2016-07-27 18:07:42,867:INFO:certbot.reporter:Reporting to user: Congratulations! Your certificate and chain have been saved at [fullchain.pem]. Your cert will expire on 2016-10-25. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew"

2行目のJSONデータに注目してみると、10月の自動更新の時では、パラメーターにwww付きのドメインが加わっていることが分かります。

本サイトの場合、Let’s Encryptで最初に取得した時に、wwwなしのドメインのみを登録していました。なのでおそらく、登録されていないドメインを参照したことで、正しく更新できなかったと考えられます。

1.1. KUSANAGI 8.0.0から、SSL周りの処理の仕方が変わっていた件

以下の2つの条件を満たすとき、kusanagi provision で www.example.com と example.com のどちらかを FQDN に指定すると、www.example.com と example.com の両方を VirtualHost として設定します。

  • www.example.com と example.com の両方が、DNS のAレコードに登録されている
  • exmaple.com が whois情報に登録されている

また上記の FQDN の指定に加え、メールアドレスを指定して Let’s EncryptでSSL証明書を取得したとき、www.example.com と example.com の両方を登録したSSL証明書を取得します。

KUSANAGI バージョンアップ情報 8.0.0-2」より引用

本サイトの場合、

  • お名前.comのDNSのAレコードに、chronoir.netとwww.chronoir.netの2つを登録している
  • chronoir.netはwhois情報に登録済み

と、2つの条件を満たしていたので、メールアドレスを指定して Let’s EncryptでSSL証明書を取得処理時に、www付きのドメインも含めていたのです。

2. 解決方法

2.1. certbotを直接叩く

今回は、KUSANAGIのコマンドではなくcertbotのコマンドを直接実行することで、取得時に登録したwwwなしのドメインのSSL証明書を更新できました。

certbot-auto renew」を実行すると、取得済みの証明書の中で有効期限が残り30日未満のものを更新します。

/usr/local/certbot/certbot-auto renew

Saving debug log to /var/log/letsencrypt/letsencrypt.log

(中略)

Congratulations, all renewals succeeded. The following certs have been renewed:
  (中略) (success)

あとは、nginxを再起動することで、証明書のエラーを解決することができました。

kusanagi nginx

2.2. KUSANAGIのシェルスクリプトを編集する

非推奨ですが、KUSANAGIのシェルスクリプトを編集して、www付きのドメインを除外するという手もあります。

「/usr/lib/kusanagi/lib/ssl.sh」を開きます。

if [ "" != "$MAILADDR" ] && [ -e /usr/local/certbot/certbot-auto ]; then
	# create lets encrypt.
	is_root_domain $FQDN
	local RET=$?
	if [ "$RET" -eq 0 ] ; then
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -d www.$FQDN -m $MAILADDR --agree-tos
	elif [ "$RET" -eq 1 ] ; then
		local APEX=`echo $FQDN | cut -c 5-`
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $APEX -d www.$APEX -m $MAILADDR --agree-tos
	else
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -m $MAILADDR --agree-tos
	fi

	# 中略
fi

上のコードでの6行目の文から「-d www.$FDQN」を、9行目の文から「-d www.$APEX」取り除きます。

if [ "" != "$MAILADDR" ] && [ -e /usr/local/certbot/certbot-auto ]; then
	# create lets encrypt.
	is_root_domain $FQDN
	local RET=$?
	if [ "$RET" -eq 0 ] ; then
		#/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -d www.$FQDN -m $MAILADDR --agree-tos
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -m $MAILADDR --agree-tos
	elif [ "$RET" -eq 1 ] ; then
		local APEX=`echo $FQDN | cut -c 5-`
		#/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $APEX -d www.$APEX -m $MAILADDR --agree-tos
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $APEX -m $MAILADDR --agree-tos
	else
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -m $MAILADDR --agree-tos
	fi

	# 中略
fi

こうすることで、SSL証明書の取得時にwwwなしのドメインのみを対象にすることができます。

2.3. 証明書にwww付きのドメインを追加登録

今回のケースの場合、wwwなしのみのドメインから、wwwなしとwww付きの両方のドメインを証明書に登録する必要があるということなので、「/usr/lib/kusanagi/lib/ssl.sh」を開き、下のコードでいう6行目の文に「–expand」を追加します。

if [ "" != "$MAILADDR" ] && [ -e /usr/local/certbot/certbot-auto ]; then
	# create lets encrypt.
	is_root_domain $FQDN
	local RET=$?
	if [ "$RET" -eq 0 ] ; then
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -d www.$FQDN -m $MAILADDR --agree-tos --expand
	elif [ "$RET" -eq 1 ] ; then
		local APEX=`echo $FQDN | cut -c 5-`
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $APEX -d www.$APEX -m $MAILADDR --agree-tos
	else
		/usr/local/certbot/certbot-auto certonly --noninteractive --webroot -w $KUSANAGI_DIR/DocumentRoot -d $FQDN -m $MAILADDR --agree-tos
	fi

	# 中略
fi

これで、www付きのドメインを含めた証明書を取得できると思いきや、まさかの404エラーで認証失敗・・・。

2016-10-26 01:25:08,870:DEBUG:certbot.main:Exiting abnormally:
Traceback (most recent call last):
  (中略)
FailedChallenges: Failed authorization procedure. www.chronoir.net (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.chronoir.net/.well-known/acme-challenge/...<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>"

そこで、「/etc/nfinx/conf.d/[プロファイル名]_http.conf」を編集し、www付きのドメインからHTTPアクセスできるようにしたら、SSL証明書を取得できるようになりました。

server {
	listen 80;
	server_name chronoir.net;

	# ...
}

server {
	listen 80;
	server_name www.chronoir.net;

	# ...
}

3. おわりに

今回は、Let’s EncryptのSSL証明書の更新エラーを解決し、本サイトのSSL証明書を再び有効にすることができました。

ちなみに、SSL証明書の更新後にQualys’ SSL LABSのSSLテストを実行すると、A+評価が出ました!ひとまず、一件落着です。

ssl2

参考サイト

[END]

コメント

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