--- name: nginx description: 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 状态 ```bash # 查看运行状态 sudo systemctl status nginx # 测试配置语法 sudo nginx -t # 查看已加载的配置 sudo nginx -T # 查看版本和编译参数 nginx -V ``` ### 启停管理 ```bash # 启动 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` **示例 — 静态网站:** ```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:** ```nginx server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } ``` ### 反向代理配置 ```nginx 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 配置 ```nginx 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; } } ``` ### 负载均衡 ```nginx 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; } } ``` ### 启用/禁用站点 ```bash # 启用站点(创建软链接) 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 ``` ### 删除站点 ```bash # 1. 禁用站点 sudo rm /etc/nginx/sites-enabled/mysite # 2. 删除配置文件(可选,保留备份) sudo rm /etc/nginx/sites-available/mysite # 3. 重载 sudo systemctl reload nginx ``` ## 三、SSL / HTTPS 管理 ### 查看已有证书 ```bash # 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) ```bash # 安装 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(已有证书) 在站点配置中加入: ```nginx 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 跳转 ```nginx server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } ``` ### 证书自动续期 Let's Encrypt 证书有效期 90 天,Certbot 安装后自动配置定时任务: ```bash # 查看自动续期配置 sudo certbot renew --dry-run # 手动触发续期 sudo certbot renew # 查看续期定时任务 sudo systemctl list-timers | grep certbot ``` ### SSL 证书检查 ```bash # 检查 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 ```nginx 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 ""; } } ``` ### 路径重写 ```nginx location /api/v1/ { rewrite ^/api/v1/(.*)$ /api/$1 break; proxy_pass http://127.0.0.1:8080; } ``` ### WebSocket 代理 ```nginx 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 白名单) ```nginx location /admin/ { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; proxy_pass http://127.0.0.1:8080; } ``` ## 五、日志和调试 ### 查看日志 ```bash # 错误日志 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 ``` ### 查看连接数 ```bash # 查看 Nginx 进程连接数 sudo ss -s # 查看连接状态 sudo netstat -anp | grep nginx ``` ### 常用调试命令 ```bash # 完整测试并显示配置 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 ```nginx if ($request_method !~ ^(GET|POST|HEAD)$) { return 405; } ``` ## 八、故障排查 ### 反向代理常见错误 #### "URL 拼写可能存在错误" 这个错误**不是 Nginx 本身返回的**,而是后端服务(如 Spring Boot、Node.js、Vite 等)返回的。 **排查步骤:** ```bash # 第1步:直接测试后端服务(排除 Nginx 影响) curl -v http://127.0.0.1:1234/ # 如果直接访问也报错 → 问题在后端,与 Nginx 无关 # 如果直接访问正常 → 问题在 Nginx 配置 ``` #### proxy_pass 路径陷阱 ```nginx # ❌ 错误:末尾多了斜杠,会把 /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/; # 这里需要斜杠 } ``` #### 必备的代理请求头 ```nginx 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; } ``` ### 配置测试失败 ```bash # 查看详细错误 sudo nginx -t 2>&1 # 查看错误日志 sudo tail -30 /var/log/nginx/error.log ``` ### 服务启动失败 ```bash # 查看 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. 查看错误日志确认原因 ### 证书过期 ```bash # 强制续期 sudo certbot renew --force-renewal # 或者重新申请 sudo certbot certonly --nginx -d example.com ``` ### 快速诊断命令 ```bash # 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 ```