文章目录
一.开发自签证书
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;
}
}
}