LoginSignup
3
3

More than 1 year has passed since last update.

HTTP/3対応のNginxをUbuntu 20.04で構築する(Vagrant版)

Last updated at Posted at 2022-01-17

概要

Welcome to the demo site for nginx-quic」を参考にHTTP/3に対応したNginxの構築を行います。
※既に同じような記事がたくさん書かれていますが、微妙に構築手順に差異があったので自分用としてまとめてみました。

動作環境

  • ホストOS: macOS Monterey 12.0.1(Intel Core i7)
  • Vagrant: 2.2.19
  • VirtualBox: 6.1.30
  • ゲストOS: Ubuntu 20.04 LTS
  • HTTP/3対応のwebサーバー: Nginx 1.21.5
  • HTTP/3対応のwebクライアント: curl 7.82.0-DEV

仮想環境の構築

「Ubuntu 20.04 LTS」の Vagrantfile を作成します。

$ vagrant init ubuntu/focal64

オリジナルの Vagrantfile をコピーします。

$ cp Vagrantfile Vagrantfile.orig

Vagrantfile の最下行に以下を追記します。(メモリのサイズに関しては環境に応じて適宜設定してください)

% diff Vagrantfile Vagrantfile.orig
70,72d69
<   config.vm.provider "virtualbox" do |vb|
<     vb.memory = "8192"
<   end

仮想環境を起動します。

$ vagrant up

仮想環境にSSHログインします。

$ vagrant ssh

各パッケージを更新します。

$ sudo apt -y update
$ sudo apt -y upgrade

BoringSSLをインストール

Experimental QUIC support for nginx」の「2. Installing」を参照すると、「You will need a BoringSSL library that provides QUIC support」とあるので、まずは BoringSSL をインストールします。
BoringSSL は「BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.」とのこと。

Building BoringSSL」のBuild Prerequisitesを参照すると以下のような記述があるため、必要なパッケージをそれぞれインストールします。

CMake 3.5 or later is required.

CMake が必要。 → cmake をインストールします。

Building with Ninja instead of Make is recommended

ビルド時は Make よりも Ninja がオススメ。 → ninja-build をインストールします。(あとの手順で make も必要なので一緒にインストールします)

C and C++ compilers with C++11 support are required.

C と C++ のコンパイラが必要。 → gcc と g++ をインストールします。

The most recent stable version of Go is required.

Goの安定版が必要。 → golang をインストールします。

the tests have an optional libunwind dependency

テストが libunwind に依存。 → libunwind-dev をインストールします。

また、 BoringSSL のページの「Clone this repo」を見ると、Gitでリポジトリを管理しているようなので、 git も一緒にインストールします。

$ sudo apt -y install \
cmake \
ninja-build \
make \
gcc \
g++ \
golang \
libunwind-dev \
git

Building BoringSSL」のBuildingの手順のとおりにインストールを行います。

$ cd ~
$ git clone https://boringssl.googlesource.com/boringssl
$ cd boringssl
$ mkdir build && cd $_
$ cmake -GNinja ..
$ sudo ninja

インストール後にテストを行う場合は「Running Tests」を参考に行います。

$ cd ..
$ sudo ninja -C build run_tests

Nginxをインストール

Experimental QUIC support for nginx」の「2. Installing」を参照すると hg コマンドを利用しているので、 mercurial をインストールします。

$ sudo apt -y install mercurial

「2. Installing」の手順に沿ってインストールを進めると、以下のようなエラーが発生する場合があります。

./auto/configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
./auto/configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.

インストールを進める上で「PCRE library」と「zlib library」が必要とのことなので、事前に libpcre3-dev と zlib1g-dev をインストールしておきます。

$ sudo apt -y install libpcre3-dev zlib1g-dev

Experimental QUIC support for nginx」の手順のとおりにインストールを行います。

$ cd ~
$ 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"
$ make
$ sudo make install

nginx コマンドの「-V」オプションでインストール時のオプション等を確認します。

$ /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.21.5
built by gcc 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04) 
built with OpenSSL 1.1.1 (compatible; BoringSSL) (running with BoringSSL)
TLS SNI support enabled
configure arguments: --with-debug --with-http_v3_module --with-cc-opt=-I../boringssl/include --with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto'

SSL証明書の作成

Homebrew を利用するため https://brew.sh/ の手順に従いインストールします。

$ cd ~
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
・
・
==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/vagrant/.profile
    eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
- Install Homebrew's dependencies if you have sudo access:
    sudo apt-get install build-essential
  For more information, see:
    https://docs.brew.sh/Homebrew-on-Linux
- We recommend that you install GCC:
    brew install gcc
- Run brew help to get started
- Further documentation:
    https://docs.brew.sh

インストールの最後に表示されている「Next steps」の指示通りコマンドを実行します。

$ echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/vagrant/.profile
$ eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

brew コマンドが実行できるか確認します。

$ brew -v
Homebrew 3.3.10
Homebrew/homebrew-core (git revision 9188a0a50d5; last commit 2022-01-17)

mkcert をインストールします。

$ brew install mkcert

自己認証局を設定します。

$ mkcert -install
Created a new local CA 💥
The local CA is now installed in the system trust store! ⚡️

mkcert へのパスが通っていない root ユーザーで実行するため事前にフルパスを確認します。

$ which mkcert
/home/linuxbrew/.linuxbrew/bin/mkcert

SSL証明書を作成します。

$ sudo mkdir /usr/local/nginx/conf/certs && cd $_
$ sudo /home/linuxbrew/.linuxbrew/bin/mkcert localhost

Created a new certificate valid for the following names 📜
 - "localhost"

The certificate is at "./localhost.pem" and the key at "./localhost-key.pem" ✅

It will expire on 17 April 2024 🗓

SSL証明書がカレントディレクトリに作成されていることを確認します。

$ ls -l localhost*
-rw------- 1 root root 1704 Jan 17 03:46 localhost-key.pem
-rw-r--r-- 1 root root 1464 Jan 17 03:46 localhost.pem

Nginxの設定ファイルの準備

Experimental QUIC support for nginxの「3. Configuration」を参考に nginx.conf を修正します。

オリジナルの nginx.conf をコピーします。

$ sudo cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.orig

nginx.conf に以下を追記します。

$ diff /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.orig 
117,137d116
<     log_format quic '$remote_addr - $remote_user [$time_local] '
<                     '"$request" $status $body_bytes_sent '
<                     '"$http_referer" "$http_user_agent" "$http3"';
< 
<     access_log logs/access.log quic;
< 
<     server {
<         # for better compatibility it's recommended
<         # to use the same port for quic and https
<         listen 8443 http3 reuseport;
<         listen 8443 ssl;
< 
<         ssl_certificate     certs/localhost.pem;
<         ssl_certificate_key certs/localhost-key.pem;
<         ssl_protocols       TLSv1.3;
< 
<         location / {
<             # required for browsers to direct them into quic port
<             add_header Alt-Svc 'h3=":8443"; ma=86400';
<         }
<     }

nginx.conf のチェックを行います。

$ sudo /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

systemd経由でNginxを起動するため、「NGINX systemd service file」を参考に制御用のファイルを作成します。

$ cat /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Nginxの起動

以下のコマンドでNginxを起動します。

$ sudo systemctl start nginx.service

ポート8443がLISTEN状態であることを確認します。

$ ss -lnt |grep ':8443'
LISTEN   0        511              0.0.0.0:8443          0.0.0.0:* 

標準でインストールされている curl コマンドでレスポンスが返ってくるか確認します。

$ curl -I https://localhost:8443
HTTP/1.1 200 OK
Server: nginx/1.21.5
Date: Mon, 17 Jan 2022 04:25:35 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 17 Jan 2022 03:04:29 GMT
Connection: keep-alive
ETag: "61e4dcbd-267"
Alt-Svc: h3=":8443"; ma=86400
Accept-Ranges: bytes

HTTP/3に対応した curl コマンドをインストール

curl のリポジトリの「HTTP3 (and QUIC)」を参考にHTTP/3に対応した curl コマンドのインストールを行います。

今回は「quiche version」の手順に従ってインストールを行います。

必要なパッケージをインストールします。

$ sudo apt -y install cargo autoconf libtool

quiche と BoringSSL のインストールを行います。

$ cd ~
$ git clone --recursive https://github.com/cloudflare/quiche
$ cd quiche
$ cargo build --package quiche --release --features ffi,pkg-config-meta,qlog
$ mkdir quiche/deps/boringssl/src/lib
$ ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) quiche/deps/boringssl/src/lib/

curl のインストールを行います。(configure実行時に「HTTP3 enabled but marked EXPERIMENTAL. Use with caution!」というメッセージが表示されますので、あくまで検証用途としての利用に留めておいた方がよさそうですね)

$ cd ..
$ git clone https://github.com/curl/curl
$ cd curl
$ autoreconf -fi

$ ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-openssl=$PWD/../quiche/quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release
  ・
  ・
  WARNING:  HTTP3 enabled but marked EXPERIMENTAL. Use with caution!

$ make
$ sudo make install

src ディレクトリ配下にHTTP/3対応の curl コマンドがインストールされたことを確認します。

$ ./src/curl --version
curl 7.82.0-DEV (x86_64-pc-linux-gnu) libcurl/7.82.0-DEV BoringSSL zlib/1.2.11 quiche/0.10.0
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS HSTS HTTP3 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL UnixSockets

HTTP/3対応の curl コマンドでHTTPリクエストを実行

先程インストールしたHTTP/3に対応した curl コマンドに「--http3」オプションを付与してリクエストを行うと、「HTTP/3 200」という結果が返ってくることが確認できました。

$ ./src/curl -I https://localhost:8443 --http3
HTTP/3 200
server: nginx/1.21.5
date: Mon, 17 Jan 2022 05:08:36 GMT
content-type: text/html
content-length: 615
last-modified: Mon, 17 Jan 2022 03:04:29 GMT
etag: "61e4dcbd-267"
alt-svc: h3=":8443"; ma=86400
accept-ranges: bytes

参考URL

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3