Nghttp2 のプロキシー nghttpx を使って、HTTP/2 対応の WordPress サイトを設定した時のメモです。nghttpx は、HTTP/2 リクエストを HTTP/1.1 などのリクエストに変換してくれる、便利なプロキシーです。今回は、フロントエンドで HTTP/2 リクエストを nghttpx が受け取り、 バックエンドのWEBサーバ(Apache)に、HTTP/1.1リクエストを送信する構成で設定してみました。
(更新)2017年5月14日 各種インストール手順を最新版に更新しました。
nghttpx には色々な動作モードがあり、今回設定するリバースプロキシーとして使えますし、クライアントプロキシーとしても動作します。詳細は、Nghttp2 の開発者 tatsuhiro-t さんが「http2.0 - HTTP/2 & SPDY プロキシー nghttpx を使う - Qiita」で、分かりやすく解説されています。
構成図
nghttpx と Apache は、同じサーバで稼働させます。
開発ツールのインストール
サーバOSは CentOS7.3 (1611) です。Nghttp2(nghttpx) はソースからコンパイルしますので、基本コマンドと開発ツールをインストールしておきます。
yum -y groupinstall development
OpenSSL 1.0.2 のインストール
ALPN(Application-Layer Protocol Negotiation)に対応している、OpenSSLバージョン1.0.2以上をインストールします。
Google Chrome バージョン51以降は、NPNが削除され、ALPNのみ対応となったようですので、WEBサーバでHTTP/2を使うには、事実上OpenSSL1.0.2以上が必須になります。
Transitioning from SPDY to HTTP/2 | Chromium Blog
まずはじめに OpenSSLのコンパイルに zlib を使うので、インストールしておきます。
OpenSSLのインストール(そこそこの時間がかかります)
wget https://www.openssl.org/source/openssl-1.0.2k.tar.gz
tar xvzf openssl-1.0.2k.tar.gz
cd openssl-1.0.2k/
./config --prefix=/usr/local/openssl-1.0.2k shared zlib
make depend
make
make test
make install
OpenSSL1.0.2 のライブラリにパスを通しておきます。
ldconfig
Nghttp2(nghttpx)のインストール
Nghttp2 が必要とするライブラリのインストール
Nghttp2 のダウンロード
※頻繁にバージョンアップされているようです。ダウンロードの前に最新リリースを確認しましょう。
https://github.com/tatsuhiro-t/nghttp2/releases/latest
wget https://github.com/nghttp2/nghttp2/releases/download/v1.22.0/nghttp2-1.22.0.tar.gz
Nghttp2 のインストール。環境変数 OPENSSL_CFLAGS と OPENSSL_LIBS に先ほどインストールした、OpenSSL1.0.2 のディレクトリパスを指定してコンパイルします。また nghttpx をコンパイルするため「-enable-app」オプションを付けます。
cd nghttp2-1.22.0/
env OPENSSL_CFLAGS="-I/usr/local/openssl-1.0.2k/include" OPENSSL_LIBS="-L/usr/local/openssl-1.0.2k/lib -lssl -lcrypto" ./configure -enable-app
make
make install
/usr/local/bin/ 下に、「nghttpx」などの Nghttp2 のコマンド群がインストールされます。
SSLサーバ証明書(自己署名)の作成
Google Chrome や Firefox など、主要なWEBブラウザが、HTTP/2 接続には HTTPS 暗号化通信を必須としているため、SSLサーバ証明書が必要になります。
・秘密鍵の作成
openssl genrsa 2048 > server.key
・CSR(証明書署名要求)の作成
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) []:<ドメイン名> 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 /etc/pki/tls/private/ mv -i server.crt /etc/pki/tls/certs/
・セキュリティ確保のため nghttpx の実行ユーザ「nghttp2」を作成
useradd -d /run/nghttp2 -s /sbin/nologin nghttp2
・秘密鍵とSSLサーバ証明書のオーナーを「nghttp2」ユーザに変更
chown nghttp2:nghttp2 /etc/pki/tls/private/server.key chown nghttp2:nghttp2 /etc/pki/tls/certs/server.crt chmod 600 /etc/pki/tls/private/server.key chmod 600 /etc/pki/tls/certs/server.crt
・CSRを削除
rm server.csr
nghttpx の設定
・ログファイルの保存先を作成
mkdir /var/log/nghttpx
・nghttpx の設定ファイルを作成します。
mkdir /etc/nghttpx/
vi /etc/nghttpx/nghttpx.conf
# デフォルトモードを指定 http2-proxy=no # 待受アドレスとポート番号 frontend=0.0.0.0,3000 # バックエンド WEBサーバのアドレスとポート番号 backend=127.0.0.1,80 # サーバ秘密鍵 private-key-file=/etc/pki/tls/private/server.key # サーバ証明書 certificate-file=/etc/pki/tls/certs/server.crt # Disable OCSP stapling. 自己署名のSSL証明書を使っている場合は有効にする no-ocsp=yes # 実行ユーザ user=nghttp2 # worker スレッド数 workers=1 # バックエンドWEBサーバとの最大接続数 backend-http1-connections-per-host=128 # 同時に実行できる最大ストリーム数 http2-max-concurrent-streams=100 # ログレベル log-level=NOTICE # アクセスログファイル accesslog-file=/var/log/nghttpx/access_log # エラーログファイル errorlog-file=/var/log/nghttpx/error_log # 接続先ホスト名を、そのままバックエンドに渡す # バックエンドのWEBサーバで、バーチャルホストを使っている場合は必須です no-host-rewrite=yes # X-Forwarded-For をバックエンドに送る add-x-forwarded-for=yes
※当然ですが行末にスペースが入っていると、正しく動作しません。これが原因で、小一時間ほど悩みました。
nghttpx の起動スクリプト作成
・nghttpx 用の systemd設定ファイルを作成します。
vi /etc/systemd/system/nghttpx.service
[Unit] Description=nghttpx After=network.target [Service] Type=simple ExecStart=/usr/local/bin/nghttpx ExecReload=/bin/kill -SIGUSR1 ${MAINPID} ExecStop=/bin/kill -SIGQUIT ${MAINPID} [Install] WantedBy=multi-user.target
・上記設定を systemd に反映
systemctl daemon-reload
・systemd に反映されているか確認
systemctl list-unit-files | grep nghttpx ---(下記のような表示であればOKです)--------------------------- nghttpx.service disabled
・起動
systemctl start nghttpx
・自動起動設定
systemctl enable nghttpx
・「nghttp2」ユーザで、nghttpx が実行されているかを確認します。
ps aux | grep nghttpx ---(下記のような表示であればOKです)--------------------------- nghttp2 8877 0.0 0.1 57344 3944 ? Ss 13:09 0:00 /usr/local/bin/nghttpx
nghttpx のログローテーション設定
・ログローテーションの設定ファイルを作成します
vi /etc/logrotate.d/nghttpx
/var/log/nghttpx/*log { daily missingok dateext rotate 60 sharedscripts postrotate /bin/systemctl reload nghttpx.service > /dev/null 2>&1 endscript }
・確認します
logrotate -dv /etc/logrotate.d/nghttpx ---(下記のような表示であればOKです)--------------------------- reading config file /etc/logrotate.d/nghttpx Handling 1 logs rotating pattern: /var/log/nghttpx/*log after 1 days (60 rotations) empty log files are rotated, old logs are removed considering log /var/log/nghttpx/access_log (略)
バックエンド WEBサーバ(Apache)の設定
Apache httpd をインストールします。
・「X-Forwarded-For」を、出力できるログフォーマット「x-combined」を追加します。
vi /etc/httpd/conf/httpd.conf
<IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined ---(下記を追加)--------------------------- LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" x-combined
・WordPress 用のバーチャルホストを追加します。
ServerName や DocumentRoot は、ご自分の環境に合わせて設定してください。CustomLog のログフォーマットは、上で追加した「x-combined」を指定します。また、環境変数「HTTPS on」を設定しておきます。(WordPress がこの値を参照します)
vi /etc/httpd/conf/httpd.conf
---(下記を追加)--------------------------- <VirtualHost *:80> SetEnv HTTPS on ServerName example.com DocumentRoot "/var/www/html" <Directory "/var/www/html"> Options FollowSymLinks AllowOverride All <files wp-config.php> order allow,deny deny from all </files> Require all granted </Directory> SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog ErrorLog logs/error_log CustomLog logs/access_log x-combined env=!nolog </VirtualHost>
WordPressのインストールは「WordPress インストールメモ(CentOS)」の記事をご参照ください。
動作確認
「https://<アドレス>:3000/」に、HTTP/2 対応のWEBブラウザで接続すると、HTTP/2 プロトコルを使って通信していることが確認できます。Safari など、HTTP/2 に対応していないWEBブラウザの場合は、自動的に nghttpx が HTTP/1.1 を使って通信してくれます。
※サーバに接続できない場合は、firewallでブロックされているかもしれません。以下のコマンドで3000/tcp の接続を許可しておきましょう。
firewall-cmd --add-port=3000/tcp --permanent firewall-cmd --reload
(2015年5月18日追記)
WordPress の管理画面にも、問題なくログインできます。ありがとうございました!(^^)
終わりに
2015年4月27日、HTTP/2 のRFC番号が、RFC7540 (HTTP/2)、 RFC7541(HPACK) に決まったようです。RFCの文章化が目前ですね!
コメント