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.


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:

1deb buster nginx
2deb-src buster nginx

Then add NGINX public key for verification and download the sources:

1sudo wget
2sudo apt-key add nginx_signing.key
3sudo apt-get update
4sudo apt-get upgrade
5sudo apt-get build-dep nginx
6sudo 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.

1cd nginx/debian/modules/ &&
2git clone
3mkdir -p boringssl/build && cd boringssl/build
4cmake .. && 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.

1config.status.nginx: config.env.nginx
2	cd $(BUILDDIR_nginx) && \
3	CFLAGS="" ./configure {...} --with-stream_ssl_preread_module \
4	--with-cc-opt="-I$(CURDIR)/debian/modules/boringssl/include $(CFLAGS) -Wno-ignored-qualifiers" \
5	--with-ld-opt="-L$(CURDIR)/debian/modules/boringssl/build/ssl \
6	-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.

1hg clone -b quic
2rsync -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:

1nginx (1.21.0-2~buster) buster; urgency=low
3  * 1.21.0-1 adds quic
5 -- Kris Kwiatkowski <>  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 which identify secret key used for signing.

To start the build use following command:

1sudo dpkg-buildpackage -b

NGINX configuration

Following instructions enable post-quantum in TLS and add support for QUIC protocol (unfortunatelly, PQ in QUIC is not supported).

  1. 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
1	ssl_protocols TLSv1.2 TLSv1.3;      # Enable both TLS 1.3 and 1.2
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.

  1. QUIC support: for HTTP/3 over QUIC add following changes to the virtual server config:
 2    listen 443 http3 quic reuseport;
 3    listen 443 ssl http2;
 5    quic_retry on;
 6    ssl_early_data on;
 8    http3_max_field_size 5000;
 9    http3_max_table_capacity 50;
10    http3_max_blocked_streams 30;
11    http3_max_concurrent_pushes 30;
12    http3_push 10;
13    http3_push_preload on;
15    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.