【QUIC対応】HTTP/3対応版nginxを使えるようにBoringSSLのビルドからやってみた

RFC9000でHTTP/3が策定されました。最近ではCloudFlareのquicheなどを用いて試験的にHTTP/3を実装することができましたが、nginx純正のHTTP/3対応版が開発されています。

今回はこのnginxを使ってみたいので、BorlingSSLのビルドからやります。

OSはCentOS8です。また、証明書などはすでに取得済みという仮定で説明を行います。以前のnginxのサーバを建てる的な記事[#1]の続きと考えてOKです。

また、rootアカウントで作業することにします。管理者アカウントで”sudo”しても問題ありません。

余談ですが、「リバースプロキシに用いているOSをDebian系に変えようかな~」とか少し思っています。Debian系でも大体同じです。

やったこと

CentOSやソフトのアップデート・ビルドに必要なソフトのインストール

# dnf update
# dnf install git hg cmake golang libunwind-devel pcre-devel zlib-devel gcc gcc-c++

私の環境はこの通りで成功しましたが、入らないソフトがあれば公式サイトでインストール方法をチェックしてみてください。定期的に変わることがあります。

BoringSSLをビルドするためのNinjaをビルド&インストールする

HTTP/3を使うにはGoogleのBoringSSLが必要です。cmakeでもビルド可能ですが、Ninjaを用いると高速にビルドができます。

とりあえず作業用ディレクトリを”/opt/”に作成してから、本題に取り掛かります。

# mkdir /opt/nginx3
# cd /opt/nginx3

# git clone git://github.com/ninja-build/ninja.git && cd ninja
# cmake -Bbuild-cmake -H.
# cmake --build build-cmake

これでninjaがビルドできますので、ninja自体のテストを行います。

# ./build-cmake/ninja_test

成功すればOKです。パスが通っているディレクトリに”ninja”を入れておきます。このディレクトリを通しても良いと思いますが、私は”sbin”に入れちゃいます。

cp ./build-cmake/ninja /usr/sbin/ninja

これでCmakeからninjaを使うことができます。

BoringSSLをビルドする

READMEどおりにやります。

# git clone https://boringssl.googlesource.com/boringssl
# cd boringssl
# mkdir build
# cd build
# cmake -GNinja ..ninja

これでcmakeができます。-GNinjaをつけてエラーが出るならば、”ninja”のパスが通っていない可能性があります。

次に、BoringSSL自体のテストを行います。

# cd ..
# ninja -C build/ run_tests

少々時間がかかります。

HTTP/3対応版nginxをビルドする

これもREADME通りですが、既存のnginxと同じくconfigureにおいて色々指定できますので、自分にあったものを選んでください。

# cd /opt/nginx3
# hg clone -b quic https://hg.nginx.org/nginx-quic
# cd nginx-quic

# ./auto/configure --with-debug --with-http_v3_module       \
                   --with-cc-opt="-I../boringssl/include"   \
                   --with-ld-opt="-L../boringssl/build/ssl  \
                                  -L../boringssl/build/crypto"\
    --prefix=/etc/nginx3/ \
    --sbin-path=/usr/sbin/nginx3 \
    --conf-path=/etc/nginx3/nginx.conf \
    --error-log-path=/var/log/nginx3/error.log \
    --http-log-path=/var/log/nginx3/access.log \
    --pid-path=/run/nginx3.pid \
    --lock-path=/run/nginx3.lock \
    --user=nginx \
    --group=nginx

configure でBoringSSLのライブラリを用いるように設定しています。また、systemdで管理したいのですが、既存のnginxが存在しますので、ここでは”nginx3″という名前にしています。

configure は一瞬で終わります。次にmakeを行いインストールをします。少々時間がかかります。

# make
# make install

一応確認します。

# /usr/sbin/nginx3 -V

それっぽいもの(BoringSSL)が表示されればOKです。

これで、”/etc/nginx3/”というディレクトリにいつもどおりの”nginx.conf”などができていますので、それなりな設定で動きます。ここでは最低限、HTTP/3が動作するような設定ファイルを記しておきます。READMEどおりです。

    http {
        log_format quic '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" "$quic"';

        access_log logs/access.log quic;

        server {
            # for better compatibility it's recommended
            # to use the same port for quic and https
            listen 4433 http3 reuseport;
            listen [::]:4433 http3 reuseport; 
            listen 4433 ssl;
            listen [::]:4433 ssl;
            ssl_certificate     certs/example.com.crt;
            ssl_certificate_key certs/example.com.key;
            ssl_protocols       TLSv1.3;

            location / {
                # required for browsers to direct them into quic port
                add_header Alt-Svc 'h3=":4433"; ma=86400';
            }
        }
    }

systemdの設定ファイルを作る

systemdに慣れていますので、こっちで管理したいです。既存のnginxのsystemdファイルをコピーしても良いですし、nginx公式サイトにも設定が載っているので好[きな方を選んでください。

# nano /lib/systemd/system/nginx3.service

[Unit] Description=The NGINX HTTP/3 and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking ExecStartPre=/usr/sbin/nginx3 -t ExecStart=/usr/sbin/nginx3 ExecReload=/usr/sbin/nginx3 -s reload ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target

[UNIT] 以下の文言をコピペして貼り付ければOKです。その後、

# systemctl daemon-reload
# systemctl start nginx
# systemctl enable nginx

でスタート&自動起動させます。エラーが出たら適宜修正してください。多分、「ディレクトリが無いよ」的なものが多いと思いますので、エラー文記載の場所でmkdirすればよろしいかと思います。

HTTP/3で通信できるかの確認

ブラウザの設定

HTTP/3が策定されて日が浅いため、デフォルトで有効にはなっていません。有効化するには自分で設定する必要があります。

Firefoxの場合

「about:config」から”http3″で検索して、”network.http.http3.enabled”を有効化します。

firefoxの開発者ツールを開いて、ネットワークタブを開き、右クリックをしてプロトコルを表示させると、HTTP/3での通信が確認できました。Wiresharkを使える方は、QUICというプロトコルで通信されていることも確認できるはずです。

nginxのテストページを少しいじってnginx-quicにしています。既存のnginxにも同じファイルがあるので、見分けをつけるためです。

Chrome系の場合

アドレスバーに”chrome://flags/#enable-quic”を入力して、quicの項目をenableに設定します。

http/3対応ページを開き、開発者ツールのネットワークタブでプロトコルを表示させると確認できると思います。

参考文献

それぞれのREADMEを見れば行けるかなとか思っていましたが、インストールするべきライブラリや、ビルドする際のconfigureの引数などはここから引用しました。ありがとうございます。

girlfellfromsky, QUIC及びHTTP/3対応のNGINXサーバーを構築, Qiita,