ApacheにHTTP/2を設定してサイトの表示速度とパフォーマンスをアップ

httpd-http2-top3

RPMパッケージを利用してウェブサーバー「Apache httpd」最新バージョンをインストールする手順を以下の記事で紹介しました。
Apache httpdの最新バージョンでは「HTTP/1.1」を拡張したプロトコルで通信パフォーマンスが向上させる「HTTP/2」を利用することができます。

参考 最新バージョンのApache httpdをインストールする手順を紹介した記事とHTTP/2についての詳細を説明した記事

Open Source
CentOS 7へApacheをインストールして最短でウェブサーバーを構築

以前のCentOS環境構築に関する記事でCentOSのインストールと基本的な設定までが完了しました。折角、作成した環境。利用しない手はありません。本記事では、以前の記事で構築したCentOSの環境を利用してウェブサーバーであるApacheの ...

Open Source
nginx-http2-top2
CentOSのNginxでHTTP/2を設定してサイト表示速度と通信効率を向上させる

nginxに関する前回の記事 でnginxの環境でFastCGIキャッシュと呼ばれるウェブサイトの処理速度を向上させるためのキャッシュ機能の設定までを紹介しました。今回はその環境にHTTPの拡張プロトコルであるHTTP/2の設定を行ってみま ...

今回は最新バージョンのApache httpdでHTTP/2を有効にする設定方法を説明していきます。
HTTP/2を有効にするための事前準備にやや手間が掛かりますが、そこさえクリアしてしまえば難しい手順はありません。是非、HTTP/2を有効にしてサイトのパフォーマンスを向上してみて下さい。

1. HTTP/2を有効にする環境

HTTP/2を有効にするApache httpdはインストール手順を紹介した以下の記事で構築した環境を利用します。

Open Source
nginx-http2-top2
CentOSのNginxでHTTP/2を設定してサイト表示速度と通信効率を向上させる

nginxに関する前回の記事 でnginxの環境でFastCGIキャッシュと呼ばれるウェブサイトの処理速度を向上させるためのキャッシュ機能の設定までを紹介しました。今回はその環境にHTTPの拡張プロトコルであるHTTP/2の設定を行ってみま ...

基本的な環境は以下の通りです。

Apache httpdの環境

  • OSのバージョンはCentOSで最新のバージョン7.6を利用
  • ウェブサーバーとしてApache httpd2.4.39がインストール
  • Apache httpdは基本的な設定が完了して、テストページが表示されている
  • サーバーにはグローバルIPアドレス(111.8.21.167)が割り当て済み
  • ドメインはrem-system.comを利用。FQDNはweb01.rem-system.comとしてDNSに登録を済み
  • ファイアウォールとしてfirewalldを設定済み

Let's Encryptでの証明書作成はドメインが正引きできる必要があるためグローバルIPアドレスを利用しています。

この環境を前提にHTTP/2通信を有効にする設定を進めていきます。Apache httpdですが「HTTP/2」を有効にするためには、以下の2点が設定されている必要があります。

  • マルチスレッド機能であるeventMPMが有効になっていること
  • SSLが有効になっていること

本記事ではeventMPMを有効にするように設定変更を行ったあとにサイトのSSLを有効化します。SSLについては無償のSSLプロジェクトであるLet's EncryptのSSL証明書を利用します。
eventMPMとSSLの設定後にHTTP/2を有効にします。

注意ポイント

eventMPMを有効にした場合、PHPはモジュール形式では動作せずphp-fpm(FastCGI)経由で動作させる必要があります。php-fpmを利用する方法は、以下の記事で紹介しています。

Open Source
apache-fpm-mpm-top
Apache eventMPMとPHP-FPMでWordPressのパフォーマンスをアップする

以前の記事で作成したphpとApacheの環境を利用してパフォーマンスを向上するための構成であるApacheのMPMをデフォルトのpreforkMPMからeventMPMへ変更する設定と、PHPをモジュールではなくCGIとして動作させるため ...

HTTP/2を有効にした環境でPHPを利用する場合にはこちらの記事もあわせて参考にして下さい。

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

Let's Encryptを利用するためにはホスト名(FQDN:ホスト名にドメイン名がついたもの、以下ホスト名と記載がある時はFQDN)が正引き(ホスト名からIPアドレスを参照)できる必要があります。本記事ではFQDNのホスト名として"web01.rem-system.com"を利用する前提としています。こちらはAレコードとしてDNSにIPを登録していますので、ホスト名の正引きができる状態になっています。(逆引きは不要です。)
本記事では参考としてAWSのRoute53で設定した場合の例を紹介します。

httpd-http2-1

上記のようにAレコードweb01.rem-system.comとIPアドレスである111.8.21.167を結びつける設定を行います。
設定の完了後にホスト名の正引きができることを確認します。Linux/Windowsの何れでも確認ができますので、ご自分の環境に合わせて行って下さい。

ホスト名の正引き設定は、ご利用のDNSサーバーやドメイン事業者によって異なるため、本記事では割愛しています。

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

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

 command
# yum -y install bind-utils

bind-utilsがインストールされると、hostコマンドが利用できるようになります。以下のように実行します。

 command
$ host web01.rem-system.com
web01.rem-system.com has address 111.8.21.167

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

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

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

 command
> nslookup web01.rem-system.com
サーバー: UnKnown
Address: ***.***.***.** ご利用のDNSサーバー
権限のない回答:
名前: web01.rem-system.com
Address: 111.8.21.167

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

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

HTTPS通信ではHTTPで利用している接続ポート80番とは異なる接続ポートである443番を利用します。以前の記事でFirewallのHTTPについてはオープンしていますが、HTTPS用の接続ポートはオープンしていないため、事前に接続ポートをオープンする設定を行います。

ファイアウォールはCentOSのデフォルトであるfirewalldを利用している前提となります。

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

設定を行う前に、現状のファイアウォール設定を確認していきます。HTTPS接続は、全てのユーザーに開放するため、インターフェイスに適用されているゾーンである"public"ゾーンの設定を確認します。

 command
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client http
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

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

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

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

 command
# firewall-cmd --add-service=https --permanent
success

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

 command
# firewall-cmd --reload
success

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

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

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

 command
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client http https
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

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

4. Apache httpdのMPM設定

本章ではApache httpdのMPMをデフォルトのpreforkMPMからeventMPMへ変更する設定を説明します。HTTP/2を有効にするためApache httpdではeventMPMで動作する必要があります。
MPMはマルチプロセッシングモジュールの略で、簡単に言うとApacheの並列処理に関する挙動の方式になります。MPMはその名の通り、Apacheのモジュールとして提供されており、設定ファイルを変更することで、MPMの変更が可能です。
MPMは主に以下の3つのモジュールがあります。

preforkMPM 安定した通信が可能だが、アクセスが多い場合CPUとメモリを多く使う
workerMPM マルチスレッドとマルチプロセスのハイブリッド型。preforkに比べてメモリとCPU使用量が少ない
eventMPM Apache2.4系から導入されたマルチスレッドとマルチプロセスのモジュール。CPUとメモリの使用量が少ない

Apache httpdをyumでインストールした場合、デフォルトではpreforkMPMモジュールが読み込まれるように設定されています。preforkMPMではHTTP/2は動作しないためeventMPMモジュールを読み込むように設定します。

4-1. デフォルトのApacheに設定されているMPMの確認

MPMは動的モジュール(DSO)として読み込まれています。先ずはモジュールとして読み込まれているMPMを確認します。現在、読み込まれているモジュールの確認はhttpdコマンドに-Mオプションを付けて実行します。

 command
# httpd -M | grep mpm
mpm_prefork_module (shared)

上記の結果からpreforkMPMが読み込まれていることが確認できます。これをeventMPMへ変更します。

パッケージで導入したApache httpdの場合にはデフォルトでpreforkMPMが読み込まれていますが、ソースコードからインストールしたApache httpdではデフォルトがeventMPMになっています。

4-2. ディレクトリの移動とMPM設定ファイルのバックアップ

MPMの設定は"/etc/httpd/conf.modules.d/"以下にある00-mpm.confファイルで行います。00-mpm.confの設定変更前に、既存のファイルをバックアップしておきます。具体的には以下の手順でコピーを行います。

 command
# cd /etc/httpd/conf.modules.d/
# cp -p 00-mpm.conf 00-mpm.conf.org

バックアップの完了後、エディタで設定ファイルを開いて変更を行います。本環境ではOSの標準的なエディタである、viエディタを利用しています。

 command
# vi 00-mpm.conf

4-3. MPM設定ファイルの編集

00-mpm.confはMPMとして用意されている3つのモジュールの何れかを読み込むように記載がされています。(2つはコメントアウトされている)デフォルトの設定は以下のように"LoadModule mpm_prefork_module modules/mod_mpm_prefork.so"が有効になっています。

 code
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so

これを以下のように「LoadModule mpm_event_module modules/mod_mpm_event.so」を有効にするように変更します。
現在、有効になっている「LoadModule mpm_prefork_module modules/mod_mpm_prefork.so」をコメントアウト(#を行頭に付ける)して、「LoadModule mpm_event_module modules/mod_mpm_event.so」からコメントを外します(#を行頭から外す)。以下のように変更します。

 code
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
LoadModule mpm_event_module modules/mod_mpm_event.so

設定ファイルの変更後に、ファイルを保存します。これで設定ファイルの変更は完了です。

4-4. 00-mpm.conf設定ファイルの反映とhttpdの確認

ここまででeventMPMでApache httpdを動作させるための設定は完了しました。変更した設定を反映するためにApache httpdを再起動します。systemctlを以下のように実行します。

 command
# systemctl restart httpd

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

 command
$ systemctl status httpd
 httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 水 2019-05-08 14:12:17 JST; 13min ago
Docs: man:httpd.service(8)
Main PID: 4035 (httpd)
Status: "Running, listening on: port 443, port 80"
CGroup: /system.slice/httpd.service
tq4035 /usr/sbin/httpd -DFOREGROUND
tq4057 /usr/sbin/httpd -DFOREGROUND
tq4058 /usr/sbin/httpd -DFOREGROUND
tq4059 /usr/sbin/httpd -DFOREGROUND
mq4070 /usr/sbin/httpd -DFOREGROUND

上記のようにActive項目「active (running)」と出力されていれば、httpdは正常に再起動していることが確認できます。

4-5. 変更後のMPMの確認

Apache httpd設定ファイル変更及び再起動後のモジュールとしてeventMPMが読み込まれていることを確認します。現在、読み込まれているモジュールの確認はhttpdコマンドに-Mオプションを付けて実行します。

 command
# httpd -M | grep mpm
mpm_event_module (shared)

結果として「mpm_event_module (shared)」が表示されれば、確認は完了です。ここまでの作業でApacheのMPMをpreforkMPMからeventMPMに変更することができました。

5. SSL通信用モジュールのインストール

HTTP/2を利用するためにはHTTPSを有効にする必要があります。SSLを有効にするためにはApache httpd向けに用意されたSSLモジュールである"mod_ssl"のインストールが必要になります。"mod_ssl"のインストールについては別の記事で導入が完了していますので、ここでは確認方法だけ紹介します。

5-1. mod_sslパッケージの確認

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

 command
# yum list installed | grep mod_ssl

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

 log
httpd24u-mod_ssl.x86_64 1:2.4.39-1.ius.centos7 @ius

続いてmod_sslがApache httpdのモジュールとして登録されていることを確認します。登録を確認するためにはhttpdコマンドを利用します。以下のように実行することでインストールパスを確認できます。

 command
# httpd -M | grep ssl
ssl_module (shared)

表示された結果に「ssl_module」が含まれれば、mod_sslはApache httpdへモジュールとして登録されています。
これでmod_sslパッケージの確認は完了です。

6. Let's Encrypt を利用したSSL証明書の取得

SSL証明書は今まで、有償のものを利用することが一般的でしたが、最近ではSSL通信の普及を行うLet's Encryptというプロジェクト(2016年4月スタート)で無料で発行しているものを利用することもできます。

メモ


Let's Encryptはシスコ(Cisco Systems)、Akamai、電子フロンティア財団(Electronic Frontier Foundation)、モジラ財団(Mozilla Foundation)などの大手企業・団体がスポンサーとして支援していますので、信頼できるものです。

本記事では無償でも信頼性が高いLet's Encryptを利用してのHTTPS設定を行っていきます。

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

Let's Encryptを利用するためのアプリケーションは"certbot"という名前でパッケージ化されています。
certbotパッケージはデフォルトで利用できるbaseレポジトリには含まれておらず、拡張レポジトリであるepelレポジトリに含まれています。epelレポジトリはApache httpdをインストールする際にインストール済みになっていますので、ここでのインストールは不要です。本章ではepelレポジトリの確認方法についてのみ紹介します。

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

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

 command
$ yum list installed | grep epel

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

 command
epel-release.noarch 7-11 @extras

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

 command
$ yum repolist

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

 code
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.yz.yamagata-u.ac.jp
* epel: ftp.yz.yamagata-u.ac.jp
* extras: ftp.yz.yamagata-u.ac.jp
* updates: ftp.yz.yamagata-u.ac.jp
リポジトリー ID リポジトリー名 状態
base/7/x86_64 CentOS-7 - Base 10,019
epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 13,139
extras/7/x86_64 CentOS-7 - Extras 413
ius/x86_64 IUS Community Packages for Enterprise Linux 7 - x86_64 575
updates/7/x86_64 CentOS-7 - Updates 1,840
repolist: 25,986

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

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

項目6-1-1. でepelレポジトリが有効になっていることが確認できましたので、certbotパッケージを確認します。

 command
yum search certbot
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.iij.ad.jp
* epel: ftp.iij.ad.jp
* extras: ftp.iij.ad.jp
* updates: ftp.iij.ad.jp
=========================== N/S matched: certbot ================================
python2-certbot.noarch : Python 2 libraries used by certbot
python2-certbot-apache.noarch : The apache plugin for certbot
python2-certbot-dns-cloudflare.noarch : Cloudflare DNS Authenticator plugin for Certbot
python2-certbot-dns-cloudxns.noarch : CloudXNS DNS Authenticator plugin for Certbot
python2-certbot-dns-digitalocean.noarch : DigitalOcean DNS Authenticator plugin for Certbot
python2-certbot-dns-dnsimple.noarch : DNSimple DNS Authenticator plugin for Certbot
python2-certbot-dns-dnsmadeeasy.noarch : DNS Made Easy DNS Authenticator plugin for Certbot
python2-certbot-dns-gehirn.noarch : Gehirn Infrastructure Service DNS Authenticator plugin for Certbot
python2-certbot-dns-google.noarch : Google Cloud DNS Authenticator plugin for Certbot
python2-certbot-dns-linode.noarch : Linode DNS Authenticator plugin for Certbot
python2-certbot-dns-luadns.noarch : LuaDNS Authenticator plugin for Certbot
python2-certbot-dns-nsone.noarch : NS1 DNS Authenticator plugin for Certbot
python2-certbot-dns-ovh.noarch : OVH DNS Authenticator plugin for Certbot
python2-certbot-dns-rfc2136.noarch : RFC 2136 DNS Authenticator plugin for Certbot
python2-certbot-dns-route53.noarch : Route53 DNS Authenticator plugin for Certbot
python2-certbot-dns-sakuracloud.noarch : Sakura Cloud DNS Authenticator plugin for Certbot
python2-certbot-nginx.noarch : The nginx plugin for certbot
certbot.noarch : A free, automated certificate authority clientName and summary matches only, use "search all" for everything.

今度は上記のようにcertbotに関するパッケージが表示されました。この中でHTTPS通信に必要なパッケージは

  • python2-certbot-apache.noarch : The apache plugin for certbot
  • certbot.noarch : A free, automated certificate authority client

の二つになります。この二つのパッケージをインストールします。先ずはcertbotからインストールを行います。
以下のコマンドでcertbotパッケージをインストールします。

 command
# yum -y install certbot

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

 log
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.tsukuba.wide.ad.jp
* epel: ftp.tsukuba.wide.ad.jp
* extras: ftp.tsukuba.wide.ad.jp
* updates: ftp.tsukuba.wide.ad.jp
依存性の解決をしています
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ certbot.noarch 0:0.31.0-2.el7 を インストール【略】
インストール:
certbot.noarch 0:0.31.0-2.el7
依存性関連をインストールしました:
pyOpenSSL.x86_64 0:0.13.1-4.el7 python-cffi.x86_64 0:1.6.0-5.el7
python-enum34.noarch 0:1.0.4-1.el7 python-idna.noarch 0:2.4-1.el7
python-ndg_httpsclient.noarch 0:0.3.2-1.el7 python-ply.noarch 0:3.4-11.el7
python-pycparser.noarch 0:2.14-1.el7 python-requests-toolbelt.noarch 0:0.8.0-1.el7
python-zope-component.noarch 1:4.1.0-5.el7 python-zope-event.noarch 0:4.0.3-2.el7
python-zope-interface.x86_64 0:4.0.5-4.el7 python2-acme.noarch 0:0.31.0-1.el7
python2-certbot.noarch 0:0.31.0-2.el7 python2-configargparse.noarch 0:0.11.0-1.el7
python2-cryptography.x86_64 0:1.7.2-2.el7 python2-future.noarch 0:0.16.0-7.el7
python2-josepy.noarch 0:1.1.0-1.el7 python2-mock.noarch 0:1.0.1-10.el7
python2-parsedatetime.noarch 0:2.4-5.el7 python2-pyasn1.noarch 0:0.1.9-7.el7
python2-pyrfc3339.noarch 0:1.0-2.el7 python2-requests.noarch 0:2.6.0-0.el7
python2-six.noarch 0:1.9.0-0.el7 pytz.noarch 0:2016.10-2.el7
完了しました!

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

6-3. python2-certbot-apacheパッケージのインストール

続いてcertbotのapache用プラグインである「python2-certbot-apache」をインストールします。"yum install"のコマンドでパッケージをインストールします。

 command
# yum -y install python2-certbot-apache
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.tsukuba.wide.ad.jp
* epel: ftp.tsukuba.wide.ad.jp
* extras: ftp.tsukuba.wide.ad.jp
* updates: ftp.tsukuba.wide.ad.jp
依存性の解決をしています
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ python2-certbot-apache.noarch 0:0.31.0-1.el7 を インストール
--> 依存性の処理をしています: python-augeas のパッケージ: python2-certbot-apache-0.31.0-1.el7.noarch
--> トランザクションの確認を実行しています。
---> パッケージ python-augeas.noarch 0:0.5.0-2.el7 を インストール
--> 依存性の処理をしています: augeas-libs のパッケージ: python-augeas-0.5.0-2.el7.noarch
--> トランザクションの確認を実行しています。
---> パッケージ augeas-libs.x86_64 0:1.4.0-6.el7_6.1 を インストール
--> 依存性解決を終了しました。依存性を解決しました
インストール中:
python2-certbot-apache noarch 0.31.0-1.el7 epel 229 k
依存性関連でのインストールをします:
augeas-libs x86_64 1.4.0-6.el7_6.1 updates 355 k
python-augeas noarch 0.5.0-2.el7 base 25 k
トランザクションの要約
総ダウンロード容量: 609 k
インストール容量: 2.0 M
Downloading packages:
(1/3): python-augeas-0.5.0-2.el7.noarch.rpm | 25 kB 00:00:00
(2/3): augeas-libs-1.4.0-6.el7_6.1.x86_64.rpm | 355 kB 00:00:00
(3/3): python2-certbot-apache-0.31.0-1.el7.noarch.rpm | 229 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
インストール中 : augeas-libs-1.4.0-6.el7_6.1.x86_64 1/3
インストール中 : python-augeas-0.5.0-2.el7.noarch 2/3
インストール中 : python2-certbot-apache-0.31.0-1.el7.noarch 3/3
検証中 : python-augeas-0.5.0-2.el7.noarch 1/3
検証中 : augeas-libs-1.4.0-6.el7_6.1.x86_64 2/3
検証中 : python2-certbot-apache-0.31.0-1.el7.noarch 3/3
インストール:
python2-certbot-apache.noarch 0:0.31.0-1.el7
依存性関連をインストールしました:
augeas-libs.x86_64 0:1.4.0-6.el7_6.1 python-augeas.noarch 0:0.5.0-2.el7
完了しました!

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

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

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

 command
$ yum list installed | grep certbot
certbot.noarch 0.31.0-2.el7 @epel
python2-certbot.noarch 0.31.0-2.el7 @epel
python2-certbot-apache.noarch 0.31.0-1.el7 @epel

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

 command
$ which certbot
/bin/certbot

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

7. SSL証明書の作成

本章ではcertbotパッケージを利用してSSL証明書を作成する手順を紹介していきます。

7-1. certbotコマンドの実行

Let's EncryptによるSSL証明書はcertbotコマンドで作成します。Apache httpdに設定したドキュメントルートが「/home/www/html/」でFQDNのホスト名が「web01.rem-system.com」の場合、以下のようにcertbotコマンドを実行します。

 command
# certbot certonly --webroot -w /home/www/html/ -d web01.rem-system.com

もし「rem-system.com」でもアクセスを行う(wwwのホスト部分が無いドメイン名でのアクセス、ZONE APEXと呼ばれます)場合は、以下のように「rem-system.com」も追加します。本記事ではZONE APEXは設定しないものとします。

 command
# certbot certonly --webroot -w /home/www/html/ -d web01.rem-system.com -d rem-system.com

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

 command
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): test@rem-system.com メールアドレスを入力
Starting new HTTPS connection (1): acme-v01.api.Let'sEncrypt.org---------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A 利用規約に了解するかを回答(Aを入力)
-------------------------------------------------------------------------------
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 メーリングリストに入るかの選択(任意)

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

 log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for web01.rem-system.com
Using the webroot path /home/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.orgIMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/web01.rem-system.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/web01.rem-system.com/privkey.pem
Your cert will expire on 2018-07-22. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot 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

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

7-2. 作成されたSSL証明書ファイルの確認

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

 command
$ cd /etc/letsencrypt/live/web01.rem-system.com

移動後に"ls"コマンドで作成されているファイルを確認します。

 command
$ ls
README cert.pem chain.pem fullchain.pem privkey.pem

ファイルが作成されていることが確認できました。各ファイルの役割は以下の通りです。

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

作成された4ファイルのうち、今回の環境で利用するものは「fullchain.pem」と 「privkey.pem」の2ファイルになります。fullchain.pemはウェブサーバーとしてnginxかApache httpdのバージョンが2.4.8以降でないと利用できません。今回はApache httpdのバージョンが2.4.39になりますので、fullchain.pemを利用します。

8. Apache httpd HTTPSとHTTP/2通信用の設定

本章ではApache httpdをSSL(HTTPS)とHTTP/2通信に対応させるための設定手順について紹介します。ここまでの手順でSSL証明書ファイルの作成まで完了しましたので、ウェブサーバーであるApache httpdへSSLとHTTP/2の設定を行います。

8-1. ssl.conf設定ファイルのバックアップ

HTTPS通信に関する設定は「/etc/httpd/conf.d」ディレクトリに含まれる「ssl.conf」に行います。設定変更を行う前にssl.confをバックアップします。
「/etc/httpd/conf.d」ディレクトリに移動して、ファイルを確認します。

 command
# cd /etc/httpd/conf.d
# ls
ssl.conf

ファイルをコピーする"cp"コマンドでssl.confのコピーを行います。

 command
# cp -p ssl.conf ssl.conf.org

コピーされたssl.conf.orgが存在することを"ls"コマンドで確認します。

 command
# ls
ssl.conf ssl.conf.org

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

8-2. ssl.conf設定ファイルの編集

設定ファイルのバックアップが完了しましたのでssl.confを編集していきます。セキュリティなどを考えると本記事で紹介している項目以外にも幾つかの設定変更が必要になりますが、その辺りは別の記事にまとめてありますので、必要に応じて別記事を参照の上、設定変更を行って下さい。

8-2-1. SSL証明書に関する設定変更

本章ではHTTPS通信を行うために必要なSSL証明書の指定を行います。変更点は2点で、SSL証明書と中間証明書ファイル、秘密鍵ファイルのパスを変更します。テキストエディタでssl.confを開きます。

 command
# vi ssl.conf

まずはSSL証明書ファイルを示す、以下の点を変更します。Apache httpdの2.4.8以降ではfullchain.pemという中間証明書とSSL証明書が1つになったファイルが「SSLCertificateFile」パラメータに設定できますので、このファイルへのパスを指定します。

 code
SSLCertificateFile /etc/pki/tls/certs/localhost.crt

「SSLCertificateFile」パラメータを、certbotで作成した「fullchain.pem」ファイルのパスに変更します。変更後は以下のようになります。

 code
SSLCertificateFile /etc/letsencrypt/live/web01.rem-system.com/fullchain.pem

次に秘密鍵ファイルのパスを設定する「SSLCertificateKeyFile」パラメータを変更します。ssl.confの以下の部分を

 code
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

certbotで作成した「privkey.pem」ファイルのパスに変更します。変更後のパラメータは以下のようになります。

 code
SSLCertificateKeyFile /etc/letsencrypt/live/web01.rem-system.com/privkey.pem

8-2-2. HTTP/2通信に関する設定変更

SSLの設定変更が終わったら、つぎに「HTTP/2通信」を行うように設定パラメータを変更します。
HTTP/2通信機能はApache httpdのモジュールとして用意されていますが、パッケージからApache httpdをインストールした環境ではモジュールは有効になっていますので、設定ファイルへ機能を有効にする記載のみで利用できます。

 code
##
## SSL Virtual Host Context
##

ssl.confの中からバーチャルホストを設定するディレクティブである上記の部分を探します。
上記ディレクティブの下の行にHTTP/2通信を有効にするための設定である"Protocols"項目を追加します。

 code
##
## SSL Virtual Host Context
##
Protocols h2 http/1.1 この行を追加

上記では HTTP/2通信を優先的に利用し、対応していないブラウザでは従来通りにHTTP/1.1を利用するという設定になります。
上記3点の変更後にssl.confファイルを保存します。変更したファイルに誤りが無いかをhttpdコマンドで確認します。確認は以下のように実行します。

 command
# httpd -t
Syntax OK

上記のように「Syntax OK」と表示されれば、設定ファイルには問題ありません。これでssl.confファイルの編集は完了です。

8-3. httpdの再起動

変更した設定を反映するためにhttpdを再起動します。

 command
# systemctl restart httpd

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

 command
$ systemctl status httpd
 httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 水 2019-05-08 14:27:13 JST; 4s ago
Docs: man:httpd.service(8)
Main PID: 4518 (httpd)
Status: "Started, listening on: port 443, port 80"
CGroup: /system.slice/httpd.service
tq4518 /usr/sbin/httpd -DFOREGROUND
tq4519 /usr/sbin/httpd -DFOREGROUND
tq4520 /usr/sbin/httpd -DFOREGROUND
tq4521 /usr/sbin/httpd -DFOREGROUND
mq4522 /usr/sbin/httpd -DFOREGROUND

上記の出力結果から、Apache httpdは正常に起動していることが確認できます。
これで設定は完了です。引き続きHTTPSとHTTP/2通信の動作確認を行います。

9. HTTPSの動作確認

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

9-1. ブラウザでの接続確認

"https://"にホストのFQDNに付けてを入力します。本記事での環境はFQDNがweb01.rem-system.comになりますので

https://web01.rem-system.com

と入力します。
ブラウザのURL欄に「保護された通信」と表示されていることが確認できます。これは正常にHTTPS通信が出来ている場合に表示されます。

cent-httpd-ssl-7-1

9-2. SSL証明書の確認

Google Chromeのデベロッパーツール(その他のツール=>デベロッパーツール)を起動して通信に問題がないことを確認します。以下のように表示されていれば、通信はセキュアに行われています。

cent-httpd-ssl-7-2

また「View certificate」をクリックすると、SSL証明書が確認できます。
「全般」タブから、以下のように証明書発行先と発行者、有効期間が確認できます。

cent-httpd-ssl-7-2-2-02

「証明のパス」タブからインストールした証明書に問題がないことが確認できます。

cent-httpd-ssl-7-2-3-03

これでHTTPS通信が正常に行われていることが確認できました。

10. HTTP/2プロトコルの動作確認

HTTPS通信までが確認できましたので、続いてHTTP/2通信が動作していることを確認していきます。利用しているブラウザは同じくGoogle Chromeになります。

10-1. HTTP/2通信の確認

Google Chromeのデベロッパーツール(その他のツール=>デベロッパーツール)を起動します。「Network」を選択して、ページをリロードします。

nginx-http2-4-1-1

表示される「Name」などのカラムを右クリックすると、表示項目の追加メニューが表示されます。「Protocol」にチェックを入れます。

nginx-http2-4-1-2

再度ページをリロードすると、接続プロトコルが表示されます。本環境では以下のように「h2」と表示されることから、HTTP/2通信が行われていることが確認できました。

nginx-http2-4-1-3

※HTTP/1.1で通信している場合にはブラウザのキャッシュを削除してみて下さい。

11. SSL証明書の更新

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

11-1. 証明書の更新確認

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

 command
# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log-----------------------
Processing /etc/letsencrypt/renewal/web01.rem-system.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer None
Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for web01.rem-system.com
Waiting for verification...
Cleaning up challenges
-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/web01.rem-system.com/fullchain.pem
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/web01.rem-system.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates above have not been saved.)
-------------------------------------------------------------------------------
IMPORTANT NOTES:
- Your account credentials have been saved in your Certbot
configuration directory at /etc/Let'sEncrypt. 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.

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

11-2. 更新コマンドの定期実行設定

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

 command
# crontab -e

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

 code
00 3 * * * certbot renew -q --deploy-hook "systemctl restart httpd"
00 5 * * * certbot renew -q --deploy-hook "systemctl restart httpd"

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

 command
# crontab -l

先ほど追加した内容が表示されれば、SSL証明書の自動更新設定は完了です。

12. まとめ

HTTP/2通信は最近では利用されているのをよく見かけるようになりました。
今後はHTTPS通信とHTTP/2通信はセットで運用することが一般的になっていくと思います。これを機会にHTTPS通信とHTTP/2通信を導入してみてはどうでしょうか。
それ程、難しい手順ではありませんので是非、設定してウェブサイトのパフォーマンス向上を行って下さい。
この記事の環境をベースにphp-fpmやデータベースであるmariaDBを導入することでセキュアなLAMP環境を作成できます。php-fpmやmariaDBの導入方法についても別の記事で紹介していますので、是非、参考にして下さい。

[st_af id="9037"]

  • この記事を書いた人
rem-profile-photo

レムシステム

レムシステムはPC・サーバー・ネットワークでの業務効率化を主な業務としている会社です。全国に対応しています。

-Apache, Linux
-