eqms内外网中转,毕竟是AI自己搞的,记录下怕忘了。
eqms内外网中转
作者: 哎呦喂
日期: 2026-05-20
目标: 将内网EQMS系统(10.188.56.27)通过公网域名 eqms.1**.com.cn 安全访问
一、架构设计
最终方案:Cloudflare Tunnel + Nginx反向代理
用户浏览器
↓ (HTTPS)
Cloudflare CDN
↓ (Cloudflare Tunnel加密通道)
cloudflared (本地服务,端口8080)
↓ (HTTP)
Nginx 反向代理 (localhost:8080)
↓ (内网HTTP)
内网EQMS系统 (10.188.56.27:80)为什么选Cloudflare Tunnel?
| 方案 | 优点 | 缺点 | 结论 |
|---|---|---|---|
| 端口转发 | 简单 | 需公网IP,不安全 | ❌ 淘汰 |
| Tailscale | 安全 | 需要客户端,手机端麻烦 | ❌ 淘汰 |
| Cloudflare WARP | 安全 | 手机端登录失败 | ❌ 淘汰 |
| Cloudflare Tunnel | 无需公网IP,HTTPS自动证书,免费 | 需要Cloudflare账号 | ✅ 采用 |
二、环境准备
2.1 系统环境
- 服务器: Windows Server (USER-20260422QU)
- 内网EQMS: 10.188.56.27:80
- 内网QTI: 10.88.248.67:9001
- 域名: 1**.com.cn (已在Cloudflare管理)
- Nginx: 1.26.2 (C:\nginx)
- Cloudflared: 2026.5.0
2.2 安装Cloudflared
# 下载
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe
# 保存到
C:\Users\Administrator\.cloudflared\cloudflared.exe三、Cloudflare Tunnel配置
3.1 登录Cloudflare
cd C:\Users\Administrator\.cloudflared
.\cloudflared.exe tunnel login浏览器打开Cloudflare授权页面,选择 1**.com.cn 域名。
3.2 创建Tunnel
# 创建tunnel
.\cloudflared.exe tunnel create my-tunnel
# 输出示例:
# Tunnel credentials written to C:\Users\Administrator\.cloudflared\46ead48d-721f-4346-939b-bc4c7a3c9b58.json
# Cloudflare chose port 8000 to 8007 for load-balancing the tunnel pool.
# Your tunnel will not try these ports until you associate them with a configuration.
# Created tunnel my-tunnel with id 46ead48d-721f-4346-939b-bc4c7a3c9b58记录Tunnel ID: 46ead48d-721f-4346-939b-bc4c7a3c9b58
3.3 配置DNS
# 为eqms子域名创建CNAME记录
.\cloudflared.exe tunnel route dns my-tunnel eqms.1**.com.cn
# 为qti子域名创建CNAME记录
.\cloudflared.exe tunnel route dns my-tunnel qti.1*.com.cn3.4 编写配置文件
文件: C:\Users\Administrator\.cloudflared\config.yml
tunnel: 46ead48d-721f-4346-939b-bc4c7a3c9b58
credentials-file: C:\Users\Administrator\.cloudflared\46ead48d-721f-4346-939b-bc4c7a3c9b58.json
ingress:
# EQMS系统
- hostname: eqms.1**.com.cn
service: http://localhost:8080
originRequest:
noTLSVerify: true
# QTI系统
- hostname: qti.1**.com.cn
service: http://localhost:8080
originRequest:
noTLSVerify: true
# 兜底规则(必须放在最后)
- service: http_status:404关键配置说明:
service: http://localhost:8080- 流量转发到本地NginxnoTLSVerify: true- 跳过TLS验证(因为Nginx用的是HTTP)- 多个hostname可以指向同一个本地服务,由Nginx根据Host头路由
四、Nginx反向代理配置
4.1 目录结构
C:\nginx\
├── conf\
│ └── nginx_eqms.conf # EQMS专属配置
├── logs\ # 日志目录
└── html\ # 静态文件目录4.2 配置文件:nginx_eqms.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 根据Host头路由到不同后端
map $host $backend_url {
hostnames;
eqms.1**.com.cn "http://10.188.56.27:80";
qti.1**.com.cn "http://10.88.248.67:9001";
default "http://10.188.56.27:80";
}
server {
listen 8080;
server_name _;
# 临时目录配置(解决Cloudflare Tunnel的temp目录问题)
client_body_temp_path C:\Users\Administrator\.qclaw\workspace\temp\client_body_temp;
proxy_temp_path C:\Users\Administrator\.qclaw\workspace\temp\proxy_temp;
fastcgi_temp_path C:\Users\Administrator\.qclaw\workspace\temp\fastcgi_temp;
# EQMS根路径
location / {
proxy_pass $backend_url;
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;
# Cookie域名重写(解决跨域登录问题)
proxy_cookie_domain $backend_url $host;
# 重定向重写
proxy_redirect http://$backend_url https://$host;
}
# QTI后端API专用路径
location /qti-app/ {
proxy_pass http://10.88.248.67:9001/qti-app/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 替换响应内容中的内网IP(解决前端JS硬编码问题)
sub_filter '//10.88.248.67:9001/' '//$host/';
sub_filter '//10.188.18.177:9001/' '//$host/';
sub_filter_once off;
}
# 健康检查
location /nginx-health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}4.3 启动Nginx
# 测试配置
cd C:\nginx
.\nginx.exe -t -c "C:\nginx\conf\nginx_eqms.conf" -p C:\nginx
# 启动
start .\nginx.exe -c "C:\nginx\conf\nginx_eqms.conf" -p C:\nginx
# 重载配置(修改配置后执行)
.\nginx.exe -s reload -c "C:\nginx\conf\nginx_eqms.conf" -p C:\nginx注意: Windows下必须用 -c 和 -p 参数指定配置文件和前缀路径,否则Nginx会找不到配置。
五、启动Cloudflare Tunnel
5.1 创建temp目录
New-Item -ItemType Directory -Force -Path C:\Users\Administrator\.qclaw\workspace\temp\client_body_temp
New-Item -ItemType Directory -Force -Path C:\Users\Administrator\.qclaw\workspace\temp\proxy_temp
New-Item -ItemType Directory -Force -Path C:\Users\Administrator\.qclaw\workspace\temp\fastcgi_temp5.2 启动Tunnel
cd C:\Users\Administrator\.cloudflared
$env:TEMP = "C:\Users\Administrator\.qclaw\workspace\temp"
$env:TMP = "C:\Users\Administrator\.qclaw\workspace\temp"
.\cloudflared.exe tunnel --config C:\Users\Administrator\.cloudflared\config.yml run my-tunnel验证启动成功:
Retrieved configuration from local configuration file
Starting tunnel tunnelID=46ead48d-721f-4346-939b-bc4c7a3c9b58
Connected to Cloudflare5.3 验证公网访问
浏览器访问: https://eqms.1**.com.cn
预期结果: 看到EQMS登录页面
六、问题排查与解决
6.1 EQMS登录后Cookie域名不匹配
问题: 登录成功后,服务端Set-Cookie的domain是 sg*****l.com,但浏览器访问的是 eqms.1**.com.cn,导致Cookie不生效,一直跳回登录页。
解决: 在Nginx配置中添加Cookie域名重写
proxy_cookie_domain $backend_url $host;这会将后端返回的 Set-Cookie: JSESSIONID=xxx; Domain=sg*****l.com 重写为 Domain=eqms.1**.com.cn
6.2 QTI系统404错误
问题: 访问 qti.1**.com.cn 返回404
原因: cloudflared config.yml 中QTI的ingress规则配置错误,service指向了错误的端口
解决: 修正 config.yml 中的service地址为 http://localhost:8080(统一由Nginx根据Host头路由)
6.3 Cloudflared temp目录不存在
问题:
could not create temp file: os: file does not exist解决: 创建temp目录并设置环境变量
$env:TEMP = "C:\Users\Administrator\.qclaw\workspace\temp"
$env:TMP = "C:\Users\Administrator\.qclaw\workspace\temp"同时在Nginx配置中添加:
client_body_temp_path C:\Users\Administrator\.qclaw\workspace\temp\client_body_temp;
proxy_temp_path C:\Users\Administrator\.qclaw\workspace\temp\proxy_temp;6.4 QTI前端JS硬编码内网IP
问题: QTI前端JS中硬编码了 //10.88.248.67:9001/ 和 //10.188.18.177:9001/,导致公网访问时API请求发到内网地址失败。
解决: 在Nginx的 /qti-app/ location块中添加sub_filter
sub_filter '//10.88.248.67:9001/' '//$host/';
sub_filter '//10.188.18.177:9001/' '//$host/';
sub_filter_once off;注意: 此方案仅适用于静态JS文件。如果IP是动态生成的(例如在JS执行时拼接),需要用其他方法(如inject JS覆盖变量)。
七、最终验证
7.1 验证EQMS访问
# 测试公网域名
curl -I https://eqms.1**.com.cn
# 预期响应
HTTP/2 200
cf-ray: xxxxxxxxxxx-xxx
cf-cache-status: DYNAMIC7.2 验证QTI访问
curl -I https://qti.1**.com.cn
# 预期响应
HTTP/2 2007.3 验证登录功能
- 打开 https://eqms.1**.com.cn
- 输入账号密码
- 登录成功,跳转到主页面
- 功能正常(点检标准查询、检修工单等)
八、开机自启动配置
8.1 创建启动脚本
文件: C:\Users\Administrator\start-eqms-tunnel.ps1
# 启动Nginx
$nginxPath = "C:\nginx\nginx.exe"
$nginxConf = "C:\nginx\conf\nginx_eqms.conf"
Start-Process -FilePath $nginxPath -ArgumentList "-c `"$nginxConf`" -p C:\nginx" -WindowStyle Hidden
# 等待Nginx启动
Start-Sleep -Seconds 3
# 设置temp目录
$env:TEMP = "C:\Users\Administrator\.qclaw\workspace\temp"
$env:TMP = "C:\Users\Administrator\.qclaw\workspace\temp"
# 启动Cloudflare Tunnel
$cloudflared = "C:\Users\Administrator\.cloudflared\cloudflared.exe"
$tunnelConfig = "C:\Users\Administrator\.cloudflared\config.yml"
Start-Process -FilePath $cloudflared -ArgumentList "tunnel --config `"$tunnelConfig`" run my-tunnel" -WindowStyle Hidden8.2 添加到Windows任务计划程序
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -File C:\Users\Administrator\start-eqms-tunnel.ps1"
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId "Administrator" -LogonType ServiceAccount
Register-ScheduledTask -TaskName "EQMS Tunnel" -Action $action -Trigger $trigger -Principal $principal九、配置文件清单
9.1 Cloudflare Tunnel配置
路径: C:\Users\Administrator\.cloudflared\config.yml
tunnel: 46ead48d-721f-4346-939b-bc4c7a3c9b58
credentials-file: C:\Users\Administrator\.cloudflared\46ead48d-721f-4346-939b-bc4c7a3c9b58.json
ingress:
- hostname: eqms.1**.com.cn
service: http://localhost:8080
originRequest:
noTLSVerify: true
- hostname: qti.1**.com.cn
service: http://localhost:8080
originRequest:
noTLSVerify: true
- service: http_status:4049.2 Nginx配置
路径: C:\nginx\conf\nginx_eqms.conf
(完整配置见第四节)
9.3 相关文件
| 文件 | 路径 | 说明 |
|---|---|---|
| Cloudflare Tunnel凭证 | C:\Users\Administrator\.cloudflared\46ead48d-721f-4346-939b-bc4c7a3c9b58.json | Tunnel身份认证 |
| Nginx主配置 | C:\nginx\conf\nginx_eqms.conf | EQMS反向代理配置 |
| Nginx日志 | C:\nginx\logs\ | 访问日志和错误日志 |
| 启动脚本 | C:\Users\Administrator\start-eqms-tunnel.ps1 | 开机自启动脚本 |
十、常见问题FAQ
Q1: 访问 eqms.1**.com.cn 显示502 Bad Gateway?
排查步骤:
- 检查cloudflared是否运行:
Get-Process cloudflared - 检查Nginx是否运行:
Get-Process nginx - 检查内网EQMS是否可访问:
curl http://10.188.56.27 - 查看Nginx错误日志:
C:\nginx\logs\error.log
Q2: 登录后一直跳回登录页?
原因: Cookie域名不匹配
解决: 确保Nginx配置中有 proxy_cookie_domain $backend_url $host;
Q3: QTI系统前端API调用失败?
原因: 前端JS硬编码了内网IP
解决: 在Nginx配置中添加sub_filter,替换响应内容中的内网IP为当前域名
Q4: 如何更新Tunnel配置?
# 1. 修改 config.yml
notepad C:\Users\Administrator\.cloudflared\config.yml
# 2. 重启Tunnel
Get-Process cloudflared | Stop-Process
cd C:\Users\Administrator\.cloudflared
.\cloudflared.exe tunnel --config config.yml run my-tunnel十一、安全建议
- Cloudflare Access: 在Cloudflare Dashboard中配置Access Policy,限制只有公司邮箱能访问
- IP白名单: 在Cloudflare Firewall Rules中设置允许访问的IP范围
- 审计日志: 开启Cloudflare Audit Logs,记录所有访问
- 定期更新: 定期更新cloudflared版本
.\cloudflared.exe update - 备份配置: 定期备份
C:\Users\Administrator\.cloudflared\目录
十二、参考资料
文档版本: v1.0
最后更新: 2026-05-20
评论区