对外公网部署
# 对外公网部署
# 一、前置检查:22001 端口状态确认
在开始任何对外方案前,先确认服务在目标端口正常监听,且防火墙策略与预期一致。
# 1.1 确认端口监听地址
在知识库服务器上执行:
# Linux
ss -tlnp | grep 22001
# Windows
netstat -ano | findstr :22001
2
3
4
5
关注 LISTEN 后面的地址:
- 显示
127.0.0.1:22001:服务仅本机可访问,适合后面所有“代理/隧道”方案,但不适合直接端口映射。 - 显示
0.0.0.0:22001或:::22001:服务监听所有网卡,内网可直接通过服务器IP:22001访问,但也意味着有被意外暴露的风险,需要重点控制防火墙。
如果服务可以配置监听地址,生产环境建议改为 127.0.0.1:22001,把“对外”完全交给代理层处理,避免端口无意中暴露。
# 1.2 防火墙放行规则(仅在需要“直接暴露”时使用)
如果选择方案一(直接端口映射),需要在知识库服务器本机防火墙放行 22001,同时确保云安全组/路由器端口映射也放行。如果选择代理/隧道方案,通常不需要在知识库服务器上对外开放 22001。
# Linux firewalld 示例(仅在方案一需要)
sudo firewall-cmd --permanent --add-port=22001/tcp
sudo firewall-cmd --reload
2
3
# 二、方案一:直接端口映射(最简,仅限测试/受控内网)
适用场景:临时演示、完全可控的内网环境、有固定公网 IP 且仅对已知 IP 开放。
风险:知识库端口直接暴露,不推荐用于生产;扫描器会直接探测 22001 等服务端口。
# 2.1 架构
客户端 → 公网IP:22001(或路由器映射端口) → 知识库服务器:22001
# 2.2 配置步骤
情形 A:云服务器有公网 IP
- 在云平台安全组中放行入方向
TCP:22001,源 IP 尽量限制为已知客户端出口 IP,不要用0.0.0.0/0。 - 确认知识库服务监听
0.0.0.0:22001或内网IP:22001(127.0.0.1不可从外部直接访问)。 - 客户端连接地址填写:
http://公网IP:22001(或https://,如果服务本身启用了 TLS)。
情形 B:内网服务器 + 路由器端口映射
- 在路由器中将公网端口(建议不要用 22001,改为随机高端口,如
39201)映射到内网知识库服务器的22001。 - 客户端填写:
http://公网IP:39201。
# 2.3 客户端切换写法
客户端中可保存为一条“直连”配置,地址形如 http://IP:端口。切换到该配置即直连 22001。
⚠️ 强烈建议:如果走这个方案,至少在知识库前置一层简单的IP 白名单,并在用完后及时关闭端口映射。生产环境请直接进入方案二或方案三。
# 三、方案二:Nginx / Caddy 反向代理(生产推荐,有公网 IP 或域名)
适用场景:有公网 IP、有域名,希望统一入口、启用 HTTPS、隐藏后端端口、叠加访问控制。这是生产环境最常规的做法:外部只访问 80/443,Nginx 把请求转发到本机 127.0.0.1:22001。
# 3.1 架构
客户端 → 域名:443(HTTPS) → Nginx → 127.0.0.1:22001(知识库)
Nginx 与知识库服务部署在同一台机器时,proxy_pass 写 127.0.0.1:22001,知识库可保持 127.0.0.1 监听,22001 完全不暴露。
# 3.2 Nginx 配置示例
创建 /etc/nginx/conf.d/knowledge.conf:
server {
listen 443 ssl http2;
server_name kb.example.com; # 替换为你的域名
ssl_certificate /etc/nginx/ssl/kb.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/kb.example.com.key;
# 安全响应头(按需)
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://127.0.0.1:22001;
proxy_http_version 1.1;
proxy_set_header Host $http_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_read_timeout 300s;
proxy_buffering off;
}
}
# HTTP 跳转 HTTPS
server {
listen 80;
server_name kb.example.com;
return 301 https://$host$request_uri;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
关键指令说明:
| 指令 | 作用 |
|---|---|
proxy_pass http://127.0.0.1:22001; | 将请求转发到本机 22001 |
proxy_set_header Host $http_host; | 保留客户端访问的域名和端口,避免后端生成错误的跳转链接 |
X-Forwarded-For / X-Real-IP | 让知识库能拿到真实客户端 IP,便于审计和限流 |
proxy_buffering off; | 如果知识库有流式问答/SSE,避免代理缓冲导致响应延迟 |
检查并重载:
sudo nginx -t && sudo systemctl reload nginx
# 3.3 客户端切换写法
客户端中新增配置:
- 地址:
https://kb.example.com - 端口:留空(HTTPS 默认 443)或按客户端要求填写
443
切换到该配置即可通过域名走 Nginx 访问,客户端完全不需要知道 22001。
# 3.4 在 Nginx 层叠加基础安全
即使知识库自身有登录,也建议在 Nginx 层做一层收敛:
- IP 白名单(如仅允许公司出口 IP / VPN 网段):
allow 203.0.113.0/24; allow 10.0.0.0/8; deny all;1
2
3 - 请求体大小限制:
client_max_body_size 100m;(按知识库上传文件上限调整)。 - 限流(防止接口被刷):可结合
limit_req_zone使用。
# 四、方案三:frp 内网穿透(无公网 IP,有云服务器中转)
适用场景:知识库部署在没有公网 IP 的内网/办公网,但有一台带公网 IP 的云服务器作为中转。frp 是成熟的 TCP 反向代理工具,适合把内网 22001 暴露到公网服务器的某个端口。
# 4.1 架构
客户端 → 云服务器公网IP:远程端口 → frps(云服务器) → frpc(内网) → 127.0.0.1:22001
# 4.2 云服务器(frps)配置
frps.toml:
bindPort = 7000
# 建议开启 token 认证
auth.method = "token"
auth.token = "替换为强随机字符串"
# Dashboard(可选,用于查看隧道状态)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "替换为强密码"
2
3
4
5
6
7
8
9
10
云服务器安全组放行:7000/tcp(frp 通信)、7500/tcp(Dashboard,可选),以及你计划对外使用的远程端口(下方示例用 22001,但更推荐换一个非默认端口,如 39201)。
# 4.3 内网知识库侧(frpc)配置
frpc.toml:
serverAddr = "云服务器公网IP"
serverPort = 7000
auth.method = "token"
auth.token = "替换为与 frps 一致的 token"
[[proxies]]
name = "knowledge-base-22001"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22001
remotePort = 39201 # 公网侧使用的端口,建议不要用 22001
2
3
4
5
6
7
8
9
10
11
12
启动 frpc 后,客户端访问 http://云服务器公网IP:39201,流量经 frps → frpc → 本机 22001。
# 4.4 客户端切换写法
客户端中新增配置:
- 地址:
http://云服务器公网IP - 端口:
39201(或你在remotePort中设定的值)
切换到该配置即通过 frp 隧道访问内网知识库。注意:frp TCP 隧道本身不终结 HTTPS;如果要对公网启用 HTTPS,应在云服务器的 frps 前面再加一层 Nginx 反向代理到 127.0.0.1:39201,或者使用 frp 的 HTTPS 类型代理(需域名和证书)。
# 4.5 frp 方案的安全要点
- 务必开启 token 认证,不要裸奔
bindPort。 remotePort不要用 22001,避免扫描器直接命中知识库常见端口。- 云服务器安全组对
remotePort的入方向尽量限制源 IP,或至少在 frps 前面用 Nginx 做 IP 白名单和限流。 - 定期更新 frp 版本,关注 Dashboard 异常连接。
# 五、方案四:零信任组网 / VPN 类方案(无公网 IP,最高收敛)
适用场景:不希望把任何知识库端口暴露到公网,只允许授权设备像在局域网一样访问 22001。代表方案:Tailscale、ZeroTier、企业 VPN。Tailscale 基于 WireGuard,零端口暴露,适合“远程办公安全访问内网知识库”的场景。
# 5.1 架构(以 Tailscale Subnet Router 为例)
授权客户端(安装 Tailscale) → WireGuard 加密隧道 → 内网 Subnet Router → 知识库服务器:22001
客户端不需要知道公网 IP 或隧道端口,只需要访问内网 IP:22001,组网层负责把流量安全地送到内网。
# 5.2 关键配置步骤
- 注册 Tailscale,创建 tailnet。
- 在内网一台常开机器上安装 Tailscale,并开启 Subnet Router,把知识库所在内网网段广播到 tailnet:然后在 Tailscale 管理后台批准该路由。
tailscale up --advertise-routes=192.168.1.0/241 - 授权客户端安装 Tailscale 并登录同一 tailnet,接受路由:
tailscale up --accept-routes1 - 在 Tailscale ACL 中限制只有特定用户/设备可以访问知识库服务器的
22001端口,不要默认全通。
# 5.3 客户端切换写法
客户端中新增配置:
- 地址:
http://知识库服务器内网IP(如http://192.168.1.50) - 端口:
22001
前提:客户端设备已加入 Tailscale/ZeroTier 网络,并获授权。切换到该配置即可通过加密隧道访问 22001,公网上不存在任何暴露的 22001 端口。
# 5.4 适用判断
| 条件 | 是否适合零信任组网 |
|---|---|
| 用户是员工/固定合作方,可安装客户端 | ✅ 非常适合 |
| 需要给完全陌生的外部用户“打开就能用” | ❌ 不适合,仍需方案二/三 |
| 对“零端口暴露”有硬性安全要求 | ✅ 首选 |
| 不想维护公网服务器和证书 | ✅ 有优势 |
# 六、方案对比与选型建议
| 维度 | 方案一:直接端口映射 | 方案二:Nginx 反向代理 | 方案三:frp 内网穿透 | 方案四:零信任组网 |
|---|---|---|---|---|
| 前置条件 | 公网 IP 或路由器管理权 | 公网 IP + 域名 | 公网云服务器 | 授权设备可装客户端 |
| 22001 是否暴露公网 | 是 | 否(仅本机) | 否(仅本机) | 否(仅内网) |
| HTTPS 支持 | 依赖服务自身 | 原生支持 | 需额外叠加 | 隧道加密,应用层可再 HTTPS |
| 配置复杂度 | 最低 | 中 | 中高 | 中 |
| 安全收敛能力 | 弱 | 强(白名单/限流/证书) | 中(依赖 frps 安全配置) | 最强(身份+ACL) |
| 适合外部陌生用户 | 不推荐 | ✅ | ✅(配合 Nginx) | ❌ |
| 推荐使用场景 | 临时测试 | 生产环境,有域名 | 无公网 IP 但有云服务器 | 员工/固定伙伴远程访问 |
选型建议:
- 有公网 IP 和域名 → 直接走 方案二,这是最标准、最可控的生产方案。
- 没有公网 IP,但有一台云服务器 → 方案三 frp + 云服务器 Nginx,兼顾可达性和安全。
- 用户是员工或固定合作方,安全要求高 → 方案四 Tailscale/ZeroTier,零端口暴露。
- 只有测试/临时演示 → 可以用方案一,但用完立即关闭映射,并限制源 IP。
# 七、通用安全加固清单(任何对外方案都应关注)
无论选择哪种方案,建议逐项确认:
- [ ] 知识库服务不要监听
0.0.0.0:22001,除非确实在受控内网且无代理层。生产环境优先127.0.0.1:22001。 - [ ] 对外入口不用 22001 作为公网端口,改用非默认端口,降低扫描命中率。
- [ ] 如果走 HTTP/HTTPS,强制 HTTPS,禁用弱 TLS 版本。
- [ ] 在代理/隧道/组网层限制源 IP 或设备身份,不要默认对全网开放。
- [ ] 对知识库的上传接口、问答接口做请求体大小和频率限制,防止被当成免费算力代理刷接口。
- [ ] 定期检查
ss -tlnp和代理/隧道日志,确认没有多余的对外监听。 - [ ] 客户端切换配置时,不同方案的地址、端口、协议(http/https)要分开保存,避免把“直连 22001”的配置误用于公网环境。
# 八、故障排查速查
| 现象 | 优先检查 |
|---|---|
| 客户端连不上代理/域名 | DNS 解析、Nginx server_name、防火墙 443/80 |
| Nginx 返回 502 | 知识库是否在 127.0.0.1:22001 正常监听;proxy_pass 地址是否正确 |
| frp 隧道建立但访问超时 | 云安全组是否放行 remotePort;frpc 的 localIP/localPort 是否正确 |
| Tailscale 能 ping 通内网但 22001 不通 | Subnet Router 路由是否批准;知识库服务器本机防火墙是否放行 22001;Tailscale ACL 是否允许该端口 |
| 客户端切换后仍连旧服务 | 检查客户端是否真正应用了新配置;部分客户端会缓存连接,切换后建议手动重连 |
文档结论:客户端已支持“填写地址自动切换”的前提下,最推荐的生产路径是 方案二(Nginx 反向代理 + HTTPS + IP 白名单);没有公网 IP 时用 方案三(frp + 云服务器) 作为过渡;安全要求最高的员工/伙伴访问走 方案四(Tailscale/ZeroTier)。方案一仅用于测试,且应严格限制源 IP 和时效。所有方案共通的底线是:不要让 22001 以裸端口形式长期暴露在公网。