元記事と経緯
CentOS7でHTTP/1.1・HTTP/2・HTTP/3完全対応のnginxを使用したく、検索していたらこの記事を見かけました。
QuicheのパッチはどうやらHTTP/3が実験的なものだった時のパッチらしく、OpenSSLのGoogleフォークであるBoringSSLを利用したほうが今後苦労しないだろう、と考えこの構成に至りました。
が、私はninja
をビルドしている暇もなく、 そもそもnpmがなんなのかよく理解していません。 パッケージのインストールにつかわれるもの??くらいな認識です。1
要求ソフトウェアのアップデート
Cmake
BoringSSLにCmake 3.10以上が必要です。
CentOS7のyumでは2.8.12しかインストールできません。そのため、Cmakeをソースからインストールします。
記事執筆時点での最新版v3.25.1
を使用していますが、より新しいバージョンに各自置き換えてください。
$ wget https://github.com/Kitware/CMake/releases/download/v3.25.1/cmake-3.25.1-linux-x86_64.sh
$ sh cmake-3.25.1-linux-x86_64.sh
インストーラーが起動します。
CMake Installer Version: 3.25.1, Copyright (c) Kitware
This is a self-extracting archive.
The archive will be extracted to: /root/cmake
If you want to stop extracting, please press <ctrl-C>.
CMake - Cross Platform Makefile Generator
Copyright 2000-2022 Kitware, Inc. and Contributors
All rights reserved.
(中略)
Do you accept the license? [yn]: y
Cmakeのインストール先を聞かれます。違いがよくわからないのでとりあえずNoを選択し、自分で/usr/local/
にインストールします。
By default the CMake will be installed in:
"/root/cmake/cmake-3.25.1-linux-x86_64"
Do you want to include the subdirectory cmake-3.25.1-linux-x86_64?
Saying no will install in: "/root/cmake" [Yn]: n
Using target directory: /root/cmake
Extracting, please wait...
Unpacking finished successfully
自分で/usr/local/
にぶち込みます。mvだと上書きしたときに絶望的なので、cpを使用しましょう。
$ cp -r bin doc man share /usr/local/
Cmakeが最新版になりました。
$ cmake --version
cmake version 3.25.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
Perl
BoringSSLにPerlが必要です。これはyumで問題ないのでyumでインストールします。
sudo yum install perl
Go
BoringSSLにGoが必要です。(BoringSSL要求ソフトウェア多くね?)これもyumでインストールします。
sudo yum install golang
gcc
CentOS7標準の4.8.5ではバージョンが古く、アップデートする必要があります。
そのため、yumでdevtoolset-11をインストールし、PATHを通した後gccを使用します。
devtoolset-11はレポジトリcentos-release-sclに含まれているので、centos-release-sclをインストールしてからdevtoolset-11をインストールします。
$ yum install centos-release-scl
$ yum install devtoolset-11
もしこれを実行したのであれば、BoringSSLのcmake
時に以下のコマンドを実行してください。
export PATH=/opt/rh/devtoolset-11/root/bin:$PATH
競合ライブラリのアンインストール
OpenSSL
すでにOpenSSLをインストールしてしまっている場合、アンインストールしないとBoringSSLと競合する(と思われる)ので、アンインストールします。
yumでアンインストール
$ sudo yum remove uninstall
make installしたものをアンインストール
$ cd /path/to/source/openssl
$ sudo make uninstall
必要ライブラリのインストール
BoringSSL
こちらも、BUILDING.md
の通りにインストールします。
が、このままでは意図しない場所2にインストールされてしまうので、configureではなくcmakeにprefixを設定します。各自で設定してください。
$ git clone https://github.com/google/boringssl.git
# cd boringssl
$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local/lib/boringssl ..
$ make
$ make install
$ # リンカにlibssl.aやlibcrypto.aなどの静的ライブラリを読み込ませる必要があるので、コピーする
$ cp */*.a /usr/local/lib/boringssl/lib/
もしgccアップデートのためにdevtoolset-11のアップデートを実行したのであれば、BoringSSLのcmake
前に以下のコマンドを実行してください。
BoringSSLがcmakeでC++11対応のgccを要求するためです。
export PATH=/opt/rh/devtoolset-11/root/bin:$PATH
Nginxのインストール
いよいよNginxをインストールします。
Nginxは記事執筆時点での最新版の1.23.2でもQUICにはまだ対応していないので、nginx-quicのリポジトリからダウンロードします。
Nginxが既に存在している場合は、各自オプションの値を変更してください。
$ wget -O nginx.tar.gz https://hg.nginx.org/nginx-quic/archive/quic.tar.gz
$ tar -zxvf nginx.tar.gz
$ cd nginx-quic-quic/
$ ./auto/configure --with-debug \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-stream_quic_module \
--with-cc-opt="-I/usr/local/lib/boringssl/include" \
--with-ld-opt="-L/usr/local/lib/boringssl/lib" \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/nginx.lock \
--user=nginx \
--group=nginx
$ make
$ make install
私の場合、Nginxをリバースプロキシとして利用する予定があったので、とりあえずいろいろ入れておけば今後再ビルドしなくていいだろうと思い、いろいろオプションをつけることにしました。
$ ./auto/configure --with-debug \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-stream_quic_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-mail \
--with-mail_ssl_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_realip_module \
--with-cc-opt="-I/usr/local/lib/boringssl/include" \
--with-ld-opt="-L/usr/local/lib/boringssl/lib" \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/nginx.lock \
--user=nginx \
--group=nginx
systemdに追加する
こんな感じのサービスファイルを入れてやれば動きます。3
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
トラブルシューティング
nginx: [emerg] getpwnam("nginx") failed
ユーザーが存在しないことによるエラーです。
上のコマンドとで「nginx」ユーザー、「nginx」グループで作成していれば下記コマンドで作成できます。
$ groupadd nginx
$ sudo useradd -g nginx -s /sbin/nologin -r nginx
ちなみに(割と困る話)
listen 443 http3 reuseport;
reuseportをつけないとHTTP/3は使用されません。
しかし、reuseportは複数使用できないようです。
nginx: [emerg] duplicate listen options for 0.0.0.0:443 in /etc/nginx/conf.d/virtualhost.conf:5
nginx: configuration file /etc/nginx/nginx.conf test failed
つまり、HTTP/3のNginxでは複数ドメインをホストできません。4
早くHTTP/3普及してくれー。サーバーソフトウェアは簡単に変えられないんだぞ。5
さて。私はインストールしたNginxを止めてApacheに戻してきます。