CentOS 7.4 で手軽になった HTTP/2 対応 Apache のインストールメモ

Linux
Linux
スポンサーリンク

CentOS 7.4(1708)から、OpenSSL 1.0.2 が導入され ALPN がサポートされました。これまでは HTTP/2(mod_http2)に対応した Apache httpd をインストールするには、OpenSSL や HTTP/2 関連ライブラリなどを自前でソースからビルドしなければなりませんでしたが、ALPN がサポートされたことにより、これらを yum からインストールできるようになりました。そこで今回は、CentOS 7.4(1708)で、HTTP/2(mod_http2)に対応した Apache httpd 2.4 をインストールする手順をまとめてみました。

そもそも「ALPN」ってなんだ?

冒頭から「ALPN」という聞きなれない単語が出てきますが、ALPNとは「Application-Layer Protocol Negotiation」の略称で、クライアントとサーバーの間でどのアプリケーションプロトコル(HTTP/2 や HTTP/1.1 など)を使ってやりとりをするかを決めるための仕組みです。

クライアントのWEBブラウザはサーバーに「HTTP/2 を使う?それとも HTTP/1.1?」と聞くのですが、 ALPN に対応していないサーバーはなにも返答してくれないので、WEBブラウザは「答えてくんないから無難に HTTP/1.1 を使っておこう」と思ってしまい、HTTP/2は使われなくなってしまうのです。

WEBブラウザとALPNに対応していないWEBサーバーとのやりとり

OpenSSL のバージョン確認

ということで、まずはじめに OpenSSL のバージョンが ALPN に対応している「1.0.2」であることを確認しておきましょう。

openssl version
 
OpenSSL 1.0.2k-fips 26 Jan 2017 ← ALPN対応

OpenSSL のバージョンが 1.0.1 の場合は、CentOS7.4(1708)にアップグレードしてください。

yum -y update

下準備

開発ツールのインストール

Apache httpd はソースからビルドしてインストールしますので、基本コマンドと開発ツールをインストールしておきます。

yum -y groupinstall base
yum -y groupinstall development

新しいバージョンのパッケージをインストールできる Software Collections(SCL)リポジトリIUSリポジトリから、HTTP/2 に対応した Apache httpd 2.4 をインストールできるのですが、現時点(2017年9月21日現在)では OpenSSL 1.0.1(ALPN未対応) のライブラリでビルドしているため、ALPN にのみ対応している Google Chrome や Firefox では HTTP/2 で通信することができません。(じつにややこしいい話なのですが Safari は ALPN の前身 NPN にも対応しているため HTTP/2 で通信できます)

(2017年10月24日追記)IUSリポジトリから HTTP/2 と ALPN に対応した Apache httpd 2.4 をインストールできるようになりました。詳しくは「HTTP/2 に対応した Apache を yum でインストール」の記事をご参照ください。

Apache のビルドに必要なライブラリのインストール

Apache httpd 2.4 と HTTP/2 モジュール(mod_http2)のインストールに必要な、ライブラリをインストールしておきます。(HTTP/2 のコアエンジン nghttp2 のライブラリは EPELリポジトリからインストールします)

yum -y install epel-release
yum -y install libnghttp2-devel
 
yum -y install openssl-devel
yum -y install expat-devel

APR と APR-util のインストール

Apache 2.4系をソースコードからインストールする場合は APR と APR-util が必要になりますのでインストールします。(現時点で yum からインストールできる APR のバージョンは 1.4 のため、Apache の event MPM がインストールされません。そのため最新版をインストールしています)

APR

cd /usr/local/src/
wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-1.6.2.tar.gz
tar xvzf apr-1.6.2.tar.gz
cd apr-1.6.2/
./configure
make
make install

APR-util

cd /usr/local/src/
wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-util-1.6.0.tar.gz
tar xvzf apr-util-1.6.0.tar.gz
cd apr-util-1.6.0/
./configure --with-apr=/usr/local/apr
make
make install

HTTP/2 対応 Apache のインストール

Apache httpd のソースコードのダウンロード

cd /usr/local/src/
wget http://ftp.riken.jp/net/apache//httpd/httpd-2.4.27.tar.gz

ダウンロードしたソースコードを解凍して、ディレクトリを移動します。

tar xvzf httpd-2.4.27.tar.gz
cd httpd-2.4.27/

HTTP/2 を使うために必要なモジュール mod_http2 と mod_ssl を有効にしてインストールします。

./configure \
--with-apr=/usr/local/apr \
--enable-http2 \
--enable-ssl \
--enable-so \
--enable-mods-shared=all \
--enable-mpms-shared=all
 
make
make install

以上で Apache が /usr/local/apache2/ 以下にインストールされました。続いてSSL証明書の作成と Apache の設定を行います。

自己署名のSSLサーバー証明書の作成

正規の認証局が発行したサーバー証明書を、無料で取得することもできます。よければご参照ください → Let's Encrypt サーバー証明書の取得と自動更新設定メモ

HTTP/2 は事実上 HTTPS が必須になりますので Apache の設定の前に、SSLサーバー証明書を作成しておきます。

秘密鍵の作成(ECDSAの256ビット鍵を生成)

openssl ecparam -name prime256v1 -genkey -out server.key

CSR(証明書署名要求)の作成(入力するのは2箇所だけです)

openssl req -new -key server.key > server.csr
 
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:<空エンター>
Locality Name (eg, city) [Default City]:<空エンター>
Organization Name (eg, company) [Default Company Ltd]:<空エンター>
Organizational Unit Name (eg, section) []:<空エンター>
Common Name (eg, your name or your server's hostname) []:www.example.com
Email Address []:<空エンター>
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:<空エンター>
An optional company name []:<空エンター>

SSLサーバー証明書の作成(有効期限10年)

openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

秘密鍵とSSL証明書を移動

mv -i server.key /usr/local/apache2/conf/
mv -i server.crt /usr/local/apache2/conf/

パーミッションを変更

chmod 600 /usr/local/apache2/conf/server.key
chmod 600 /usr/local/apache2/conf/server.crt

SELinux を有効にしている場合は、秘密鍵とSSL証明書にセキュリティコンテキストをつけておきましょう。(Apache 起動時にエラーが発生することがあります)

restorecon -v /usr/local/apache2/conf/server.key
restorecon -v /usr/local/apache2/conf/server.crt

CSRを削除

rm server.csr

Apache の HTTP/2 設定

初期状態では、HTTP/2 が有効になっていませんので、有効になるように設定します。

vim /usr/local/apache2/conf/httpd.conf
以下のモジュールを有効にします。

#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
 ↓
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
 
#LoadModule http2_module modules/mod_http2.so
 ↓
LoadModule http2_module modules/mod_http2.so
 
#LoadModule ssl_module modules/mod_ssl.so
 ↓
LoadModule ssl_module modules/mod_ssl.so

Apache の動作モードが event MPM もしくは worker MPM であることを確認します。Apache バージョン 2.4.27 以降では prefork MPM で HTTP/2(mod_http2)は動作しない ので注意です。

LoadModule mpm_event_module modules/mod_mpm_event.so
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so ← prefork MPM で HTTP/2 は使えない!
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

ServerName のコメントを外しておきます。(ホスト名はご自分の環境に書き換えてください)

#ServerName www.example.com:80
 ↓
ServerName www.example.com:80

SSLの設定ファイルを読込むようにしておきます。

#Include conf/extra/httpd-ssl.conf
 ↓
Include conf/extra/httpd-ssl.conf

続いて、SSL と HTTP/2 の設定です。
vim /usr/local/apache2/conf/extra/httpd-ssl.conf

HTTP/2 は古くて危険と言われている暗号化方式では動作しないため、安全な暗号化方式に変更します。下は設定の一例です。HTTP/2の技術仕様書で推奨されない暗号化方式が確認できます。
RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2) appendix-A

SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
 ↓
SSLCipherSuite "ECDHE-ECDSA-AES128-GCM-SHA256 \
ECDHE-ECDSA-AES256-GCM-SHA384 \
ECDHE-ECDSA-AES128-SHA \
ECDHE-ECDSA-AES256-SHA \
ECDHE-ECDSA-AES128-SHA256 \
ECDHE-ECDSA-AES256-SHA384 \
ECDHE-RSA-AES128-GCM-SHA256 \
ECDHE-RSA-AES256-GCM-SHA384 \
ECDHE-RSA-AES128-SHA \
ECDHE-RSA-AES256-SHA \
ECDHE-RSA-AES128-SHA256 \
ECDHE-RSA-AES256-SHA384 \
DHE-RSA-AES128-GCM-SHA256 \
DHE-RSA-AES256-GCM-SHA384 \
DHE-RSA-AES128-SHA \
DHE-RSA-AES256-SHA \
DHE-RSA-AES128-SHA256 \
DHE-RSA-AES256-SHA256 \
EDH-RSA-DES-CBC3-SHA"

HTTP/2 を有効にするためバーチャルホスト設定の先頭あたりに「Protocols h2 http/1.1」ディレクティブを追加します。Protocolsディレクティブ の初期値は「http/1.1」のため HTTP/2 が使われません。これを「h2 http/1.1」とすることで、WEBブラウザが対応していれば HTTP/2 を使い、対応していなければ HTTP/1.1 を使うようにできます。

<VirtualHost _default_:443>
Protocols h2 http/1.1 ←追加

(関連記事)安全な SSL/TLS 設定にするための10のポイント(Apache httpd 2.4)

systemd サービスファイルの作成

インストールした Apache httpd 用の systemd サービスファイル(起動スクリプトのようなもの)を作成します。

vim /etc/systemd/system/httpd.service

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
 
[Service]
Type=forking
ExecStart=/usr/local/apache2/bin/apachectl start
ExecReload=/usr/local/apache2/bin/apachectl graceful
ExecStop=/usr/local/apache2/bin/apachectl stop
 
[Install]
WantedBy=multi-user.target

作成したサービスファイルを systemd に反映

systemctl daemon-reload

systemd に反映されているか確認

systemctl list-unit-files | grep httpd
httpd.service disabled ←この表示があればOK

起動

systemctl start httpd

自動起動設定

systemctl enable httpd

firewalld設定

HTTP(80/tcp) と HTTPS(443/tcp) を開けておきます。

firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload

・確認
firewall-cmd --list-all

public (default, active)
interfaces: enp0s3 enp0s8
sources:
services: dhcpv6-client ssh
ports: 443/tcp 80/tcp ←この表示があればOK
(略)

ログのローテーション設定

・設定ファイルを作成します
vim /etc/logrotate.d/httpd

/usr/local/apache2/logs/*log { 
    daily 
    missingok 
    dateext 
    rotate 60 
    create 644 daemon daemon
    sharedscripts 
    postrotate 
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript 
}

・確認します
logrotate -dv /etc/logrotate.d/httpd
-----(下記のような表示であればOKです)-----

reading config file /etc/logrotate.d/httpd
 
Handling 1 logs
 
rotating pattern: /usr/local/apache2/logs/*log after 1 days (60 rotations)
empty log files are rotated, old logs are removed
(略)

HTTP/2 の動作確認

WEBブラウザで「https://<アドレス>/」に接続してみると(自己署名のSSL証明書の場合は警告が出ます)、通信プロトコルのバージョンが HTTP/2 になっていることが確認できると思います。

WEBブラウザの開発ツール画面で通信プロトコルを表示

FastCGI PHP の設定

設定の所でもふれましたが Apache で HTTP/2(mod_http2)を動作させるには prefork MPM が使えません。ここで問題となるのが prefork MPM が必須のモジュール版 PHP(mod_php)も使えないことです。

そのため Apache で HTTP/2 を動作させている場合に PHP を使うには FastCGI で PHP を設定する必要がありますので、簡単にその設定方法をご紹介します。

Apache httpd の FastCGIモジュール「mod_fcgid」をインストールします。

cd /usr/local/src/
wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache//httpd/mod_fcgid/mod_fcgid-2.3.9.tar.gz
 
tar xvzf mod_fcgid-2.3.9.tar.gz
cd mod_fcgid-2.3.9/
APXS=/usr/local/apache2/bin/apxs ./configure.apxs
make
make install

・php-cgi のラッパースクリプトを作成します。
vim /usr/local/bin/php-wrapper

#!/bin/sh
export PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_CHILDREN=0
exec /usr/bin/php-cgi

作成したラッパースクリプトのオーナーを、WEBサーバーの実行ユーザー「daemon」に変更し実行権限をつけます。

chown daemon /usr/local/bin/php-wrapper
chmod u+x /usr/local/bin/php-wrapper

Apache を設定します。
vim /usr/local/apache2/conf/httpd.conf

<Directory "/usr/local/apache2/htdocs">
(略)
#Options Indexes FollowSymLinks
 ↓
Options FollowSymLinks ExecCGI
 
# 下記を追加
AddType text/html .php
DirectoryIndex index.php
AddHandler fcgid-script .php
FcgidWrapper /usr/local/bin/php-wrapper .php

Apache を再起動します。

systemctl restart httpd

設定の詳細は「FastCGI PHP の設定方法 と mod_php とのパフォーマンスの比較(Apache httpd)」をご参照ください。

おわりに

少し手軽になった Apache + HTTP/2 のインストールですが、運用の手間を考えると yum 一発でインストールしたいところです。SCLリポジトリあたりで対応してくれるといいですね!

コメント

タイトルとURLをコピーしました