Experimenting with NGINX
This page describes how to enable support for some features on NGINX, i.e. post-quantum schemes or QUIC protocol. Page is updated on as-needed bases, some parts of it may be specific to Debian Linux.
Sources
I’ll get NGINX sources, change it’s the build configuration, re-compile the server and rebuild deb
package. To get sources, we have to add the NGINX repositories to the /etc/apt/sources/list
.
The following two lines go to the end of a file:
://nginx.org/packages/mainline/debian buster nginx
deb https-src https://nginx.org/packages/mainline/debian buster nginx deb
Then add NGINX public key for verification and download the sources:
sudo wget https://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
sudo apt-get update
sudo apt-get upgrade
sudo apt-get build-dep nginx
sudo apt-get source nginx
Sources should now be downloaded to the nginx
directory.
Link NGINX with the BoringSSL
My current setup of HTTP server uses bssl
. The choice comes from the fact that it’s simpler, documentation is clearer and it contains more modern features (or those I’m intersted in).
To link NGINX with BoringSSL, one needs to copy the sources to nginx/debian/modules
and compile it.
cd nginx/debian/modules/ &&
git clone https://github.com/google/boringssl
mkdir -p boringssl/build && cd boringssl/build
cmake .. && make -j 8
Following step instructs NGINX to use BoringSSL instead of OpenSSL (used by default). To do that, one needs to modify the rules file nginx/debian/rules
.
config.status.nginx: config.env.nginx
cd $(BUILDDIR_nginx) && \
CFLAGS="" ./configure {...} --with-stream_ssl_preread_module \
--with-cc-opt="-I$(CURDIR)/debian/modules/boringssl/include $(CFLAGS) -Wno-ignored-qualifiers" \
--with-ld-opt="-L$(CURDIR)/debian/modules/boringssl/build/ssl \
-L$(CURDIR)/debian/modules/boringssl/build/crypto""
Example above shows how to modify a “release” target, but if needed, debug target can be modified in exact same way. Notice that -Wno-ignored-qualifiers
has been added. That’s because BoringSSL throws compilation warnings, which become errors in the NGINX build.
Adding QUIC support
The QUIC protocol specified by RFC9000 opens new possibilities. Something I would definitely like to try. Clone the newest version and overwrite whatever is currently provided by NGINX.
hg clone -b quic https://hg.nginx.org/nginx-quic
rsync -r nginx-quic/ nginx
Again, the rules file needs to be modified to enable the support. Add --with-http_v3_module --with-http_quic_module --with-stream_quic_module
to config.env.nginx
and config.env.nginx_debug
targets (somewhere after --with-stream_ssl_preread_module
).
Package creation
Following commands re-create debian package with NGINX, which the can be installed by dpkg
. This two step procedure requires, first to modify nginx/debian/changelog
file and add information about changes done to the package. Add something like:
nginx (1.21.0-2~buster) buster; urgency=low
* 1.21.0-1 adds quic
-- Kris Kwiatkowski <kris@amongbytes.com> Tue, 12 Jun 2021 16:01:22 +0300
Next step is to build a package. Build process will use GPG key to sign the package. To specify a key I use -kkris@amongbytes.com
which identify secret key used for signing.
To start the build use following command:
sudo dpkg-buildpackage -b -kkris@amongbytes.com
NGINX configuration
Following instructions enable post-quantum in TLS and add support for QUIC protocol (unfortunatelly, PQ in QUIC is not supported).
- Post-Quantum support: BoringSSL supports post-quantum key exchange. It can be enabled only in TLS v1.3 and uses a variant of NTRU-HRSS mixed with X25519, called
CECPQ2
(detailed description here). To enable that support, following line needs to be added to nginx.conf
ssl_protocols TLSv1.2 TLSv1.3; # Enable both TLS 1.3 and 1.2
ssl_ecdh_curve CECPQ2:X25519:P-256; # Enable PQ key exchange
It is important to add CECPQ2 as a first on that list as well as add some classical key exchange algorithm for backward compatibility. This server supports post-quantum key exchange.
- QUIC support: for HTTP/3 over QUIC add following changes to the virtual server config:
server{
listen 443 http3 quic reuseport;
listen 443 ssl http2;
quic_retry on;
ssl_early_data on;
http3_max_field_size 5000;
http3_max_table_capacity 50;
http3_max_blocked_streams 30;
http3_max_concurrent_pushes 30;
http3_push 10;
http3_push_preload on;
add_header alt-svc '$quic=":443"; ma=3600';
The add_header alt-svc is need to make sure that the web browser will know that your server supported http/3. Other settings also need to setup in order for the NGINX QUIC not to produce 404 error on your file assets.