diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ca344..5ecc101 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ # 变更日志 +## 2026-07-09 + +### 新增 +- nginx.conf: 添加全局性能优化(sendfile、tcp_nopush、tcp_nodelay) +- nginx.conf: 添加 Gzip 压缩配置 +- nginx.conf: 添加 SSL 安全配置(TLSv1.2/1.3、强加密套件) +- nginx.conf: 添加反代全局默认参数(timeout、buffer、headers) +- nginx.conf: 添加客户端超时和 keepalive 配置 +- CLAUDE.md: 创建项目文档,记录 SSL 证书配置规范 +- README.md: 完善项目文档 + +### 修复 +- www-ai.conf: 补全 `_next/static` 缓存(expires 1y) +- issue-ai.conf: 补全 `_next/static` 缓存(expires 1y) +- assets-ai.conf: 补全 `_next/static` 缓存(expires 1y) +- cloud-ai.conf: 切换到 resolver 变量模式 +- token-ai.conf: 切换到 resolver 变量模式 +- sso-ai.conf: 修正证书路径 + proxy_ssl_verify off +- 所有站点: 统一使用 Let's Encrypt 证书(移除 CloudFlare Origin 自签名证书) + +### 安全 +- SSL: 禁用 TLSv1.0/1.1,仅允许 TLSv1.2/1.3 +- SSL: 配置强加密套件(ECDHE+AESGCM/CHACHA20) +- SSL: 删除不安全的 CloudFlare Origin 证书 + --- + +## 2026-07-02 + +- 新增 monitor-ai.conf 监控站点配置 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..0956803 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,223 @@ +# CLAUDE.md — nginx-proxy-ai + +tlyq.ai 反向代理服务,管理所有子站点的 SSL 终止、路由转发和性能优化。 + +## 项目概述 + +nginx-proxy-ai 是 tlyq.ai 域名的统一入口,负责: +- SSL/TLS 终止(所有 HTTPS 流量) +- 反向代理到后端 Docker 容器 +- Gzip 压缩 +- 静态资源缓存 +- HTTP → HTTPS 强制跳转 + +## SSL 证书配置(必遵) + +### 证书来源 + +| 证书路径 | 类型 | 用途 | +|---------|------|------| +| `/etc/letsencrypt/live/www.tlyq.ai/` | Let's Encrypt | **所有站点共用** | +| `/etc/letsencrypt/live/www.tlyq.ai-0001/` | Let's Encrypt | SSO 站点专用 | + +### ⚠️ 禁止事项 + +1. **禁止使用 CloudFlare Origin 证书**:这是自签名证书,浏览器不信任 +2. **禁止手动放置证书文件**:必须通过 certbot 申请 +3. **禁止修改 `/etc/letsencrypt/` 目录权限** + +### 新增站点证书流程 + +1. 申请证书: + ```bash + ssh txjp "certbot certonly --webroot -w /var/www/html -d new-site.tlyq.ai" + ``` + +2. 配置 nginx 引用现有证书(推荐共用 `www.tlyq.ai`): + ```nginx + ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem; + ``` + +3. 重载配置: + ```bash + ssh txjp "docker exec nginx-ai nginx -s reload" + ``` + +### 证书续期检查 + +```bash +# 检查证书有效期 +ssh txjp "openssl x509 -in /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem -noout -dates" + +# 检查续期定时器 +ssh txjp "systemctl list-timers | grep certbot" +``` + +## 文件结构 + +``` +nginx-proxy-ai/ +├── nginx.conf # 主配置(全局优化参数) +├── nginx-local.conf # 本地测试配置 +├── docker-compose.yml # 生产 Docker 配置 +├── docker-compose.local.yml # 本地测试 Docker 配置 +├── conf.d/ # 站点反向代理配置 +│ ├── www-ai.conf # www.tlyq.ai +│ ├── cloud-ai.conf # cloud.tlyq.ai(纯静态) +│ ├── token-ai.conf # token.tlyq.ai(纯静态) +│ ├── issue-ai.conf # issue.tlyq.ai +│ ├── assets-ai.conf # assets.tlyq.ai +│ ├── git-ai.conf # git.tlyq.ai(Gitea) +│ ├── oa-ai.conf # oa.tlyq.ai +│ ├── sso-ai.conf # sso.tlyq.ai(Authelia) +│ ├── monitor-ai.conf # monitor.tlyq.ai +│ ├── root-domain.conf # tlyq.ai → www.tlyq.ai 跳转 +│ └── letsencrypt.conf # ACME HTTP-01 验证 +├── certs/ # 本地测试自签名证书(不纳入生产) +└── static/ # 静态文件目录 +``` + +## 部署流程 + +### 生产部署(txjp 服务器) + +```bash +# 1. 上传配置(排除本地测试文件) +rsync -avz --exclude='node_modules' --exclude='.git' \ + --exclude='nginx-local.conf' --exclude='docker-compose.local.yml' \ + --exclude='certs/' \ + ./ txjp:/root/docker/nginx-proxy-ai/ + +# 2. 验证配置 +ssh txjp "docker exec nginx-ai nginx -t" + +# 3. 平滑重载 +ssh txjp "docker exec nginx-ai nginx -s reload" +``` + +### 本地测试 + +```bash +docker compose -f docker-compose.local.yml up -d +``` + +## 性能优化参数 + +### 全局优化(nginx.conf http 块) + +```nginx +# IO 优化 +sendfile on; +tcp_nopush on; +tcp_nodelay on; + +# Keepalive +keepalive_timeout 65; +keepalive_requests 1000; + +# 客户端超时 +client_max_body_size 16m; +client_body_buffer_size 128k; +client_header_timeout 30s; +send_timeout 30s; + +# Gzip +gzip on; +gzip_min_length 1k; +gzip_comp_level 5; +gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml; +``` + +### SSL 安全配置 + +```nginx +ssl_protocols TLSv1.2 TLSv1.3; +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; +ssl_prefer_server_ciphers on; +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 1d; +ssl_session_tickets on; +server_tokens off; +``` + +### 反代默认参数 + +```nginx +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; +proxy_set_header Connection ""; +proxy_connect_timeout 3s; +proxy_send_timeout 30s; +proxy_read_timeout 30s; +proxy_buffer_size 16k; +proxy_buffers 8 16k; +proxy_busy_buffers_size 32k; +``` + +## 常用排查命令 + +```bash +# 配置语法检查 +docker exec nginx-ai nginx -t + +# 查看完整合并配置 +docker exec nginx-ai nginx -T + +# 查看 SSL 配置 +docker exec nginx-ai nginx -T | grep -E 'ssl_protocols|ssl_ciphers|ssl_certificate' + +# 测试 SSL 连接 +echo | openssl s_client -connect 127.0.0.1:443 -servername www.tlyq.ai 2>/dev/null | grep -E 'Protocol|Cipher' + +# 检查证书有效期 +ssh txjp "openssl x509 -in /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem -noout -dates" +``` + +## 故障排查 + +### SSL 不安全提示 + +1. 检查证书是否为 Let's Encrypt: + ```bash + ssh txjp "openssl x509 -in /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem -noout -issuer" + ``` + 应显示 `Let's Encrypt`,而非 `CloudFlare` + +2. 检查 SSL 协议和加密套件: + ```bash + docker exec nginx-ai nginx -T | grep -E 'ssl_protocols|ssl_ciphers' + ``` + 必须配置 `ssl_protocols TLSv1.2 TLSv1.3` + +### 502 Bad Gateway + +1. 检查后端容器是否运行: + ```bash + docker ps | grep -E 'www-ai|assets-ai|issue-ai' + ``` + +2. 检查容器网络连通性: + ```bash + docker exec nginx-ai ping assets-ai + ``` + +### 配置不生效 + +1. 确认配置语法正确: + ```bash + docker exec nginx-ai nginx -t + ``` + +2. 确认已重载: + ```bash + docker exec nginx-ai nginx -s reload + ``` + +3. 确认容器挂载路径正确: + ```bash + docker inspect nginx-ai | grep -A5 Mounts + ``` diff --git a/README.md b/README.md index ccda0f5..af6bcdf 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,176 @@ # nginx-proxy-ai — tlyq.ai 反向代理 -tlyq.ai 各站点的 nginx 反向代理配置,统一管理 SSL 和路由规则。 +tlyq.ai 各站点的 nginx 反向代理配置,统一管理 SSL 证书、路由规则和性能优化。 + +## 架构 + +``` +客户端 → nginx:80/443 → 后端容器(Docker 内网) + ↓ + SSL 终止 + Gzip + 缓存 + 限流 +``` + +- **生产环境**:`docker-compose.yml`,端口 80/443,挂载 `/etc/letsencrypt` 证书 +- **本地测试**:`docker-compose.local.yml`,端口 9443-9445,自签名证书 ## 代理站点 -| 子域名 | 后端容器 | -|--------|---------| -| www.tlyq.ai | www-ai | -| cloud.tlyq.ai | cloud-ai | -| token.tlyq.ai | token-ai | -| issue.tlyq.ai | issue-ai | -| assets.tlyq.ai | assets-ai | -| git.tlyq.ai | gitea-ai | +| 子域名 | 后端容器 | 端口 | 说明 | +|--------|---------|------|------| +| www.tlyq.ai | www-ai | 3000 | 图灵引擎官网 | +| cloud.tlyq.ai | cloud-ai | 80 | 智算系统云平台(纯静态) | +| token.tlyq.ai | token-ai | 80 | Token 工厂(纯静态) | +| issue.tlyq.ai | issue-ai | 3000 | 工单系统 | +| assets.tlyq.ai | assets-ai | 3000 | 资产管理系统 | +| git.tlyq.ai | gitea-ai | 3000 | Gitea 代码托管 | +| oa.tlyq.ai | oa-ai | 3000 | OA 统一门户 | +| sso.tlyq.ai | authelia | 9091 | Authelia SSO 认证中心 | +| monitor.tlyq.ai | monitor-ai | 3000 | 告警监控中心 | + +## SSL 证书 + +### 证书来源 + +| 域名 | 证书类型 | 有效期 | 备注 | +|------|---------|--------|------| +| www.tlyq.ai | Let's Encrypt | 2026-07-01 ~ 2026-09-29 | **主证书**,所有站点共用 | +| www.tlyq.ai-0001 | Let's Encrypt | — | SSO 站点专用 | + +### ⚠️ 重要:禁止使用 CloudFlare Origin 证书 + +CloudFlare Origin 证书是自签名证书,浏览器不信任,会导致 SSL 不安全提示。 + +**所有站点必须使用 Let's Encrypt 公共信任证书。** + +### 证书续期 + +Let's Encrypt 证书有效期 90 天,需自动续期: + +```bash +# 检查续期定时器 +systemctl list-timers | grep certbot + +# 手动续期 +certbot renew --deploy-hook "docker exec nginx-ai nginx -s reload" +``` + +### 新增站点证书 + +1. 使用 certbot 申请证书: + ```bash + certbot certonly --webroot -w /var/www/html -d new-site.tlyq.ai + ``` + +2. 在 `conf.d/` 添加配置,引用 `www.tlyq.ai` 的证书: + ```nginx + ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem; + ``` + +3. 重启 nginx: + ```bash + docker exec nginx-ai nginx -s reload + ``` + +## 性能优化配置 + +### 全局配置(nginx.conf) + +| 配置项 | 值 | 说明 | +|--------|---|------| +| `sendfile` | on | 零拷贝文件传输 | +| `tcp_nopush` | on | 聚合响应头和 body | +| `tcp_nodelay` | on | keepalive 连接不延迟发送 | +| `keepalive_timeout` | 65s | 客户端 keep-alive 超时 | +| `keepalive_requests` | 1000 | 单连接最大请求数 | +| `gzip` | on | 启用 Gzip 压缩 | +| `gzip_comp_level` | 5 | 压缩级别(1-9,5 为平衡点) | +| `gzip_types` | text/css/js/json/xml/svg | 压缩的 MIME 类型 | + +### SSL 安全配置 + +```nginx +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...; +ssl_prefer_server_ciphers on; +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 1d; +ssl_session_tickets on; +``` + +### 反代配置 + +```nginx +proxy_connect_timeout 3s; # 连接后端超时 +proxy_send_timeout 30s; # 发送请求超时 +proxy_read_timeout 30s; # 读取响应超时 +proxy_buffer_size 16k; # 响应头缓冲 +proxy_buffers 8 16k; # 响应体缓冲 +``` ## 部署 -修改 `conf.d/` 下对应配置文件后,重启容器或 reload nginx。 +### 生产部署 -详见 `docker-compose.yml`。 +```bash +# 上传配置到服务器 +rsync -avz --exclude='node_modules' --exclude='.git' \ + --exclude='nginx-local.conf' --exclude='docker-compose.local.yml' \ + --exclude='certs/' \ + ./ txjp:/root/docker/nginx-proxy-ai/ + +# 重启 nginx +ssh txjp "docker exec nginx-ai nginx -t && docker exec nginx-ai nginx -s reload" +``` + +### 本地测试 + +```bash +docker compose -f docker-compose.local.yml up -d +``` + +访问:`https://localhost:9444`(assets)、`https://localhost:9445`(issue) + +## 文件结构 + +``` +nginx-proxy-ai/ +├── nginx.conf # 生产环境主配置 +├── nginx-local.conf # 本地测试主配置 +├── docker-compose.yml # 生产环境 Docker 配置 +├── docker-compose.local.yml # 本地测试 Docker 配置 +├── conf.d/ # 各站点反向代理配置 +│ ├── www-ai.conf +│ ├── cloud-ai.conf +│ ├── token-ai.conf +│ ├── issue-ai.conf +│ ├── assets-ai.conf +│ ├── git-ai.conf +│ ├── oa-ai.conf +│ ├── sso-ai.conf +│ ├── monitor-ai.conf +│ ├── root-domain.conf # 根域名跳转 +│ └── letsencrypt.conf # ACME 验证 +├── certs/ # 本地测试自签名证书 +├── static/ # 静态文件 +└── README.md +``` + +## 常用命令 + +```bash +# 测试配置语法 +docker exec nginx-ai nginx -t + +# 平滑重载配置 +docker exec nginx-ai nginx -s reload + +# 查看完整合并配置 +docker exec nginx-ai nginx -T + +# 查看 nginx 版本 +docker exec nginx-ai nginx -v + +# 查看当前生效的 SSL 配置 +docker exec nginx-ai nginx -T | grep ssl +```