Web、サーバ、ソフトウェア、バグ・脆弱性 などの情報を何人かで集まって書いていく IT/Web情報系ブログ

Nginx+LiteSpeedでHTTP/2(h2c)を使用する

投稿日:   最終更新日:2017/09/06  投稿者:ktm@s

このブログのウェブサーバーは記事作成現在OpenLiteSpeedを使っている。

少し前にこのブログをApache2+PHP7環境に移行してWordPressの動作が速くなった。ついでにWebサーバーもApache2より速いと噂のOpenLiteSpeedに変えてみたら更に速くなった。そんなOpenLiteSpeed(とPHP7)でWordPressを動かすところまでを書く。環境Debian GNU/Linux 8.8 (jessie)OpenLiteSpeed 1.4.26PHP 7.1.6MySQL 5.5必要なパッケージを入れるapt-get install curl gcc make g++ zlib1g-dev libpcre3-dev libssl-dev libgeoip-dev libxml2-dev libpng-dev libexpat1-devOpenLiteSpeedのビルドとインストールlibssl-devを入れてるのに...

OpenLiteSpeed+PHP7のページ表示速度はApache2+PHP7と比較してはるかに向上してるように感じる。
それはLiteSpeed自体の処理の速さに加えて新たにHTTP/2のServerPush機能を使っていることも大きいし、他にもウェブ管理画面が楽という個人的に大きなメリットがある。
(もちろんHTTP/2はApache2でもNginxでも使える)

これと言った不満もないため、うちの自宅サーバーのウェブサーバーもApache2からOpenLiteSpeedに乗り換えようと思ったのだが、フロントにNginxを置いてリバースプロキシとして使っているため、HTTP/2通信をする為にどのような設定が必要になるのか?という点で全て通して説明されている日本語の参考サイトが見当たらなかった。

本記事ではフロントエンドにNginx(リバースプロキシ)を置いてバックエンドにOpenLiteSpeedという構成でHTTP/2を使う設定を書く。

環境

Nginx,OpenLiteSpeedそれぞれにDebian Jessie(8.8)を新たにインストールして設定した。
Debian9だと記事作成時点ではLiteSpeedのPHP7がまだ対応されていないので注意。

Nginxには「ngx_http_v2_upstream」パッチを当てる必要がある。
また、Debian8.8のOpenSSLはデフォルトで1.0.1tだが、OpenSSL1.0.2以上である必要があるようだ。

  • Nginx 1.13.2
  • OpenLiteSpeed 1.4.26
  • OpenSSL 1.0.2

スポンサーリンク

Nginxのビルド

Nginx側のインストールに関しては以下のページが非常に参考になった。
本記事の手順もほぼそのままなのだが、OpenLiteSpeedと組み合わせる上での修正や新たにインストールしないといけないパッケージがあるため、内容の重複はあるが詳細手順を書く。

以前書いたとおり、ApacheではリバースプロキシでバックエンドとHTTP2通信することができます。asnokaze.hatenablog.comNginxの場合は、開発者のメーリングリストでGoogleの人が書いてる「ngx_http_v2_upstream」パッチを利用することでバックエンド(upstream)とHTTP2通信することが出来るようになります。 パッチ Output chain: propagate last_buf flag to c->send_chain() Upstream keepalive: pr…

必要パッケージのインストール

PCREライブラリとOpenSSLライブラリは新規インストールしたDebianではインストール必須だった。
何故かmakeもgccもcurlも入ってないので入れておく。

インストール

sudo apt-get install mercurial libpcre3-dev libssl-dev make gcc curl

nginxのクローン作成

パッチファイルにあわせたバージョンにupdateする。

hg clone http://hg.nginx.org/nginx/
cd ./nginx
hg update -r 7039

OpenSSL1.0.2のダウンロード

Debian8.8のOpenSSLは1.0.1tだが、諸々の事情で1.0.2が必要になる。

wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz
tar -xvzf openssl-1.0.2h.tar.gz 

詳細が知りたい人は以下のページを参照。

# ssl対応でサイトパフォーマンスがあがるらしいあるサイトのはじめてのSSL対応の作業中、「**SSL対応するとはやくなるで!!**」(https://hyper-text.org/archives/2015/01...

パッチファイルの保存

NginxにGoogleの人が作ったパッチをあてる必要があるので保存しておく。
diffから終わりまでを1.patchから連番で保存する。

次に先ほど保存したパッチファイルを順にあてていく。
パッチファイルのパスは保存場所に応じて適当に読み替える。

patch -p1 < ./1.patch
patch -p1 < ./2.patch
patch -p1 < ./3.patch
patch -p1 < ./4.patch
patch -p1 < ./5.patch
patch -p1 < ./6.patch
patch -p1 < ./7.patch
patch -p1 < ./8.patch
patch -p1 < ./9.patch
patch -p1 < ./10.patch
patch -p1 < ./11.patch
patch -p1 < ./12.patch
patch -p1 < ./13.patch
patch -p1 < ./14.patch

ビルド

usernameをユーザー名に変更し、OpenSSL1.0.2ディレクトリへの正しいパスにすること。

./auto/configure  --with-http_ssl_module --with-http_v2_module --with-openssl=/home/username/openssl-1.0.2h
make

sudo make install

インストール場所や起動・停止など

aptでインストールしたNginxと違い、/usr/local/nginxにインストールされる。

#起動
sudo /usr/local/nginx/sbin/nginx

#再起動
sudo /usr/local/nginx/sbin/nginx -s reload

#停止
sudo /usr/local/nginx/sbin/nginx -s stop

#バージョン確認
sudo /usr/local/nginx/sbin/nginx -V

aptでインストールしたNginxから設定を移植したい場合

DebianでNginxをapt-get installすると /etc/nginx にNginxがインストールされてconf.dディレクトリにリバースプロキシの設定を放り込むことになる。
今回ビルドしたNginxでは/usr/local/nginx/conf/nginx.confに全ての設定を書くことになるため、設定は全てnginx.conf内の適切な場所にコピペしてあげると動く。
(confディレクトリに持ってくるだけではダメ)

OpenLiteSpeedのインストール

インストールまではxx2zzの記事をそのまま使えばよいが、ビルド前に必要な処理があるので記す。

少し前にこのブログをApache2+PHP7環境に移行してWordPressの動作が速くなった。ついでにWebサーバーもApache2より速いと噂のOpenLiteSpeedに変えてみたら更に速くなった。そんなOpenLiteSpeed(とPHP7)でWordPressを動かすところまでを書く。環境Debian GNU/Linux 8.8 (jessie)OpenLiteSpeed 1.4.26PHP 7.1.6MySQL 5.5必要なパッケージを入れるapt-get install curl gcc make g++ zlib1g-dev libpcre3-dev libssl-dev libgeoip-dev libxml2-dev libpng-dev libexpat1-devOpenLiteSpeedのビルドとインストールlibssl-devを入れてるのに...

ビルド前に必要な処理

src/http/ntwkiolink.cpp を編集し、HTTP2_PLAIN_DEVを有効にする。
xx2zzの調査によると、HTTP2_PLAIN_DEVが無効のままビルドすると、強制的にHTTPとしてh2cのデータを処理しようとして400エラーが出る。
HTTP2_PLAIN_DEVを有効にすると、逆にHTTP/2以外の通信(HTTP, SPDY)を受け付けなくなることに注意。

65行目のコメントアウト(//)をはずす。

//#define HTTP2_PLAIN_DEV
↓
#define HTTP2_PLAIN_DEV

実行ユーザー・グループを変更したい場合

そのままインストールすると、実行ユーザー・グループがnouser:nogroupになる。
これを任意のユーザー・グループ(例えばwww-data:www-data)に変更したい場合、ビルド時のオプションに「–with-user=www-data –with-group=www-data」を追加してやる事で指定できる。

./configure --with-openssl=/usr --enable-http2 --with-user=www-data --with-group=www-data

HTTP/2通信するための設定(Nginx側)

パッチを当てたことにより「proxy_http_version 2.0;」が指定可能になる。

HTTPS化

NginxでLet’sEcnrypt証明書を取得するための設定を反映させる。
証明書を取得する過程でドキュメントルートに指定したディレクトリにファイルを作ってhttpで確認しにくるため、証明書取得のための設定を先に書く。

nginx.confの設定

sudo vi /usr/local/nginx/conf/nginx.conf

server {
    listen 80;
    server_name ドメイン;

    location ^~ /.well-known/acme-challenge {
        root ドキュメントルート;
    }
}

再起動して反映。

sudo /usr/local/nginx/sbin/nginx -s reload

Let’sEncrypt証明書の取得

apt-get install git
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto certonly --webroot -w ドキュメントルート -d ドメイン -m 適当なメールアドレス --agree-tos
openssl dhparam 2048 -out /etc/letsencrypt/live/ドメイン/dhparam.pem

HTTP/2を使うための設定

sudo vi /usr/local/nginx/conf/nginx.conf

server {
    proxy_http_version 2.0;

    #証明書更新の際に80が必要
    listen 80;
    listen 443 ssl http2;
    server_name ドメイン;

    #Let's Encrypt用
    location ^~ /.well-known/acme-challenge {
        root ドキュメントルート;
    }

    ssl_certificate /etc/letsencrypt/live/ドメイン/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ドメイン/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/letsencrypt/live/ドメイン/dhparam.pem;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass LiteSpeedのIP;
    }
}

再起動して反映。

sudo /usr/local/nginx/sbin/nginx -s reload

HTTP2通信するための設定(LiteSpeed側)

管理画面にログインして設定を行う。
Nginx⇔LiteSpeed間はh2cなのでリスナーは80だけで良い。SSL証明書も関連の設定も不要。

  1. サーバー → 一般 → 「HTTP/2 Over Cleartext TCPを有効にする」を「はい」に
  2. リスナー → SSL → 「SPDY/HTTP2を有効にする」の「HTTP2」にチェックを入れる

その後バーチャルホスト設定を適当に行ってLiteSpeedを再起動する。

確認その他

HTTP/2が使えているか

HTTP/2が使えているかChromeのデベロッパーツールなんかで確認する。
Networkでプロトコルを表示させてh2になっていればOK。

ただし、Nginx-OpenLiteSpeed間はtcpdumpしないとわからない。

LiteSpeed側でクライアントIPを取得する

デフォルトだとログにはNginxのIPアドレスが記録されてしまう。
正しいクライアントIPを取得するためにはLiteSpeedの管理画面で以下の通り設定する。

  • サーバー設定 → 一般 → 「ヘッダーにクライアントIPを使用する」を「はい」

なおNginx側で以下のヘッダーをセットする必要がある。
(この記事の通りに設定した場合はすでに書いてある)

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

あとがき

以上でフロントエンドにNginx、バックエンドにOpenLiteSpeedという構成でHTTP/2が使えるようになった。
LiteSpeedは非常に軽くPHP7も普通に使えるのでお勧めできる。
無償版ではrewriteは使えてもhtaccessは使えないのだが、そのあたりに書きたいことは管理画面で設定したほうがむしろ楽だったりするのでApache2と比較してデメリットは感じない。

LiteSpeedに関しては以下の記事と被る部分はできるだけ省いたのでこちらも確認して欲しい。

少し前にこのブログをApache2+PHP7環境に移行してWordPressの動作が速くなった。ついでにWebサーバーもApache2より速いと噂のOpenLiteSpeedに変えてみたら更に速くなった。そんなOpenLiteSpeed(とPHP7)でWordPressを動かすところまでを書く。環境Debian GNU/Linux 8.8 (jessie)OpenLiteSpeed 1.4.26PHP 7.1.6MySQL 5.5必要なパッケージを入れるapt-get install curl gcc make g++ zlib1g-dev libpcre3-dev libssl-dev libgeoip-dev libxml2-dev libpng-dev libexpat1-devOpenLiteSpeedのビルドとインストールlibssl-devを入れてるのに...

- Nginx, OpenLiteSpeed , , , ,

Message

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

関連記事