無料で使用できるSSL証明書「Let’s Encript」を導入して早2ヶ月。
Cronで自動更新するように設定していたのですが、とある日期限を知らせるメールが届きました。
Your certificate (or certificates) for the names listed below will expire in
19 days (on 06 Jul 17 14:52 +0000). Please make sure to renew
your certificate before then, or visitors to your website will encounter errors.
「あと19日で期限が切れるよ」とのことで自動更新に失敗したんだなーと思いつつ、それなら手動でやればいいかと軽く考えたものの、これが結構ハマりました。
Webrootで更新
Let’s Encriptの更新にはざっくり言うとスタンドアローンとウェブルートの2種類があります。
更新時に80番ポートを使用するので、スタンドアローンで更新する場合にはサーバを一度止める必要があります。
サーバが稼働した公開状態だと衝突してしまうからです。
一方、サーバを動かしたまま更新したい時にはウェブルートという方法を使用します。
ルートディレクトリに「.well-known」というフォルダを作っておいてその中で更新を行う事でポートの衝突を防ぐことができます。サーバを止めなくて良いので、こちらがオススメということになります。
更新は「/etc/letsencrypt/renewal/ドメイン名.conf」の中身を参照するので、その中身が「authenticator = webroot」となっていれば下記のコマンドを打った時にWebrootで更新してくれます。
しかしこれを打つと、下記のようなエラーが出ました。
検索して調べてみると、IPアドレスとDNSレコードが一致していない可能性があるとのこと。しかし、何年も前から稼働しているサーバとブログなのでそれは有り得ません。
SSL化した時にリダイレクトしたせいかなとか考えたものの80番も443番もちゃんと外部からアクセスできるし、ドキュメントルートのパスも間違えていない。どうしてかなーと色々試しながら調べていくこと数日。やっと原因っぽいものに辿り着きました。「.well-knownフォルダ」以下にアクセスできない状態になっているようです。
試しにテスト用のHTMLファイルを作成してアップロードし「https://mndangler.net/.well-known/test.html」を叩いてみると403が返ってきました。サーバがアクセスを拒否しています。
そこでやっと気が付きました。自分でやったNginxのセキュリティ設定のせいだ、と。
Nginxのdrop.confの設定で「.」から始まるファイルやフォルダへのアクセスを拒否していたのです。
そりゃ更新もできません。
Nginxの設定を見直す
drop.confの以下をコメントアウトしました。
drop.conf# .から始まるファイルの場合アクセスを拒否し、アクセスログ、Not foundログを無効にする
#location ~ /\. {
# deny all;
# access_log off;
# log_not_found off;
#}
続いて、server用の設定を書いているconfファイルに以下を追記しました。
参考にされる場合は、/your/webroot/pathの部分を各自のドキュメントルートにしてください。
server {
listen 80;
~ 略 ~
# cerbotのwebroot用
location ^~ /.well-known/acme-challenge/ {
root /your/webroot/path;
}
}
構文チェックをしてから、OKが出たらNginxをリロード。
Cerbotのディレクトリに移動して、いざ更新。
ドキドキしながら数秒待つと、やっと成功!
ここで終わってはいけません。サーバをリロードしないと反映されません。
これでブログを開いて証明書を確認すると、有効期限がちゃんと3ヶ月先になっていました。
結論
自分でやった、たいして意味のないセキュリティ強化が首を締める羽目になってしまいました。
今後はちゃんと自動更新できるように、今回いじった設定はそのまま残しておいて、2ヶ月後の更新を見守りたいと思います。