一、背景与需求分析
FUXA 是一款基于 Web 的开源 SCADA/HMI 可视化平台,通常部署在工业现场或企业内网中,用于采集 PLC、Modbus、OPC UA 等设备数据并做实时监控。实际项目中,运维人员、管理层或远程专家往往需要在外部网络(公网、异地办公网、移动网络)访问这套内网监控平台。
由此带来的核心需求可以归纳为以下几点:
- 可达性:外网终端能够稳定访问 FUXA 的 Web 页面与 WebSocket 实时数据通道。
- 安全性:不能把内网监控端口直接暴露在公网,需要身份认证、传输加密与访问控制。
- 低改造成本:尽量不改动 FUXA 源码与现场网络结构。
- 可运维性:方案要便于部署、监控和故障排查。
下面先梳理几种典型技术方案,再给出最常用方案的完整落地示例。
二、几种典型技术方案对比
2.1 方案一:路由器端口映射(NAT 端口转发)
在出口路由器或防火墙上,把公网 IP 的某个端口映射到内网 FUXA 服务器的 1881 端口。这是最直接的做法,配置简单,但存在明显缺陷:
- 需要公网固定 IP,多数企业宽带不具备。
- 直接暴露服务端口,攻击面大,缺少认证与加密。
- 无法做细粒度访问控制与审计。
因此该方案仅适合临时调试,不建议用于生产环境。
2.2 方案二:VPN 远程接入
通过 IPSec VPN、OpenVPN 或 WireGuard,让外网终端先接入企业内网,再像内网设备一样访问 FUXA。安全性较好,但需要为每个访问者分配 VPN 账号并安装客户端,移动端体验一般,且 VPN 网关本身需要公网入口。
2.3 方案三:反向代理 + 内网穿透(最常用)
在公网侧部署一台带公网 IP 的服务器,通过 Nginx 做反向代理,配合 frp、ngrok 等内网穿透工具,把内网 FUXA 服务安全地映射到公网域名上。该方案兼顾安全性、成本与可维护性,是当前工业互联网与中小型监控项目中最常见的做法。
2.4 方案四:云厂商 IoT 网关 / API 网关托管
借助阿里云、腾讯云、AWS 等云平台的 API 网关或 IoT 通信网关,将内网数据通过 MQTT 上报到云端,再由云端页面展示。适合大规模设备接入,但需要改造数据链路,FUXA 原生页面无法直接复用。
2.5 方案五:ZeroTier / Tailscale 组网
基于 SD-WAN 的虚拟组网方案,把内网服务器与外网终端加入同一虚拟局域网,无需公网 IP。部署轻量、穿透能力强,适合小团队快速使用,但依赖第三方协调服务器,企业合规性需评估。
2.6 方案选型结论
| 方案 | 安全性 | 部署成本 | 改造量 | 适用场景 |
|---|---|---|---|---|
| 端口映射 | 低 | 低 | 无 | 临时调试 |
| VPN 接入 | 高 | 中 | 小 | 固定人员远程运维 |
| 反向代理 + 内网穿透 | 高 | 中低 | 小 | 生产环境通用 |
| 云 IoT 网关 | 高 | 高 | 大 | 大规模设备上云 |
| ZeroTier/Tailscale | 中高 | 低 | 无 | 小团队快速组网 |
综合来看,反向代理 + 内网穿透是使用最广泛、性价比最高的方案,下文以此为主线展开。
三、最常用方案:Nginx 反向代理 + frp 内网穿透
3.1 整体架构
flowchart LR
A[外网浏览器/移动端] -->|HTTPS 443| B[公网服务器 Nginx]
B -->|反向代理| C[frps 服务端]
C -->|加密隧道| D[内网 frpc 客户端]
D -->|HTTP/WebSocket| E[FUXA 服务 1881]
E --> F[PLC / Modbus / OPC UA 设备]
架构说明:
- 公网服务器承担统一入口,负责 TLS 终止、域名解析与访问控制。
- frps 与 frpc 之间建立加密隧道,内网无需开放任何入站端口。
- FUXA 的 HTTP 页面与 WebSocket 实时通道都通过同一隧道转发。
3.2 技术栈清单
| 组件 | 作用 | 推荐版本 |
|---|---|---|
| FUXA | 内网 SCADA 可视化平台 | 1.1.x 及以上 |
| frp | 内网穿透隧道 | 0.52.0 及以上 |
| Nginx | 反向代理、TLS 终止 | 1.24 及以上 |
| Let's Encrypt / Certbot | 免费 HTTPS 证书 | 最新稳定版 |
| Docker / Docker Compose | 容器化部署 | 24.x 及以上 |
| Linux(Ubuntu/CentOS) | 服务器操作系统 | Ubuntu 22.04 LTS |
3.3 公网服务器:部署 frps
在公网服务器上准备 frps 配置文件:
# /etc/frp/frps.ini
[common]
bind_port = 7000
token = YourStrongToken_ChangeMe
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = Admin@123456
vhost_http_port = 8080
vhost_https_port = 8443
max_pool_count = 20
使用 Docker 启动 frps:
docker run -d --name frps \
--restart always \
-p 7000:7000 \
-p 7500:7500 \
-p 8080:8080 \
-p 8443:8443 \
-v /etc/frp/frps.ini:/etc/frp/frps.ini \
snowdreamtech/frps:0.52.3
3.4 内网服务器:部署 frpc
在内网 FUXA 所在服务器上配置 frpc,把本地 1881 端口映射到公网 frps:
# /etc/frp/frpc.ini
[common]
server_addr = 1.2.3.4
server_port = 7000
token = YourStrongToken_ChangeMe
[fuxa_web]
type = http
local_ip = 127.0.0.1
local_port = 1881
custom_domains = fuxa.example.com
[fuxa_ws]
type = tcp
local_ip = 127.0.0.1
local_port = 1881
remote_port = 18810
启动 frpc:
docker run -d --name frpc \
--restart always \
--network host \
-v /etc/frp/frpc.ini:/etc/frp/frpc.ini \
snowdreamtech/frpc:0.52.3
提示:FUXA 的实时数据依赖 WebSocket,若使用 http 类型代理,需确保 Nginx 正确转发 Upgrade 头,否则页面能打开但数据不刷新。
3.5 公网服务器:配置 Nginx 反向代理
server {
listen 80;
server_name fuxa.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name fuxa.example.com;
ssl_certificate /etc/letsencrypt/live/fuxa.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fuxa.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# 基础认证,防止匿名访问
auth_basic "FUXA Monitor";
auth_basic_user_file /etc/nginx/.htpasswd;
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_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
生成基础认证账号:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd fuxa_admin
sudo nginx -t && sudo systemctl reload nginx
3.6 申请 HTTPS 证书
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d fuxa.example.com --agree-tos -m ops@example.com
sudo systemctl enable certbot.timer
3.7 验证与排障
- 访问
https://fuxa.example.com,确认登录页正常加载。 - 打开浏览器开发者工具,检查 WebSocket 连接状态是否为 101 Switching Protocols。
- 在 frps 面板
http://公网IP:7500查看隧道在线状态。 - 若页面白屏,检查 FUXA 的
base href与反向代理路径是否一致。
四、安全加固建议
- 最小暴露面:公网仅开放 443 与 frps 的 7000 端口,其余端口一律关闭。
- 强口令与令牌:frp token、Nginx Basic Auth、FUXA 登录口令均使用高强度随机值。
- IP 白名单:在 Nginx 中通过
allow/deny限制来源网段,或结合云安全组。 - 访问审计:开启 Nginx access log,定期分析异常访问。
- 隧道加密:frp 支持 TLS 加密隧道,可在
[common]中开启tls_enable = true。 - 定期升级:关注 FUXA 与 frp 的安全公告,及时升级版本。
五、方案总结
对于 FUXA 这类内网 SCADA 平台的外网访问需求,Nginx 反向代理 + frp 内网穿透在安全性、成本与改造量之间取得了良好平衡,是工程实践中最常用的方案。若企业已有成熟 VPN 体系,也可采用 VPN 接入作为补充;若设备规模较大且有上云规划,则可考虑云 IoT 网关方案。无论选择哪种方式,都应坚持“不直接暴露内网服务端口、全链路加密、最小权限访问”三条基本原则。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/ponygame/article/details/169914944



