Kaynağa Gözat

feat: Nginx Stream + SSL Preread 多子域名自动分流方案 v2.0

架构: TCP 层 ssl_preread 协议检测 + 模块化配置文件

端口映射:
- 40130 chanking.zhonjin.com → 127.0.0.1:5004 (主 Web 服务)
- 40715 mqtt.zhonjin.com     → 127.0.0.1:8085 (MQTT 服务)
- 40716 baolin.zhonjin.com   → 127.0.0.1:5000 (宝林服务 A)
- 40719 baolin.zhonjin.com   → 127.0.0.1:5001 (宝林服务 B)

配置文件:
- nginx.conf: 主配置(40130 + include 指令)
- zhonjin_http.conf: 子域名 HTTP 服务配置
- zhonjin_stream.conf: 子域名 Stream 分流配置
- zhonjin.com.conf: 配置总览说明

文档:
- CHANGELOG.md: 变更日志
- TECH_DOC.md: 完整技术方案
- RASPBERRYPI_SETUP.md: 树莓派 5 部署指南
- QA_ARCHIVE.md: 问答归档
steven_roc 4 gün önce
işleme
e0dd492d4d
10 değiştirilmiş dosya ile 2317 ekleme ve 0 silme
  1. 87 0
      CHANGELOG.md
  2. 246 0
      QA_ARCHIVE.md
  3. 531 0
      RASPBERRYPI_SETUP.md
  4. 181 0
      README.md
  5. 744 0
      TECH_DOC.md
  6. 73 0
      git_push.sh
  7. 137 0
      nginx.conf
  8. 106 0
      zhonjin.com.conf
  9. 139 0
      zhonjin_http.conf
  10. 73 0
      zhonjin_stream.conf

+ 87 - 0
CHANGELOG.md

@@ -0,0 +1,87 @@
+# 变更日志 (CHANGELOG)
+
+本文件记录 Nginx Stream + SSL Preread 自动分流方案的所有变更,按时间倒序排列。
+
+格式参考:[Keep a Changelog](https://keepachangelog.com/zh-CN/)
+
+---
+
+## [v2.0] - 2026-10-06
+
+### 架构变更
+- **配置文件模块化**:将 nginx.conf 拆分为模块化结构,子域名配置独立管理
+  - `nginx.conf` — 主配置(40130 端口 + 全局参数 + include 指令)
+  - `zhonjin_http.conf` — 子域名 HTTP 服务配置,include 到 http 块
+  - `zhonjin_stream.conf` — 子域名 Stream 分流配置,include 到 stream 块
+  - `zhonjin.com.conf` — 配置总览说明文档
+
+### 新增
+
+#### 服务组 2:mqtt.zhonjin.com:40715 → 内网服务 8085
+- **域名**:`mqtt.zhonjin.com`(独立子域名)
+- **外网地址**:
+  - HTTP: `http://mqtt.zhonjin.com:40715` → 自动 301 跳转
+  - HTTPS: `https://mqtt.zhonjin.com:40715`
+- **映射目标**:`http://127.0.0.1:8085`
+- **内部端口**:HTTPS `127.0.0.1:5007` / HTTP 跳转 `127.0.0.1:5008`
+- **Stream 监听**:`40715`,使用 `$backend_target_40715` 变量分流
+- **SSL Session Cache**:`shared:SSL_mqtt:5m`
+- **日志**:`/var/log/nginx/stream_access_40715.log`
+
+#### 服务组 3:baolin.zhonjin.com:40716 → 内网服务 5000
+- **域名**:`baolin.zhonjin.com`(独立子域名)
+- **外网地址**:
+  - HTTP: `http://baolin.zhonjin.com:40716` → 自动 301 跳转
+  - HTTPS: `https://baolin.zhonjin.com:40716`
+- **映射目标**:`http://127.0.0.1:5000`
+- **内部端口**:HTTPS `127.0.0.1:5009` / HTTP 跳转 `127.0.0.1:5010`
+- **Stream 监听**:`40716`,使用 `$backend_target_40716` 变量分流
+- **SSL Session Cache**:`shared:SSL_baolin_1:5m`
+- **日志**:`/var/log/nginx/stream_access_40716.log`
+
+#### 服务组 4:baolin.zhonjin.com:40719 → 内网服务 5001
+- **域名**:`baolin.zhonjin.com`(独立子域名)
+- **外网地址**:
+  - HTTP: `http://baolin.zhonjin.com:40719` → 自动 301 跳转
+  - HTTPS: `https://baolin.zhonjin.com:40719`
+- **映射目标**:`http://127.0.0.1:5001`
+- **内部端口**:HTTPS `127.0.0.1:5011` / HTTP 跳转 `127.0.0.1:5012`
+- **Stream 监听**:`40719`,使用 `$backend_target_40719` 变量分流
+- **SSL Session Cache**:`shared:SSL_baolin_2:5m`
+- **日志**:`/var/log/nginx/stream_access_40719.log`
+
+### 技术说明
+- 各服务组使用不同子域名,但共用同一通配符证书 `*.zhonjin.com`
+- 每个服务组独立 map 变量,互不干扰
+- SSL session cache 名称按域名+编号命名,避免冲突
+
+---
+
+## [v1.0] - 初始版本
+
+### 新增
+- 基础架构:Nginx stream 模块 + ssl_preread 协议检测
+- 服务组 1:chanking.zhonjin.com:40130 → 内网服务 5004
+- HTTP 自动 301 跳转到 HTTPS
+- WebSocket 支持(Upgrade 头透传)
+- SSL 安全配置:TLSv1.2/1.3, HSTS, 强加密套件
+- Stream 独立日志:`stream_access.log`, `stream_error.log`
+
+---
+
+## 已知问题
+
+> 待发现后记录,格式:
+> - **[日期] 问题描述**:影响范围 / 临时解决方案 / 永久修复方案
+
+---
+
+## Bug 修复记录
+
+> 记录所有 bug 修复,格式:
+> ### [日期] Bug 标题
+> - **现象**:描述问题表现
+> - **根因**:分析根本原因
+> - **修复方案**:具体修改内容
+> - **影响文件**:涉及的文件列表
+> - **验证方式**:如何确认修复有效

+ 246 - 0
QA_ARCHIVE.md

@@ -0,0 +1,246 @@
+# 问答归档 (Q&A Archive)
+
+Nginx Stream + SSL Preread 自动分流方案 — 技术问答归档
+
+> **持续更新**:每次技术问答后自动归档  
+> **最后更新**:2026-10-06
+
+---
+
+## 目录
+
+- [架构相关](#架构相关)
+- [配置相关](#配置相关)
+- [域名与证书](#域名与证书)
+- [性能相关](#性能相关)
+- [故障排查](#故障排查)
+- [端口扩展](#端口扩展)
+- [树莓派部署](#树莓派部署)
+
+---
+
+## 架构相关
+
+### Q1: 为什么使用 stream + ssl_preread 而不是传统的 http 模块 redirect?
+
+**A:** 传统方案需要在 Nginx 的 HTTP 模块中直接监听外网端口并处理 SSL,所有 HTTP 和 HTTPS 流量必须使用同一端口。而 stream + ssl_preread 方案的优势:
+
+1. **端口灵活性**:可以在任意非标准端口同时处理 HTTP 和 HTTPS 流量
+2. **TCP 层分流**:不解密 TLS,性能开销更低
+3. **协议检测**:通过 `ssl_preread` 在 TCP 层检测 ClientHello,无需证书即可完成分流
+4. **后端隔离**:后端服务只需提供 HTTP,SSL 终结完全由 Nginx 处理
+
+### Q2: 为什么不直接用 Nginx 的 `if ($scheme = http)` 来做跳转?
+
+**A:** `if` 指令在 Nginx 中是 "if is evil" 的,有以下问题:
+1. 在 `stream` 上下文中无法使用 `$scheme` 变量(stream 不解析 HTTP)
+2. `if` 在 `location` 上下文中有已知的副作用和限制
+3. 通过 stream 层的物理分流更干净,每个路径独立互不干扰
+
+### Q3: 每个端口都需要独立的 map 变量吗?
+
+**A:** 是的。Nginx 的 map 指令在同一上下文中,如果多个 stream server 共享同一个 map,它们会路由到相同的后端。每个端口需要独立的服务组(不同的 SSL 终结端口和不同的后端),因此需要独立的 map 变量。
+
+### Q4: 为什么把子域名配置拆成独立文件而不是全部写在 nginx.conf 里?
+
+**A:** 模块化配置的优势:
+1. **独立维护**:新增子域名只需编辑对应的 include 文件,不影响主配置
+2. **减少冲突**:不同团队/项目的配置不会互相干扰
+3. **易于审计**:配置分散在小文件中,便于审查
+4. **热重载安全**:`nginx -t` 可验证所有 include 文件
+5. **结构清晰**:`nginx.conf` 保持简洁,只负责全局配置和 include 指令
+
+---
+
+## 配置相关
+
+### Q5: `backlog=4096` 的含义是什么?需要调整吗?
+
+**A:** `backlog` 是 TCP 监听队列的最大长度。超过 backlog 的连接会被丢弃。
+- 默认值通常是 511(Linux)
+- 4096 适合中等并发场景
+- 高并发场景可增加到 65535(需同时调整 `net.core.somaxconn`)
+
+### Q6: `proxy_timeout 3600s` 为什么要设这么大?
+
+**A:** 需要与 HTTP 模块的 `proxy_read_timeout` 保持一致:
+1. stream 层的超时控制的是 TCP 连接空闲超时
+2. 如果后端有 WebSocket 长连接,可能需要保持数小时
+3. 设为 3600s 可覆盖绝大多数长连接场景
+4. 如果确认没有长连接需求,可以缩短到 60-300s 以释放资源
+
+### Q7: `proxy_next_upstream off` 为什么禁用故障转移?
+
+**A:** 在 stream 上下文中:
+1. TCP 层无法确定请求是否已部分传输
+2. 非幂等请求(如 POST)重试可能导致数据重复
+3. 只有一个 upstream 时此选项实际无影响,但显式禁用更安全
+
+### Q8: `include` 指令的路径有什么要求?
+
+**A:** 
+- `include` 路径可以是绝对路径或相对路径(相对于 nginx.conf 所在目录)
+- 推荐使用绝对路径,避免歧义
+- 支持通配符:`include /etc/nginx/conf.d/*.conf;`
+- include 的文件中不能再嵌套 include stream 块(stream 块不支持嵌套 include stream)
+
+---
+
+## 域名与证书
+
+### Q9: 多个子域名可以共用同一个 SSL 证书吗?
+
+**A:** 可以,使用通配符证书 `*.zhonjin.com` 即可覆盖所有子域名:
+- `chanking.zhonjin.com` ✓
+- `mqtt.zhonjin.com` ✓
+- `baolin.zhonjin.com` ✓
+- 其他 `*.zhonjin.com` ✓
+
+申请命令:
+```bash
+sudo certbot certonly --manual --preferred-challenges dns \
+    -d zhonjin.com -d "*.zhonjin.com"
+```
+
+### Q10: 不同子域名使用同一个 IP,Nginx 如何区分?
+
+**A:** 本方案中,不同子域名通过**不同端口**区分,而非 SNI 区分:
+- `chanking.zhonjin.com:40130` → stream 端口 40130
+- `mqtt.zhonjin.com:40715` → stream 端口 40715
+- `baolin.zhonjin.com:40716` → stream 端口 40716
+
+每个 stream server 独立监听自己的端口,转发到对应的 HTTPS server,HTTPS server 通过 `server_name` 匹配域名。
+
+### Q11: `ssl_preread` 能否根据 SNI(域名)分流到不同后端?
+
+**A:** 可以。`ssl_preread` 不仅能检测是否为 TLS,还能读取 SNI 信息:
+```nginx
+map $ssl_preread_server_name $sni_backend {
+    "mqtt.zhonjin.com"    127.0.0.1:8085;
+    "baolin.zhonjin.com"  127.0.0.1:5000;
+    default               127.0.0.1:5004;
+}
+```
+但本方案使用端口区分,因此不需要 SNI 分流。
+
+### Q12: 通配符证书 `*.zhonjin.com` 是否覆盖 `zhonjin.com`(不带子域名前缀)?
+
+**A:** 不覆盖。通配符证书只匹配 `*.zhonjin.com`,不匹配裸域 `zhonjin.com`。申请时需要同时指定:
+```bash
+-d zhonjin.com -d "*.zhonjin.com"
+```
+
+---
+
+## 性能相关
+
+### Q13: 这个方案的性能瓶颈在哪里?
+
+**A:** 主要瓶颈点:
+1. **SSL 握手**:RSA/ECDHE 密钥交换是 CPU 密集操作,可使用 `ssl_session_cache` 复用
+2. **stream 转发**:几乎无额外开销(TCP 层直通)
+3. **文件描述符**:高并发时需要足够的 fd 配额
+4. **树莓派 CPU**:ARM 处理器 SSL 性能较弱,可通过 session cache 和硬件加速缓解
+
+### Q14: SSL Session Cache 大小怎么计算?
+
+**A:** 
+- `shared:SSL_mqtt:5m` 表示 5MB 共享内存
+- 每个 SSL session 约 500 bytes
+- 5MB ≈ 10,000 个并发 SSL session
+- 4 个服务组总计约 25MB,对 8GB 树莓派完全可接受
+
+---
+
+## 故障排查
+
+### Q15: 如何判断 HTTP 流量是否正确到达跳转 server?
+
+**A:** 查看 stream 访问日志:
+```bash
+tail -f /var/log/nginx/stream_access_40715.log
+# 正常 HTTP 访问应该看到 upstream 指向跳转端口
+```
+
+### Q16: 301 跳转后浏览器显示 "重定向循环" 怎么办?
+
+**A:** 常见原因:
+1. HTTP 跳转 server 的 `return 301` URL 中端口写错了
+2. HTTPS server 意外把请求又转回了 HTTP
+3. 后端应用的 `siteurl` 配置为 HTTP
+
+排查:
+```bash
+curl -v http://mqtt.zhonjin.com:40715 2>&1 | grep Location
+# 确认 Location 是 https:// 开头且端口正确
+```
+
+### Q17: `nginx -t` 报错 "include file not found" 怎么办?
+
+**A:** 
+1. 检查文件是否存在:`ls -la /etc/nginx/conf.d/zhonjin_http.conf`
+2. 检查目录是否存在:`ls -la /etc/nginx/stream.d/`
+3. 检查文件权限:确保 nginx 用户(www-data)有读权限
+4. 检查路径拼写
+
+### Q18: stream include 不生效?
+
+**A:** 
+- 确认 nginx 版本 ≥ 1.26(支持 stream 块内 include)
+- 确认 include 路径正确
+- 确认 `nginx -t` 通过
+- 检查 stream 块的 include 是否在正确位置(stream 块内部)
+
+---
+
+## 端口扩展
+
+### Q19: 新增端口映射时,如何确保不影响已有服务?
+
+**A:** 遵循检查清单:
+1. ✅ 新增的 map 变量名不与已有的冲突
+2. ✅ 新增的 HTTPS/HTTP 内部端口不与已有的冲突
+3. ✅ SSL session cache 名称不重复
+4. ✅ stream 日志文件路径不重复
+5. ✅ 防火墙放行新端口
+6. ✅ `nginx -t` 通过后再 reload
+
+### Q20: 端口范围有没有限制?
+
+**A:** 
+- 有效端口范围:1-65535
+- 1024 以下需要 root 权限监听
+- 建议使用 10000-65535 范围的非特权端口
+- 避免与常见服务端口冲突
+
+---
+
+## 树莓派部署
+
+### Q21: 树莓派跑这个方案会不会性能不足?
+
+**A:** 树莓派 5 8G 完全够用:
+1. stream 模块是 TCP 层直通,CPU 开销极低
+2. 树莓派 5 的 Cortex-A76 支持 ARMv8 crypto 扩展
+3. 个人/小型团队场景,并发量通常在 100 以内
+4. 实际测试:树莓派 4 就能处理 500+ SSL req/s
+
+### Q22: SD 卡会被日志写坏吗?
+
+**A:** 长期高频写入确实会影响 SD 卡寿命。建议:
+1. 将日志目录挂载为 tmpfs(内存文件系统)
+2. 或使用外接 SSD/USB 驱动器存储日志
+3. 配置 logrotate 限制日志大小
+4. 对于非关键场景,可以关闭 stream access_log
+
+### Q23: 树莓派上编译 Nginx 需要多长时间?
+
+**A:** 
+- 树莓派 5(Cortex-A76):约 5-10 分钟(`make -j4`)
+- 树莓派 4(Cortex-A72):约 10-20 分钟
+- 树莓派 3:约 30-60 分钟
+- 建议直接使用 APT 安装,避免编译
+
+---
+
+*新问答将按类别追加到对应章节中。*

+ 531 - 0
RASPBERRYPI_SETUP.md

@@ -0,0 +1,531 @@
+# 树莓派 5 8G 部署指南
+
+Nginx Stream + SSL Preread 自动分流方案在树莓派 5 上的完整安装、编译和运行指南。
+
+> **适用系统**:Ubuntu 24.04 for Raspberry Pi / Raspberry Pi OS (Bookworm)  
+> **硬件**:Raspberry Pi 5 8GB  
+> **最后更新**:2026-10-06
+
+---
+
+## 目录
+
+1. [系统准备](#1-系统准备)
+2. [Nginx 安装](#2-nginx-安装)
+3. [从源码编译 Nginx(可选)](#3-从源码编译-nginx可选)
+4. [SSL 证书配置](#4-ssl-证书配置)
+5. [配置部署](#5-配置部署)
+6. [防火墙设置](#6-防火墙设置)
+7. [性能优化](#7-性能优化)
+8. [开机自启与守护进程](#8-开机自启与守护进程)
+9. [验证与测试](#9-验证与测试)
+10. [常见问题](#10-常见问题)
+
+---
+
+## 1. 系统准备
+
+### 1.1 系统更新
+
+```bash
+sudo apt update && sudo apt upgrade -y
+sudo apt install -y curl wget git vim htop net-tools build-essential
+```
+
+### 1.2 确认系统版本
+
+```bash
+lsb_release -a
+uname -r
+uname -m          # 应为 aarch64
+free -h           # 应为 8GB
+```
+
+### 1.3 设置静态 IP(推荐)
+
+```bash
+sudo vim /etc/netplan/50-cloud-init.yaml
+```
+
+```yaml
+network:
+  version: 2
+  ethernets:
+    eth0:
+      dhcp4: no
+      addresses:
+        - 192.168.1.100/24
+      routes:
+        - to: default
+          via: 192.168.1.1
+      nameservers:
+        addresses: [8.8.8.8, 114.114.114.114]
+```
+
+```bash
+sudo netplan apply
+```
+
+### 1.4 设置时区
+
+```bash
+sudo timedatectl set-timezone Asia/Shanghai
+timedatectl
+```
+
+---
+
+## 2. Nginx 安装
+
+### 2.1 方式一:APT 安装(推荐)
+
+```bash
+sudo apt install -y nginx-full
+nginx -v
+nginx -V 2>&1 | grep -o "with-stream"
+```
+
+### 2.2 方式二:PPA 安装(获取更新版本)
+
+```bash
+sudo add-apt-repository ppa:nginx/stable
+sudo apt update
+sudo apt install -y nginx-full
+```
+
+### 2.3 验证模块完整性
+
+```bash
+nginx -V 2>&1 | grep -E "with-stream|with-http_ssl_module|with-http_v2_module"
+```
+
+**必需模块清单**:
+
+| 模块 | 用途 |
+|------|------|
+| `with-stream` | TCP/UDP 代理 |
+| `with-stream_ssl_module` | Stream SSL 支持 |
+| `with-stream_ssl_preread_module` | TLS ClientHello 预读 |
+| `with-http_ssl_module` | HTTP SSL 终结 |
+| `with-http_v2_module` | HTTP/2 支持 |
+
+---
+
+## 3. 从源码编译 Nginx(可选)
+
+### 3.1 安装编译依赖
+
+```bash
+sudo apt install -y \
+    build-essential libpcre3 libpcre3-dev \
+    zlib1g zlib1g-dev libssl-dev \
+    libgd-dev libgeoip-dev libxml2-dev libxslt1-dev
+```
+
+### 3.2 下载源码
+
+```bash
+NGINX_VERSION="1.26.3"
+cd /tmp
+wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
+tar -xzf nginx-${NGINX_VERSION}.tar.gz
+cd nginx-${NGINX_VERSION}
+```
+
+### 3.3 编译配置
+
+```bash
+./configure \
+    --prefix=/etc/nginx \
+    --sbin-path=/usr/sbin/nginx \
+    --modules-path=/usr/lib/nginx/modules \
+    --conf-path=/etc/nginx/nginx.conf \
+    --error-log-path=/var/log/nginx/error.log \
+    --http-log-path=/var/log/nginx/access.log \
+    --pid-path=/var/run/nginx.pid \
+    --lock-path=/var/run/nginx.lock \
+    --user=www-data \
+    --group=www-data \
+    --with-stream \
+    --with-stream_ssl_module \
+    --with-stream_ssl_preread_module \
+    --with-http_ssl_module \
+    --with-http_v2_module \
+    --with-http_geoip_module \
+    --with-http_realip_module \
+    --with-http_gzip_static_module \
+    --with-http_sub_module \
+    --with-http_stub_status_module \
+    --with-pcre-jit \
+    --with-cc-opt="-march=armv8-a+crc -mtune=cortex-a76" \
+    --with-ld-opt="-Wl,-z,relro -Wl,-z,now"
+```
+
+**树莓派特定编译优化**:
+
+| 参数 | 说明 |
+|------|------|
+| `-march=armv8-a+crc` | 利用 ARMv8 CRC 指令加速 |
+| `-mtune=cortex-a76` | 针对树莓派 5 的 Cortex-A76 优化 |
+| `-Wl,-z,relro` | 只读重定位,安全加固 |
+| `--with-pcre-jit` | PCRE JIT 编译,正则加速 |
+
+### 3.4 编译安装
+
+```bash
+make -j4    # 4 核并行编译,约 5-15 分钟
+sudo make install
+nginx -V
+```
+
+### 3.5 创建 Systemd 服务
+
+```bash
+sudo vim /etc/systemd/system/nginx.service
+```
+
+```ini
+[Unit]
+Description=The nginx HTTP and reverse proxy server
+After=network-online.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/var/run/nginx.pid
+ExecStartPre=/usr/sbin/nginx -t
+ExecStart=/usr/sbin/nginx
+ExecReload=/bin/kill -s HUP $MAINPID
+ExecStop=/bin/kill -s QUIT $MAINPID
+PrivateTmp=true
+TimeoutStopSec=5
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target
+```
+
+```bash
+sudo systemctl daemon-reload
+sudo systemctl enable nginx
+```
+
+---
+
+## 4. SSL 证书配置
+
+### 4.1 安装 Certbot
+
+```bash
+sudo apt install -y certbot python3-certbot-nginx
+```
+
+### 4.2 申请通配符证书
+
+```bash
+sudo certbot certonly --manual --preferred-challenges dns \
+    -d zhonjin.com -d "*.zhonjin.com"
+```
+
+按提示添加 DNS TXT 记录,覆盖所有子域名:
+- `zhonjin.com`
+- `chanking.zhonjin.com`
+- `mqtt.zhonjin.com`
+- `baolin.zhonjin.com`
+
+### 4.3 证书目录权限
+
+```bash
+sudo chmod 755 /etc/letsencrypt/live/
+sudo chmod 644 /etc/letsencrypt/live/zhonjin.com/fullchain.pem
+sudo chmod 600 /etc/letsencrypt/live/zhonjin.com/privkey.pem
+sudo chown root:root /etc/letsencrypt/live/zhonjin.com/privkey.pem
+```
+
+### 4.4 自动续期
+
+```bash
+sudo certbot renew --dry-run    # 测试续期
+sudo crontab -e
+# 添加:
+0 3 * * * certbot renew --quiet --post-hook "nginx -s reload"
+```
+
+---
+
+## 5. 配置部署
+
+### 5.1 部署配置文件
+
+```bash
+# 创建配置目录
+sudo mkdir -p /etc/nginx/conf.d /etc/nginx/stream.d
+
+# 备份原始配置
+sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
+
+# 部署新配置
+sudo cp nginx.conf /etc/nginx/nginx.conf
+sudo cp zhonjin_http.conf /etc/nginx/conf.d/zhonjin_http.conf
+sudo cp zhonjin_stream.conf /etc/nginx/stream.d/zhonjin_stream.conf
+
+# 测试并重载
+sudo nginx -t
+sudo systemctl reload nginx
+```
+
+### 5.2 验证端口监听
+
+```bash
+sudo ss -tlnp | grep nginx
+
+# 预期输出应包含:
+# 0.0.0.0:40130    (stream 外网 - chanking)
+# 0.0.0.0:40715    (stream 外网 - mqtt)
+# 0.0.0.0:40716    (stream 外网 - baolin)
+# 0.0.0.0:40719    (stream 外网 - baolin)
+# 127.0.0.1:5005   (HTTPS 内网)
+# 127.0.0.1:5006   (HTTP 跳转)
+# ... 其他内部端口
+```
+
+---
+
+## 6. 防火墙设置
+
+### 6.1 UFW 防火墙(推荐)
+
+```bash
+sudo ufw enable
+sudo ufw allow 22/tcp          # SSH
+sudo ufw allow 40130/tcp       # chanking
+sudo ufw allow 40715/tcp       # mqtt
+sudo ufw allow 40716/tcp       # baolin
+sudo ufw allow 40719/tcp       # baolin
+sudo ufw default deny incoming
+sudo ufw default allow outgoing
+sudo ufw status verbose
+```
+
+### 6.2 iptables(备选)
+
+```bash
+sudo iptables -A INPUT -p tcp --dport 40130 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 40715 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 40716 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 40719 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
+sudo iptables -A INPUT -j DROP
+
+sudo apt install -y iptables-persistent
+sudo netfilter-persistent save
+```
+
+---
+
+## 7. 性能优化
+
+### 7.1 内核参数优化
+
+```bash
+sudo vim /etc/sysctl.d/99-nginx-performance.conf
+```
+
+```ini
+net.core.somaxconn = 65535
+net.ipv4.tcp_max_syn_backlog = 65535
+net.ipv4.tcp_fin_timeout = 30
+net.ipv4.tcp_tw_reuse = 1
+net.ipv4.tcp_keepalive_time = 600
+net.core.rmem_max = 16777216
+net.core.wmem_max = 16777216
+net.ipv4.tcp_rmem = 4096 87380 16777216
+net.ipv4.tcp_wmem = 4096 65536 16777216
+fs.file-max = 2097152
+```
+
+```bash
+sudo sysctl -p /etc/sysctl.d/99-nginx-performance.conf
+```
+
+### 7.2 文件描述符限制
+
+```bash
+sudo vim /etc/security/limits.conf
+```
+
+```
+* soft nofile 65535
+* hard nofile 65535
+www-data soft nofile 65535
+www-data hard nofile 65535
+```
+
+### 7.3 Systemd 服务优化
+
+```bash
+sudo mkdir -p /etc/systemd/system/nginx.service.d
+sudo vim /etc/systemd/system/nginx.service.d/override.conf
+```
+
+```ini
+[Service]
+LimitNOFILE=65535
+Nice=-5
+CPUQuota=80%
+```
+
+```bash
+sudo systemctl daemon-reload
+sudo systemctl restart nginx
+```
+
+### 7.4 树莓派特定优化
+
+```bash
+# 禁用 swap(减少 SD 卡写入)
+sudo dphys-swapfile swapoff
+sudo apt remove -y dphys-swapfile
+
+# 使用 tmpfs 存储日志(减少 SD 卡写入)
+sudo vim /etc/fstab
+# 添加:
+tmpfs /var/log/nginx tmpfs defaults,noatime,size=50m 0 0
+```
+
+> **注意**:使用 tmpfs 存储日志时,日志在重启后会丢失。如需持久化日志,建议使用外接 USB 存储。
+
+---
+
+## 8. 开机自启与守护进程
+
+### 8.1 启用开机自启
+
+```bash
+sudo systemctl enable nginx
+sudo systemctl start nginx
+sudo systemctl status nginx
+```
+
+### 8.2 监控脚本
+
+```bash
+sudo vim /usr/local/bin/nginx-monitor.sh
+```
+
+```bash
+#!/bin/bash
+if ! pgrep -x nginx > /dev/null; then
+    echo "$(date): Nginx 进程不存在,尝试重启..." >> /var/log/nginx-monitor.log
+    sudo systemctl start nginx
+    echo "$(date): Nginx 已重启" >> /var/log/nginx-monitor.log
+fi
+```
+
+```bash
+sudo chmod +x /usr/local/bin/nginx-monitor.sh
+
+# 每 5 分钟检查一次
+sudo crontab -e
+# 添加:
+*/5 * * * * /usr/local/bin/nginx-monitor.sh
+```
+
+---
+
+## 9. 验证与测试
+
+### 9.1 完整功能验证
+
+```bash
+# 测试 HTTPS 访问(各域名)
+curl -I https://chanking.zhonjin.com:40130
+curl -I https://mqtt.zhonjin.com:40715
+curl -I https://baolin.zhonjin.com:40716
+curl -I https://baolin.zhonjin.com:40719
+
+# 测试 HTTP → HTTPS 跳转(各域名)
+curl -I http://chanking.zhonjin.com:40130    # 应返回 301
+curl -I http://mqtt.zhonjin.com:40715        # 应返回 301
+curl -I http://baolin.zhonjin.com:40716      # 应返回 301
+curl -I http://baolin.zhonjin.com:40719      # 应返回 301
+
+# 验证 SSL 证书
+echo | openssl s_client -connect chanking.zhonjin.com:40130 -servername chanking.zhonjin.com 2>/dev/null | openssl x509 -noout -dates
+echo | openssl s_client -connect mqtt.zhonjin.com:40715 -servername mqtt.zhonjin.com 2>/dev/null | openssl x509 -noout -dates
+```
+
+### 9.2 性能基准测试
+
+```bash
+sudo apt install -y apache2-utils
+
+# 压力测试
+ab -n 1000 -c 50 https://chanking.zhonjin.com:40130/
+ab -n 1000 -c 50 https://mqtt.zhonjin.com:40715/
+```
+
+---
+
+## 10. 常见问题
+
+### Q1: 编译时报内存不足
+
+```bash
+# 添加临时 swap
+sudo fallocate -l 2G /tmp/swapfile
+sudo chmod 600 /tmp/swapfile
+sudo mkswap /tmp/swapfile
+sudo swapon /tmp/swapfile
+# 编译完成后移除
+sudo swapoff /tmp/swapfile && sudo rm /tmp/swapfile
+```
+
+### Q2: stream 模块报 "unknown directive"
+
+```bash
+dpkg -l | grep nginx
+sudo apt install -y nginx-full    # 替换 nginx-light
+```
+
+### Q3: include 文件找不到
+
+```bash
+sudo mkdir -p /etc/nginx/conf.d /etc/nginx/stream.d
+sudo cp zhonjin_http.conf /etc/nginx/conf.d/
+sudo cp zhonjin_stream.conf /etc/nginx/stream.d/
+```
+
+### Q4: 通配符证书不生效
+
+```bash
+# 检查证书覆盖域名
+openssl x509 -in /etc/letsencrypt/live/zhonjin.com/fullchain.pem \
+    -noout -text | grep -A1 "Subject Alternative Name"
+# 应包含 *.zhonjin.com
+```
+
+### Q5: 树莓派 SD 卡写入寿命
+- 将日志目录挂载为 tmpfs
+- 使用外接 SSD/USB 存储持久化日志
+- 关闭不必要的日志
+
+---
+
+## 快速部署脚本
+
+```bash
+#!/bin/bash
+set -e
+echo "=== 树莓派 5 Nginx 快速部署 ==="
+sudo apt update && sudo apt upgrade -y
+sudo apt install -y nginx-full certbot python3-certbot-nginx
+sudo mkdir -p /etc/nginx/conf.d /etc/nginx/stream.d
+sudo cp nginx.conf /etc/nginx/nginx.conf
+sudo cp zhonjin_http.conf /etc/nginx/conf.d/zhonjin_http.conf
+sudo cp zhonjin_stream.conf /etc/nginx/stream.d/zhonjin_stream.conf
+sudo nginx -t && sudo systemctl reload nginx
+sudo ufw allow 40130/tcp 40715/tcp 40716/tcp 40719/tcp
+echo "=== 部署完成,请配置 SSL 证书 ==="
+```

+ 181 - 0
README.md

@@ -0,0 +1,181 @@
+# Nginx Stream + SSL Preread 自动分流方案
+
+> 基于 Nginx stream 模块 + ssl_preread 的 TCP 层协议检测自动分流,支持多子域名、多端口,HTTP 自动跳转 HTTPS。
+
+## 项目概述
+
+本方案使用 Nginx 的 `stream` 模块配合 `ssl_preread` 功能,在 **TCP 层**(OSI 第 4 层)检测入站流量类型并自动分流:
+
+- **TLS 流量** → Nginx SSL 终结 → 反向代理到内网 HTTP 服务
+- **明文 HTTP 流量** → 301 永久重定向到 HTTPS
+
+用户无论输入 `http://` 还是 `https://`,均可自动获得 HTTPS 加密访问。
+
+## 架构特点
+
+- ✅ **TCP 层分流**:不解密 TLS,性能开销极低
+- ✅ **多子域名支持**:chanking / mqtt / baolin 等子域名独立配置
+- ✅ **协议自动检测**:通过 ssl_preread 预读 ClientHello 判断协议
+- ✅ **HTTP 自动跳转**:明文流量 301 重定向到 HTTPS
+- ✅ **端口隔离**:每个外网端口独立 stream server + 独立 map 变量
+- ✅ **配置模块化**:主配置与子域名配置分离,便于独立维护
+- ✅ **WebSocket 支持**:完整透传 Upgrade 头
+- ✅ **安全加固**:TLSv1.2/1.3、HSTS、强加密套件、通配符证书
+
+## 端口与域名映射表
+
+| 域名 | 外网端口 | 后端服务 | HTTPS 内部端口 | HTTP 跳转端口 | 用途 |
+|------|---------|---------|---------------|-------------|------|
+| **chanking.zhonjin.com** | 40130 | 127.0.0.1:5004 | 5005 | 5006 | 主 Web 服务 |
+| **mqtt.zhonjin.com** | 40715 | 127.0.0.1:8085 | 5007 | 5008 | MQTT 服务 |
+| **baolin.zhonjin.com** | 40716 | 127.0.0.1:5000 | 5009 | 5010 | 宝林服务 A |
+| **baolin.zhonjin.com** | 40719 | 127.0.0.1:5001 | 5011 | 5012 | 宝林服务 B |
+
+## 数据流
+
+```
+外网请求 (HTTP/HTTPS)
+    │
+    ▼
+stream 端口监听 (40130/40715/40716/40719)
+    │
+    ├─ ssl_preread 检测协议
+    │
+    ├─ TLS 流量 ──→ HTTPS server (SSL 终结) ──→ proxy_pass 后端 HTTP 服务
+    │
+    └─ 明文 HTTP ──→ HTTP server ──→ 301 重定向到 HTTPS
+```
+
+## 配置文件结构
+
+```
+/etc/nginx/
+├── nginx.conf                      # 主配置(40130 + 全局参数 + include)
+├── conf.d/
+│   └── zhonjin_http.conf           # 子域名 HTTP 服务(mqtt/baolin)
+└── stream.d/
+    └── zhonjin_stream.conf         # 子域名 Stream 分流(mqtt/baolin)
+```
+
+## 快速部署
+
+### 1. 安装 Nginx
+
+```bash
+sudo apt update
+sudo apt install -y nginx-full certbot python3-certbot-nginx
+```
+
+### 2. 申请通配符 SSL 证书
+
+```bash
+sudo certbot certonly --manual --preferred-challenges dns \
+    -d zhonjin.com -d "*.zhonjin.com"
+```
+
+### 3. 部署配置
+
+```bash
+sudo mkdir -p /etc/nginx/conf.d /etc/nginx/stream.d
+sudo cp nginx.conf /etc/nginx/nginx.conf
+sudo cp zhonjin_http.conf /etc/nginx/conf.d/zhonjin_http.conf
+sudo cp zhonjin_stream.conf /etc/nginx/stream.d/zhonjin_stream.conf
+sudo nginx -t && sudo systemctl reload nginx
+```
+
+### 4. 配置防火墙
+
+```bash
+sudo ufw allow 40130/tcp
+sudo ufw allow 40715/tcp
+sudo ufw allow 40716/tcp
+sudo ufw allow 40719/tcp
+```
+
+### 5. 验证
+
+```bash
+# HTTPS 访问
+curl -I https://chanking.zhonjin.com:40130
+curl -I https://mqtt.zhonjin.com:40715
+curl -I https://baolin.zhonjin.com:40716
+curl -I https://baolin.zhonjin.com:40719
+
+# HTTP 跳转(应返回 301)
+curl -I http://chanking.zhonjin.com:40130
+curl -I http://mqtt.zhonjin.com:40715
+curl -I http://baolin.zhonjin.com:40716
+curl -I http://baolin.zhonjin.com:40719
+```
+
+## 项目文件说明
+
+| 文件 | 说明 |
+|------|------|
+| [nginx.conf](./nginx.conf) | 主配置文件(全局参数 + 40130 端口 + include 指令) |
+| [zhonjin_http.conf](./zhonjin_http.conf) | 子域名 HTTP 服务配置(include 到 http 块) |
+| [zhonjin_stream.conf](./zhonjin_stream.conf) | 子域名 Stream 分流配置(include 到 stream 块) |
+| [zhonjin.com.conf](./zhonjin.com.conf) | 配置总览说明文档 |
+| [CHANGELOG.md](./CHANGELOG.md) | 变更日志(持续更新) |
+| [TECH_DOC.md](./TECH_DOC.md) | 完整技术方案文档(持续更新) |
+| [RASPBERRYPI_SETUP.md](./RASPBERRYPI_SETUP.md) | 树莓派 5 部署指南 |
+| [QA_ARCHIVE.md](./QA_ARCHIVE.md) | 技术问答归档(持续更新) |
+| [git_push.sh](./git_push.sh) | Git 仓库初始化与推送脚本 |
+
+## 环境要求
+
+| 组件 | 最低版本 | 推荐版本 |
+|------|----------|----------|
+| Nginx | 1.11.5+ | 1.26+ |
+| 操作系统 | Ubuntu 22.04 | Ubuntu 24.04 / 树莓派 5 |
+| SSL 证书 | Let's Encrypt 通配符 | Let's Encrypt + 自动续期 |
+
+### 必需 Nginx 模块
+
+- `ngx_stream_module` — TCP/UDP 代理
+- `ngx_stream_ssl_preread_module` — TLS ClientHello 预读
+- `ngx_http_ssl_module` — HTTP SSL 终结
+- `ngx_http_v2_module` — HTTP/2 支持
+
+## 安全配置
+
+- **TLS 协议**:仅 TLSv1.2 / TLSv1.3
+- **HSTS**:max-age=31536000(1 年)
+- **加密套件**:ECDHE + AES-GCM 系列
+- **内部端口**:仅监听 127.0.0.1,外部不可直接访问
+- **版本隐藏**:`server_tokens off`
+- **通配符证书**:`*.zhonjin.com` 覆盖所有子域名
+
+## 扩展新端口
+
+详见 [TECH_DOC.md - 端口扩展指南](./TECH_DOC.md#14-端口扩展指南)
+
+简要步骤:
+1. 在 `zhonjin_http.conf` 中添加 HTTPS server + HTTP 跳转 server
+2. 在 `zhonjin_stream.conf` 中添加 map + stream server
+3. 配置防火墙放行新端口
+4. `sudo nginx -t && sudo systemctl reload nginx`
+
+## Git 仓库
+
+```bash
+# 克隆仓库
+git clone https://git.zhonjin.com:40717/steven_roc/nginx-stream-ssl-preread.git
+
+# 首次推送(使用 git_push.sh)
+chmod +x git_push.sh
+./git_push.sh
+```
+
+## 许可证
+
+MIT License
+
+## 维护者
+
+- **steven_roc**
+- 仓库地址:`https://git.zhonjin.com:40717/steven_roc`
+
+---
+
+*本项目文档持续更新,详见各文档说明。*

+ 744 - 0
TECH_DOC.md

@@ -0,0 +1,744 @@
+# 技术方案文档 (TECH_DOC)
+
+Nginx Stream + SSL Preread 自动分流方案 — 完整技术文档
+
+> **版本**:v2.0  
+> **最后更新**:2026-10-06  
+> **维护者**:steven_roc  
+> **持续更新**:本文档随项目演进持续更新
+
+---
+
+## 目录
+
+1. [方案概述](#1-方案概述)
+2. [架构设计](#2-架构设计)
+3. [配置文件结构](#3-配置文件结构)
+4. [环境要求](#4-环境要求)
+5. [软件依赖](#5-软件依赖)
+6. [端口规划](#6-端口规划)
+7. [配置详解](#7-配置详解)
+8. [SSL 证书管理](#8-ssl-证书管理)
+9. [安全策略](#9-安全策略)
+10. [日志管理](#10-日志管理)
+11. [性能调优](#11-性能调优)
+12. [部署与运维](#12-部署与运维)
+13. [故障排查](#13-故障排查)
+14. [端口扩展指南](#14-端口扩展指南)
+
+---
+
+## 1. 方案概述
+
+### 1.1 核心目标
+
+通过 Nginx 的 `stream` 模块 + `ssl_preread` 功能,在 **TCP 层**(OSI 第 4 层)检测入站流量的协议类型,实现:
+
+- **TLS 流量** → 由 Nginx HTTP 模块进行 SSL 终结 → 反向代理到内网 HTTP 服务
+- **明文 HTTP 流量** → 301 永久重定向到对应端口的 HTTPS 地址
+
+用户无论输入 `http://` 还是 `https://`,都能自动获得 HTTPS 加密访问。
+
+### 1.2 多子域名架构
+
+本方案支持多个子域名共享同一服务器 IP,通过不同端口区分服务:
+
+| 域名 | 外网端口 | 后端服务 | 用途 |
+|------|---------|---------|------|
+| chanking.zhonjin.com | 40130 | 127.0.0.1:5004 | 主 Web 服务 |
+| mqtt.zhonjin.com | 40715 | 127.0.0.1:8085 | MQTT 服务 |
+| baolin.zhonjin.com | 40716 | 127.0.0.1:5000 | 宝林服务 A |
+| baolin.zhonjin.com | 40719 | 127.0.0.1:5001 | 宝林服务 B |
+
+### 1.3 设计原则
+
+| 原则 | 说明 |
+|------|------|
+| **TCP 层分流** | stream 模块工作在 TCP 层,不解密 TLS,仅通过 ClientHello 预读判断协议 |
+| **SSL 终结集中化** | 所有 SSL 证书由 Nginx 统一管理,后端服务只需提供 HTTP |
+| **端口隔离** | 每个外网端口独立 stream server + 独立 map 变量,互不干扰 |
+| **域名隔离** | 不同子域名通过独立的 server_name 配置区分,支持各自的后端服务 |
+| **配置模块化** | 主配置与子域名配置分离,便于独立维护 |
+| **向后兼容** | 新增服务组不影响已有配置,所有模块松耦合 |
+
+---
+
+## 2. 架构设计
+
+### 2.1 整体架构图
+
+```
+                       外网用户请求
+                            │
+              ┌─────────────┼─────────────┐
+              │             │             │
+        chanking:40130  mqtt:40715  baolin:40716/40719
+              │             │             │
+              └─────────────┼─────────────┘
+                            │
+                  ┌─────────┴─────────┐
+                  │  Stream 模块       │
+                  │  ssl_preread on   │
+                  │  协议检测(TCP层)    │
+                  └─────────┬─────────┘
+                            │
+               ┌────────────┼────────────┐
+               │ TLS        │            │ 明文 HTTP
+               ▼            │            ▼
+        ┌────────────┐     │     ┌────────────┐
+        │ HTTPS 服务  │     │     │ HTTP 服务   │
+        │ (SSL 终结)  │     │     │ (301 跳转)  │
+        │ :5005      │     │     │ :5006      │
+        │ :5007      │     │     │ :5008      │
+        │ :5009      │     │     │ :5010      │
+        │ :5011      │     │     │ :5012      │
+        └──────┬─────┘     │     └──────┬─────┘
+               │           │            │
+               └───────────┼────────────┘
+                           │
+                 ┌─────────┴─────────┐
+                 │  反向代理          │
+                 │  proxy_pass       │
+                 └─────────┬─────────┘
+                           │
+              ┌────────────┼────────────┐
+              ▼            ▼            ▼
+        ┌──────────┐ ┌──────────┐ ┌──────────┐
+        │ :5004    │ │ :8085    │ │ :5000    │  ...
+        │ 内网服务  │ │ 内网服务  │ │ 内网服务  │
+        └──────────┘ └──────────┘ └──────────┘
+```
+
+### 2.2 数据流详解
+
+**HTTPS 请求流程:**
+1. 用户访问 `https://mqtt.zhonjin.com:40715`
+2. TCP 连接到达 Nginx stream 模块监听的 40715 端口
+3. `ssl_preread on` 预读 ClientHello,`$ssl_preread_protocol` 值为 `TLS`
+4. map `$backend_target_40715` 匹配 `default` → 转发到 `127.0.0.1:5007`
+5. HTTP 模块 5007 端口接收 TLS 连接,完成 SSL 终结
+6. `proxy_pass` 将请求转发到后端 `http://127.0.0.1:8085`
+7. 后端响应通过 Nginx 加密后返回用户
+
+**HTTP 请求流程:**
+1. 用户访问 `http://baolin.zhonjin.com:40716`
+2. TCP 连接到达 Nginx stream 模块
+3. `ssl_preread` 预读失败(非 TLS),`$ssl_preread_protocol` 值为空 `""`
+4. map `$backend_target_40716` 匹配 `""` → 转发到 `127.0.0.1:5010`
+5. HTTP 模块 5010 端口返回 `301 Moved Permanently`,`Location: https://baolin.zhonjin.com:40716$request_uri`
+6. 浏览器自动重定向到 HTTPS 地址
+
+---
+
+## 3. 配置文件结构
+
+### 3.1 文件布局
+
+```
+/etc/nginx/
+├── nginx.conf                          # 主配置(全局参数 + 40130 端口 + include 指令)
+├── conf.d/
+│   └── zhonjin_http.conf               # 子域名 HTTP 服务配置(mqtt/baolin)
+└── stream.d/
+    └── zhonjin_stream.conf             # 子域名 Stream 分流配置(mqtt/baolin)
+```
+
+### 3.2 文件职责
+
+| 文件 | 职责 | include 位置 |
+|------|------|-------------|
+| `nginx.conf` | 全局参数、服务组1(40130)、include 指令 | 主配置入口 |
+| `zhonjin_http.conf` | 子域名的 HTTPS server + HTTP 跳转 server | http 块内 |
+| `zhonjin_stream.conf` | 子域名的 stream map + stream server | stream 块内 |
+
+### 3.3 模块化优势
+
+- **独立维护**:新增子域名只需编辑对应的 include 文件,不影响主配置
+- **减少冲突**:不同团队的配置不会互相干扰
+- **易于审计**:配置分散在小文件中,便于审查
+- **热重载安全**:`nginx -t` 可验证所有 include 文件
+
+---
+
+## 4. 环境要求
+
+### 4.1 操作系统
+
+| 操作系统 | 版本要求 | 备注 |
+|----------|----------|------|
+| Ubuntu | 22.04+ | 推荐,原生支持 Nginx 1.24+ |
+| Ubuntu | 24.04 | 完全兼容,推荐用于新部署 |
+| Debian | 12+ | 原生支持 |
+| CentOS/RHEL | 9+ | 需使用 EPEL 源 |
+| Raspberry Pi OS | Bookworm+ | 兼容 Ubuntu 24.04 方案 |
+
+### 4.2 Nginx 版本要求
+
+| 功能 | 最低版本 | 推荐版本 | 说明 |
+|------|----------|----------|------|
+| stream 模块 | 1.9.0+ | 1.26+ | TCP 层代理核心 |
+| ssl_preread | 1.11.5+ | 1.26+ | TCP 层 TLS 预读 |
+| ssl_preread_buffer_size | 1.23.4+ | 1.26+ | 可选,大 ClientHello 支持 |
+| http2 指令 | 1.25.1+ | 1.26+ | 新版 `http2 on` 指令 |
+| stream include | 1.26+ | 1.26+ | stream 块内 include 指令 |
+
+### 4.3 硬件要求
+
+| 资源 | 最低配置 | 推荐配置 | 说明 |
+|------|----------|----------|------|
+| CPU | 1 核 | 2+ 核 | stream 模块 CPU 消耗较低 |
+| 内存 | 256MB | 512MB+ | SSL session cache 占用内存 |
+| 磁盘 | 1GB 可用 | 5GB+ | 日志存储需要空间 |
+| 网络 | 100Mbps | 1Gbps | 取决于业务流量 |
+
+---
+
+## 5. 软件依赖
+
+### 5.1 必装软件
+
+```bash
+# Ubuntu/Debian
+sudo apt update
+sudo apt install -y nginx-full    # nginx-full 包含 stream 模块
+sudo apt install -y certbot python3-certbot-nginx   # Let's Encrypt 证书管理
+
+# 验证 stream 模块已加载
+nginx -V 2>&1 | grep -o with-stream
+# 预期输出: with-stream
+```
+
+### 5.2 模块确认
+
+```bash
+# 动态模块方式(如使用动态加载)
+ls /usr/lib/nginx/modules/ngx_stream_module.so
+
+# 静态编译方式(nginx -V 检查)
+nginx -V 2>&1 | grep -E "with-stream|with-http_ssl_module|with-http_v2_module"
+```
+
+### 5.3 可选工具
+
+| 工具 | 用途 | 安装命令 |
+|------|------|----------|
+| `htop` | 进程监控 | `apt install htop` |
+| `tcpdump` | 网络抓包调试 | `apt install tcpdump` |
+| `openssl` | 证书/SSL 调试 | `apt install openssl` |
+| `curl` | HTTP 测试 | `apt install curl` |
+| `logrotate` | 日志轮转(系统自带) | 默认已安装 |
+
+---
+
+## 6. 端口规划
+
+### 6.1 完整端口映射表
+
+| 域名 | 外网端口 | HTTPS 内网端口 | HTTP 跳转端口 | 后端服务 | 用途 |
+|------|---------|---------------|-------------|---------|------|
+| chanking.zhonjin.com | 40130 | 5005 | 5006 | 127.0.0.1:5004 | 主 Web 服务 |
+| mqtt.zhonjin.com | 40715 | 5007 | 5008 | 127.0.0.1:8085 | MQTT 服务 |
+| baolin.zhonjin.com | 40716 | 5009 | 5010 | 127.0.0.1:5000 | 宝林服务 A |
+| baolin.zhonjin.com | 40719 | 5011 | 5012 | 127.0.0.1:5001 | 宝林服务 B |
+
+### 6.2 端口命名规则
+
+- **外网端口**(4xxxx):stream 模块监听,对外暴露
+- **HTTPS 内网端口**(50xx):HTTP 模块 SSL 终结入口
+- **HTTP 跳转端口**(50xx):HTTP 模块 301 跳转入口
+- **后端服务端口**:实际业务服务监听端口
+
+### 6.3 防火墙配置
+
+```bash
+# UFW 防火墙
+sudo ufw allow 40130/tcp
+sudo ufw allow 40715/tcp
+sudo ufw allow 40716/tcp
+sudo ufw allow 40719/tcp
+
+# 或使用 iptables
+sudo iptables -A INPUT -p tcp --dport 40130 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 40715 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 40716 -j ACCEPT
+sudo iptables -A INPUT -p tcp --dport 40719 -j ACCEPT
+```
+
+**注意**:内部端口(5005-5012)无需对外开放,stream 模块通过 localhost 转发即可。
+
+---
+
+## 7. 配置详解
+
+### 7.1 主配置(nginx.conf)
+
+主配置文件包含:
+- 全局参数(worker、events、日志格式)
+- `load_module` 加载 stream 模块
+- 服务组 1(chanking.zhonjin.com:40130)的完整配置
+- `include` 指令引入子域名配置
+
+```nginx
+# nginx.conf 末尾 include 指令
+http {
+    # ... 服务组 1 配置 ...
+    include /etc/nginx/conf.d/zhonjin_http.conf;
+}
+
+stream {
+    # ... 服务组 1 的 stream 配置 ...
+    include /etc/nginx/stream.d/zhonjin_stream.conf;
+}
+```
+
+### 7.2 Stream 模块配置
+
+```nginx
+stream {
+    # 独立 map 变量(每个端口唯一)
+    map $ssl_preread_protocol $backend_target_40715 {
+        ""      127.0.0.1:5008;     # 明文HTTP → 301跳转
+        default 127.0.0.1:5007;     # TLS流量 → SSL入口
+    }
+
+    server {
+        listen 40715 backlog=4096;
+        tcp_nodelay on;
+        ssl_preread on;
+        proxy_pass $backend_target_40715;
+        proxy_connect_timeout 10s;
+        proxy_timeout        3600s;
+        proxy_next_upstream   off;
+        access_log /var/log/nginx/stream_access_40715.log stream_main;
+    }
+}
+```
+
+**关键参数说明:**
+
+| 参数 | 值 | 说明 |
+|------|-----|------|
+| `backlog` | 4096 | TCP 监听队列长度,高并发时增大 |
+| `tcp_nodelay` | on | 禁用 Nagle 算法,减少小包延迟 |
+| `ssl_preread` | on | 只读预读 ClientHello,不解密 |
+| `proxy_connect_timeout` | 10s | 与后端建立连接的超时 |
+| `proxy_timeout` | 3600s | 连接空闲超时,WebSocket 长连接需设大 |
+| `proxy_next_upstream` | off | 禁用重试,防止非幂等请求重复执行 |
+
+### 7.3 HTTPS Server 配置
+
+```nginx
+server {
+    listen 127.0.0.1:5007 ssl;
+    http2 on;
+    server_name mqtt.zhonjin.com;
+
+    ssl_certificate     /etc/letsencrypt/live/zhonjin.com/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/zhonjin.com/privkey.pem;
+    ssl_session_cache   shared:SSL_mqtt:5m;
+    ssl_session_timeout 1d;
+    ssl_session_tickets off;
+    ssl_protocols       TLSv1.2 TLSv1.3;
+    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:...;
+    ssl_prefer_server_ciphers off;
+
+    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+    location / {
+        proxy_pass http://127.0.0.1:8085;
+        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 Upgrade           $http_upgrade;
+        proxy_set_header Connection        $connection_upgrade;
+        proxy_connect_timeout 5s;
+        proxy_read_timeout    3600s;
+        proxy_send_timeout    60s;
+    }
+}
+```
+
+### 7.4 HTTP 跳转配置
+
+```nginx
+server {
+    listen 127.0.0.1:5008;
+    server_name mqtt.zhonjin.com;
+    return 301 https://$host:40715$request_uri;
+}
+```
+
+**注意**:301 跳转 URL 中的端口号必须与对应的外网端口一致。`$host` 变量会自动保留用户访问的域名。
+
+---
+
+## 8. SSL 证书管理
+
+### 8.1 通配符证书方案
+
+所有子域名共用同一个通配符证书:
+
+```
+证书覆盖域名:
+  - zhonjin.com
+  - *.zhonjin.com(覆盖所有子域名)
+    ├── chanking.zhonjin.com
+    ├── mqtt.zhonjin.com
+    └── baolin.zhonjin.com
+```
+
+### 8.2 证书申请
+
+```bash
+# 申请通配符证书(DNS 验证)
+sudo certbot certonly --manual --preferred-challenges dns \
+    -d zhonjin.com -d "*.zhonjin.com"
+```
+
+按提示添加 DNS TXT 记录完成验证。
+
+### 8.3 证书路径
+
+| 文件 | 路径 | 说明 |
+|------|------|------|
+| 证书链 | `/etc/letsencrypt/live/zhonjin.com/fullchain.pem` | 包含中间证书 |
+| 私钥 | `/etc/letsencrypt/live/zhonjin.com/privkey.pem` | 证书私钥 |
+| 根证书 | `/etc/letsencrypt/live/zhonjin.com/chain.pem` | 仅中间 CA |
+
+### 8.4 自动续期
+
+```bash
+# 测试续期
+sudo certbot renew --dry-run
+
+# 添加 crontab 自动续期
+sudo crontab -e
+# 添加以下行(每天凌晨 3 点检查)
+0 3 * * * certbot renew --quiet --post-hook "nginx -s reload"
+```
+
+### 8.5 证书监控
+
+```bash
+# 检查证书有效期
+openssl x509 -in /etc/letsencrypt/live/zhonjin.com/fullchain.pem -noout -dates
+
+# 检查证书域名覆盖
+openssl x509 -in /etc/letsencrypt/live/zhonjin.com/fullchain.pem -noout -text | grep -A1 "Subject Alternative Name"
+```
+
+---
+
+## 9. 安全策略
+
+### 9.1 SSL/TLS 安全配置
+
+| 配置项 | 值 | 说明 |
+|--------|-----|------|
+| `ssl_protocols` | TLSv1.2 TLSv1.3 | 禁用 SSLv3/TLSv1.0/1.1 |
+| `ssl_session_tickets` | off | 禁用 session tickets,增强前向安全 |
+| `ssl_prefer_server_ciphers` | off | 现代推荐做法,优先客户端偏好 |
+| HSTS | max-age=31536000 | 强制浏览器使用 HTTPS,1 年有效期 |
+
+### 9.2 网络安全
+
+- **内部端口不暴露**:所有 HTTP/HTTPS server 仅监听 `127.0.0.1`,外部无法直接访问
+- **server_tokens off**:隐藏 Nginx 版本号
+- **防火墙仅开放外网端口**:40130, 40715, 40716, 40719
+- **证书统一管理**:通配符证书覆盖所有子域名
+
+### 9.3 建议加固项
+
+```nginx
+# 可选:限制请求体大小(在 http 块中)
+client_max_body_size 100m;
+
+# 可选:添加安全响应头
+add_header X-Content-Type-Options "nosniff" always;
+add_header X-Frame-Options "SAMEORIGIN" always;
+add_header X-XSS-Protection "1; mode=block" always;
+```
+
+---
+
+## 10. 日志管理
+
+### 10.1 日志文件清单
+
+| 日志文件 | 类型 | 说明 |
+|----------|------|------|
+| `/var/log/nginx/error.log` | error | 全局错误日志 |
+| `/var/log/nginx/access.log` | access | HTTP 服务访问日志 |
+| `/var/log/nginx/stream_error.log` | error | Stream 模块错误日志 |
+| `/var/log/nginx/stream_access_40130.log` | access | Stream 端口 40130 访问日志 |
+| `/var/log/nginx/stream_access_40715.log` | access | Stream 端口 40715 访问日志 |
+| `/var/log/nginx/stream_access_40716.log` | access | Stream 端口 40716 访问日志 |
+| `/var/log/nginx/stream_access_40719.log` | access | Stream 端口 40719 访问日志 |
+
+### 10.2 Logrotate 配置
+
+```bash
+# /etc/logrotate.d/nginx(系统通常已自带)
+/var/log/nginx/*.log {
+    daily
+    missingok
+    rotate 52
+    compress
+    delaycompress
+    notifempty
+    create 0640 www-data adm
+    sharedscripts
+    postrotate
+        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
+    endscript
+}
+```
+
+### 10.3 日志分析
+
+```bash
+# 查看最近 100 条 stream 访问记录
+tail -100 /var/log/nginx/stream_access_40715.log
+
+# 统计各端口流量
+wc -l /var/log/nginx/stream_access_*.log
+
+# 查看错误日志
+tail -f /var/log/nginx/stream_error.log
+```
+
+---
+
+## 11. 性能调优
+
+### 11.1 内核参数优化
+
+```bash
+# /etc/sysctl.conf 添加
+net.core.somaxconn = 65535
+net.ipv4.tcp_max_syn_backlog = 65535
+net.ipv4.tcp_fin_timeout = 30
+net.ipv4.tcp_tw_reuse = 1
+net.ipv4.tcp_keepalive_time = 600
+```
+
+```bash
+sudo sysctl -p
+```
+
+### 11.2 Nginx 工作进程
+
+```nginx
+worker_processes auto;
+worker_rlimit_nofile 65535;
+
+events {
+    worker_connections 8192;
+    multi_accept on;
+    use epoll;
+}
+```
+
+### 11.3 SSL 性能优化
+
+```nginx
+ssl_stapling on;
+ssl_stapling_verify on;
+resolver 8.8.8.8 114.114.114.114 valid=300s;
+resolver_timeout 5s;
+```
+
+---
+
+## 12. 部署与运维
+
+### 12.1 部署步骤
+
+```bash
+# 1. 安装 Nginx(含 stream 模块)
+sudo apt install -y nginx-full certbot python3-certbot-nginx
+
+# 2. 申请通配符 SSL 证书
+sudo certbot certonly --manual --preferred-challenges dns \
+    -d zhonjin.com -d "*.zhonjin.com"
+
+# 3. 创建配置目录
+sudo mkdir -p /etc/nginx/conf.d /etc/nginx/stream.d
+
+# 4. 部署配置文件
+sudo cp nginx.conf /etc/nginx/nginx.conf
+sudo cp zhonjin_http.conf /etc/nginx/conf.d/zhonjin_http.conf
+sudo cp zhonjin_stream.conf /etc/nginx/stream.d/zhonjin_stream.conf
+
+# 5. 测试配置
+sudo nginx -t
+
+# 6. 重载 Nginx
+sudo systemctl reload nginx
+
+# 7. 配置防火墙
+sudo ufw allow 40130/tcp
+sudo ufw allow 40715/tcp
+sudo ufw allow 40716/tcp
+sudo ufw allow 40719/tcp
+
+# 8. 验证服务
+curl -I http://chanking.zhonjin.com:40130     # 应返回 301
+curl -I https://chanking.zhonjin.com:40130    # 应返回 200
+curl -I http://mqtt.zhonjin.com:40715         # 应返回 301
+curl -I https://mqtt.zhonjin.com:40715        # 应返回 200
+curl -I http://baolin.zhonjin.com:40716       # 应返回 301
+curl -I https://baolin.zhonjin.com:40716      # 应返回 200
+curl -I http://baolin.zhonjin.com:40719       # 应返回 301
+curl -I https://baolin.zhonjin.com:40719      # 应返回 200
+```
+
+### 12.2 日常运维命令
+
+```bash
+# 查看 Nginx 状态
+sudo systemctl status nginx
+
+# 重载配置(不中断服务)
+sudo nginx -t && sudo systemctl reload nginx
+
+# 查看当前监听端口
+sudo ss -tlnp | grep nginx
+
+# 查看连接数
+sudo ss -tnp | grep nginx | wc -l
+```
+
+### 12.3 配置文件备份
+
+```bash
+# 备份当前配置
+sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%Y%m%d)
+sudo cp /etc/nginx/conf.d/zhonjin_http.conf /etc/nginx/conf.d/zhonjin_http.conf.bak.$(date +%Y%m%d)
+sudo cp /etc/nginx/stream.d/zhonjin_stream.conf /etc/nginx/stream.d/zhonjin_stream.conf.bak.$(date +%Y%m%d)
+```
+
+---
+
+## 13. 故障排查
+
+### 13.1 常见问题及解决
+
+| 问题 | 可能原因 | 排查方法 | 解决方案 |
+|------|----------|----------|----------|
+| `nginx -t` 报错 unknown directive | stream 模块未加载 | `nginx -V 2>&1 \| grep stream` | 安装 `nginx-full` 或加载模块 |
+| `nginx -t` 报错 include 文件找不到 | include 路径错误 | 检查文件是否存在 | 确认路径和目录权限 |
+| 端口无响应 | 防火墙阻挡 | `sudo ufw status` | 放行端口 |
+| HTTP 不跳转 | map 变量名冲突 | 检查 stream 中 map 变量是否唯一 | 每个端口使用独立变量名 |
+| SSL 握手失败 | 证书路径错误 | `openssl s_client -connect localhost:5007` | 检查证书路径和权限 |
+| 域名解析错误 | DNS 未配置 | `dig mqtt.zhonjin.com` | 添加 A 记录指向服务器 IP |
+| WebSocket 断开 | proxy_timeout 过短 | 检查 stream 和 http 超时配置 | 保持两者一致(3600s) |
+| 502 Bad Gateway | 后端服务未启动 | `curl http://127.0.0.1:8085` | 启动后端服务 |
+| 端口冲突 | 其他程序占用 | `sudo ss -tlnp \| grep :PORT` | 停止冲突程序或更换端口 |
+
+### 13.2 调试技巧
+
+```bash
+# 1. TCP 层面验证 stream 转发
+openssl s_client -connect mqtt.zhonjin.com:40715 -servername mqtt.zhonjin.com
+
+# 2. 检查 SSL 证书链
+echo | openssl s_client -connect mqtt.zhonjin.com:40715 -showcerts 2>/dev/null | openssl x509 -noout -dates
+
+# 3. 查看 stream 模块流量
+tail -f /var/log/nginx/stream_access_40715.log
+
+# 4. 抓包分析 TCP 流量
+sudo tcpdump -i any port 40715 -n -c 100
+
+# 5. 验证 HTTP 跳转
+curl -v http://mqtt.zhonjin.com:40715 2>&1 | grep Location
+```
+
+---
+
+## 14. 端口扩展指南
+
+### 14.1 新增端口映射步骤
+
+当需要新增一组端口映射时(以 `newservice.zhonjin.com:40800` → 后端 6000 为例):
+
+**Step 1:在 `zhonjin_http.conf` 中添加 server 配置**
+
+```nginx
+# HTTPS 服务
+server {
+    listen 127.0.0.1:NEW_HTTPS_PORT ssl;
+    http2 on;
+    server_name newservice.zhonjin.com;
+    # ... SSL 配置(复制已有模式,注意 ssl_session_cache 名称唯一)
+    location / {
+        proxy_pass http://127.0.0.1:6000;
+        # ... proxy 配置
+    }
+}
+
+# HTTP 跳转
+server {
+    listen 127.0.0.1:NEW_HTTP_PORT;
+    server_name newservice.zhonjin.com;
+    return 301 https://$host:40800$request_uri;
+}
+```
+
+**Step 2:在 `zhonjin_stream.conf` 中添加分流配置**
+
+```nginx
+map $ssl_preread_protocol $backend_target_40800 {
+    ""      127.0.0.1:NEW_HTTP_PORT;
+    default 127.0.0.1:NEW_HTTPS_PORT;
+}
+
+server {
+    listen 40800 backlog=4096;
+    tcp_nodelay on;
+    ssl_preread on;
+    proxy_pass $backend_target_40800;
+    proxy_connect_timeout 10s;
+    proxy_timeout        3600s;
+    proxy_next_upstream   off;
+    access_log /var/log/nginx/stream_access_40800.log stream_main;
+}
+```
+
+**Step 3:更新防火墙并重载**
+
+```bash
+sudo ufw allow 40800/tcp
+sudo nginx -t && sudo systemctl reload nginx
+```
+
+### 14.2 端口编号建议
+
+| 端口范围 | 用途 | 示例 |
+|----------|------|------|
+| 40100-40199 | 核心 Web 服务 | 40130 |
+| 40700-40799 | 扩展服务组 | 40715, 40716, 40719 |
+| 40800-40899 | 预留扩展 | - |
+
+---
+
+## 附录
+
+### A. 配置文件清单
+
+| 文件 | 路径 | 说明 |
+|------|------|------|
+| nginx.conf | 项目根目录 | 主配置 |
+| zhonjin_http.conf | 项目根目录 | HTTP 服务配置 |
+| zhonjin_stream.conf | 项目根目录 | Stream 分流配置 |
+| zhonjin.com.conf | 项目根目录 | 配置总览说明 |
+
+### B. 相关文档
+
+- [CHANGELOG.md](./CHANGELOG.md) - 变更日志
+- [RASPBERRYPI_SETUP.md](./RASPBERRYPI_SETUP.md) - 树莓派部署指南
+- [QA_ARCHIVE.md](./QA_ARCHIVE.md) - 问答归档
+- [README.md](./README.md) - 项目说明

+ 73 - 0
git_push.sh

@@ -0,0 +1,73 @@
+#!/bin/bash
+# ============================================================================
+# Git 初始化并推送到 Gogs 仓库
+# 仓库地址: https://git.zhonjin.com:40717/steven_roc/nginx-stream-ssl-preread
+# ============================================================================
+
+set -e
+
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+echo -e "${GREEN}=== Git 仓库初始化与推送 ===${NC}"
+
+# 1. 配置 Git
+git config user.name "steven_roc" 2>/dev/null || true
+git config user.email "steven_roc@zhonjin.com" 2>/dev/null || true
+
+# 2. 初始化 Git 仓库
+if [ ! -d .git ]; then
+    git init
+    echo -e "${GREEN}[✓] Git 仓库已初始化${NC}"
+else
+    echo -e "${YELLOW}[i] Git 仓库已存在,跳过初始化${NC}"
+fi
+
+# 3. 添加远程仓库
+REMOTE_URL="https://steven_roc:1942ce3d6478f7a572fee3dd4891e49f6c416aad@git.zhonjin.com:40717/steven_roc/nginx-stream-ssl-preread.git"
+
+git remote get-url origin 2>/dev/null && git remote remove origin
+git remote add origin "$REMOTE_URL"
+echo -e "${GREEN}[✓] 远程仓库已配置${NC}"
+
+# 4. 添加所有文件
+git add -A
+echo -e "${GREEN}[✓] 文件已添加到暂存区${NC}"
+
+# 5. 提交
+git commit -m "feat: Nginx Stream + SSL Preread 多子域名自动分流方案 v2.0
+
+架构: TCP 层 ssl_preread 协议检测 + 模块化配置文件
+
+端口映射:
+- 40130 chanking.zhonjin.com → 127.0.0.1:5004 (主 Web 服务)
+- 40715 mqtt.zhonjin.com     → 127.0.0.1:8085 (MQTT 服务)
+- 40716 baolin.zhonjin.com   → 127.0.0.1:5000 (宝林服务 A)
+- 40719 baolin.zhonjin.com   → 127.0.0.1:5001 (宝林服务 B)
+
+配置文件:
+- nginx.conf: 主配置(40130 + include 指令)
+- zhonjin_http.conf: 子域名 HTTP 服务配置
+- zhonjin_stream.conf: 子域名 Stream 分流配置
+- zhonjin.com.conf: 配置总览说明
+
+文档:
+- CHANGELOG.md: 变更日志
+- TECH_DOC.md: 完整技术方案
+- RASPBERRYPI_SETUP.md: 树莓派 5 部署指南
+- QA_ARCHIVE.md: 问答归档"
+
+echo -e "${GREEN}[✓] 已提交${NC}"
+
+# 6. 推送
+git branch -M main
+git push -u origin main --force
+echo -e "${GREEN}[✓] 已推送到 Gogs 仓库${NC}"
+
+echo ""
+echo -e "${GREEN}=== 推送完成 ===${NC}"
+echo -e "仓库地址: https://git.zhonjin.com:40717/steven_roc/nginx-stream-ssl-preread"
+echo ""
+echo -e "${YELLOW}安全提示: 推送完成后建议从 .git/config 中移除 token,${NC}"
+echo -e "${YELLOW}改用 git credential 或 SSH key 管理认证。${NC}"

+ 137 - 0
nginx.conf

@@ -0,0 +1,137 @@
+# ============================================================================
+# Nginx Stream + SSL Preread 自动分流主配置
+# 架构:TCP层协议检测 → TLS/HTTP分流 → SSL终结 → 反向代理内网服务
+# 版本:v2.0
+# 最后更新:2026-10-06
+#
+# 配置结构:
+#   nginx.conf          — 主配置(40130 端口 + 基础架构)
+#   zhonjin_http.conf   — 子域名 HTTP 服务配置(include 到 http 块)
+#   zhonjin_stream.conf — 子域名 Stream 分流配置(include 到 stream 块)
+#   zhonjin.com.conf    — 配置总览说明文档
+# ============================================================================
+
+load_module /usr/lib/nginx/modules/ngx_stream_module.so;
+
+user www-data;                      # Debian: www-data / CentOS: nginx
+worker_processes auto;
+pid /run/nginx.pid;
+error_log /var/log/nginx/error.log warn;
+
+events {
+    worker_connections 8192;
+}
+
+# ============================================================================
+# HTTP 块:SSL 终结 + 反向代理 + HTTP→HTTPS 跳转
+# ============================================================================
+http {
+    include       /etc/nginx/mime.types;
+    default_type  application/octet-stream;
+
+    sendfile        on;
+    tcp_nopush      on;
+    tcp_nodelay     on;
+    keepalive_timeout  65;
+    server_tokens off;
+
+    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+                    '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
+                    'proto=$ssl_protocol sni=$ssl_server_name';
+    access_log /var/log/nginx/access.log main;
+
+    # WebSocket 升级映射(全局定义,各 location 引用)
+    map $http_upgrade $connection_upgrade {
+        default upgrade;
+        ''      close;
+    }
+
+    # ========================================================================
+    # 服务组 1:外网端口 40130 → 内网服务 http://127.0.0.1:5004
+    # 域名:chanking.zhonjin.com
+    # ========================================================================
+
+    # HTTPS 服务:SSL 终结,反代内网 5004
+    server {
+        listen 127.0.0.1:5005 ssl;
+        http2 on;
+        server_name chanking.zhonjin.com;
+
+        ssl_certificate     /etc/letsencrypt/live/zhonjin.com/fullchain.pem;
+        ssl_certificate_key /etc/letsencrypt/live/zhonjin.com/privkey.pem;
+        ssl_session_cache   shared:SSL:10m;
+        ssl_session_timeout 1d;
+        ssl_session_tickets off;
+        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;
+        ssl_prefer_server_ciphers off;
+
+        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+        location / {
+            proxy_pass http://127.0.0.1:5004;
+            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 Upgrade           $http_upgrade;
+            proxy_set_header Connection        $connection_upgrade;
+            proxy_connect_timeout 5s;
+            proxy_read_timeout    3600s;
+            proxy_send_timeout    60s;
+        }
+    }
+
+    # HTTP 服务:301 跳转到 HTTPS(端口 40130)
+    server {
+        listen 127.0.0.1:5006;
+        server_name chanking.zhonjin.com;
+        return 301 https://$host:40130$request_uri;
+    }
+
+    # ========================================================================
+    # 子域名扩展配置(mqtt.zhonjin.com / baolin.zhonjin.com)
+    # ========================================================================
+    include /etc/nginx/conf.d/zhonjin_http.conf;
+}
+
+# ============================================================================
+# Stream 块:TCP 层协议检测 + 自动分流
+# ============================================================================
+stream {
+    error_log /var/log/nginx/stream_error.log warn;
+
+    log_format stream_main '$remote_addr [$time_local] $protocol '
+                           'preread=$ssl_preread_protocol status=$status '
+                           'upstream=$upstream_addr bytes=$bytes_sent';
+
+    # ========================================================================
+    # Stream 服务组 1:外网端口 40130 → 内网 5004(chanking.zhonjin.com)
+    # ========================================================================
+    map $ssl_preread_protocol $backend_target_40130 {
+        ""      127.0.0.1:5006;     # 明文HTTP → 301跳转到HTTPS
+        default 127.0.0.1:5005;     # TLS流量 → SSL解密入口
+    }
+
+    server {
+        listen 40130 backlog=4096;
+        tcp_nodelay on;
+
+        ssl_preread on;
+        # nginx >=1.23.4 才启用,低版本注释掉!当前版本 1.26.3
+        #ssl_preread_buffer_size 16k;
+
+        proxy_pass $backend_target_40130;
+        proxy_connect_timeout 10s;
+        proxy_timeout        3600s;
+        proxy_next_upstream   off;
+
+        access_log /var/log/nginx/stream_access_40130.log stream_main;
+    }
+
+    # ========================================================================
+    # 子域名扩展 Stream 配置(mqtt / baolin)
+    # ========================================================================
+    include /etc/nginx/stream.d/zhonjin_stream.conf;
+}

+ 106 - 0
zhonjin.com.conf

@@ -0,0 +1,106 @@
+# ============================================================================
+# zhonjin.com 全域名 Nginx 配置总览
+# 文件:zhonjin.com.conf(说明文档)
+# 最后更新:2026-10-06
+# ============================================================================
+#
+# 【架构说明】
+#
+# 本方案将 Nginx 配置拆分为模块化文件,便于按子域名独立管理:
+#
+#   nginx.conf           — 主配置文件
+#                          - 全局参数(worker、events、日志格式)
+#                          - 服务组 1:chanking.zhonjin.com:40130 → 127.0.0.1:5004
+#                          - include 指令引用子配置文件
+#
+#   zhonjin_http.conf    — 子域名 HTTP 服务配置(include 到 http 块)
+#                          部署路径:/etc/nginx/conf.d/zhonjin_http.conf
+#                          - 服务组 2:mqtt.zhonjin.com:40715    → 127.0.0.1:8085
+#                          - 服务组 3:baolin.zhonjin.com:40716  → 127.0.0.1:5000
+#                          - 服务组 4:baolin.zhonjin.com:40719  → 127.0.0.1:5001
+#
+#   zhonjin_stream.conf  — 子域名 Stream 分流配置(include 到 stream 块)
+#                          部署路径:/etc/nginx/stream.d/zhonjin_stream.conf
+#                          - Stream 服务组 2-4 的 map + server
+#
+#   zhonjin.com.conf     — 本文件,配置总览说明
+#
+# ============================================================================
+#
+# 【端口与域名映射表】
+#
+#   外网端口  | 域名                       | 后端服务           | HTTPS 内部端口 | HTTP 跳转端口
+#   ----------|----------------------------|--------------------|---------------|---------------
+#   40130     | chanking.zhonjin.com       | 127.0.0.1:5004     | 5005          | 5006
+#   40715     | mqtt.zhonjin.com           | 127.0.0.1:8085     | 5007          | 5008
+#   40716     | baolin.zhonjin.com         | 127.0.0.1:5000     | 5009          | 5010
+#   40719     | baolin.zhonjin.com         | 127.0.0.1:5001     | 5011          | 5012
+#
+# ============================================================================
+#
+# 【数据流】
+#
+#   外网请求 (HTTP/HTTPS)
+#       │
+#       ▼
+#   stream 端口监听 (40130/40715/40716/40719)
+#       │
+#       ├─ ssl_preread 检测协议
+#       │
+#       ├─ TLS 流量 ──→ HTTPS server (SSL 终结) ──→ proxy_pass 后端 HTTP 服务
+#       │
+#       └─ 明文 HTTP ──→ HTTP server ──→ 301 重定向到 HTTPS
+#
+# ============================================================================
+#
+# 【SSL 证书说明】
+#
+# 所有子域名共用同一个通配符证书:
+#   - 证书路径:/etc/letsencrypt/live/zhonjin.com/fullchain.pem
+#   - 私钥路径:/etc/letsencrypt/live/zhonjin.com/privkey.pem
+#
+# 证书覆盖域名(通配符 *.zhonjin.com):
+#   - zhonjin.com
+#   - chanking.zhonjin.com
+#   - mqtt.zhonjin.com
+#   - baolin.zhonjin.com
+#   - 其他 *.zhonjin.com 子域名
+#
+# 申请命令:
+#   sudo certbot certonly --manual --preferred-challenges dns \
+#       -d zhonjin.com -d "*.zhonjin.com"
+#
+# ============================================================================
+#
+# 【部署步骤】
+#
+#   # 1. 部署配置文件
+#   sudo cp nginx.conf /etc/nginx/nginx.conf
+#   sudo cp zhonjin_http.conf /etc/nginx/conf.d/zhonjin_http.conf
+#   sudo cp zhonjin_stream.conf /etc/nginx/stream.d/zhonjin_stream.conf
+#
+#   # 2. 创建目录(如果不存在)
+#   sudo mkdir -p /etc/nginx/conf.d /etc/nginx/stream.d
+#
+#   # 3. 测试并重载
+#   sudo nginx -t
+#   sudo systemctl reload nginx
+#
+# ============================================================================
+#
+# 【新增端口映射指南】
+#
+# 当需要新增一组端口映射时:
+#
+#   1. 在 zhonjin_http.conf 中添加 HTTPS server + HTTP 跳转 server
+#   2. 在 zhonjin_stream.conf 中添加 map + stream server
+#   3. 更新本文件的映射表
+#   4. sudo nginx -t && sudo systemctl reload nginx
+#
+# 注意事项:
+#   - map 变量名必须唯一(如 $backend_target_40800)
+#   - SSL session cache 名称必须唯一(如 shared:SSL_xxx:5m)
+#   - 内部端口不能与已有端口冲突
+#   - 301 跳转 URL 中的端口号必须与外网端口一致
+#
+# ============================================================================

+ 139 - 0
zhonjin_http.conf

@@ -0,0 +1,139 @@
+# ============================================================================
+# 子域名 HTTP 服务配置
+# 文件:zhonjin_http.conf
+# 用途:mqtt.zhonjin.com / baolin.zhonjin.com 的 HTTPS SSL 终结 + HTTP 301 跳转
+# 挂载方式:在 nginx.conf 的 http 块中 include 本文件
+# 路径:/etc/nginx/conf.d/zhonjin_http.conf
+# ============================================================================
+
+# ========================================================================
+# 服务组 2:外网端口 40715 → 内网服务 http://127.0.0.1:8085
+# 域名:mqtt.zhonjin.com
+# ========================================================================
+
+# HTTPS 服务:SSL 终结,反代内网 8085
+server {
+    listen 127.0.0.1:5007 ssl;
+    http2 on;
+    server_name mqtt.zhonjin.com;
+
+    ssl_certificate     /etc/letsencrypt/live/zhonjin.com/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/zhonjin.com/privkey.pem;
+    ssl_session_cache   shared:SSL_mqtt:5m;
+    ssl_session_timeout 1d;
+    ssl_session_tickets off;
+    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;
+    ssl_prefer_server_ciphers off;
+
+    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+    location / {
+        proxy_pass http://127.0.0.1:8085;
+        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 Upgrade           $http_upgrade;
+        proxy_set_header Connection        $connection_upgrade;
+        proxy_connect_timeout 5s;
+        proxy_read_timeout    3600s;
+        proxy_send_timeout    60s;
+    }
+}
+
+# HTTP 服务:301 跳转到 HTTPS(端口 40715)
+server {
+    listen 127.0.0.1:5008;
+    server_name mqtt.zhonjin.com;
+    return 301 https://$host:40715$request_uri;
+}
+
+# ========================================================================
+# 服务组 3:外网端口 40716 → 内网服务 http://127.0.0.1:5000
+# 域名:baolin.zhonjin.com
+# ========================================================================
+
+# HTTPS 服务:SSL 终结,反代内网 5000
+server {
+    listen 127.0.0.1:5009 ssl;
+    http2 on;
+    server_name baolin.zhonjin.com;
+
+    ssl_certificate     /etc/letsencrypt/live/zhonjin.com/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/zhonjin.com/privkey.pem;
+    ssl_session_cache   shared:SSL_baolin_1:5m;
+    ssl_session_timeout 1d;
+    ssl_session_tickets off;
+    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;
+    ssl_prefer_server_ciphers off;
+
+    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+    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;
+        proxy_set_header Upgrade           $http_upgrade;
+        proxy_set_header Connection        $connection_upgrade;
+        proxy_connect_timeout 5s;
+        proxy_read_timeout    3600s;
+        proxy_send_timeout    60s;
+    }
+}
+
+# HTTP 服务:301 跳转到 HTTPS(端口 40716)
+server {
+    listen 127.0.0.1:5010;
+    server_name baolin.zhonjin.com;
+    return 301 https://$host:40716$request_uri;
+}
+
+# ========================================================================
+# 服务组 4:外网端口 40719 → 内网服务 http://127.0.0.1:5001
+# 域名:baolin.zhonjin.com
+# ========================================================================
+
+# HTTPS 服务:SSL 终结,反代内网 5001
+server {
+    listen 127.0.0.1:5011 ssl;
+    http2 on;
+    server_name baolin.zhonjin.com;
+
+    ssl_certificate     /etc/letsencrypt/live/zhonjin.com/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/zhonjin.com/privkey.pem;
+    ssl_session_cache   shared:SSL_baolin_2:5m;
+    ssl_session_timeout 1d;
+    ssl_session_tickets off;
+    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;
+    ssl_prefer_server_ciphers off;
+
+    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+
+    location / {
+        proxy_pass http://127.0.0.1:5001;
+        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 Upgrade           $http_upgrade;
+        proxy_set_header Connection        $connection_upgrade;
+        proxy_connect_timeout 5s;
+        proxy_read_timeout    3600s;
+        proxy_send_timeout    60s;
+    }
+}
+
+# HTTP 服务:301 跳转到 HTTPS(端口 40719)
+server {
+    listen 127.0.0.1:5012;
+    server_name baolin.zhonjin.com;
+    return 301 https://$host:40719$request_uri;
+}

+ 73 - 0
zhonjin_stream.conf

@@ -0,0 +1,73 @@
+# ============================================================================
+# 子域名 Stream 分流配置
+# 文件:zhonjin_stream.conf
+# 用途:mqtt.zhonjin.com / baolin.zhonjin.com 的 TCP 层协议检测 + 自动分流
+# 挂载方式:在 nginx.conf 的 stream 块中 include 本文件
+# 路径:/etc/nginx/stream.d/zhonjin_stream.conf
+# ============================================================================
+
+# ========================================================================
+# Stream 服务组 2:外网端口 40715 → 内网 8085(mqtt.zhonjin.com)
+# ========================================================================
+map $ssl_preread_protocol $backend_target_40715 {
+    ""      127.0.0.1:5008;     # 明文HTTP → 301跳转到HTTPS
+    default 127.0.0.1:5007;     # TLS流量 → SSL解密入口
+}
+
+server {
+    listen 40715 backlog=4096;
+    tcp_nodelay on;
+
+    ssl_preread on;
+
+    proxy_pass $backend_target_40715;
+    proxy_connect_timeout 10s;
+    proxy_timeout        3600s;
+    proxy_next_upstream   off;
+
+    access_log /var/log/nginx/stream_access_40715.log stream_main;
+}
+
+# ========================================================================
+# Stream 服务组 3:外网端口 40716 → 内网 5000(baolin.zhonjin.com)
+# ========================================================================
+map $ssl_preread_protocol $backend_target_40716 {
+    ""      127.0.0.1:5010;     # 明文HTTP → 301跳转到HTTPS
+    default 127.0.0.1:5009;     # TLS流量 → SSL解密入口
+}
+
+server {
+    listen 40716 backlog=4096;
+    tcp_nodelay on;
+
+    ssl_preread on;
+
+    proxy_pass $backend_target_40716;
+    proxy_connect_timeout 10s;
+    proxy_timeout        3600s;
+    proxy_next_upstream   off;
+
+    access_log /var/log/nginx/stream_access_40716.log stream_main;
+}
+
+# ========================================================================
+# Stream 服务组 4:外网端口 40719 → 内网 5001(baolin.zhonjin.com)
+# ========================================================================
+map $ssl_preread_protocol $backend_target_40719 {
+    ""      127.0.0.1:5012;     # 明文HTTP → 301跳转到HTTPS
+    default 127.0.0.1:5011;     # TLS流量 → SSL解密入口
+}
+
+server {
+    listen 40719 backlog=4096;
+    tcp_nodelay on;
+
+    ssl_preread on;
+
+    proxy_pass $backend_target_40719;
+    proxy_connect_timeout 10s;
+    proxy_timeout        3600s;
+    proxy_next_upstream   off;
+
+    access_log /var/log/nginx/stream_access_40719.log stream_main;
+}