Let's Encryptを使ってHTTPSサーバの設定
2017年以降、iOSアプリからWebへの接続でHTTPSが必須になるなんて話を耳にしたので、今のところ(2016年7月)は不要でしたが、将来的に確実に必要になってくるだろうと思い、管理しているサーバをHTTPSに対応することにしました。
最初はHTTPSサーバに必要な証明書の種類すら知らず、証明書発行にはそこそこのお金がかかるものと思っていましたが、調べてみると「Let's Encrypt」を使って自動で簡単に、しかも無料で構築できるようで、管理しているサーバをhttps(暗号化に対応)に対応させたいだけなら問題ないみたいだったので、使ってみることにしました。
目次
- 環境
- 証明書の種類
- 必要なもの
- Let's Encryptクライアントのインストール
- 証明書の取得
- Apacheの設定
- 証明書の自動更新
環境
CentOS 6.3
Apache 2.2.15
証明書の種類
参考:SSLサーバ証明書の料金比較と選び方総まとめ | ServerKurabe
証明書の種類としては以下のように3種類あり、「Let's Encrypt」で使えるのはドメイン認証(DV)タイプ。
種類 | 価格 | 備考 |
---|---|---|
EV認証(EV) | 高い | 企業・法人向け、確認作業が厳しいので信頼性が高い |
組織認証(OV) | EVよりは割安 | 企業・法人向け |
ドメイン認証(DV) | 割安 | 主に個人向け |
必要なもの
HTTPSに対応させたいドメイン、Git、Openssl、Apache が必要。
自分の環境ではGitが入っていなかったので、下記を参考にインストール。
CentOSに最新版のGitをインストール・アップデートする方法 - TASK NOTES
なぜか最新のソースからインストールができず、最終的に「yum」でインストール。そのため、Gitのバージョンが「1.7.1」とだいぶ古かったですが、今回はとくに問題ありませんでした。
yum install git
git --version
# git version 1.7.1
Let's Encryptクライアントのインストール
クライアント「certbot」のインストール(場所はどこでもいい)。
cd /usr/local/
git clone https://github.com/certbot/certbot
続いて依存パッケージのインストール。
cd certbot/
./certbot-auto
自分の環境の場合、この依存パッケージのインストールで以下のようなエラーが出ました。
どうやらPythonのバージョンが古いらしく、原因と解決方法はこちらに記載されていました。(CentOS6でLet's Encryptを使おうとするとpython2.7が入らずに詰まる - PCがあれば何でもできる!)
上記のサイトに従って下記を実施。
# SCLをインストール
yum install centos-release-SCL
# python2.7 と scl utilsをインストール
yum update
yum install scl-utils python27 python27-scldevel
# python2.7をbash上で有効化
scl enable python27 bash
もう一度、依存パッケージのインストールを行うと問題なく完了。
証明書の取得
すでに公開しているサイトでサービスを止めたくなかったので「webroot」を使います。
./certbot-auto certonly --webroot -w /var/www/example -d example.com -m sample@example.com --agree-tos
成功時には以下のメッセージが表示されます。
完了後、設定に必要な各証明書のシンボリックリンクが「/etc/letsencrypt/live/example.com<ドメイン名>/」配下に保存されています。
Apacheの設定
「/etc/httpd/conf.d/ssl.conf」に以下の設定を追加または修正。
<VirtualHost *:443>
ServerName example.com
DocumentRoot "/var/www/example"
SSLEngine on
SSLHonorCipherOrder on
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
SSLProtocol all -SSLv2
SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
<Directory "/var/www/example">
Options FollowSymLinks
AllowOverride None
# it's only needed on Apache >=2.4
# Require all granted
</Directory>
SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
ErrorLog logs/ssl_error_log
CustomLog logs/ssl_access_log combined env=!nolog
</VirtualHost>
7行目「Header set Strict-Transport-Security」の設定について(http のリクエストが勝手に https にリダイレクトされるときは Strict-Transport-Security を疑おう - べにやまぶろぐ)
19行目「Require all granted」を有効にすると、自分の環境(Apache2.2)では、サイトにアクセスした際に「500 Internal Server Error」が発生しました。
その時のエラーログは以下の通り。
詳しくはこちら(Apache: "AuthType not set!" 500 Error - Stack Overflow)
証明書の自動更新
証明書の有効期間は取得後90日間となっていて定期的に更新する必要があるようなので、「/etc/crontab」に設定を追加します。毎月1日の朝6時に更新チェックを行うようにする場合は以下のとおり。
実行時はPythonのバージョンを毎回切り替える必要があるので「scl enable python27」を使用しています。