Nginx 完全配置指南 - 从入门到精通

📝 写在前面:本文提供一份「开箱即用」的 Nginx 配置模板,每个配置项都有详细注释。你可以根据需求删除或修改不需要的部分。


📚 目录

  1. Nginx 基础知识
  2. 配置文件结构
  3. 全局配置(nginx.conf)
  4. HTTP 核心配置
  5. 虚拟主机配置(Server)
  6. 反向代理配置
  7. 负载均衡配置
  8. HTTPS/SSL 配置
  9. WebSocket 配置
  10. 性能优化配置
  11. 安全加固配置
  12. 常用场景配置模板
  13. 避坑指南与操作手册
  14. 故障排查指南

1. Nginx 基础知识

1.1 什么是 Nginx?

Nginx 是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器。

核心特点:

  • ⚡ 高并发:支持数万并发连接
  • 💪 低内存:每个连接仅占用几 KB 内存
  • 🔄 热部署:无需停机即可更新配置
  • 📦 模块化:功能可通过模块扩展

1.2 安装 Nginx

Ubuntu/Debian:

sudo apt update
sudo apt install nginx

CentOS/RHEL:

sudo yum install epel-release
sudo yum install nginx

验证安装:

nginx -v        # 查看版本
nginx -t        # 测试配置文件语法
nginx -s reload # 重新加载配置

1.3 常用命令

# 启动 Nginx
sudo systemctl start nginx

# 停止 Nginx
sudo systemctl stop nginx

# 重启 Nginx
sudo systemctl restart nginx

# 重新加载配置(推荐,不中断服务)
sudo systemctl reload nginx

# 查看状态
sudo systemctl status nginx

# 设置开机自启
sudo systemctl enable nginx

2. 配置文件结构

2.1 配置文件位置

/etc/nginx/
├── nginx.conf                 # 主配置文件
├── conf.d/                    # 额外配置目录
├── sites-available/           # 可用站点配置(Ubuntu/Debian)
├── sites-enabled/             # 已启用站点配置(软链接)
├── modules-enabled/           # 已启用模块
├── snippets/                  # 可复用的配置片段
└── mime.types                 # MIME 类型定义

2.2 配置文件语法结构

# 全局配置
user www-data;
worker_processes auto;

# events 块:事件驱动配置
events {
    worker_connections 1024;
}

# http 块:HTTP 服务器配置
http {
    # 全局 HTTP 配置
    
    # server 块:虚拟主机配置
    server {
        # 此虚拟主机的配置
    }
    
    # 可以有多个 server 块
    server {
        # 另一个虚拟主机
    }
}

2.3 配置文件优先级

Nginx 会按照以下顺序加载配置:

  1. /etc/nginx/nginx.conf
  2. /etc/nginx/conf.d/*.conf(按字母顺序)
  3. /etc/nginx/sites-enabled/*(按字母顺序)

3. 全局配置(nginx.conf)

3.1 完整的全局配置模板

# ============================================
# 全局配置块
# 作用于整个 Nginx 服务器
# ============================================

# 运行 Nginx 的用户和用户组
# 格式:user 用户 [用户组];
# 推荐:使用专用用户 www-data 或 nginx
user www-data;

# 工作进程数
# auto:自动检测 CPU 核心数
# 数字:指定固定数量(如 4)
# 最佳实践:设置为 CPU 核心数
worker_processes auto;

# 工作进程的优先级
# 范围:-20(最高)到 19(最低)
# 默认:0
worker_priority -5;

# 主进程 PID 文件位置
# 用于管理进程(启动、停止、重载)
pid /run/nginx.pid;

# 错误日志配置
# 格式:error_log 文件路径 [日志级别];
# 日志级别:debug | info | notice | warn | error | crit
# 生产环境推荐:warn 或 error
error_log /var/log/nginx/error.log warn;

# 包含动态模块配置
include /etc/nginx/modules-enabled/*.conf;

# ============================================
# 事件驱动配置块
# 配置连接处理方式
# ============================================
events {
    # 每个工作进程的最大连接数
    # 总最大连接数 = worker_processes × worker_connections
    # 推荐:1024 到 4096(根据内存调整)
    worker_connections 2048;
    
    # 是否允许同时接受多个连接
    # on:启用(提高性能)
    # off:禁用
    multi_accept on;
    
    # 使用的事件驱动模型
    # Linux 推荐:epoll
    # FreeBSD 推荐:kqueue
    use epoll;
    
    # 工作进程在空闲时是否保持连接打开
    # on:启用(减少连接建立开销)
    accept_mutex off;
    
    # 设置 accept_mutex 的等待时间
    # accept_mutex_delay 500ms;
}

4. HTTP 核心配置

4.1 完整的 HTTP 块配置模板

http {
    # ============================================
    # 基础设置
    # ============================================
    
    # 启用 sendfile
    # on:使用内核级文件传输(高性能)
    # off:使用用户空间传输
    sendfile on;
    
    # 启用 TCP_NOPUSH
    # on:在 sendfile 时优化数据包发送
    # 需要同时启用 sendfile
    tcp_nopush on;
    
    # 启用 TCP_NODELAY
    # on:禁用 Nagle 算法,减少延迟
    # 适用于实时应用
    tcp_nodelay on;
    
    # 保持连接超时时间
    # 格式:keepalive_timeout 秒数 [header_timeout];
    # 0:禁用保持连接
    # 推荐:65 秒(浏览器默认)
    keepalive_timeout 65;
    
    # 保持连接的最大请求数
    # 超过此数量后关闭连接
    keepalive_requests 1000;
    
    # 读取请求头超时
    client_header_timeout 15;
    
    # 读取请求体超时
    client_body_timeout 15;
    
    # 发送响应超时
    send_timeout 15;
    
    # 隐藏 Nginx 版本号
    # on:隐藏(安全考虑)
    # off:显示
    server_tokens off;
    
    # 哈希表大小设置
    # 用于存储服务器名称
    # 如果服务器名称很长,需要增大此值
    server_names_hash_bucket_size 64;
    # server_name_in_redirect off;
    
    # ============================================
    # MIME 类型设置
    # ============================================
    
    # 包含 MIME 类型定义文件
    include /etc/nginx/mime.types;
    
    # 默认 MIME 类型
    # 当无法识别文件类型时使用
    default_type application/octet-stream;
    
    # ============================================
    # 日志配置
    # ============================================
    
    # 访问日志配置
    # 格式:access_log 文件路径 [格式名] [buffer=大小];
    # off:禁用访问日志
    access_log /var/log/nginx/access.log;
    
    # 自定义日志格式
    # combined:默认格式
    # main:常用格式
    # $request_time:【关键】Nginx 处理该请求的总耗时(秒)
    # $upstream_response_time:【关键】后端应用处理耗时
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    'rt=$request_time urt=$upstream_response_time';
    
    # JSON 格式日志(推荐用于日志分析)
    log_format json_combined escape=json '{'
        '"time_local":"$time_local",'
        '"remote_addr":"$remote_addr",'
        '"remote_user":"$remote_user",'
        '"request":"$request",'
        '"status": "$status",'
        '"body_bytes_sent":"$body_bytes_sent",'
        '"request_time":"$request_time",'
        '"http_referrer":"$http_referer",'
        '"http_user_agent":"$http_user_agent",'
        '"http_x_forwarded_for":"$http_x_forwarded_for"'
    '}';
    
    # ============================================
    # Gzip 压缩配置
    # ============================================
    
    # 启用 Gzip 压缩
    gzip on;
    
    # 压缩级别
    # 范围:1(最低)到 9(最高)
    # 推荐:6(性能和压缩率的平衡)
    gzip_comp_level 6;
    
    # 最小压缩大小
    # 小于此值不压缩(压缩收益小)
    # 推荐:1KB(1024 字节)
    gzip_min_length 1024;
    
    # 压缩的 MIME 类型
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml
        application/xml+rss
        application/atom+xml
        image/svg+xml;
    
    # 是否在响应头中添加 Vary: Accept-Encoding
    # on:添加(推荐,支持缓存)
    gzip_vary on;
    
    # 压缩缓冲区
    # 格式:gzip_buffers 数量 大小;
    gzip_buffers 16 8k;
    
    # 压缩所需的最低 HTTP 版本
    gzip_http_version 1.1;
    
    # 是否对代理请求进行压缩
    # any:对所有代理请求压缩
    # off:不压缩代理请求
    gzip_proxied any;
    
    # 禁用对特定 User-Agent 的压缩
    # MSIE [4-6]\.:IE4-6 不支持 gzip
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";
    
    # ============================================
    # SSL/TLS 优化配置
    # ============================================
    
    # SSL 会话缓存
    # 格式:ssl_session_cache 类型 大小;
    # shared:所有工作进程共享
    # 大小:1MB ≈ 4000 个会话
    ssl_session_cache shared:SSL:10m;
    
    # SSL 会话超时时间
    ssl_session_timeout 10m;
    
    # 禁用旧版 SSL 协议
    # 仅使用 TLSv1.2 和 TLSv1.3
    ssl_protocols TLSv1.2 TLSv1.3;
    
    # 优先使用服务器端加密套件
    ssl_prefer_server_ciphers on;
    
    # 加密套件配置
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    
    # OCSP Stapling(提高 SSL 握手速度)
    ssl_stapling on;
    ssl_stapling_verify on;
    
    # ============================================
    # 文件缓存配置
    # ============================================
    
    # 打开文件缓存
    # max:缓存最大文件数
    # inactive:非活跃时间
    open_file_cache max=1000 inactive=20s;
    
    # 缓存检查间隔
    open_file_cache_valid 30s;
    
    # 最小使用次数
    open_file_cache_min_uses 2;
    
    # 是否缓存文件查找错误
    open_file_cache_errors on;
    
    # ============================================
    # 包含其他配置
    # ============================================
    
    # 包含 conf.d 目录下的所有配置
    include /etc/nginx/conf.d/*.conf;
    
    # 包含启用的站点配置
    include /etc/nginx/sites-enabled/*;
}

5. 虚拟主机配置(Server)

5.1 基础虚拟主机模板

# ============================================
# 基础 HTTP 虚拟主机
# ============================================
server {
    # 监听端口
    # 80:HTTP 默认端口
    # default_server:设置为默认服务器
    listen 80;
    listen [::]:80;  # IPv6
    
    # 是否设置为默认服务器
    # 当请求的域名不匹配任何 server_name 时使用
    # default_server;
    
    # 服务器名称(域名)
    # _ :匹配所有域名(通配符)
    # example.com:精确匹配
    # *.example.com:子域名通配符
    # ~^(.+)\.example\.com$:正则匹配
    server_name example.com www.example.com;
    
    # 根目录
    # 网站文件存放位置
    root /var/www/html;
    
    # 默认索引文件
    # 按顺序查找,找到即返回
    index index.html index.htm index.php;
    
    # 字符编码
    charset utf-8;
    
    # 访问日志
    # /dev/null:不记录日志
    access_log /var/log/nginx/example.com.access.log main;
    
    # 错误日志
    error_log /var/log/nginx/example.com.error.log warn;
    
    # ============================================
    # Location 配置(核心)
    # ============================================
    
    # 根路径
    location / {
        # 尝试顺序:
        # 1. $uri:精确匹配文件
        # 2. $uri/:匹配目录
        # 3. =404:返回 404 错误
        try_files $uri $uri/ =404;
        
        # 或转发到 index.php(用于 PHP 应用)
        # try_files $uri $uri/ /index.php?$query_string;
    }
    
    # 禁止访问隐藏文件(以 . 开头)
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # favicon.ico 不记录日志
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
    
    # robots.txt 不记录日志
    location = /robots.txt {
        log_not_found off;
        access_log off;
    }
    
    # 静态文件缓存
    # 匹配图片、CSS、JS 等静态资源
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        # 缓存时间:30 天
        expires 30d;
        
        # 添加缓存控制头
        add_header Cache-Control "public, immutable";
        
        # 不记录访问日志
        access_log off;
    }
}

5.2 多域名配置

# ============================================
# 多个虚拟主机配置示例
# ============================================

# 虚拟主机 1:网站 A
server {
    listen 80;
    server_name site-a.com www.site-a.com;
    root /var/www/site-a;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# 虚拟主机 2:网站 B
server {
    listen 80;
    server_name site-b.com www.site-b.com;
    root /var/www/site-b;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# 虚拟主机 3:默认服务器(处理未知域名)
server {
    listen 80 default_server;
    server_name _;
    
    # 返回 444(Nginx 特殊代码,直接关闭连接)
    return 444;
}

6. 反向代理配置

6.1 基础反向代理

server {
    listen 80;
    server_name proxy.example.com;
    
    # ============================================
    # 反向代理配置
    # ============================================
    
    location / {
        # 代理目标地址
        # 可以是本地服务或远程服务器
        proxy_pass http://127.0.0.1:3000;
        
        # 使用的 HTTP 协议版本
        # 1.1:支持长连接和 WebSocket
        proxy_http_version 1.1;
        
        # ============================================
        # 请求头设置
        # ============================================
        
        # 传递客户端真实 IP
        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;
        
        # 传递客户端主机名
        # proxy_set_header X-Forwarded-Host $host;
        # proxy_set_header X-Forwarded-Port $server_port;
        
        # ============================================
        # 超时设置
        # ============================================
        
        # 与后端服务器建立连接的超时时间
        proxy_connect_timeout 60s;
        
        # 向后端服务器发送请求的超时时间
        proxy_send_timeout 60s;
        
        # 从后端服务器读取响应的超时时间
        proxy_read_timeout 60s;
        
        # ============================================
        # 缓冲设置
        # ============================================
        
        # 启用响应缓冲
        # on:Nginx 先缓存整个响应再发送给客户端
        # off:直接流式传输
        proxy_buffering on;
        
        # 缓冲区数量和大小
        proxy_buffers 4 16k;
        
        # 第一个缓冲区大小
        proxy_buffer_size 32k;
        
        # 临时文件写入阈值
        proxy_max_temp_file_size 1024m;
        
        # ============================================
        # 其他设置
        # ============================================
        
        # 禁用重定向
        # proxy_redirect off;
        
        # 自定义重定向
        proxy_redirect http://127.0.0.1:3000/ /;
    }
}

6.2 带认证的反向代理

server {
    listen 80;
    server_name admin.example.com;
    
    # HTTP Basic 认证
    auth_basic "Admin Panel";
    auth_basic_user_file /etc/nginx/.htpasswd;
    
    location / {
        proxy_pass http://127.0.0.1:8080;
        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-User $remote_user;
    }
}

生成密码文件:

# 安装 htpasswd 工具
sudo apt install apache2-utils

# 创建密码文件(首次)
sudo htpasswd -c /etc/nginx/.htpasswd admin

# 添加更多用户
sudo htpasswd /etc/nginx/.htpasswd user2

6.3 代理多个路径到不同后端

server {
    listen 80;
    server_name api.example.com;
    
    # API 路径代理到后端服务
    location /api/ {
        proxy_pass http://127.0.0.1:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # WebSocket 路径
    location /ws/ {
        proxy_pass http://127.0.0.1:3001/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    
    # 静态文件
    location /static/ {
        alias /var/www/static/;
        expires 30d;
    }
}

7. 负载均衡配置

7.1 基础负载均衡

# ============================================
# 后端服务器组(upstream)
# ============================================
upstream backend {
    # 负载均衡算法(默认轮询)
    # 其他选项:ip_hash、least_conn、hash
    
    # 后端服务器列表
    server 192.168.1.10:8000;
    server 192.168.1.11:8000;
    server 192.168.1.12:8000;
    
    # 权重配置(weight)
    # server 192.168.1.10:8000 weight=3;
    # server 192.168.1.11:8000 weight=2;
    # server 192.168.1.12:8000 weight=1;
    
    # 备用服务器(backup)
    # 仅当其他服务器都不可用时启用
    # server 192.168.1.13:8000 backup;
    
    # 服务器状态
    # down:标记为不可用
    # server 192.168.1.14:8000 down;
    
    # 健康检查参数
    # max_fails:最大失败次数
    # fail_timeout:失败后暂停时间
    # server 192.168.1.15:8000 max_fails=3 fail_timeout=30s;
    
    # 【重要】保持连接池
    # 说明:极大提升代理性能,避免频繁建立 TCP 连接
    keepalive 32;
}

server {
    listen 80;
    server_name lb.example.com;
    
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

7.2 不同负载均衡算法

# ============================================
# 1. IP Hash:同一 IP 始终访问同一服务器
# ============================================
upstream backend_ip_hash {
    ip_hash;
    server 192.168.1.10:8000;
    server 192.168.1.11:8000;
}

# ============================================
# 2. 最少连接:优先分配给连接数最少的服务器
# ============================================
upstream backend_least_conn {
    least_conn;
    server 192.168.1.10:8000;
    server 192.168.1.11:8000;
}

# ============================================
# 3. URL Hash:同一 URL 始终访问同一服务器
# ============================================
upstream backend_url_hash {
    hash $request_uri consistent;
    server 192.168.1.10:8000;
    server 192.168.1.11:8000;
}

# ============================================
# 4. 加权轮询:按权重分配
# ============================================
upstream backend_weighted {
    server 192.168.1.10:8000 weight=3;
    server 192.168.1.11:8000 weight=2;
    server 192.168.1.12:8000 weight=1;
}

7.3 健康检查配置

upstream backend {
    # 被动健康检查(Nginx 开源版)
    server 192.168.1.10:8000 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8000 max_fails=3 fail_timeout=30s;
    
    # 主动健康检查(需要 Nginx Plus 或第三方模块)
    # health_check interval=5s fails=3 passes=2;
}

server {
    listen 80;
    server_name health.example.com;
    
    location / {
        proxy_pass http://backend;
        
        # 下次请求超时时间
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 10s;
    }
}

8. HTTPS/SSL 配置

8.1 基础 HTTPS 配置

server {
    # 监听 443 端口,启用 SSL
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    server_name example.com www.example.com;
    
    # ============================================
    # SSL 证书配置
    # ============================================
    
    # SSL 证书文件
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    
    # SSL 私钥文件
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # 信任的 CA 证书(客户端证书认证时使用)
    # ssl_trusted_certificate /etc/nginx/ssl/ca.pem;
    
    # ============================================
    # SSL 协议和加密套件
    # ============================================
    
    # 支持的 SSL 协议
    # TLSv1.3:最新版本,推荐
    # TLSv1.2:广泛支持,推荐
    # TLSv1.1:已弃用,不推荐
    # TLSv1:已弃用,不推荐
    # SSLv3:已弃用,禁用
    ssl_protocols TLSv1.2 TLSv1.3;
    
    # 优先使用服务器端加密套件
    ssl_prefer_server_ciphers on;
    
    # 加密套件配置
    # Mozilla Modern 兼容配置
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    
    # ============================================
    # SSL 会话优化
    # ============================================
    
    # SSL 会话缓存
    # shared:所有工作进程共享
    # 10m:10MB 缓存(约 40000 个会话)
    ssl_session_cache shared:SSL:10m;
    
    # SSL 会话超时时间
    ssl_session_timeout 10m;
    
    # SSL 会话票据(Session Tickets)
    # on:启用(提高性能,但安全性略低)
    # off:禁用(更安全)
    ssl_session_tickets off;
    
    # ============================================
    # OCSP Stapling
    # ============================================
    
    # 启用 OCSP Stapling
    # on:启用(提高 SSL 握手速度)
    ssl_stapling on;
    ssl_stapling_verify on;
    
    # 解析器(用于 OCSP 验证)
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    # ============================================
    # Diffie-Hellman 参数
    # ============================================
    
    # DH 参数文件(增强安全性)
    # 生成命令:openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    
    # ============================================
    # 安全头设置
    # ============================================
    
    # HSTS(HTTP Strict Transport Security)
    # 强制浏览器使用 HTTPS
    # max-age:有效期(秒)
    # includeSubDomains:包含子域名
    # preload:允许加入浏览器预加载列表
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    
    # ============================================
    # 网站配置
    # ============================================
    
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# ============================================
# HTTP 自动跳转 HTTPS
# ============================================
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    
    # 301 永久重定向到 HTTPS
    return 301 https://$server_name$request_uri;
}

8.2 Let’s Encrypt 自动证书

安装 Certbot:

sudo apt install certbot python3-certbot-nginx

获取证书:

# 自动配置 Nginx
sudo certbot --nginx -d example.com -d www.example.com

# 仅获取证书(手动配置)
sudo certbot certonly --nginx -d example.com

自动续期:

# 测试续期
sudo certbot renew --dry-run

# Certbot 会自动添加定时任务续期

8.3 自签名证书(开发测试用)

# 生成私钥和证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/selfsigned.key \
  -out /etc/nginx/ssl/selfsigned.crt \
  -subj "/C=CN/ST=State/L=City/O=Organization/CN=localhost"

9. WebSocket 配置

9.1 标准 WebSocket 代理

server {
    listen 80;
    server_name ws.example.com;
    
    location /ws {
        # 代理到 WebSocket 服务器
        proxy_pass http://127.0.0.1:8080;
        
        # 使用 HTTP/1.1(WebSocket 需要)
        proxy_http_version 1.1;
        
        # ============================================
        # WebSocket 关键配置
        # ============================================
        
        # 升级连接
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # ============================================
        # 标准代理头
        # ============================================
        
        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;
        
        # ============================================
        # 超时配置(WebSocket 长连接)
        # ============================================
        
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
        
        # ============================================
        # 其他设置
        # ============================================
        
        # 禁用缓冲(实时通信)
        proxy_buffering off;
    }
}

9.2 Socket.IO 配置

server {
    listen 80;
    server_name socketio.example.com;
    
    location /socket.io/ {
        proxy_pass http://127.0.0.1:3000/socket.io/;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
        
        # 禁用缓冲
        proxy_buffering off;
    }
}

10. 性能优化配置

10.1 Worker 进程优化

# ============================================
# 全局配置优化
# ============================================

# 工作进程数 = CPU 核心数
worker_processes auto;

# 每个工作进程最大打开文件数
worker_rlimit_nofile 100000;

events {
    # 每个工作进程最大连接数
    worker_connections 4096;
    
    # 同时接受多个连接
    multi_accept on;
    
    # 使用 epoll(Linux 高性能)
    use epoll;
}

http {
    # ============================================
    # 连接优化
    # ============================================
    
    # 保持连接超时
    keepalive_timeout 65;
    
    # 保持连接最大请求数
    keepalive_requests 10000;
    
    # ============================================
    # 文件传输优化
    # ============================================
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    # ============================================
    # 缓冲优化
    # ============================================
    
    # 输出缓冲
    output_buffers 2 32k;
    
    # postpond 输出
    postpone_output 1460;
    
    # ============================================
    # 文件缓存
    # ============================================
    
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    # ============================================
    # FastCGI 缓存(用于 PHP)
    # ============================================
    
    fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi:100m inactive=60m max_size=500m;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_use_stale error timeout invalid_header http_500;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
    
    # ============================================
    # Proxy 缓存
    # ============================================
    
    proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy:100m inactive=60m max_size=500m;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_cache_bypass $http_cache_control;
    
    # ============================================
    # 限制配置
    # ============================================
    
    # 限制客户端请求体大小
    client_max_body_size 50m;
    
    # 限制请求体缓冲区大小
    client_body_buffer_size 128k;
    
    # 限制大型客户端请求头
    large_client_header_buffers 4 16k;
}

10.2 启用 HTTP/2

server {
    # 启用 HTTP/2
    listen 443 ssl http2;
    
    server_name example.com;
    
    # SSL 证书配置
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    # HTTP/2 推送(可选)
    location / {
        root /var/www/html;
        
        # 推送 CSS 文件
        http2_push /style.css;
        
        # 或使用推送预加载
        http2_push_preload on;
    }
}

10.3 启用 Brotli 压缩

# 需要安装 libbrotli 模块

http {
    # 启用 Brotli
    brotli on;
    
    # 压缩级别(0-11)
    brotli_comp_level 6;
    
    # 最小压缩大小
    brotli_min_length 1000;
    
    # 压缩的 MIME 类型
    brotli_types text/plain text/css application/json application/javascript text/xml application/xml;
    
    # 缓冲区大小
    brotli_buffers 16 8k;
}

11. 安全加固配置

11.1 安全头配置

server {
    listen 443 ssl http2;
    server_name example.com;
    
    # ============================================
    # 安全响应头
    # ============================================
    
    # HSTS:强制 HTTPS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    
    # 防止点击劫持
    # DENY:完全禁止嵌入
    # SAMEORIGIN:仅允许同源嵌入
    # ALLOW-FROM uri:允许指定来源
    add_header X-Frame-Options "SAMEORIGIN" always;
    
    # XSS 防护
    # 1; mode=block:启用并阻止页面加载
    add_header X-XSS-Protection "1; mode=block" always;
    
    # 防止 MIME 类型嗅探
    add_header X-Content-Type-Options "nosniff" always;
    
    # Referrer 策略
    # no-referrer:不发送 Referrer
    # no-referrer-when-downgrade:HTTPS→HTTP 不发送
    # origin:仅发送源
    # origin-when-cross-origin:跨域时仅发送源
    # same-origin:同源时发送完整 URL
    # strict-origin:仅发送源,HTTPS→HTTP 不发送
    # strict-origin-when-cross-origin:混合策略
    # unsafe-url:始终发送完整 URL
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # 内容安全策略(CSP)
    # 根据需求配置,示例为宽松配置
    add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';" always;
    
    # 权限策略(Permissions Policy)
    # 限制浏览器功能
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
    
    # ============================================
    # 隐藏敏感信息
    # ============================================
    
    # 隐藏 Nginx 版本号
    server_tokens off;
    
    # 隐藏 PHP 版本
    fastcgi_hide_header X-Powered-By;
    
    # 隐藏 Server 头(需要额外模块)
    # more_clear_headers 'Server';
    
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

11.2 访问限制

server {
    listen 80;
    server_name admin.example.com;
    
    # ============================================
    # IP 白名单
    # ============================================
    
    location /admin {
        # 仅允许特定 IP
        allow 192.168.1.0/24;  # 内网
        allow 10.0.0.0/8;      # VPN
        allow 1.2.3.4;         # 特定 IP
        deny all;              # 拒绝其他所有
        
        proxy_pass http://127.0.0.1:8080;
    }
    
    # ============================================
    # IP 黑名单
    # ============================================
    
    location /public {
        # 拒绝特定 IP
        deny 1.2.3.4;
        deny 5.6.7.8;
        allow all;
        
        proxy_pass http://127.0.0.1:3000;
    }
    
    # ============================================
    # 基于地理位置限制(需要 GeoIP 模块)
    # ============================================
    
    # 配置 GeoIP
    # geoip_country /usr/share/GeoIP/GeoIP.dat;
    
    location /cn-only {
        # 仅允许中国访问
        # if ($geoip_country_code != CN) {
        #     return 403;
        # }
        
        proxy_pass http://127.0.0.1:4000;
    }
    
    # ============================================
    # HTTP Basic 认证
    # ============================================
    
    location /private {
        auth_basic "Private Area";
        auth_basic_user_file /etc/nginx/.htpasswd;
        
        proxy_pass http://127.0.0.1:5000;
    }
}

11.3 速率限制

http {
    # ============================================
    # 限制区域定义
    # ============================================
    
    # 按二进制 IP 地址限制
    # zone=区域名:大小 rate=每秒请求数
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    
    # 按连接数限制
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    server {
        listen 80;
        server_name example.com;
        
        # ============================================
        # 应用速率限制
        # ============================================
        
        # 一般请求:10 req/s,突发 20
        location / {
            limit_req zone=general burst=20 nodelay;
            proxy_pass http://127.0.0.1:3000;
        }
        
        # API:100 req/s,突发 200
        location /api/ {
            limit_req zone=api burst=200 nodelay;
            proxy_pass http://127.0.0.1:3001;
        }
        
        # 登录:5 req/min,防暴力破解
        location /login {
            limit_req zone=login burst=5 nodelay;
            proxy_pass http://127.0.0.1:3002;
        }
        
        # ============================================
        # 连接数限制
        # ============================================
        
        location /download/ {
            # 单个 IP 最大 10 个连接
            limit_conn conn_limit 10;
            
            alias /var/www/downloads/;
        }
        
        # ============================================
        # 自定义错误响应
        # ============================================
        
        # 速率限制错误页面
        error_page 429 = @rate_limit_exceeded;
        
        location @rate_limit_exceeded {
            default_type application/json;
            return 429 '{"error": "Too Many Requests", "message": "Please slow down"}';
        }
        
        # 设置限制状态码(可选)
        limit_req_status 429;
        limit_conn_status 429;
    }
}

11.4 防止常见攻击

server {
    listen 80;
    server_name example.com;
    
    # ============================================
    # 防止目录遍历
    # ============================================
    
    # 禁用目录列表
    autoindex off;
    
    # ============================================
    # 防止信息泄露
    # ============================================
    
    # 禁止访问敏感文件
    location ~* \.(env|git|svn|htaccess|htpasswd|ini|log|sh|sql)$ {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 禁止访问备份文件
    location ~* \.(bak|backup|old|orig|original|save|swp|tmp)$ {
        deny all;
    }
    
    # ============================================
    # 防止 SQL 注入和 XSS(简单规则)
    # ============================================
    
    # 检测常见攻击模式
    # if ($request_uri ~* "(union.*select|insert.*into|delete.*from|drop.*table|select.*from|cast\(|exec|execute|truncate|char\(|script|javascript|alert\(|onmouse|onkey|onload|onclick|iframe)") {
    #     return 403;
    # }
    
    # ============================================
    # 防止 User-Agent 攻击
    # ============================================
    
    # 禁止空 User-Agent
    if ($http_user_agent = "") {
        return 403;
    }
    
    # 禁止恶意 User-Agent
    if ($http_user_agent ~* (bot|crawl|spider|scan|nikto|sqlmap|nmap|masscan)) {
        return 403;
    }
    
    # ============================================
    # 限制请求方法
    # ============================================
    
    # 仅允许 GET、POST、HEAD
    if ($request_method !~ ^(GET|POST|HEAD)$) {
        return 405;
    }
    
    # ============================================
    # 限制 URI 长度
    # ============================================
    
    # URI 超过 255 字节拒绝
    if ($request_uri ~ "^[^\?]{256,}") {
        return 414;
    }
    
    # ============================================
    # 客户端请求限制
    # ============================================
    
    # 限制请求体大小(50MB)
    client_max_body_size 50m;
    
    # 限制请求头缓冲区大小
    client_header_buffer_size 1k;
    large_client_header_buffers 4 16k;
    
    # 请求头超时
    client_header_timeout 15;
    
    # 请求体超时
    client_body_timeout 15;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

12. 常用场景配置模板

12.1 静态网站

server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;
    index index.html;
    
    # 字符编码
    charset utf-8;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
    
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }
}

12.2 PHP 应用(WordPress 等)

server {
    listen 80;
    server_name blog.example.com;
    root /var/www/wordpress;
    index index.php index.html;
    
    # ============================================
    # WordPress 固定链接支持
    # ============================================
    
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    # ============================================
    # PHP 处理
    # ============================================
    
    location ~ \.php$ {
        # PHP-FPM 套接字
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        # 或 TCP 连接
        # fastcgi_pass 127.0.0.1:9000;
        
        # FastCGI 参数
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        
        # 超时设置
        fastcgi_connect_timeout 60s;
        fastcgi_send_timeout 60s;
        fastcgi_read_timeout 60s;
        
        # 缓冲设置
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
    }
    
    # ============================================
    # WordPress 安全配置
    # ============================================
    
    # 禁止访问 wp-config.php
    location = /wp-config.php {
        deny all;
    }
    
    # 禁止访问 wp-admin 目录下的 PHP(除了 admin-ajax.php)
    location ~* /wp-admin/ {
        location ~* \.php$ {
            fastcgi_pass unix:/run/php/php8.1-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
    
    # 禁止访问上传目录中的 PHP
    location ~* /wp-content/uploads/.*\.php$ {
        deny all;
    }
    
    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt|doc|docx|xls|xlsx)$ {
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
    }
    
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }
}

12.3 Node.js 应用

server {
    listen 80;
    server_name node.example.com;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        
        # 标准 proxy 头
        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;
        
        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 禁用缓冲(用于 Server-Sent Events)
        proxy_buffering off;
    }
}

12.4 React/Vue SPA 应用

server {
    listen 80;
    server_name spa.example.com;
    root /var/www/spa/dist;
    index index.html;
    
    # 启用 Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    
    location / {
        # 所有路由都返回 index.html
        try_files $uri $uri/ /index.html;
    }
    
    # API 代理
    location /api/ {
        proxy_pass http://127.0.0.1:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # 静态资源长缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

12.5 Git 服务器(Gitea)

server {
    listen 80;
    server_name git.example.com;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        
        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 100M;
        
        # 超时设置
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 300;
    }
}

12.6 Docker Registry

server {
    listen 443 ssl http2;
    server_name registry.example.com;
    
    # SSL 证书
    ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem;
    
    # 基础认证
    auth_basic "Docker Registry";
    auth_basic_user_file /etc/nginx/.htpasswd;
    
    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        
        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;
        
        # Docker Registry 特殊头
        proxy_set_header Docker-Distribution-Api-Version registry/2.0;
        
        # 大文件上传支持
        client_max_body_size 0;
        
        # 禁用请求体缓冲
        proxy_request_buffering off;
    }
}

13. 避坑指南与操作手册

13.1 修改配置后如何生效?

标准"三板斧"操作:

# 1. 检查语法(必须!)
nginx -t
# 必须看到 "syntax is ok" 和 "test is successful" 才能进行下一步

# 2. 平滑重载(推荐,不中断服务)
nginx -s reload
# 或
systemctl reload nginx

# 3. 服务重启(仅特殊情况需要)
systemctl restart nginx
# 只有在添加了新的 Nginx 模块或修改了 SSL 证书路径等底层变更时才需要

13.2 常见权限问题(403 Forbidden)

现象: 访问网站报错 403 Forbidden

原因: 90% 是文件权限问题

  • Nginx 的运行用户(nginx.conf 第一行的 user nginx;)没有权限读取网站目录
  • 错误示范:把网站放在 /root/ 目录下。Nginx 用户通常无法访问 /root

解决方案:

# 把网站放在正确位置
mv /root/my_website /var/www/

# 设置正确权限
chown -R nginx:nginx /var/www/my_website
chmod -R 755 /var/www/my_website

13.3 文件上传报错(413 Request Entity Too Large)

现象: 上传大图片或视频时直接报错

解决:

# 在 http 块中添加
client_max_body_size 100m;

13.4 502 Bad Gateway

原因:

  • 后端服务未启动
  • 后端服务端口配置错误
  • 代理超时时间过短
  • 代理缓冲区过小

解决方案:

# 检查后端服务
systemctl status your-backend-service

# 调整代理配置
proxy_connect_timeout 60s;
proxy_read_timeout 600s;
proxy_buffer_size 128k;
proxy_buffers 4 256k;

13.5 Too Many Open Files

现象: 日志中出现 Too many open files

解决:

# 临时修改
ulimit -n 65535

# 永久修改(编辑 /etc/security/limits.conf)
* soft nofile 65535
* hard nofile 65535

# 或在 Nginx 配置中
worker_rlimit_nofile 100000;

14. 故障排查指南

14.1 常用调试命令

# 测试配置文件语法
sudo nginx -t

# 查看 Nginx 版本和编译参数
nginx -V

# 重新加载配置
sudo systemctl reload nginx

# 查看错误日志
sudo tail -f /var/log/nginx/error.log

# 查看访问日志
sudo tail -f /var/log/nginx/access.log

# 查看 Nginx 进程
ps aux | grep nginx

# 查看 Nginx 状态
sudo systemctl status nginx

# 查看端口监听
sudo ss -tuln | grep nginx
sudo netstat -tuln | grep nginx

14.2 常见错误

错误 1:Permission denied

# 检查文件权限
ls -la /var/www/html

# 修改所有者
sudo chown -R www-data:www-data /var/www/html

# 检查 SELinux(CentOS)
getenforce
setenforce 0  # 临时禁用

错误 2:Address already in use

# 查看占用端口的进程
sudo lsof -i :80

# 杀掉进程
sudo kill -9 <PID>

错误 3:Too many open files

# 查看系统限制
ulimit -n

# 修改限制(临时)
ulimit -n 65535

# 永久修改(编辑 /etc/security/limits.conf)
* soft nofile 65535
* hard nofile 65535

错误 4:upstream timed out

# 增加超时时间
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

14.3 性能排查

# 查看 Nginx 连接状态
sudo watch -n 1 'netstat -an | grep :80 | wc -l'

# 查看工作进程状态
ps -ef | grep nginx

# 使用 ab 进行压力测试
ab -n 1000 -c 100 http://example.com/

# 查看系统负载
top
htop

📝 配置清单

✅ 安全配置清单

  • 隐藏版本号(server_tokens off)
  • 配置 HTTPS
  • 启用 HSTS
  • 设置安全响应头(X-Frame-Options 等)
  • 禁止访问敏感文件
  • 配置速率限制
  • 配置访问控制(IP 白名单/认证)
  • 定期更新 SSL 证书

✅ 性能配置清单

  • 启用 sendfile
  • 启用 Gzip 压缩
  • 配置文件缓存
  • 配置静态资源缓存
  • 启用 HTTP/2
  • 优化 worker_processes 和 worker_connections
  • 配置 keepalive

✅ 监控配置清单

  • 配置访问日志
  • 配置错误日志
  • 设置日志轮转
  • 配置状态监控页面(stub_status)
  • 设置告警通知

🎯 总结

本文提供了 Nginx 的全面配置指南,包括:

  1. 基础配置:worker、events、http 核心配置
  2. 虚拟主机:单站点、多站点配置
  3. 反向代理:标准代理、认证代理、多路径代理
  4. 负载均衡:轮询、权重、IP Hash、健康检查
  5. HTTPS:SSL/TLS 配置、Let’s Encrypt
  6. WebSocket:标准配置、Socket.IO 配置
  7. 性能优化:缓存、压缩、HTTP/2、连接优化
  8. 安全加固:安全头、访问控制、速率限制、防攻击
  9. 常用场景:静态网站、PHP、Node.js、SPA、Git 等
  10. 故障排查:调试命令、常见错误、性能排查

💡 使用建议:

  • 根据需求选择配置项,删除不需要的部分
  • 生产环境建议开启所有安全配置
  • 测试环境可以适当放宽限制
  • 定期检查和更新配置
  • 使用版本控制管理配置文件

🔗 参考资料:

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐