×

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  #################
}
In

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

Apply Certificate by acme.sh

acme.sh official wiki You definately need a domain before apply, you can get one at any registars, like name, namecheap, spaceship, gandi...

Read out all

Manuscript for my server

Based on debian 12. Better reading about some common UNIX commands here Enhance safety by changing SSH port, enabling pubkey login, and...

Read out all