Nginx 配置自签证书、负载均衡及现代化生产级配置模板指南


一.开发自签证书

1.1 OpenSSL下载

# ubuntu
sudo apt-get update
sudo apt-get install openssl

1.2生成证书

特别注意,若使用docker,一定要保证ssl文件在容器卷中

# 创建存放证书的目录
sudo mkdir /usr/local/mydata/nginx/ssl

cd /usr/local/mydata/nginx/ssl
# 1. 生成加密的服务器私钥(需要输入密码)
sudo openssl genpkey -algorithm EC \
  -pkeyopt ec_paramgen_curve:secp384r1 \
  -out encrypted_private_key.pem \
  -aes256
# 2. 使用加密私钥生成 CSR(需要输入密码)该请求包含组织、域名等信息,用于验证证书的所有权和身份。
sudo openssl req -new -key encrypted_private_key.pem -out certificate_signing_request.csr
# 3. 使用加密私钥生成自签名证书(需要输入密码)
sudo openssl x509 -req -days 365 \
  -in certificate_signing_request.csr \
  -signkey encrypted_private_key.pem \
  -out self_signed_certificate.crt \
#  -addext "subjectAltName = DNS:example.com, DNS:*.example.com"  # 替换为你的域名
# 4. 生成无密码版本的私钥(可选,根据安全需求决定是否保留加密版)
sudo openssl ec -in encrypted_private_key.pem -out private_key.pem

# 设置证书和私钥权限(至少可读)
sudo chmod 644 ./self_signed_certificate.crt
sudo chmod 600 ./private_key.pem  # 私钥应严格保护

# 检查文件所有者(通常 Nginx 用户为 nginx 或 www-data)
sudo chown nginx:nginx /usr/share/nginx/ssl/*  # 根据实际用户调整
# 检查文件所有者(通常 Nginx 用户为 nginx 或 www-data)
sudo chown nginx:nginx /usr/share/nginx/ssl/*  # 根据实际用户调整

csr信息
在这里插入图片描述


二.nginx现代化配置

在 Windows 11 系统中,由于 80 端口被 IP Helper 服务占用(该服务是支持 IPv6 隧道技术的核心组件),因此window测试建议默认使用 81 端口。
关于 HTTP/3 协议的支持条件:Nginx 版本需达到 1.25.1 或更高
若使用 Docker 部署,需使用包含 QUIC 模块的镜像(官方 Nginx Docker 镜像暂未默认包含该模块)

配置文件中已注释部分资源限制头和 HTTP/3 相关配置项,启用前请检查具体环境需求并调整相应参数。
注意:系统支持在相同端口同时提供 HTTP/2 和 HTTP/3 服务,HTTP3还需要打开443的UDP服务。

worker_processes  auto;
worker_rlimit_nofile 65535;  # 提高文件描述符限制
events {
    worker_connections  1024;
    use epoll;                # 高效的事件模型(Linux)
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #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;
    tcp_nodelay     on;
    keepalive_timeout  65;
    types_hash_max_size 2048;
    server_names_hash_bucket_size 64;
    server_tokens off;        # 隐藏 Nginx 版本
   
    # 启用Gzip压缩
    gzip on;
    # 设置压缩级别(1-9),数值越大压缩比越高,但消耗的CPU资源也越多
    gzip_comp_level 6;
    # 设置压缩的最小文件大小(单位:字节)
    gzip_min_length 1024;
    # 指定需要压缩的MIME类型
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    # 启用对代理服务器的Gzip压缩
    gzip_proxied any;
    # 启用对Vary头的支持,以便缓存服务器能够正确处理Gzip压缩的内容
    gzip_vary on;

	# 推荐的 TLS 参数
    ssl_protocols TLSv1.2 TLSv1.3;
    # 服务器优先选择自己配置的加密套件顺序
    ssl_prefer_server_ciphers on;  
    # 使用此加密套件。
    ssl_ciphers HIGH:!aNULL:!MD5;
     # TLS 优化
     #ssl_ecdh_curve X25519:P-256;  # 椭圆曲线优化
     #ssl_dhparam /etc/nginx/dhparam.pem;  # DH 参数(用于 TLSv1.2)
     ssl_buffer_size 4k;  # 减少内存占用
    
    # 支持 OCSP Stapling(可选,优化TLS握手)
    #ssl_stapling on;
    #ssl_stapling_verify on;
    # 关键:指定 CA 证书路径(自签名证书即为自身)
    #ssl_trusted_certificate "/usr/share/ssl/self_signed_certificate.crt";
    #resolver 223.5.5.5 8.8.8.8 valid=300s;
    #resolver_timeout 5s;
    
    # 日志优化
    access_log off;
    error_log /var/log/nginx/error.log warn;

    # SSL 会话缓存
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;  # 防止会话固定攻击
    # 上游服务器配置(示例)可自由配置负载均衡
    upstream backend {
        server backend1.example.com:8080;
        server backend2.example.com:8080;
        keepalive 32;  # 保持长连接
    }
    
    # 模拟80端口转发443
	server {
		listen 80;
		listen [::]:80;
		server_name localhost;
		return 301 https://$host$request_uri; # 将HTTP请求重定向到HTTPS
	}
	# 模拟相同端口, 多域名代理
	server {
      listen 80;
      server_name a.com;
      location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # 可选:处理大文件上传的缓冲区设置
        client_max_body_size 10m;
        client_body_buffer_size 128k;

        # 可选:代理超时设置
        proxy_connect_timeout 90;
        proxy_send_timeout 90;
        proxy_read_timeout 90;
        send_timeout 90;
      }
    }
    
    # 模拟相同端口, 多域名代理
    server {
      listen 80;
      server_name www.baidu.com;
      location / {
	    proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
      }
    }
	# https静态请求和动态请求处理
    server {
        # prod-api 和 dev-api 的配置都需要加,否则会报验证码已失效。
        listen 443 ssl;
        listen  [::]:443 ssl;
        listen 443 quic reuseport;
        listen  [::]:443 quic reuseport;
        http2 on;
        server_name localhost;
        # 若使用容器,填写容器内映射ssl绝对地址
        ssl_certificate      "/usr/share/ssl/self_signed_certificate.crt";
        # 若使用容器,填写容器内映射ssl绝对地址
        ssl_certificate_key  "/usr/share/ssl/private_key.pem";
         # HSTS 头部(强制 HTTPS)
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
         # CSP 头部(内容安全策略)
#         add_header Content-Security-Policy "default-src 'self';
#             script-src 'self';
#             style-src 'self';
#             img-src 'self' https: data:;
#             font-src 'self' https: data:;" always;
        # 其他安全头部
        add_header X-Content-Type-Options nosniff always;
        add_header X-Frame-Options SAMEORIGIN always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
        # 指定使用 QUIC 的 ALPN
        ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384;
        ssl_conf_command Groups X25519:P-256;
		# HTTP/3 特定配置
        #quic_max_idle_timeout 30s;  # 空闲连接超时
        #quic_retry on;  # 启用 0-RTT 重试
        add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400' always;  # 告知客户端支持 HTTP/3
        # 处理静态请求 其中app1,app2模拟两个不相关项目,前端路由不需要加app1或app2前缀。
        # 但是访问静态资源需要增加app1或app2前缀,如下
        # vite.config.js
		#export default defineConfig({
		#  base: process.env.NODE_ENV === 'production' ? '/manage/' : './'})
        location /app1/ {
			# 若使用容器,填写容器内绝对地址 /usr/share/nginx/html
            alias   html/;
            index  index.html index.htm;
            # 解决f5情况下 资源404
            try_files $uri $uri/ /app1/index.html;
            expires 7d;
        }
        location /app2/ {
			# 若使用容器,填写容器内绝对地址 /usr/share/nginx/html
            alias   html/;
            index  index.html index.htm;
            # 解决f5情况下 资源404
            try_files $uri $uri/ /app2/index.html;
            expires 7d;
        }
        
        # 处理生产模式下 后端反向代理
        location /prod-api/ { #后端访问子路径,项目.env.development中的配置
		   proxy_pass http://backend; #后端访问接口
    	   proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
           # 可选:处理大文件上传的缓冲区设置
           client_max_body_size 10m;
           client_body_buffer_size 128k;

           # 可选:代理超时设置
           proxy_connect_timeout 90;
           proxy_send_timeout 90;
           proxy_read_timeout 90;
           send_timeout 90;
            
        }
  		# 处理开发模式下 后端反向代理
        location /dev-api/ {
		   proxy_pass http://127.0.0.1:13578/;
    	   proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
           # 可选:处理大文件上传的缓冲区设置
           client_max_body_size 10m;
           client_body_buffer_size 128k;

           # 可选:代理超时设置
           proxy_connect_timeout 90;
           proxy_send_timeout 90;
           proxy_read_timeout 90;
           send_timeout 90;
            
        }
         # 重写请求路径 后端反向代理
         location /api {
           rewrite ^/api(.*)$ /$1 break;
    	   proxy_pass http://backend;
    	   proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
           # 可选:处理大文件上传的缓冲区设置
           client_max_body_size 10m;
           client_body_buffer_size 128k;

           # 可选:代理超时设置
           proxy_connect_timeout 90;
           proxy_send_timeout 90;
           proxy_read_timeout 90;
           send_timeout 90;
       }
	# 全局静态资源缓存(需确保路径正确) 如果静态资源分散在多个目录(如 /portal/ 和 /manage/),建议使用 alias 映射,而非依赖 root。
		location ~ \.(js|css|png|jpg|jpeg|webp|gif|ico)$ {
    		# 静态文件的根路径不依赖于root,而是通过alias来映射项目目录
            alias /usr/share/nginx/html$uri;
    		expires 30d;
    		add_header Cache-Control "public, max-age=31536000, immutable";
    		add_header Vary "Accept-Encoding";
		}
    }
}

三.docker-nginx配置

重新挂载nginx

sudo docker run -p 80:80 --name nginx \
--privileged=true --restart=always \
-v /usr/local/mydata/nginx/html:/usr/share/nginx/html \
-v /usr/local/mydata/nginx/logs:/var/log/nginx \
-v /usr/local/mydata/nginx/conf:/etc/nginx \
-v /usr/local/mydata/nginx/ssl:/usr/share/ssl \
--add-host=host.docker.internal:host-gateway \
-d nginx:1.26.2

四.常见错误

4.1 the event “ngx_master_xxxx” was not signaled for 5s

在这里插入图片描述

六.nginx负载均衡配置

6.1 轮询

# 定义上游服务器组,名字为 backend_servers
upstream backend_servers {
    # 第一个后端服务器,监听 8081 端口
    server 127.0.0.1:8081;
    # 第二个后端服务器,监听 8082 端口
    server 127.0.0.1:8082;
    # 第三个后端服务器,监听 8083 端口
    server 127.0.0.1:8083;
}

server {
    # 监听 80 端口
    listen 80;
    # 服务器名称,可以根据实际情况修改
    server_name example.com;

    location / {
        # 将请求代理到定义的上游服务器组
        proxy_pass http://backend_servers;
        # 设置代理的请求头
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}    

6.2 weight 权重

http {
    upstream backend_servers {
        # 服务器 1,权重为 1
        server 192.168.1.100:8080 weight=1;
        # 服务器 2,权重为 2,被分配到请求的概率是服务器 1 的两倍
        server 192.168.1.101:8080 weight=2;
        # 服务器 3,权重为 3,被分配到请求的概率是服务器 1 的三倍
        server 192.168.1.102:8080 weight=3;
    }

    server {
        listen 80;
        server_name your_domain.com;

        location / {
            # 将请求代理到后端服务器组
            proxy_pass http://backend_servers;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

6.3 ip_hash

# 定义负载均衡的后端服务器组
upstream backend_servers {
    # 使用 ip_hash 算法进行负载均衡
    ip_hash;

    # 后端服务器列表
    server 192.168.1.100:80;
    server 192.168.1.101:80;
    server 192.168.1.102:80;
}

# 定义虚拟主机
server {
    listen 80;
    server_name example.com;

    location / {
        # 将请求代理到后端服务器组
        proxy_pass http://backend_servers;

        # 以下是一些常用的代理配置
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}    

6.4 最少连接数代理

http {
    # 定义一个名为 backend_servers 的上游服务器组
    upstream backend_servers {
        # 使用 least_conn 指令开启最少连接数负载均衡算法
        least_conn;
        # 后端服务器 1
        server 192.168.1.100:8080;
        # 后端服务器 2
        server 192.168.1.101:8080;
    }

    server {
        # 监听 80 端口
        listen 80;
        # 这里可以替换为你的域名
        server_name your_domain.com;

        location / {
            # 将请求代理到 upstream 定义的后端服务器组
            proxy_pass http://backend_servers;
            # 设置请求头,传递客户端的真实主机名
            proxy_set_header Host $host;
            # 设置请求头,传递客户端的真实 IP 地址
            proxy_set_header X-Real-IP $remote_addr;
            # 设置请求头,传递客户端的完整转发信息
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最难不过坚持丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值