Compiling nginx with BoringSSL doesn’t support OCSP Stapling right now. I choose to use QuicTLS to enable http3.
Install dependencies
apt update apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config libjemalloc-dev
Compile QuicTLS
choose somewhere you like to store the sorce code. like /usr/local/src/ or /tmp or simply your home
# cd /usr/local/src/ wget https://github.com/quictls/openssl/archive/refs/tags/openssl-3.1.5-quic1.tar.gz tar -xzf openssl-3.1.5-quic1.tar.gz cd openssl-openssl-3.1.5-quic1 ./config --prefix=$(pwd)/build no-shared make make install_sw cd ../
Compile brotli if you need
Brotli is a generic-purpose lossless compression algorithm that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman coding and 2nd order context modeling, with a compression ratio comparable to the best currently available general-purpose compression methods. It is similar in speed with deflate but offers more dense compression.
# cd /usr/local/src/ git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli cd ngx_brotli/deps/brotli mkdir out && cd out cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. cmake --build . --config Release --target brotlienc cd ../../../..
If you don’t need it, just remove the --add-module=../ngx_brotli
parameter in nginx configuration.
Now compile nginx with these module
you can change these these parameters as you like:
- –user=www –group=www #the user program use
- –prefix= #where should program install,like: /usr/local/share
- –with #the module you may need,included in nginx source code
# cd /usr/local/src/ hg clone https://hg.nginx.org/nginx cd nginx ./auto/configure --user=www-data --group=www-data --prefix=/usr/local/share/nginx --sbin-path=/usr/sbin/nginx --pid-path=/run/nginx.pid --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --with-pcre-jit --add-module=/usr/local/src/ngx_brotli --with-http_v2_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_ssl_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_stub_status_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-threads --with-http_slice_module --with-http_random_index_module --with-http_secure_link_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-http_v3_module --with-cc-opt="-I../openssl-openssl-3.1.5-quic1/build/include" --with-ld-opt="-L../openssl-openssl-3.1.5-quic1/build/lib64" make make install # ln -s /somewhere/else/nginx /usr/sbin/nginx
--with-cc-opt
option allows you to specify extra parameters for the C compiler (typically gcc or clang), like necessary header files. Through this option, you can include optimization flags, define specific include paths.
Similar to --with-cc-opt
, --with-ld-opt
option is designed to specify extra parameters for the linker during the linking phase, like library files. It allows you to define the library’s link path or incorporate specific linking options. These parameters are utilized when assembling the compiled object files into the final executable or library.
You can also define these paths explicitly:
- –prefix=/usr/local/share/nginx
- –sbin-path=/usr/sbin/nginx #you may let the binary we just compiled install to the path /usr/sbin, otherwise you may need to link the binary to /usr/sbin,e.g:ln -s /usr/local/share/nginx /usr/sbin/nginx
- –conf-path=/etc/nginx/nginx.conf #config path
- –http-log-path=/var/log/nginx/access.log
- –error-log-path=/var/log/nginx/error.log
- –lock-path=/var/lock/nginx.lock
- –pid-path=/run/nginx.pid
Add user
If you never install nginx or php before, you may need this. The default user name nginx and php installed by apt
maybe www-data
, if you need to change the user name they runs, be aware of the file permissions.
configure systemd service
For nginx service:
nano /usr/lib/systemd/system/nginx.service
input following text:
[Unit] Description=A high performance web server and a reverse proxy server After=network.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed [Install] WantedBy=multi-user.target
let systemd start nginx
# reload systemd systemctl daemon-reload # start running nginx systemctl start nginx # enable boot-time startup systemctl enable nginx
Command for reloading nginx
systemctl reload nginx # or service nginx reload
Bash script for installation
#!/bin/bash # Exit on errors set -e # Update and install dependencies apt update apt install -y build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config libjemalloc-dev # Remove existing ngx_brotli if present if [ -d "/usr/local/src/openssl-openssl-3.1.5-quic1" ]; then echo "Removing existing openssl-openssl-3.1.5-quic1 installation..." rm -rf /usr/local/src/openssl-openssl-3.1.5-quic1 fi # Compile QuicTLS cd /usr/local/src wget https://github.com/quictls/openssl/archive/refs/tags/openssl-3.1.5-quic1.tar.gz tar -xzf openssl-3.1.5-quic1.tar.gz cd openssl-openssl-3.1.5-quic1 ./config --prefix=$(pwd)/build no-shared make make install_sw # Remove existing ngx_brotli if present if [ -d "/usr/local/src/ngx_brotli" ]; then echo "Removing existing ngx_brotli installation..." rm -rf /usr/local/src/ngx_brotli fi # Install Brotli compression cd /usr/local/src git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli cd ngx_brotli/deps/brotli mkdir out && cd out cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. cmake --build . --config Release --target brotlienc # Remove existing Nginx if present if [ -d "/usr/local/src/nginx" ]; then echo "Removing existing Nginx installation..." rm -rf /usr/local/src/nginx fi # Clone Nginx and configure with QuicTLS and Brotli cd /usr/local/src hg clone https://hg.nginx.org/nginx cd nginx ./auto/configure --user=www-data --group=www-data --prefix=/usr/local/share/nginx --sbin-path=/usr/sbin/nginx --pid-path=/run/nginx.pid --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --with-pcre-jit --add-module=/usr/local/src/ngx_brotli --with-http_v2_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_ssl_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_stub_status_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-threads --with-http_slice_module --with-http_random_index_module --with-http_secure_link_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-http_v3_module --with-cc-opt="-I../openssl-openssl-3.1.5-quic1/build/include" --with-ld-opt="-L../openssl-openssl-3.1.5-quic1/build/lib64" make make install # Add Nginx user and group groupadd -f www-data useradd -g www-data -s /sbin/nologin www-data || true # Create systemd service file for Nginx cat <<EOF > /usr/lib/systemd/system/nginx.service [Unit] Description=A high performance web server and a reverse proxy server After=network.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed [Install] WantedBy=multi-user.target EOF # Reload systemd daemon and enable Nginx service systemctl daemon-reload systemctl enable nginx.service echo "Nginx installed and service created. Use 'systemctl start nginx' to start Nginx."
Example for nginx.conf
Notice: only one virtual server can enable quic reuseport
for now if you have multi virtual servers.
If you need to reverse proxy some proxy services, here is another reference.
remove #
if you want to enable any functions.
#user www-data; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #brotli on; #enable brotli #brotli_comp_level 6; #compression level, default for 6,max for 11,it needs more cpu performance to reach higher compression level #brotli_buffers 16 8k; #buffer quantity and size #brotli_min_length 20; #minimal length to compress, only equal or higher to be compressed, here set to 20 byte #brotli_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml text/html application/json image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl image/x-icon image/jpeg image/gif image/png image/bmp; #file type allow to compress #brotli_static on; #enables Brotli compression for static files #brotli_window 512k; #sets the size of the sliding window used by the Brotli compression algorithm. #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 logs/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; server { # Listen on ipv4 listen 80 default; listen [::]:80; # Redirect all insecure http:// requests to https:// return 301 https://$host$request_uri; # root /www/nginx/html/; #return 403; } # HTTPS server # REJECT HANDSHAKE from request don't contain any host name server { listen 443 ssl default_server; http2 on; listen [::]:443 ssl default_server; listen 443 quic reuseport; ssl_reject_handshake on; ssl_protocols TLSv1.2 TLSv1.3; ssl_session_timeout 10m; ssl_session_cache shared:SSL_cache:10m; } # YOUR server START HERE server { listen 443 ssl; # listen [::]:443 ssl; #ipv6 optional # listen 443 quic reuseport; # listen [::]:443 quic reuseport; http2 on; server_name your_domain.tld; #your domain # add_header Alt-Svc 'h3=":443"; ma=86400'; #prefered server ciphers optional #ssl_prefer_server_ciphers on; #ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; # QUIC-specific settings #ssl_early_data on; #ssl_session_tickets on; #quic_retry on; #certificate location ssl_certificate /etc/ssl/private/your_domain.tld.cer; ssl_certificate_key /etc/ssl/private/your_domain.tld.key; ssl_session_timeout 5m; ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; # HSTS (ngx_http_headers_module is required) (63072000 seconds) # HTTP Strict Transport Security:enforcing secure connections (HTTPS) on the client side. Be care to enable this if you may use unsecure method later # add_header Strict-Transport-Security max-age=63072000; # add_header Strict-Transport-Security "max-age=63072000;includeSubDomains" always; #or like this, all the sub-domain will enable HSTS too # enable OCSP Stapling # ssl_stapling on; # ssl_stapling_verify on; # ssl_trusted_certificate /path/to/origin_ca_ecc_root.cer; # resolver 8.8.8.8 8.8.4.4 valid=300s; # resolver_timeout 5s; # If you are using CDN from cloudflare, you may add this block only allow access from cloudflare for better security or privacy, otherwise remove this. allow 127.0.0.1; allow 10.0.0.0/20; allow 173.245.48.0/20; allow 103.21.244.0/22; allow 103.22.200.0/22; allow 103.31.4.0/22; allow 141.101.64.0/18; allow 108.162.192.0/18; allow 190.93.240.0/20; allow 188.114.96.0/20; allow 197.234.240.0/22; allow 198.41.128.0/17; allow 162.158.0.0/15; allow 104.16.0.0/13; allow 104.24.0.0/14; allow 172.64.0.0/13; allow 131.0.72.0/22; deny all; index index.html; location / { index index.html; } } ########### HTTP END HERE ################# }