[Sy] Amazon Linux(2017.09 release) + Nginx の環境で Let's Encrypt の SSL/TLS 証明書を自動更新する設定
前回は、無料SSL/TLS証明書 Let’s Encrypt を使って Amazon Linux + Nginx 環境でHTTPSの設定を行いました。今回は 自動更新 の設定について説明します。
前回の記事はこちら。
⇒ [Sy] Amazon Linux(2017.09 release) + Nginx の環境で Let's Encrypt の SSL/TLS 証明書を取得して HTTPS の設定をする手順0. 更新前の証明書の状態を確認
まずは現状の確認 をしましょう。前回の記事で取得した証明書を見に行きます。
ec2-user
として SSH でログインします。
証明書があるディレクトリ(/etc/letsencrypt
)は root 権限がないと入れないので、
$ sudo su
で root に切り替えます。(以降#
が頭についているのは root での操作を表します)
続けて、/etc/letsencrypt/archive/[対象のドメイン]
というディレクトリがあるはずなので、そこへ移動してファイルを確認します。
例として、lets-test.utano.me
の証明書であれば、ここにあります。
# cd /etc/letsencrypt/archive/lets-test.utano.me/
# ll
total 16
-rw-r--r-- 1 root root 1805 Oct 20 12:02 cert1.pem
-rw-r--r-- 1 root root 1647 Oct 20 12:02 chain1.pem
-rw-r--r-- 1 root root 3452 Oct 20 12:02 fullchain1.pem
-rw-r--r-- 1 root root 1704 Oct 20 12:02 privkey1.pem
さらに、ここにあるファイルは以下のとおり /etc/letsencrypt/live/[対象のドメイン]
という別のディレクトリ内に、シンボリックリンクがつくられてます。
# cd /etc/letsencrypt/live/lets-test.utano.me/
# ll
total 4
lrwxrwxrwx 1 root root 42 Oct 20 12:02 cert.pem -> ../../archive/lets-test.utano.me/cert1.pem
lrwxrwxrwx 1 root root 43 Oct 20 12:02 chain.pem -> ../../archive/lets-test.utano.me/chain1.pem
lrwxrwxrwx 1 root root 47 Oct 20 12:02 fullchain.pem -> ../../archive/lets-test.utano.me/fullchain1.pem
lrwxrwxrwx 1 root root 45 Oct 20 12:02 privkey.pem -> ../../archive/lets-test.utano.me/privkey1.pem
-rw-r--r-- 1 root root 543 Oct 20 12:02 README
この live
ディレクトリにある privkey1.pem
と fullchain.pem
を nginx
の設定ファイルで指定してあげることで、HTTPS で通信できるようになっています。 (nginx
の設定については、前回記事を参照してください)
確認が終わったので、一旦 ec2-user
での操作に戻ります。
# exit
1. cron を使って自動更新のコマンドを実行する
ではいよいよ更新をしてみます。以下のコマンドで cron の設定を記述します。
$ crontab -e
vim
と同じように操作できます。i
を押すなりして、入力モードに切り替え、以下のように1行コマンドのスケジュールを記述します。
(「保存してください」と下に書いてるので、そこまでは保存はしないでそのまま読み進めてください)
*/5 * * * * sudo /home/ec2-user/certbot-auto renew --force-renew --debug --nginx && sudo service nginx restart
cron についての細かい説明は今回は省略しますが、この例だと、「分を5で割り切れる時」=「5,10,…,55分の時」に実行する、というスケジューリングになります。
設定したコマンドは2つに分かれていて、
$ sudo /home/ec2-user/certbot-auto renew --force-renew --debug --nginx
$ sudo service nginx restart
というコマンドを連続で実行することになります。
1つ目のコマンドの certbot-auto renew
という部分が 自動更新 のための基本コマンドです。
その基本コマンドに、 前回の取得時と同様に --debug
と --nginx
オプションを忘れずに付けます。
さらに、 通常更新日時が近づいてきてないと自動更新できないようになっているので、 強制的に更新するために --force-renew
オプションを付けます。
ということで、1つ目のコマンドで 証明書の更新自体はできます。
ただ、更新された証明書を nginx
に改めて読み込ませる必要があるので、2つ目のコマンドで nginx
を再起動しているわけです。
この2つのコマンド(証明書の更新+ngins
再起動)を組み合わせ、それを cron
で自動で実行することで、証明書の定期的な自動更新ができるようになります。
では、 cron
の設定を保存してください。
そしてすぐに以下のコマンドを入力して cron のログを監視しながら数分待ちます。
$ sudo tail -f /var/log/cron
こんな感じのログが表示され、リアルタイムで追記されていきます。
Oct 21 01:01:01 ip-10-0-0-153 run-parts(/etc/cron.hourly)[30266]: starting 0anacron
Oct 21 01:01:01 ip-10-0-0-153 anacron[30275]: Anacron started on 2017-10-21
Oct 21 01:01:01 ip-10-0-0-153 anacron[30275]: Jobs will be executed sequentially
Oct 21 01:01:01 ip-10-0-0-153 anacron[30275]: Normal exit (0 jobs run)
Oct 21 01:01:01 ip-10-0-0-153 run-parts(/etc/cron.hourly)[30277]: finished 0anacron
Oct 21 01:22:33 ip-10-0-0-153 crontab[30375]: (ec2-user) BEGIN EDIT (ec2-user)
Oct 21 01:23:30 ip-10-0-0-153 crontab[30375]: (ec2-user) REPLACE (ec2-user)
Oct 21 01:23:30 ip-10-0-0-153 crontab[30375]: (ec2-user) END EDIT (ec2-user)
Oct 21 01:23:37 ip-10-0-0-153 crontab[30378]: (ec2-user) BEGIN EDIT (ec2-user)
Oct 21 01:23:51 ip-10-0-0-153 crontab[30378]: (ec2-user) END EDIT (ec2-user)
しばらく待っていると、1行ログが追記されます。
Oct 21 01:25:01 ip-10-0-0-153 CROND[30384]: (ec2-user) CMD (sudo /home/ec2-user/certbot-auto renew --force-renew --debug --nginx && sudo service nginx restart)
cron
によって先ほどのコマンドが実行されたことがわかります。
では処理がうまくいったのか確認しにいきましょう。
Ctrl + C
でログの監視を終了します。
2. 自動更新処理の結果を確認
数分待っていると、以下のようなメッセージがターミナル上に表示されます。(出てこなくても気にしなくて良いです)
You have new mail in /var/spool/mail/ec2-user
これは、デフォルトだと cron
の実行ログがそのユーザ宛にメールとして送られてくるという設定になっているので、先ほど実行された自動更新処理のログが送られてきたためです。
では中身を見てみましょう。
$ less /var/spool/mail/ec2-user
ファイルが開けたら、次のようなメール形式(From〜から始まる形)でのテキストが確認できるはずです。
ちょっと見づらいですが、まずチェックすべきなのは、 From〜の行末にある時間 です。
この例だと Sat Oct 21 01:25:13 2017
となっており、先ほど cron
の処理が流れた時間と一致します。
一致する時間のメールが見つかれば、その本文(X-Cron-Env:
という行の終わったあとあたりから)がログになるので、見てみます。
From root@ip-10-0-0-153.ap-northeast-1.compute.internal Sat Oct 21 01:25:13 2017
Return-Path: <root@ip-10-0-0-153.ap-northeast-1.compute.internal>
Received: from ip-10-0-0-153.ap-northeast-1.compute.internal (localhost [127.0.0.1])
by ip-10-0-0-153.ap-northeast-1.compute.internal (8.14.4/8.14.4) with ESMTP id v9L1PDQr030468
for <ec2-user@ip-10-0-0-153.ap-northeast-1.compute.internal>; Sat, 21 Oct 2017 01:25:13 GMT
Received: (from ec2-user@localhost)
by ip-10-0-0-153.ap-northeast-1.compute.internal (8.14.4/8.14.4/Submit) id v9L1P2Hh030430;
Sat, 21 Oct 2017 01:25:02 GMT
Date: Sat, 21 Oct 2017 01:25:02 GMT
Message-Id: <201710210125.v9L1P2Hh030430@ip-10-0-0-153.ap-northeast-1.compute.internal>
X-Authentication-Warning: ip-10-0-0-153.ap-northeast-1.compute.internal: ec2-user set sender to root using -f
From: root@ip-10-0-0-153.ap-northeast-1.compute.internal (Cron Daemon)
To: ec2-user@ip-10-0-0-153.ap-northeast-1.compute.internal
Subject: Cron <ec2-user@ip-10-0-0-153> sudo /home/ec2-user/certbot-auto renew --force-renew --debug --nginx && sudo service nginx restart
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ec2-user>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ec2-user>
X-Cron-Env: <USER=ec2-user>
(↓ここから本文)
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for lets-test.utano.me
Waiting for verification...
Cleaning up challenges
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/lets-test.utano.me.conf
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/lets-test.utano.me/fullchain.pem
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/lets-test.utano.me/fullchain.pem (success)
-------------------------------------------------------------------------------
Stopping nginx: [ OK ]
Starting nginx: [ OK ]
前回の証明書取得のときと同じようなログが確認できます。Congratulations, ...
とあるように、成功したようです。
そして最後の2行で、nginx
の再起動を行ってるのも確認できます。
続いて、この記事の最初に確認した /etc/letsencrypt/
ディレクトリの下のファイルはどうなっているか見てみます。
先ほどと同じように、 root に切り替えてから、
$ sudo su
まずは archive
ディレクトリの方を見てみます。
# cd /etc/letsencrypt/archive/lets-test.utano.me/
# ll
total 32
-rw-r--r-- 1 root root 1805 Oct 20 12:02 cert1.pem
-rw-r--r-- 1 root root 1805 Oct 21 01:25 cert2.pem
-rw-r--r-- 1 root root 1647 Oct 20 12:02 chain1.pem
-rw-r--r-- 1 root root 1647 Oct 21 01:25 chain2.pem
-rw-r--r-- 1 root root 3452 Oct 20 12:02 fullchain1.pem
-rw-r--r-- 1 root root 3452 Oct 21 01:25 fullchain2.pem
-rw-r--r-- 1 root root 1704 Oct 20 12:02 privkey1.pem
-rw-r--r-- 1 root root 1704 Oct 21 01:25 privkey2.pem
cron
が実行された時間でそれぞれ xxxx2.pem
というファイルが新しく作成されているのがわかります。これが更新された証明書たちになります。
続いて、 live
ディレクトリの方を見てみます。
# cd /etc/letsencrypt/live/lets-test.utano.me/
# ll
total 4
lrwxrwxrwx 1 root root 42 Oct 21 01:25 cert.pem -> ../../archive/lets-test.utano.me/cert2.pem
lrwxrwxrwx 1 root root 43 Oct 21 01:25 chain.pem -> ../../archive/lets-test.utano.me/chain2.pem
lrwxrwxrwx 1 root root 47 Oct 21 01:25 fullchain.pem -> ../../archive/lets-test.utano.me/fullchain2.pem
lrwxrwxrwx 1 root root 45 Oct 21 01:25 privkey.pem -> ../../archive/lets-test.utano.me/privkey2.pem
-rw-r--r-- 1 root root 543 Oct 20 12:02 README
見事に、更新前は xxxx1.pem
というファイルを参照していたのが、 xxxx2.pem
というファイルに切り替わっています。
このようにシンボリックリンクの自動切り替えをしてくれているため、 nginx
の設定ファイルはまったく触る必要がないわけです。
では最後にブラウザ上(Chrome)でも証明書の有効期限が更新されていることを確認します。
Developer Tools を起動し、「Security」タブを開き「View certificate」ボタンをクリックします。
すると Expires(有効期限)が更新した時間の3ヶ月後くらいになっているかと思います。
(本来ちゃんと3ヶ月後になるはずですが、タイムゾーンの設定次第でちょっとずれて見えます)
以上で確認まで終了です。
ターミナルに戻り、 root から抜けておいてください。
# exit
3. cron のスケジューリングを本来やりたい間隔に変更する
先ほどはテストのために5分間隔で更新処理をスケジューリングしましたが、実際はそんなに細かくする必要はないので、例えば1ヶ月ごと(UTCで毎月1日の0時5分)に更新するなど、適切な間隔にしておきましょう。
以下のコマンドで設定を編集します。
$ crontab -e
「毎月1日の0時5分」であれば、このように書けばOKです。
05 00 01 * * sudo /home/ec2-user/certbot-auto renew --force-renew --debug --nginx && sudo service nginx restart
念のため、最初の1,2ヶ月は更新時間の直後にチェックすると良いでしょう。