Nginxのリバースプロキシでバックエンドとhttp2通信する

以前書いたとおり、ApacheではリバースプロキシでバックエンドとHTTP2通信することができます。

asnokaze.hatenablog.com

f:id:ASnoKaze:20170531004524p:plain:w450

Nginxの場合は、開発者のメーリングリストGoogleの人が書いてる「ngx_http_v2_upstream」パッチを利用することでバックエンド(upstream)とHTTP2通信することが出来るようになります。

ビルド

環境はUbuntu16.04

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

# 順番にパッチを当ててく
$ patch -p1 < ./1.patch
...

$ ./auto/configure  --with-http_ssl_module --with-http_v2_module
$ make

#今回はインストールしてしまう
$ sudo make install

設定

proxy_http_versionに2.0が指定できるようになります。
proxy_passにhttp://を指定すると、h2cダイレクトでバックエンドと接続しに行きます
(証明書は適当に準備)

#nginx.conf
    proxy_http_version 2.0;

    upstream backend {
        server 127.0.0.1;
    }

    server {
        listen       443 ssl http2;
        server_name  localhost;

        ssl_certificate      /home/yuki/server.crt;
        ssl_certificate_key  /home/yuki/server.key;

        location / {
          proxy_pass http://backend/test;
        }
    }

その他、h2cダイレクトではなくhttpsでプロキシする際に、ALPNを使うように出来るようですがちょっと動作が怪しいようです....

proxy_ssl_alpn on;

動作確認

バックエンドはh2cで接続できるようにしておきます。

#nginx.conf
    server {
        listen       80 http2;
        server_name  localhost;
    }

ブラウザでサーバにアクセスすると、バックエンド(/proxy/)もHTTP/2.0で接続できている事が確認できました

$ tail /var/log/nginx/access.log
127.0.0.1 - - [02/Jul/2017:16:36:40 +0000] "GET /proxy/ HTTP/2.0" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
192.168.0.104 - - [02/Jul/2017:16:36:40 +0000] "GET / HTTP/2.0" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"