CentOS 7のnginxでSSLを設定。Let’s Encryptで安全なウェブサイトを構築する。

2018/07/16 CentOS, Nginx, サーバー構築

centos-nginx-ssl-top
前回の記事「CentOS7のnginxでPHP7を利用する。最短でPHP7系の環境を構築する手順。」でnginxの設定とphpの導入までが完了しました。
参考:本サイトのnginxに関連する記事
>「CentOS 7へのnginxのインストール。最短でバーチャルホストまでを利用する。」
>「CentOS7のnginxでPHP7を利用する。最短でPHP7系の環境を構築する手順。」
本記事では、ウェブサーバー(nginx)のHTTP通信を暗号化してセキュアな通信を行うための機能であるHTTPS通信をnginxで利用するまでの手順を紹介します。

スポンサーリンク

HTTPSはウェブの通信で利用されているHTTP通信をSSLという機能を利用して暗号化を行っているものになります。現在、GoogleのchromeだとHTTPSに対応していないウェブサイトには警告が出力される他、SEOにも影響があるようです。
出来ればウェブサーバーの導入時には、HTTPS機能も有効にして、上記のような制限に引っ掛からないように設定したほうが良いので、早い段階での設定をオススメします。
サーバー証明書は今まで、有償のものを利用することが一般的でしたが、最近ではSSL通信の普及を行うLet’s Encryptというプロジェクト(2016年4月スタート)で無料で発行しているものを利用することもできます。
因みにLet’s Encryptはシスコ(Cisco Systems)、Akamai、電子フロンティア財団(Electronic Frontier Foundation)、モジラ財団(Mozilla Foundation)などの大手企業・団体がスポンサーとして支援していますので、信頼できるものです。
本記事ではLet’s Encryptを利用してのHTTPS設定を行っていきます。

尚、導入する環境は記事
>「CentOS 7へのnginxのインストール。最短でバーチャルホストまでを利用する。」
で紹介していますが、基本的な環境は以下の通りです。

  • OSのバージョンはCentOSで最新のバージョン7.5を利用しています。(2016年6月現在)
  • ウェブサーバーとしてnginx1.15.0がインストールされています。(2018年6月現在、mainline最新版)
  • nginxは基本的な設定が完了して、バーチャルホストが二つ設定されています。
  • バーチャルホストは”www.testdom.com”と”www.testdom2.com”になります。
  • phpとphp-fpmの7.2系がインストールされて、テスト用のphpinfoが表示されています。
  • サーバーはインターネットへ接続されており、グローバルIPアドレスが一つ、割り当てられています。
  • ファイアウォールとしてfirewalldを設定しています。

この環境を前提に各バーチャルホストでHTTPSの設定を進めていきます。
※項目8-1.でも紹介していますが、2018年6月現在、epelレポジトリに含まれるcertbotのバージョン0.24は更新の確認でエラーが発生する可能性があります。回避方法については、項目8-1.をご覧下さい。
追記:2018年7月現在のcertbotパッケージ、バージョン0.25.1-1.el7では不具合が解決しています。

目次

1.ホスト名の正引き確認

Let’s Encryptを利用するためにはホスト名(FQDN:ホスト名にドメイン名がついたもの、以下ホスト名と記載がある時はFQDN)が正引き(ホスト名からIPアドレスを参照)できる必要があります。本記事では、ホスト名として以前の記事で設定されている”www.testdom.com”と”www.testdom2.com”を利用する前提としています。こちらはAレコードとしてDNSにIPアドレスを登録していますので、ホスト名の正引きができる状態になっています。(逆引きは不要です。)
設定を行う前に、ホスト名の正引きができることを確認します。Linux/Windowsの何れでも確認ができますので、ご自分の環境に合わせて行って下さい。※ホスト名の正引き設定は、ご利用のDNSサーバーによって異なるため、本記事では割愛しています。

1-1.hostコマンドによる正引きの確認(Linux)

Linuxではhostコマンドによるホスト名の確認が可能です。使い方はhostコマンドにホスト名を付けて実行します。
以下が実行例になります。尚、hostコマンドはデフォルトでインストールされていないため、yumコマンドでbind-utilsをインストールします。

bind-utilsがインストールされると、hostコマンドが利用できるようになります。”www.testdom.com”を確認する場合、以下のようにコマンドを実行します。

合わせて、もう一つのバーチャルホストである”www.testdom2.com”も確認します。

こちらも正常に応答がありました。
指定したホスト名に対して、IPアドレスが表示されれば、DNSの設定は完了しています。
もしホスト名が見つからないという警告が表示された場合には、ご利用のDNS設定を見直して下さい。ここでは正常に確認ができたという前提で先へ進めていきます。

1-2.nslookupコマンドによる正引きの確認(Windows)

ホスト名の正引きはWindowsでも確認が出来ます。ウェブサーバーへbind-utilsをインストールしたくない場合などは、ご利用のWindowsから確認してください。Windowsの場合は、コマンドプロンプトを開いて、以下のように実行します。

合わせて、もう一つのバーチャルホストである”www.testdom2.com”も確認します。

上記のようにIPアドレスの回答があれば、正引きの確認は完了です。

2.ファイアウォールへの接続許可設定

HTTPS通信ではHTTPで利用している接続ポート80番とは異なる接続ポートである443番を利用します。以前の記事ではHTTPS用の接続ポートはオープンしていないため、事前に接続ポートをオープンする設定を行います。
尚、ファイアウォールはCentOSのデフォルトであるfirewall-cmdを利用している前提となります。

2-1.現状のファイアウォール設定を確認

先ず、現状の設定を確認していきます。HTTPS接続は、全てのユーザーに開放するため、インターフェイスに適用されているゾーン、”public”ゾーンの設定を確認します。

上記のようにHTTPは許可されていますが、HTTPSは許可されていません。

2-2.HTTPSサービスの接続許可を追加

項目2-1.で確認した”public”ゾーンの接続許可サービスにHTTPSを追加します。追加は以下のように行います。

”success”と表示されれば設定は完了です。設定を反映するためにファイアウォールの設定を読み込みます。

”success”と表示されれば設定の読み込みは完了です。

2-3.HTTPSサービスの追加確認

設定した内容が正常に反映されているかを確認します。確認は以下のように行います。

”services”の項目にhttpsが追加されていることが確認できれば、確認は完了です。
ここまででファイアウォールの接続許可は完了しました。

4.Let’s Encrypt を利用したサーバー証明書の取得

引き続き、SSL証明書に関する設定を行います。HTTP通信をHTTPSへ変更するためには、サーバー証明書(サーバーの身分証明書)が必要になります。本章ではLet’s Encryptを利用してサーバー証明書を発行する手順を紹介していきます。

4-1.certbotパッケージ導入前の設定

Let’s Encryptを利用するためのアプリケーションは”certbot”という名前でパッケージ化されています。
certbotはCentOSのベースレポジトリには含まれておらず、epelレポジトリに含まれています。epelレポジトリはphpの7.2系を導入する際にインストールされていますので、ここでは導入は不要ですが、確認だけは行っておきます。

4-1-1.epelレポジトリの確認

epelレポジトリがインストールされたことを確認します。インストールされているパッケージはyumコマンドで確認できます。以下のようにyumを実行することで、epelレポジトリがインストールされていることを確認します。

出力結果として、epelレポジトリパッケージが表示されることを確認します。

上記の応答結果から、epelレポジトリパッケージがインストールされていることが確認できました。
epelがレポジトリリストに追加されていることを確認します。以下のように実行することで、現在、利用が可能なレポジトリリストを確認できます。

応答結果にepelが表示されればepelレポジトリを利用する準備は完了しています。

これでepelレポジトリの確認は完了です。

4-2.certbotパッケージのインストール

epelレポジトリに含まれるcertbotパッケージを確認します。

今度は上記のようにcertbotに関するパッケージが表示されました。この中でnginx環境でLet’s Encryptを利用するのに必要なパッケージは

  • certbot.noarch : A free, automated certificate authority client

のになります。このパッケージをインストールします。以下のコマンドでcertbotパッケージをインストールします。

実行結果は以下のようになります。

エラーの出力がなく”完了しました!”と表示されれば、certbotパッケージは正常にインストールされています。

4-3.certbotインストール後の確認

certbotがインストールされたことを確認します。インストールされているパッケージはyumコマンドで確認できます。以下のようにyumを実行することで、certbotパッケージがインストールされていることを確認します。

結果として上記のように”certbot””python2-certbot”が表示されればパッケージはインストールされています。
続いてcertbotがインストールされた場所を確認します。インストールされた場所(パス)を確認するためにはwhichコマンドを利用します。以下のように実行することでインストールパスを確認できます。

この結果から、certbotが/bin以下にインストールされたことが確認できます。これでcertbotのインストールが正常に終了したことが確認できました。

5.サーバー証明書の作成

ここまででサーバー証明書を作成するためのcertbotパッケージがインストールされましたので、certbotコマンドを利用してサーバー証明書を作成する手順を紹介していきます。本環境ではバーチャルホストが二つ用意されていますので、各バーチャルホスト事にコマンドを実行します。

5-1.certbotコマンドの実行 www.testdom.com用

Let’s Encryptによるサーバー証明書はcertbotコマンドで作成します。nginxに設定したバーチャルホストのドキュメントルートが”/home/www/www.testdom.com/”でFQDNのホスト名が”www.testdom.com”の場合、以下のように実行します。

”testdom.com”でもアクセスを行う(wwwのホスト部分が無い)場合は、以下のようにtestdom.comも追加します。本環境ではホスト部分無しでもアクセスしたいので、こちらで実行します。

実行すると初回の実行時のみ、以下のように対話型のウィザードが起動します。
幾つかの質問がありますので、回答します。

回答が終わると、証明書の作成が始まります。

上記のように”Congratulations!”と表示されればサーバー証明書の作成は完了です。サーバー証明書の保存場所は上記にも記載されているように/etc/letsencrypt/live/www.testdom.com/ディレクトリになります。(FQDN名のディレクトリは自動的に作成されます。)

5-2.certbotコマンドの実行 www.testdom2.com用

もう一つのバーチャルホスト用に証明書を作成します。nginxに設定したドキュメントルートが”/home/www/www.testdom2.com/”でFQDNのホスト名が”www.testdom2.com”の場合、以下のように実行します。

もし”testdom.com”でもアクセスを行う(wwwのホスト部分が無い)場合は、以下のようにtestdom.comも追加します。本環境ではホスト部分無しでもアクセスしたいので、こちらで実行します。

実行すると、以下のように対話型のウィザードが起動します。二回目の実行の場合は質問はありません。

上記のように”Congratulations!”と表示されればサーバー証明書の作成は完了です。サーバー証明書の保存場所は上記にも記載されているように/etc/letsencrypt/live/www.testdom2.com/ディレクトリになります。(FQDN名のディレクトリは自動的に作成されます。)

5-3.サーバー証明書ファイルの確認

実際に作成されたサーバー証明書ファイルを確認してみます。作成ディレクトリへ移動します。

ファイルを確認します。

ファイルが作成されていることが確認できました。同じくwww.testdom2.comも確認します。

ファイルを確認します。

こちらもファイルが作成されていることが確認できました。
ファイル構成は以下のようになります。

作成された証明書用ファイルの役割は以下の通りです。

  • cert.pem サーバー証明書本体
  • chain.pem 中間証明書
  • privkey.pem 秘密鍵ファイル
  • fullchain.pem サーバー証明書と中間証明書のセット

このファイルのうちnginxで利用するものは”fullchain.pem” ”privkey.pem”の2ファイルになります。fullchain.pemはウェブサーバーとしてnginx、かhttpd(Apache)のバージョンが2.4.8以降の場合利用する中間証明書を含んだ証明書ファイルになります。これでサーバー証明書の作成と確認は完了です。

5-4.dhparam用ファイルの作成

nginxのSSLを設定する際に、必要なパラメーターとして”ssl_dhparam”があります。これはnginxの1.11.0から必須になったパラメーターで、鍵交換アルゴリズムで使用される素数を格納するファイルになります。
このファイルはopensslコマンドで作成する必要がありますので、その手順を紹介します。ファイルを保存するパスは”/etc/nginx/ssl/”を指定します。

スポンサーリンク

5-4-1.ファイルの保存用ディレクトリ作成

dhparam用ファイルを保存する先のディレクトリ(/etc/nginx/ssl)を作成します。mkdirコマンドを実行します。

特にエラーなどのメッセージが出力されなければ、ディレクトリを作成は完了です。

5-4-2.opensslコマンドによるファイルの作成

opensslコマンドでdhparam用ファイルを作成します。以下のように実行します。

実行結果は以下のようになります。

サーバーの性能によっては、かなり時間が掛かりますが、途中で止めずに暫く待ってみて下さい。(多分、終わります!)
エラーが表示されずにプロンプトに戻れば、コマンドの実行は完了です。
作成されたファイルを確認します。

上記のようにファイルが作成されていることが確認できます。この時点でのディレクトリツリーは以下のようになります。

一度、実際の環境と比較してみて下さい。

6.nginxへのSSL通信用の設定

「項目5.サーバー証明書の作成」でサーバー証明書ファイルの作成まで完了しましたので、ウェブサーバーであるnginx側へSSLの設定を行います。設定が必要なファイルはバーチャルホスト用の設定ファイル”ドメイン名”.confになります。
以下が現状のフォルダとファイルの構成です。

上記ディレクトリツリー上の”sites-available”ディレクトリに含まれる設定ファイル”www.testdom.com.conf”と”www.testdom2.com.conf”が設定の対象です。

6-1.www.testdom.com.conf設定ファイルのバックアップ

HTTPS通信に関する設定はバーチャルホスト用設定ファイルであるwww.testdom.com.confに行います。先ずはこのファイルをバックアップします。
以下の手順でコピーを行います。

コピーされたバックアップファイルが存在することを確認します。

コピーしたファイル”www.testdom.com.conf.org”があることが確認できました。

6-2.www.testdom.com.conf 設定ファイルの編集

ファイルのバックアップが完了しましたのでwww.testdom.com.conを編集していきます。本記事では、HTTPS通信を行うために必要な設定を行う前提としています。先ずは稼働させてみて、必要に応じて、運用後に調整行っても良いと思います。
viテキストエディタで、www.testdom.com.conを開きます。

ファイルの内容は以下になります。前回の記事
>「CentOS 7のnginxでPHP7を利用する。最短でPHP7系の環境を構築する手順。」
でphp(php-fpm)が動作するところまでの設定が完了している環境が前提です。

この内容をSSLに対応させるため、以下のように変更します。

各設定項目の詳細を説明します。まず、最初のserverディレクティブは以下のように変更します。

上記はバーチャルホストの名前と、通常のHTTPでリクエストがあったアクセスをHTTPSへリダイレクトするための設定です。
次のserverディレクティブがバーチャルホストとSSL通信を有効にするための設定です。

ここまでがバーチャルホストの基本設定になります。バーチャルホスト名とアクセスログ、待ち受けポートの設定です。
次にSSLの詳細な設定になります。証明書ファイルのパスや、セッション時間の設定、有効化する暗号化アルゴリズムを設定します。この部分はある程度、変更頂いてもよいかと思います。

本設定で重要な部分は、ssl_certificateの部分です。Let’s Encryptで作成したバーチャルホストの証明書ファイルのパスを指定します。
またssl_dhparamについては最近のnginxの場合、設定を推奨する項目になっています。こちらについては証明書ファイルを作成する必要があります。「項目5.サーバー証明書の作成」で作成したdhparam用ファイルのパスを指定します。
最後にバーチャルホストのドキュメントルートとphpの動作設定です。この項目については基本的には変更はありません。

上記のようにlocationディレクティブを記載する場所の変更が必要になります。全ての変更が完了できたらファイルを保存します。

6-3.www.testdom2.com.conf 設定ファイルの編集

「項目6-2.www.testdom.com.conf 設定ファイルの編集」と同じようにバーチャルホスト用の設定ファイルであるwww.testdom2.com.confをSSLに対応させるように変更します。変更点はwww.testdom.com.confと同じになりますので、ここでは変更前のファイルと変更後のファイルを紹介します。

この内容ををSSにL対応させるため、以下のように変更します。

上記の変更後にwww.testdom2.confファイルを保存します。これで設定ファイルの変更は完了です。

6-4.バーチャルホスト用の設定ファイルの確認

項目6-2.と項目6-3.で変更したファイルに誤りが無いかをコマンドで確認します。確認はnginxコマンドを以下のように実行します。

上記のように” test is successful”と表示されれば、設定ファイルには問題ありません。これでバーチャルホスト用設定ファイルの確認は完了です。

6-5.nginxの再起動

ファイルの変更を行った場合には設定ファイルの再読み込みとして、nginxの再起動が必要になります。systemctlコマンドでnginxを再起動します。

エラーが出力されなければ、正常に再起動は完了しています。
再起動後にnginxのstatusを確認します。

上記の出力結果から、nginxは正常に再起動していることが確認できます。
これでバーチャルホスト側の設定は完了です。引き続き、HTTPS通信の動作確認を行います。

7.HTTPSの動作確認

「項目6.nginxへのSSL通信用の設定」まででHTTPS通信の設定が完了しましたので、ここからは実際にブラウザでサイトへ接続して、正常にHTTPSが動作していることを確認していきます。利用しているブラウザはGoogle Chromeになります。

7-1.ブラウザでの接続確認 www.testdom.com

利用しているブラウザにURLを入力します。以前は保護されていないと表示された部分が「保護された通信」に変わっています。この状態は正常にHTTPS通信が出来ている場合に表示されます。
centos-nginx-ssl-7-1

7-2.サーバー証明書の確認 www.testdom.com

Google Chromeのデベロッパーツール(その他のツール=>デベロッパーツール)を起動して通信に問題がないことを確認します。以下のように表示されていれば、通信はセキュアに行われています。
centos-nginx-ssl-7-2
また[View certificate]をクリックすると、サーバー証明書が確認できます。
centos-nginx-ssl-7-2-2
これでHTTPS通信が正常に行われていることが確認できました。作成したテスト用のindex.htmlファイルは削除しておきます。

7-3.ブラウザでの接続確認 www.testdom2.com

利用しているブラウザにURLを入力します。以前は保護されていないと表示された部分が「保護された通信」に変わっています。この状態は正常にHTTPS通信が出来ている場合に表示されます。
centos-nginx-ssl-7-3

7-4.サーバー証明書の確認 www.testdom2.com

Google Chromeのデベロッパーツール(その他のツール=>デベロッパーツール)を起動して通信に問題がないことを確認します。以下のように表示されていれば、通信はセキュアに行われています。
centos-nginx-ssl-7-4
また[View certificate]をクリックすると、サーバー証明書が確認できます。
centos-nginx-ssl-7-4-2
これでHTTPS通信が正常に行われていることが確認できました。作成したテスト用のindex.htmlファイルは削除しておきます。

8.サーバー証明書の更新

「項目7.7.HTTPSの動作確認」まででサーバー証明書の組み込みと動作確認までが完了しました。このままの状態で基本的な設定は完了していますが、サーバー証明書は有効期間というものがあります。
通常、サーバー証明書は1~3年ぐらいの有効期限で取得しますが、Let’s Encryptの場合、これが90日間と決まっています。90日が経過すると、有効期限が切れてしまい、サーバー証明書が無効である警告がブラウザに表示されてしまいます。これではHTTPSを設定した意味がなくなるため、有効期限を定期的に更新する設定を本章では紹介していきます。

8-1.証明書の更新確認時のエラー

※本章で紹介しているdry-runによる証明書更新のテストですが、2018年6月現在でepelに含まれるcertbot(バージョン0.24)だとエラーで失敗するようです。
追記:2018年7月現在のcertbotパッケージ、バージョン0.25.1-1.el7では不具合が解決しています。0.25をご利用の場合は、この項目については飛ばして下さい。

表示されるエラー内容

0.23と0.25では正常に確認が完了することから、恐らく0.24にあるバグだと考えられますが、この問題はtestバージョンのcertbot 0.25を利用することで回避できます。正式な0.25のリリースを待つほうが良いのですが、testingのバージョンをインストールすることも出来ます。
以下のように実行します。

実行結果は以下の通りです。

実行後にcertbotのバージョンを確認してみます。

上記のようにバージョンが0.25に変更されています。このバージョンでは更新テストによるエラーは出力されません。因みにバージョン0.23では問題なくテストの実行が可能です。これから先の内容はdry-run(更新テスト)が実行できる環境であるという前提で進めて行きます。

8-2.証明書の更新確認

Let’s Encryptでは証明書の更新手順が用意されています。具体的にはcertbotコマンドに”renew”オプションを付けて実行します。更新設定を行う前に更新が実行できるかをテストします。
テストは”–dry-run”オプションを付けることで行うことができます。
具体的には以下のように実行します。

以下が実行結果になります。

実行結果にふくまれる”Congratulations, all renewals succeeded.”から正常に更新ができることを確認できました。これで確認は完了です。

8-3.更新コマンドの定期実行設定

更新コマンドの実行が確認できましたので、定期的に実行するようにcronに設定を行います。cronの設定にはcrontabにコマンドを利用します。crontabはrootユーザーで実行します。設定はcrontabコマンドを以下のように実行します。

実行するとエディタが起動します。以下を追記します。”–deploy-hook”オプションは、サーバー証明書の更新が行われた場合のみ実行するコマンドを指定できます。更新時にはnginxを再起動して、更新された証明書を読み込む必要があるため、nginx再起動用のコマンドを指定します。
本記事では以下のように設定を行います。

上記は毎日3:00と5:00に更新コマンドを実行する場合の記載です。(2回実行するように記載しているのは、1回目が失敗した場合のため)もし他の時刻にしたい場合には、3と5を適宜変更します。変更後にはファイルを保存します。(viコマンドと同じ保存手順)
設定後にcrontabの内容を確認します。確認は

と実行します。先ほど追加した設定が表示されれば、自動更新の設定は完了です。

9.まとめ

Apacheに引き続き、nginxでもHTTPS通信を行う場合の手順を紹介しました。バーチャルホスト事に設定することができますので、サイトが多い環境ではメリットが出やすい設定です。Apacheと比較すると、設定内容が煩雑ですが、一度覚えると比較的簡単に設定できるようになると思います。是非、設定してHTTPS通信のメリットを感じて下さい。

関連する記事


Facebookでのご購読が便利です。

Twitter・Feedlyでもご購読できます。

Twitterでフォローする Feedlyでフォローする

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  • スポンサーリンク