RFC9000

序章

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

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

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

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

やったこと

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をビルドする

公式の解説 どおりにやります。

# 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

configureBoringSSLのライブラリを用いるように設定しています。また、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
# 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というプロトコルで通信されていることも確認できるはずです。

Firefox-HTTP3

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

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

Brave-setting-http3

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

Brave-HTTP3