タイトルの通りですが、社内で利用するRedmineサーバを外部公開したついでにSSL化して、その際のサーバ証明書を無料のLet's Encryptを使用することにしました。メモがてら証明書作成・実装から自動更新設定までを紹介します。
Let's Encrypt 導入
環境は以下です。
・CentOS7.2
・Apache 2.4.6
今回、プライグインはWebroot プラグインを使用します。
プラグインは、サーバ証明書を
- どのように取得するか
- どのようにインストールするか
その方法によってどのプラグインを使うかを決めます。Webroot以外には、Apache/Nginx/Standalone/manual などがあります。
Webrootプラグインは、サーバ証明書取得・更新時に動作中のWebサーバを停止する必要はありませんが、証明書を取得するドメインを運用しているWebサーバ上で取得・更新処理を実行する必要があります。詳しい説明は以下。
https://letsencrypt.jp/docs/using.html#webroot
certbot のインストール
SSL・TLS証明書の取得はCertbotクライアントをインストールする必要があります。
epel リポジトリの追加後にyumでインストールが可能です。
1 2 |
# yum install epel-release # yum install certbot |
証明書の取得
証明書の取得は以下のコマンドで可能です。
1 2 3 4 5 6 7 8 9 10 11 12 |
# certbot certonly --webroot -w /var/lib/redmine/public -d pig-log.com ------------------------------------------------------------------------------- Saving debug log to /var/log/letsencrypt/letsencrypt.log Enter email address (used for urgent renewal and security notices) (Enter 'c' tocancel):xxx@gmail.com # メールアドレスを入力 Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org ------------------------------------------------------------------------------- Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights. ------------------------------------------------------------------------------- (Y)es/(N)o: N #メールアドレスを共有してもよいか |
certonly で証明書取得のみとなります。
--webroot でプラグインを指定します。
-w(--webroot-path) でドキュメントルートを指定します。
-d でドメインを指定します。
コマンドを実行すると、メールアドレスの入力を求められるので、何かあったときの通知先メールアドレスを入力します。その後、そのメールアドレスを共有してもよいか聞かれるので、Y or N を入力します。
しばらくすると以下のようにサーバ証明書や秘密鍵の取得が完了します。
1 2 3 4 5 6 7 8 9 10 11 12 |
# ls -l `pwd`/* -rw-r--r-- 1 root root 543 Jul 31 18:10 /etc/letsencrypt/live/pig-log.com/README lrwxrwxrwx 1 root root 53 Jul 31 18:10 /etc/letsencrypt/live/pig-log.com/cert.pem -> ../../archive/pig-log.com/cert1.pem lrwxrwxrwx 1 root root 54 Jul 31 18:10 /etc/letsencrypt/live/pig-log.com/chain.pem -> ../../archive/pig-log.com/chain1.pem lrwxrwxrwx 1 root root 58 Jul 31 18:10 /etc/letsencrypt/live/pig-log.com/fullchain.pem -> ../../archive/pig-log.com/fullchain1.pem lrwxrwxrwx 1 root root 56 Jul 31 18:10 /etc/letsencrypt/live/pig-log.com/privkey.pem -> ../../archive/pig-log.com/privkey1.pem # ls -l `pwd`/* -rw-r--r-- 1 root root 1834 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/cert1.pem -rw-r--r-- 1 root root 1647 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/chain1.pem -rw-r--r-- 1 root root 3481 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/fullchain1.pem -rw-r--r-- 1 root root 1704 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/privkey1.pem |
/etc/letsencrypt/live/DomaiName/ というディレクトリにサーバ証明書などへのシンボリックリンクが保存され、実体は、/etc/letsencrypt/archive/DomaiName/ に保存されます。
シンボリックリンクが作成されるのは、詳しくは後述しますが、更新時に実体のファイルが、1,2,3.pem…と連番で作成されるためです。(ssl.conf の証明書設置パスを変更する必要がない)
設定ファイル編集
証明書を発行できたので、設定ファイルに設置パスを記述します。今回はApacheへの設定となります。
1 2 3 |
SSLCertificateFile /etc/letsencrypt/live/pig-log.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/pig-log.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/pig-log.com/chain.pem |
設定を反映します。
1 |
# systemctl restart httpd |
以上で反映されているはずです。https://DomainName へアクセスして証明書を確認してみます。
更新
Let's Encrypt のサーバ証明書は有効期限が3ヶ月となっているため、結構短いスパンでの更新が必要となります。が、自動更新の機能がサポートされています。便利ですね。
以下のコマンド1発で更新が可能です。
1 |
# certbot renew |
実行したところ、「まだ、更新される予定ではありません」とのことでスキップされてしまった。。。
1 2 3 |
The following certs are not due for renewal yet: /etc/letsencrypt/live/pig-log.com/fullchain.pem (skipped) No renewals were attempted. |
調べてみると、有効期限が残り30日未満でないと更新されないらしい。ただ、強制オプションがあるので試してみた。
1 |
# certbot renew --force-renew |
出力されたメッセージを見ると無事に更新されたようなので、取得した実体ファイルを見てみると、末尾に2と付いたファイル群が出来上がってますね。
1 2 3 4 5 6 7 8 9 |
# ls -ltr `pwd`/* -rw-r--r-- 1 root root 1704 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/privkey1.pem -rw-r--r-- 1 root root 1834 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/cert1.pem -rw-r--r-- 1 root root 3481 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/fullchain1.pem -rw-r--r-- 1 root root 1647 Jul 31 18:10 /etc/letsencrypt/archive/pig-log.com/chain1.pem -rw-r--r-- 1 root root 1704 Aug 10 13:20 /etc/letsencrypt/archive/pig-log.com/privkey2.pem -rw-r--r-- 1 root root 3481 Aug 10 13:20 /etc/letsencrypt/archive/pig-log.com/fullchain2.pem -rw-r--r-- 1 root root 1647 Aug 10 13:20 /etc/letsencrypt/archive/pig-log.com/chain2.pem -rw-r--r-- 1 root root 1834 Aug 10 13:20 /etc/letsencrypt/archive/pig-log.com/cert2.pem |
次にリンクの向き先を見てみると、しっかり末尾2のファイルに向いています。
1 2 3 4 5 6 |
# ll `pwd`/* -rw-r--r-- 1 root root 543 Jul 31 18:10 /etc/letsencrypt/live/pig-log.com/README lrwxrwxrwx 1 root root 53 Aug 10 13:20 /etc/letsencrypt/live/pig-log.com/cert.pem -> ../../archive/pig-log.com/cert2.pem lrwxrwxrwx 1 root root 54 Aug 10 13:20 /etc/letsencrypt/live/pig-log.com/chain.pem -> ../../archive/pig-log.com/chain2.pem lrwxrwxrwx 1 root root 58 Aug 10 13:20 /etc/letsencrypt/live/pig-log.com/fullchain.pem -> ../../archive/pig-log.com/fullchain2.pem lrwxrwxrwx 1 root root 56 Aug 10 13:20 /etc/letsencrypt/live/pig-log.com/privkey.pem -> ../../archive/pig-log.com/privkey2.pem |
そして、Webブラウザで確認してみると、、、証明書の有効期間が変わっていません。(10日ほど前に実装したので日付は変わるはずなのに。。。)
そういえば、Apacheの再起動をしていませんでした。設定ファイルを変更したわけではないので、忘れてました。。。
1 |
# systemctl restart httpd |
再起動後、Webで確認すると、ちゃんと有効期限が更新されていました。
じゃあ、定期的にCronで回すとしても、スクリプトにはApacheのリスタートも書かないといけないなぁ、と思っていたらありましたよ便利なオプションが。
--post-hook というオプションで証明書更新後に実行するコマンドを指定できます。ちなみに、--pre-hook を使用すると更新の前に実行するコマンドを指定できます。これは、更新時にWebサーバの停止が必要になる Standalone プラグインを使用する場合に使うみたいですね。今回は停止不要の Webroot プラグインを使用しているので、--post-hook のみを使用します。
1 |
# certbot renew --force-renew --post-hook "systemctl restart httpd" |
実行した結果抜粋が以下。ちゃんと更新されてリスタートも実行されているようです。実体のファイルも末尾が3で作成されていました。リンクの向き先も変更されていました。
1 2 3 |
Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/pig-log.com/fullchain.pem (success) Running post-hook command: systemctl restart httpd |
自動更新
Cronで実行するタイミングですが、毎週1回日曜日の夜間くらいに実行させておけばよいと思います。実行させるコマンドは以下。
1 |
# certbot renew --post-hook "systemctl restart httpd" |
強制しないことで、有効期限が30日未満となった際だけ更新されます。--post-hook オプションで指定するApacheリスタートコマンドも更新されるときにしか実行されません。
逆に、強制にしてしまうとタイミングの計算が面倒ですし、更新のし過ぎは、取得数の制限に引っかかってしまうこともあるようです。1サイト程度では大丈夫なようですが、余計な負荷はかけたくないですね。制限についての詳細は以下。
https://letsencrypt.jp/faq/#RateLimiting
以上です。
↓↓↓ 持っていると便利な一冊。