Experiment with HTTP3 using NGINX and Quiche-Ubuntu – HTTP3 is the third and upcoming major version of the Hypertext Transfer Protocol used to exchange information on the World Wide Web, alongside HTTP/1.1 and HTTP/2
Time needed: 45 minutes
How to Build NGINX with HTTP/3 & QUIC Support
- Install & Update Ubuntu
Install Ubuntu server and update to the latest patch release
- Download NGINX & QUIC source code
Get NGINX distribution & QUIC from NGINX official Site
- Install Development Tools
Need to install development tools required to build NGINX
- Install BoringSSL
Download & build boring SSL
- Add additional Modules to NGINX
Download PageSpeed & Brotli modules (Optional)
- Modify NGINX rules
Modify NGINX rules to add HTTP/3, QUIC. Brotli & PageSpeed
- Build NGINX
Build NGINX with HTTP/3, QUIC, Brotli & PageSpeed Support
- Install NGINX
Install NGINX on Ubuntu Server
- Configure NGINX Web Server with SSL
Configure nginx.conf & server block
Install Ubuntu Server
Install Ubuntu server & add Nginx Repository. Please follow steps to modify “/etc/apt/sources/list” & Repository to Ubuntu distribution
nano /etc/apt/sources.list
Add below lines to end of the list
deb [arch=amd64] https://nginx.org/packages/mainline/ubuntu focal nginx
deb-src https://nginx.org/packages/mainline/ubuntu focal nginx
sudo apt-get update
sudo apt-get upgrade
- Ubuntu 20.10: groovy
- Ubuntu 20.04.1 LTS: focal
- Ubuntu 18.04.5 LTS: bionic
- Ubuntu 16.04.7 LTS: xenial
- Ubuntu 14.04.6 LTS: trusty
- Ubuntu 12.04.5 LTS: precise
Based on your Ubuntu version please change code name according to above list. After repository change we need to add Nginx keys to the Ubuntu. Execute below Commands to add keys
sudo wget https://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
sudo apt-get update
sudo apt-get upgrade
Download NGINX & QUIC source code
Next we need to download Nginx source code from Nginx official distribution & build dependencies.
sudo apt-get build-dep nginx
sudo apt-get source nginx
After executing code above, it will create a folder named nginx_XXXXX. XXXXX and it is the version number of Nginx.
Since we have now the NGINX source code, what we need to do now is to replace the code with NGINX quic. But before that, we have to install mercurial as this is needed to compile the NGINX.
sudo apt-get install mercurial
Then we will clone the latest NGINX repo from https://hg.nginx.org/nginx-quic.
cd ~/
hg clone -b quic https://hg.nginx.org/nginx-quic
Now we need to overwrite all content of our nginx-quic directory to the Nginx source code folder.
rsync -r nginx-quic/ nginx-1.21.0
Install Development Tools
Now we need to install other development tools require to build Nginx. Please execute below commands to install required dev tools.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install dpkg-dev
sudo apt-get install uuid-dev
sudo apt-get install cmake
sudo apt-get install mercurial
sudo apt-get install golang
sudo apt-get install libunwind-dev
sudo apt-get install unzip
Next we are going to download BoringSSL, Brotli & PageSpeed modules. All modules should under /debian/modules directory.
First we need to create /debian/modules folder. Make sure to change “nginx-1.21.0” according to your version.
mkdir ~/nginx-1.21.0/debian/modules
We can now pull a copy of BoringSSL (Google) from the official repo Github page.
cd ~/nginx-1.21.0/debian/modules
git clone https://github.com/google/boringssl
cd boringssl/
mkdir build
cd build
cmake ../
make -j 8
Add additional Modules to NGINX
So we are done with BoringSSL & next we need to download & extract additional modules to the /modules directory.
Change to the modules directory and download PageSpeed module from Google Git.
PageSpeed
cd ~/nginx-1.21.0/debian/modules
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v1.13.35.2-stable.zip
unzip v1.13.35.2-stable.zip
sudo mv incubator-pagespeed-ngx-1.13.35.2-stable ngx_pagespeed
Then go inside to the ngx_pagespeed folder, we need to add the PSOL libraries for pagespeed.
cd ngx_pagespeed
sudo wget https://dl.google.com/dl/page-speed/psol/1.13.35.2-x64.tar.gz
sudo tar -xzvf 1.13.35.2-x64.tar.gz
Brotli
For Brotli, we have just to download the repository from Github to the debian/modules
folder.
cd ~/nginx-1.21.0/debian/modules
git clone --recursive https://github.com/google/ngx_brotli
Modify NGINX rules
Hooray, we are done with all dev tools and libraries to build Nginx with HTTP/3, QUIC, Brotli & Pagespeed support
Adding BoringSSL and HTTP/3 to NGINX
Now we need to modify Nginx rules file to add BoringSSL & HTTP/3 support & qualifiers error of BoringSSL. Please edit rule file according to below instructions.
nano ~/nginx-1.21.0/debian/rules
You can see two lines starts with config.env.nginx and config.env.nginx_debug. Make sure to add below code to both of the lines end of the ssl_preread_module
--with-http_v3_module --with-http_quic_module --with-stream_quic_module
Add below to both lines to ignore qualifier issue of BoringSSL
-Wno-ignored-qualifiers
Example : CFLAGS=”-Wno-ignored-qualifiers”
Next we have to add the BoringSSL module to –with-cc-opt and –with-ld-opt with the following values. You need to replace the existing option at the end of the config, or else you’ll get an error saying, “./auto/configure: error: certain modules require OpenSSL QUIC support“.
--with-cc-opt="-I../modules/boringssl/include $(CFLAGS)" --with-ld-opt="-L../modules/boringssl/build/ssl -L../modules/boringssl/build/crypto $(LDFLAGS)"
You must remove –with-cc-opt & –with-ld-opt completely from existing rule file & replace with above one.
Adding PageSpeed and Brotli to NGINX
To add PageSpeed and Brotli to NGINX, similar to adding BoringSSL and http/3 on our NGINX, we have to add it on the debian/rules
compile configuration.
cd ~/
nano ~/nginx-1.21.0/debian/rules
Same as previous, you may see two lines starts with config.env.nginx and config.env.nginx_debug. Make sure to add below code to both of the lines end of the --sbin-path=/usr/sbin/nginx
--add-module="$(CURDIR)/debian/modules/ngx_pagespeed" --add-module="$(CURDIR)/debian/modules/ngx_brotli"
Compiling NGINX QUIC
Finally you are ready to compile Nginx with HTTP/3, QUIC, Brotli & PageSpeed support. First yo need to change changelog according to your build information.
nano ~/nginx-1.21.0/debian/changelog
Add below lines to of the change file and change according to your preferences.
nginx (nginx_1.21.0.1~bionic+pagespeed+brotli+http3+quic) bionic; urgency=low
* nginx_1.21.0.1
-- YOUR_NAME <[email protected]> Sat, 10 Jul 2021 16:02:03 +0300
After that, we can compile NGINX.
cd ~/nginx-1.21.0
sudo dpkg-buildpackage -b
Once you done with the build process please install newly build Ngix package using below command
sudo dpkg -i nginx_1.21.0.1~bionic+pagespeed+brotli_amd64.deb
Check your Nginx configuration using below command.
nginx -t
Configure NGINX Web Server with SSL
We need to remove default .conf file and replace nginx.conf file with below config.
rm /etc/nginx/conf.d/default.conf
nano /etc/nginx/nginx.conf
Remove all content of nginx.conf and replace with;
user www-data;
worker_processes auto;
include /etc/nginx/modules-enabled/*.conf;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# PageSpeed Settings
##
pagespeed on;
pagespeed FileCachePath /var/ngx_pagespeed_cache;
##
# Access/Error Log Settings
##
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
##
# Http Core Module Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
##
# Gzip Settings
##
pagespeed FetchWithGzip off;
pagespeed HttpCacheCompressionLevel 0;
#gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/x-font-ttf application/x-web-app-manifest+json application/xml+rss text/javascript image/svg+xml image/x-icon;
##
# Brotli Settings
##
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types application/octec-stream text/xml image/svg+xml application/x-font-ttf image/vnd.microsoft.icon application/x-font-opentype application/json font/eot application/vnd.ms-fontobject application/javascript font/otf application/xml application/xhtml+xml text/javascript application/x-javascript text/plain application/x-font-trutype application/xml+rss image/x-icon font/opentype text/css image/x-win-bitmap application/x-web-app-manifest+json;
##
# SSL Configuration
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# FastCGI Cache Settings
##
fastcgi_cache_path /etc/nginx-cache levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Cache-Control Expires;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Create web root directory & change permission to www-data (Nginx user group)
mkdir /var/www
sudo chown -R www-data:www-data /var/www
Now we need to make the server block directory according to above config “include /etc/nginx/sites-enabled/*;
“
mkdir /etc/nginx/sites-available
ln -s /etc/nginx/sites-available /etc/nginx/sites-enabled
Then let’s create a configuration for our first HTTP/3 website.
nano /etc/nginx/sites-available/example.com.conf
Add below code to the above file
server{
listen 80;
index index.html index.nginx-debian.html;
server_name yourdomain.com www.yourdomain.com
root /var/www/yourdomain.com;
}
Now we need to install SSL from free SSL authority to enable HTTP/3 & QUIC support.
Ready to install letsencrypt free SSL cert using certbot.
sudo add-apt-repository ppa:certbot/certbot
Then, create an SSL for your website. Replace example.com with your domain
sudo certbot --nginx -d example.com -d www.example.com
Certbot will automatically add SSL config to above file and finally we need to enable HTTP/3 & QUIC. Modify your config according to below code.
server {
listen 443 ssl; # TCP listener for HTTP/1.1
listen 443 http3 reuseport; # UDP listener for QUIC+HTTP/3
ssl_protocols TLSv1.3; # QUIC requires TLS 1.3
ssl_certificate ssl/www.example.com.crt;
ssl_certificate_key ssl/www.example.com.key;
add_header Alt-Svc 'h3=":443"'; # Advertise that HTTP/3 is available
add_header QUIC-Status $quic; # Sent when QUIC was used
}
For more information please visit official Nginx QUIC and HTTP/3 page
Introducing a Technology Preview of NGINX Support for QUIC and HTTP/3
Restart Nginx Server
sudo service nginx restart
Check your website and you should now see h3-29 on the protocol header when checking it on Web browser’s Developer tools. You can also check your website at the following http/3 checker tools:
If you need OCSP support please visit Github issue page and try yourself to enable.
Patch that enables OCSP stapling for nginx with **BoringSSL**
Thanks you for your time and please comment if you have any concerns.
Related Articles : How To Install Nginx Web Server on Ubuntu 18.04
[…] Experiment with HTTP/3 using NGINX and Quiche-Ubuntu […]
http_quic_module was merged into http_v3_module