Files
qwen-skills/nginx/SKILL.md
T

11 KiB
Raw Blame History

name, description
name description
nginx Nginx Web 服务器管理 — 站点配置、SSL 证书管理、反向代理、负载均衡、热重载、 Let's Encrypt 自动续期

Nginx 管理助手

功能概述

本 Skill 提供完整的 Nginx 操作能力,包括站点管理、SSL/HTTPS 配置、反向代理、负载均衡、Let's Encrypt 证书管理等。支持直接编辑配置文件并热重载生效。

系统环境(用户环境)

系统:Ubuntu Linux
Nginx 版本:1.24.0
配置目录:/etc/nginx/
主配置:/etc/nginx/nginx.conf
站点配置:/etc/nginx/sites-available/ (可用) / sites-enabled/ (启用)
额外配置:/etc/nginx/conf.d/
SSL 模板:/etc/letsencrypt/options-ssl-nginx.conf
DH 参数:/etc/letsencrypt/ssl-dhparams.pem
日志路径:/var/log/nginx/error.log, /var/log/nginx/access.log

一、基础操作

查看 Nginx 状态

# 查看运行状态
sudo systemctl status nginx

# 测试配置语法
sudo nginx -t

# 查看已加载的配置
sudo nginx -T

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

启停管理

# 启动
sudo systemctl start nginx

# 停止
sudo systemctl stop nginx

# 重启(完全停止再启动)
sudo systemctl restart nginx

# 热重载(加载新配置,不中断连接)
sudo systemctl reload nginx

# 禁用/启用开机自启
sudo systemctl disable nginx
sudo systemctl enable nginx

二、站点管理

创建新站点

步骤:

  1. /etc/nginx/sites-available/ 创建配置文件
  2. /etc/nginx/sites-enabled/ 创建软链接
  3. 测试配置:sudo nginx -t
  4. 重载生效:sudo systemctl reload nginx

示例 — 静态网站:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

示例 — HTTP 跳转到 HTTPS

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

反向代理配置

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;

        # WebSocket 支持
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

HTTPS + SSL 配置

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # SSL 证书路径(Let's Encrypt
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # 使用 Certbot 提供的安全 SSL 配置模板
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

负载均衡

upstream backend {
    least_conn;  # 最少连接优先
    server 10.0.0.2:8080 weight=3;
    server 10.0.0.3:8080 weight=2;
    server 10.0.0.4:8080 backup;  # 备用服务器
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

启用/禁用站点

# 启用站点(创建软链接)
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite

# 禁用站点(删除软链接)
sudo rm /etc/nginx/sites-enabled/mysite

# 测试并重载
sudo nginx -t && sudo systemctl reload nginx

删除站点

# 1. 禁用站点
sudo rm /etc/nginx/sites-enabled/mysite

# 2. 删除配置文件(可选,保留备份)
sudo rm /etc/nginx/sites-available/mysite

# 3. 重载
sudo systemctl reload nginx

三、SSL / HTTPS 管理

查看已有证书

# Let's Encrypt 证书目录
ls /etc/letsencrypt/live/

# 查看证书到期时间
sudo certbot certificates

# 或者手动查看
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates

申请 Let's Encrypt 证书(Certbot

# 安装 certbot(如未安装)
sudo apt install certbot python3-certbot-nginx

# 为单个域名申请证书
sudo certbot --nginx -d example.com -d www.example.com

# 自动配置 Nginx(Certbot 会修改配置文件)
# 或使用 --nginx 参数让它自动配置 SSL

# 仅获取证书,不修改 Nginx 配置
sudo certbot certonly --nginx -d example.com

手动配置 SSL(已有证书)

在站点配置中加入:

listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

强制 HTTPS 跳转

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

证书自动续期

Let's Encrypt 证书有效期 90 天,Certbot 安装后自动配置定时任务:

# 查看自动续期配置
sudo certbot renew --dry-run

# 手动触发续期
sudo certbot renew

# 查看续期定时任务
sudo systemctl list-timers | grep certbot

SSL 证书检查

# 检查 SSL 配置是否正确
openssl s_client -connect example.com:443 -servername example.com

# 查看证书信息
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -text -noout | grep -E "Issuer|Subject|Validity"

四、反向代理和 upstream 进阶

长连接 upstream

upstream api_backend {
    keepalive 32;  # 保持长连接数

    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
}

server {
    location /api/ {
        proxy_pass http://api_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

路径重写

location /api/v1/ {
    rewrite ^/api/v1/(.*)$ /api/$1 break;
    proxy_pass http://127.0.0.1:8080;
}

WebSocket 代理

location /ws/ {
    proxy_pass http://127.0.0.1:9000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;
}

限制访问(IP 白名单)

location /admin/ {
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;

    proxy_pass http://127.0.0.1:8080;
}

五、日志和调试

查看日志

# 错误日志
sudo tail -20 /var/log/nginx/error.log

# 访问日志
sudo tail -20 /var/log/nginx/access.log

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

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

查看连接数

# 查看 Nginx 进程连接数
sudo ss -s

# 查看连接状态
sudo netstat -anp | grep nginx

常用调试命令

# 完整测试并显示配置
sudo nginx -T

# 检查配置语法(不检查合法性)
sudo nginx -t

# 查看已启用的站点
ls /etc/nginx/sites-enabled/

# 查看默认 SSL 配置
cat /etc/letsencrypt/options-ssl-nginx.conf

六、工作流程

创建新站点(完整流程)

  1. 创建目录sudo mkdir -p /var/www/example.com
  2. 编写配置:在 /etc/nginx/sites-available/example.com 创建配置
  3. 创建软链接sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
  4. 测试sudo nginx -t
  5. 重载sudo systemctl reload nginx
  6. 如需 HTTPS:执行 sudo certbot --nginx -d example.com -d www.example.com

修改站点配置(完整流程)

  1. 编辑配置sudo nano /etc/nginx/sites-available/example.com
  2. 测试sudo nginx -t
  3. 重载sudo systemctl reload nginx
  4. 验证:检查 sudo systemctl status nginx

启用 HTTPS(已有站点)

  1. 申请证书sudo certbot --nginx -d example.com -d www.example.com
  2. Certbot 自动:修改配置文件,添加 HTTPS server 块,自动配置重定向
  3. 验证sudo systemctl reload nginx && openssl s_client -connect example.com:443

七、安全最佳实践

  1. 使用 TLS 1.2+ssl_protocols 仅启用 TLSv1.2 TLSv1.3
  2. 使用 Certbot 配置模板include /etc/letsencrypt/options-ssl-nginx.conf
  3. 启用 HSTS(可选):add_header Strict-Transport-Security "max-age=31536000" always;
  4. 禁止显示 Nginx 版本server_tokens off;(在主配置 http 块中)
  5. 定期更新证书:配置自动续期后无需手动操作
  6. 限制请求方法:仅允许 GET/POST/HEAD
    if ($request_method !~ ^(GET|POST|HEAD)$) {
        return 405;
    }
    

八、故障排查

反向代理常见错误

"URL 拼写可能存在错误"

这个错误不是 Nginx 本身返回的,而是后端服务(如 Spring Boot、Node.js、Vite 等)返回的。

排查步骤:

# 第1步:直接测试后端服务(排除 Nginx 影响)
curl -v http://127.0.0.1:1234/

# 如果直接访问也报错 → 问题在后端,与 Nginx 无关
# 如果直接访问正常 → 问题在 Nginx 配置

proxy_pass 路径陷阱

# ❌ 错误:末尾多了斜杠,会把 /app/ 替换成 /
location /app/ {
    proxy_pass http://127.0.0.1:8080/;
}

# ✅ 正确:末尾无斜杠,保持原路径
location /app/ {
    proxy_pass http://127.0.0.1:8080;  # 不加 /
}

# 特殊情况:需要去掉前缀时
location /api/ {
    # rewrite + proxy_pass 末尾斜杠 = 去掉 /api 前缀
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://127.0.0.1:8080/;  # 这里需要斜杠
}

必备的代理请求头

location / {
    proxy_pass http://127.0.0.1:1234;
    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;
}

配置测试失败

# 查看详细错误
sudo nginx -t 2>&1

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

服务启动失败

# 查看 systemctl 日志
sudo journalctl -xe --no-pager | tail -50

# 查看端口占用
sudo lsof -i :80
sudo lsof -i :443

502 Bad Gateway

  1. 检查后端服务是否运行:curl -I http://127.0.0.1:8080
  2. 检查 upstream 配置
  3. 查看错误日志确认原因

证书过期

# 强制续期
sudo certbot renew --force-renewal

# 或者重新申请
sudo certbot certonly --nginx -d example.com

快速诊断命令

# 1. 检查 Nginx 和后端端口
sudo lsof -i :1234
sudo netstat -tlnp | grep nginx

# 2. 直接测试后端
curl -v http://127.0.0.1:1234/

# 3. 测试 Nginx 配置
sudo nginx -t

# 4. 查看实时日志
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# 5. 查看完整的已加载配置
sudo nginx -T