My nginx config file

This server is powered by nginx. I will record some useful configuration snippets here.

multiplex 443 port

Although useful to MUX https traffic based on their domain name, this can be pretty complicated and may sometimes incur redirection issues with some applications.

stream {
    map $ssl_preread_server_name $backend_name {
        web.lqy.me website_0;
        app.lqy.me app_0;
        default website_1;
    }
    
    upstream website_0 {
        server 127.0.0.1:10000;
    }

    upstream website_1 {
        server 127.0.0.1:10001;
    }
    
    upstream app_0 {
        server 127.0.0.1:10002;
    }
    
    upstream app_0_ssl {
        server 127.0.0.1:10003;
    }
    
    server {
        listen 443 reuseport;
        listen [::]:443 reuseport;
        proxy_pass  $backend_name;
        proxy_protocol on;
        ssl_preread on;
    }
    
    # strip proxy_protocol header for app listen at `app_0_ssl`
    server {
        listen 10002 proxy_protocol;
        proxy_pass app_0_ssl;
    }
    
}

http {
    server {
        listen 80 default_server;
        # redirect http to https
        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 10000 ssl proxy_protocol default_server;
        server_name  web.lqy.me;
        include /etc/nginx/sslconfig;
        ssl_session_cache shared:SSL10000:10m;
        
        # return visitor IP example:
        location / {
            default_type text/plain;
            return 200 "Your IP:\n$proxy_protocol_addr\n";
        }
    }
}

    server {
        listen 10001 ssl proxy_protocol default_server;
        server_name  app.lqy.me;
        include /etc/nginx/sslconfig;
        # to restrict access to certain IPs
        ssl_session_cache shared:SSL10001:10m;
        
        # reverse proxy example:
        location / {
            proxy_pass http://127.0.0.1:10005;
        }
    }    
}

SSL config

ssl_certificate /etc/nginx/ssl/cer;
ssl_certificate_key /etc/nginx/ssl/key;

ssl_session_timeout 1d;
ssl_session_tickets off;
# You can generate DHPrama file using:
# openssl dhparam -out /etc/nginx/ssl/dhparam 2048  
# install and start haveged if low entropy
ssl_dhparam /etc/nginx/ssl/dhparam;
ssl_protocols TLSv1.3;
ssl_ciphers ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;

# replace with the IP address of your resolver
#resolver 127.0.0.1;

# add HSTS optionally
#add_header Strict-Transport-Security "max-age=63072000" always;

restrict IP access

set $flag_deny 1;
if ($proxy_protocol_addr = "allowed IP 1") {
  set $flag_deny 0;
} 

if ($proxy_protocol_addr = "allowed IP 2") {
  set $flag_deny 0;
} 

if ($flag_deny = 1) {
  return 403;
}

reveal visitor’s real IP when using CloudFlare CDN

Include below in main config’s http block: include /etc/nginx/cloudflare;

# IPv4:
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;

# IPv6:
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

# localhost and Docker's IP range
set_real_ip_from 127.0.0.1;
set_real_ip_from 172.21.0.1;

real_ip_header CF-Connecting-IP;

You can use cron to run this script once a week to update Cloudflare IP range automatically:

0 0 * * 0 /root/update-cf-ips-nginx

#!/bin/bash

CFG_PATH=/etc/nginx/cloudflare
echo "# IPv4:" >> $CFG_PATH;
for i in `curl -s https://www.cloudflare.com/ips-v4`; do
    echo "set_real_ip_from $i;" >> $CFG_PATH;
done
echo "" >> $CFG_PATH;
echo "# IPv6:" >> $CFG_PATH;
for i in `curl -s https://www.cloudflare.com/ips-v6`; do
    echo "set_real_ip_from $i;" >> $CFG_PATH;
done
echo "" >> $CFG_PATH;
# localhost
echo "set_real_ip_from 127.0.0.1;" >> $CFG_PATH;
# docker
echo "set_real_ip_from 172.17.0.1;" >> $CFG_PATH;
echo "real_ip_header CF-Connecting-IP;" >> $CFG_PATH;

nginx -t && nginx -s reload