【初心者向け】AWS上でのブログシステム構築16 Let’s Encryptを用いたSSLの設定

本記事も今回で最後になります。最初に書き始めたときは10回ぐらいかかるかな、と思っていましたが、意外と書きたいことが多く、蓋を開けると全16回と約1.5倍の分量になってしまいました。。。

それはさておき、最終回である今回は、ブログシステムとブラウザ間の設定を暗号化するSSLの設定について説明したいと思います。

なお、SSLの設定は、以下AWSの公式サイトの記載を参考にしました。

チュートリアル: Amazon Linux で SSL/TLS を使用できるように Apache ウェブサーバーを設定する

<スポンサーリンク>

セキュリティグループの設定

通常、Webサーバーと通信を行うためには、”http”という通信方法を使いますが、SSLによる暗号化通信を行う場合には”https”という通信方法を用います。

この通信を可能とするため、まずは「セキュリティグループ」の設定変更を行いましょう。

AWSのサービス一覧より「EC2」を選択し、左側のメニューより「セキュリティグループ」を選択します。

セキュリティグループの設定画面が表示されますので、ブログシステムに適用されているセキュリティグループを選択し、下のタブから「インバウンド」を選択、さらにその中の「編集」ボタンを押します。

するとセキュリティグループ内容の設定画面が表示されます。

ここで、「ルールの追加」ボタンを押した上で以下のように入力し、「保存」ボタンを押します。

タイプ HTTPS
ソース カスタム、0.0.0.0/0

なお、ソースの”0.0.0.0/0″とは、全てのコンピュータからのアクセスを許可するという意味です。もしもアクセスさせる範囲を限定させたい場合には、ここにその範囲を示すネットワークアドレスを入力します。(例:10.0.1.0~10.0.1.255の範囲に制限したい場合は、10.0.1.0/24と入力します)

これでひとまず、”https”による通信を通すよう、セキュリティグループ上の設定は完了しました。

SSLの利用設定

SSLを使うためには、「SSLサーバー証明書」というものを取得する必要があります。これは、少し前まで複数あるCA (Certificate Authorityの略で、インターネットにおいて、接続者の身分を証明する電子証明書を発行する組織、日本語では「認証局」という) のうち1つから有償で取得するものでした。しかしながら、今は「Let’s Encrypt」という認証局から無償で取得することができます。

本記事では、この「Let’s Encrypt」を使って、無償で証明書を取得し、SSL化を行いたいと思います。

Certbotの導入

まずはLet’s Encryptから証明書を取得するために必要な「Certbot」というソフトウェアを導入し、このソフトウェアを実行できるよう、権限設定を行います。

$ sudo curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
$ sudo chmod 700 /usr/bin/certbot-auto

上の例では、Certbotを”/usr/bin/”にダウンロードの上、所有者 ( =特権ユーザー ) の読み書き実行権限を付与しています。

サーバー証明書の生成

まずは以下のコマンドを実行下さい。

$ sudo certbot-auto certonly --webroot -w 'ドキュメントルート' -d 'ホスト名+ドメイン' --email 'メールアドレス' –debug

「ドキュメントルート」にはWebサーバーのドキュメントルートを設定します。apacheデフォルトのドキュメントルートは”/var/www/html”であり、本記事でもここにWordPressを導入しました。(例示では” ‘ “を入れていますが、説明のため便宜的に付けたものであり、実際にコマンドを実行する際には” ‘ “は取ってください。「ホスト名+ドメイン」及び「メールアドレス」も同様です。)

また、「ホスト名+ドメイン」の箇所ですが、前回のDNSの設定時にホスト名として”www”を指定していれば、”www + ドメイン名”、していない場合はドメイン名のみを指定します。

「メールアドレス」にはご自身のメールアドレスを指定すれば問題ありません。

なお、Certbotによる証明書取得はAmazon Linuxでは正式サポートされていないため、”-debug”オプションを付けなければ証明書の取得に失敗しますので、ご留意下さい。

このコマンドを実行することにより、SSL化に必要となる証明書が生成されます。生成に成功した場合、以下のメッセージが表示されますので、確認下さい。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/'ホスト名+ドメイン名'/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/'ホスト名+ドメイン名'/privkey.pem
   Your cert will expire on 2017-12-20. 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"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

“mod_ssl”の導入

apacheにてSSLによる通信を行うためには、apacheモジュールの1つである”mod_ssl”を導入する必要があります。本記事に従い、apache2.4を導入している場合には、以下のようにこのモジュールを導入します。

$ sudo yum install -y mod24_ssl

証明書パスの設定

証明書の生成を行うことにより、いくつかの証明書ファイルが生成されますが、そのうち以下のファイルについてはapacheに保管場所を知らせる必要があります。(詳細については、証明書による認証の仕組みを理解する必要がありますが、ここでは省略します。)

cert.pem サーバー証明書
privkey.pem 秘密鍵
chain.pem 中間証明書

そのため、apacheの設定ファイルの1つである”/etc/httpd/conf.d/ssl.conf”の、
“SSLCertificateFile”
“SSLCertificateKeyFile”
“SSLCertificateChainFile”
と記載されている行を、以下のように書き換えます。

SSLCertificateFile /etc/letsencrypt/live/'ホスト名+ドメイン名'/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/'ホスト名+ドメイン名'/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/'ホスト名+ドメイン名'/chain.pem
/* ホスト名+ドメイン名の箇所の" ' "は削除して下さい */

なお、”/etc/letsencrypt/live/’ホスト名+ドメイン名’/というディレクトリは、生成された証明書類が保管されているディレクトリです。

暗号化方式の設定

実はSSLで用いることのできる暗号化アルゴリズムは複数あるのですが、今となっては脆弱性のあるものも含まれています。そこで、強固な暗号化方式のみ利用するよう設定を行います。

設定は上記同様、”/etc/httpd/conf.d/ssl.conf”で行います。

書き換える箇所は4か所あります。それぞれ、以下の内容にて上書きして下さい。なお、設定に失敗して不安定な動作になってしまった時にすぐ戻せるよう、元の記述の先頭に”#”を付けてで無効化しつつ、新たに追記するのが安全でよいでしょう。

SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLProxyCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
SSLProxyProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2

httpアクセスの無効化

さて、ここまでくると、SSL化の設定はほぼ完了です。しかし、このままではhttpにてアクセスすることも可能なため、せっかくSSL化した意味が半減してしまいます。

そこで、http経由でアクセスされた時に、自動的にhttps経由のアクセスに変換するよう、設定を行いましょう。

なお、この変換のことを、「リダイレクト」とも呼んだりします。

先ほどと同様、”/etc/httpd/conf.d/ssl.conf”に以下を追記しましょう。追記する場所は、このファイルの最後で構いません。

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

設定の有効化

これまで行ってきた設定を有効化しましょう。有効化はhttpd ( apache ) を再起動するだけです。

$ sudo service httpd restart

これでブラウザから”https://www.ドメイン名/”でアクセスしてみて下さい。問題なくアクセスできるはずです。

また、リダイレクトが有効に機能しているかを確かめるため、”http://www.ドメイン名/”でもアクセスしてみて下さい。自動的にURLが”https://www.ドメイン名/”に切り替わったら、これまでの設定は全てうまくいっています。

証明書期限更新の自動化

ここまできたら、もうひと手間かけて、便利な設定を行ってみましょう。それが、証明書の自動更新です。

Let’s Encryptで取得した証明書には3か月という期限があるため、定期的に更新作業を行う必要があります。ただ、こういった定期的な作業はついつい忘れがちになってしまいますよね。

そこで、”cron”というLinuxで定期的に実行させるタスクを管理する仕組みを使って、更新処理を自動化したいと思います。

Amazon Linuxではcronがデフォルトで稼働しているはずですが、念のために稼働しているか確かめてみましょう。

$ /etc/rc.d/init.d/crond status
crond (pid  2864) is running...

“crond is running…”と表示されれば、無事、cronは稼働しています。

続いて、証明書の更新を自動化するよう、cronに対する設定を行いましょう。

更新用のcron設定ファイル(ここでは”letsencrypt”ファイルとします)を作成し、内容を編集しましょう。

$ sudo vim /etc/cron.d/letsencrypt /* 設定ファイルの作成 */
00 16 * * 2 root /usr/bin/certbot-auto renew --post-hook "service httpd restart" /* 作成したファイル内にこの一文を追記 */

多少横道に逸れるかもしれませんが、cronは今後も使う機会があると思いますし、設定内容を知って損はないので、簡単に内容を説明します。

/* cron設定ファイルの形式 */
分 時 日 月 曜日 <実行コマンド>

非常にシンプルな形式です。「分」から「曜日」までには、<実行コマンド>を実行したいタイミングを数字で指定します。上の実例で「日」と「月」の箇所にきさいされている”*”は「毎回」という意味です。また、「曜日」については、0と7が日曜日、1以降は順に、月、火、水、木、金、土を表します。

また、設定ファイルは”/etc/cron.d/”ディレクトリに任意の名前で格納すれば有効化されます。

ここで、改めてcronに設定した内容を見てみましょう。

「分」から「曜日」までの記述については、毎週火曜日、16:00にコマンドが実行されることを意味しています。また、その後続いている”/usr/bin/certbot-auto”以降の記述は、このコマンドを実行することにより証明書の更新処理を試み、更新可能な状態であれば証明書を更新の上、httpdを再起動するという処理を示しています。

なお、「週次で更新処理を行うんだったら、数日間、有効期限切れの状態になる可能性もあるのでは?」と考えられる方もいらっしゃるかもしれませんが、心配は要りません。更新期限の少なくとも1週間前には更新処理ができるようになりますので。

今回の記事はずいぶん長くなってしまいましたが、これで通信をSSL化できるようになりました。

終わりに

さて、今回ここまで説明してきた基本的な知識があれば、あとはインターネットや書籍で調べることにより、AWSを使ってやりたいことはある程度やれるようになっていると思います。

私もAWSを使った面白いアイデアが沸いたら、また記事にしたいと思います。

今までご覧いただいた皆様、お付き合い頂いて本当にありがとうございました。