↓ 跳过正文

客户开白名单得等半天?我直接写了个自助开通门户,半分钟搞定

·3530 字·8 分钟·
作者
闫工
十年运营商机房 IT 运维,CCIE。做数据中心网络架构、GPU 服务器与裸金属交付,顺手写点自研小工具。

📌 转载说明:本文首发于微信公众号《闫工的算力工具箱》 原文链接:https://mp.weixin.qq.com/s/e43aRRzPR3wexjmA0OkkcQ

【闫工的工具箱 · 第 24 弹|提效干货】
#

大家好!我是闫工。

我们这边多客户通过 SSLVPN 接进来,各自访问自己的裸金属服务器。每加一个访问需求,客户提工单 → 我排期 → 手工登录防火墙敲命令。一个“就加一个 IP”的需求,客户得等我半天。

更麻烦的是越权和留痕。图省事直接授权一整个 /24 段,客户就能横向摸到同网段其他机器;规则加多了以后,同一条策略被不同客户各建好几条,规则表越滚越乱;出问题了想查"谁在什么时候改了什么",翻不出来。

后来我干脆做了个门户:客户自己提交,后端自动下发,全程留痕。这篇把架构、设计、踩的坑都写出来。

— — —

先说说人工开白名单到底烦在哪
#

痛点具体表现后果
效率低客户提工单 → 我排期 → 手工登录敲命令一个简单开通要等数小时
易越权为省事直接授权整个 /24 网段客户可横向访问同网段其他机器
规则碎片化同 server、同 port 被多个客户 IP 各建一条规则表爆炸,没人敢动
无审计手工操作不留记录出问题追不到人

四个问题里,越权和碎片化是最要命的——前者是安全风险,后者是维护灾难。所以这个门户不只是"把工单搬到网页上",核心是把规则模型重新设计一遍。

— — —

这个门户长什么样
#

客户开白名单得等半天?我直接写了个自助开通门户,半分钟搞定

图:客户经 SSLVPN(或可选域名)接入门户 VM,门户后端 SSH 到防火墙管理口下发白名单,防火墙双机 RBM 主备自动同步

访问路径有两条:

  • 直连

    客户连上 SSLVPN 后,浏览器直接访问门户的静态 IP(在 Trust 区);

  • 域名(可选)

    经一台 docker nginx 反代到门户 443。这条路有个坑,后面第五节讲。

下发路径是:门户后端用运维账号 SSH 到防火墙管理口,调用 H3C 命令生成或撤销白名单,防火墙双机通过 RBM 从主同步到备。整个过程客户看不到命令,也不需要知道防火墙在哪。

几个关键组件:

组件干什么的
门户 VMWeb 界面 + 后端脚本 + 数据库,库里存 legacy / active 两套策略数据
nginx 反代docker 部署,接入可选域名
防火墙H3C F5000 系列,白名单策略 + 14 个 wg_*_src 源对象组
数据库策略双轨:legacy(老规则)→ active(迁移后),迁移期并行

📌 为什么要有两套数据?迁移不是一次做完的,得分批。legacy 是历史遗留的散乱规则,active 是迁移后的规范规则。每迁完一批就核对一次,核对通过才把 legacy 那批作废。这样迁移能分批推进,不用停机切换。

— — —

核心设计:一条规则管一批 IP
#

这是整个项目里我想得最久的一个点。

按"客户 + IP"逐条建规则的后果是什么? 同一台服务器、同一个端口,被多个客户的 IP 各建一条 rule,规则表很快爆炸。

我的做法是共享规则模型:同一组 (server, port) 的多个授权 IP,共用一条 rule,IP 的差异下沉到源对象组(src object-group)。

举个例子:多个客户都要访问 10.27.0.1:9203,那就只维护 1 条 rule,把各客户 IP 都加进同一个 src 对象组;也可以按客户拆成 wg_客户_src 组,让一条 rule 引用多个组。

这套模型我在真机上验证过,提交和撤销的全链路行为正确。

还有一条容易被忽略的规则:提交的 IP 一律按 /32 归一,存裸 IP(不带 /32 后缀)。

理由很实在:同一个 IP,如果有时写 10.27.0.1、有时写 10.27.0.1/32,在做比对和去重的时候就会被当成两个不同的地址,规则碎片就是这么来的。

— — —

门户怎么用:批量提交、双角色、审计留痕
#

批量提交:单条失败不影响其他
#

  • 输入框支持逗号分隔多个 IP,中英文逗号都认(兼容不同输入法);
  • 逐个 IP 校验,单个失败不影响其他——成功的正常入库,失败的单独提示;
  • 提交后弹 loading 模态框,预期 30~45 秒,因为后端要真的 SSH 到防火墙上把策略下发下去。

双角色门户
#

左侧菜单按角色动态渲染,客户看到的和管理员看到的完全是两套:

角色菜单项
admin开通新客户 / 客户列表 / 审计日志
客户添加白名单 / 我的白名单

还有个减少退回工单的小设计:按客户预置必填项提示。比如某个客户必须带端口 12222、9203,某个客户必须授权某个特定服务器 IP 以防规则碎片——客户一登录,页面上就醒目提示,不用我每次口头交代。

审计留痕
#

提交和撤销操作全部写审计日志,admin 可按客户、时间查询。

撤销走的是"在已有规则上增删成员"的语义(add_to_existing),而不是重建整条 rule——这样既保留规则连续性,也不会因为撤销操作引入新的规则 ID。

— — —

我踩的坑:一个 /32 引发的撤销失效
#

客户开白名单得等半天?我直接写了个自助开通门户,半分钟搞定

图:表单提交时的校验提示——源 IP 若不在该客户任一授权网段内会被拒绝,并明确提示当前授权网段

这是整个项目里最值得记的一个坑,而且是真机验证时才暴露的。

现象:共享规则模型在真机验证时,提交 /32 授权正常,但撤销之后防火墙上规则还在。

排查过程:提交成功、撤销命令也执行了、防火墙没报错,但规则就是没掉。

根因:生成规则地址行的函数,对 /32 生成的是

subnet 10.27.0.1 255.255.255.255

而生成撤销行的函数,对同一个地址生成的是

host 10.27.0.1

两条命令的写法不对称。防火墙是按字面写法匹配的,撤销命令找不到对应条目,于是静默失效——连个报错都没有。

修复:统一 /32 在正向与撤销路径下的写法,要么都用 host,要么都用 subnet 255.255.255.255,保证可逆。

⚠️ 闫工经验谈:凡是"生成—撤销"成对出现的脚本逻辑,必须真机正反各跑一遍。只验证正向下发,一定漏掉这类不对称 bug。

顺带还有个小坑:传入 10.27.0.1/32 时解析服务端 zone 报错,原因是 ip_network() 默认 strict 模式,对带主机位的 /32 后缀会抛异常。改用 ip_network(strict=False) 就好了。

这两个坑其实是一个源头——代码内部对 IP 的表示没统一。一处按裸 IP 处理,一处按带掩码处理,两边就会打架。所以前面说"提交的 IP 一律按 /32 归一存裸 IP",不只是为了去重,也是为了少一类 bug。

— — —

客户那边怎么用
#

前提是已经连上 SSLVPN。

  1. 登录

    浏览器访问门户地址,输账号密码;

  2. 首次登录强制改密

    初始密码必须先改;

  3. 添加白名单

    填服务器 IP、端口、源 IP。源 IP 支持批量逗号分隔,中英文逗号都识别;单个 IP 失败不影响其他;

  4. 等待下发

    提交后弹 loading,后端 SSH 到防火墙下发,预期 30~45 秒;

  5. 在我的白名单核对

    查看已提交与已生效的记录。

撤销在「我的白名单」里选条目操作,生效时间跟下发一样,30~45 秒。

还有一个坑:内网域名接入。最后的落地方式是本机 hosts + docker nginx 反代的 conf.d 配置,内网通过 hosts 访问生效。

客户侧的使用流程就这么简单。如果你想在自己的环境里搭一套,下面这几个部署要点可以参考。

— — —

部署要点
#

项配置
系统Ubuntu 22.04,nginx 监听 443(TLS)反代到本地 uvicorn 127.0.0.1:8000
应用FastAPI + SQLite(wl.db),systemd 托管
下发通道门户后端以运维账号 SSH 到防火墙管理口,调用 H3C 命令(Paramiko / Netmiko 建通道)
双机冗余RBM 主 → 备 auto-sync;备墙要单独镜像运维账号和对应规则段

双机这块有个容易漏的点:主备同步的是策略配置,但运维账号、特定规则段这些要单独在备墙上镜像一份。否则主墙故障切过去,门户的下发通道直接就断了——客户点提交,卡在 loading 上转圈。

— — —

老规则迁移和权限收紧
#

迁移是分批做的,五步:

  1. 建源对象组

    用运维账号建 14 个 wg_客户_src 对象组;

  2. 老规则改名 + 源对象组化

    8 家客户全部完成,交付一份命名对照表(旧规则名 ↔ 新对象组);

  3. DB 对齐

    legacy → active 逐客户核对。比如某客户 13 条、另一个客户 5 条(端口 12222、9203 要对齐)、再一个客户 11 条,还有客户的 server_ip 需要修正;

  4. 清理冗余

    删掉某客户的 41 条冗余规则,既消除数据冗余,也消除潜在权限风险;

  5. 权限收紧:/24 → /32

    7 家客户的授权网段从 /24 收窄到实际裸金属的 /32,消除横向越权;同时补上遗漏的服务器条目,把授权只留实际需要的那一个 /32,从源头掐掉规则碎片。

先在单个客户上跑通全链路试点(提交 + 撤销,含 add_to_existing 语义),确认无误后其余客户分批迁移。

— — —

这套门户解决了什么
#

  • 客户不用等我

    提交即下发,30~45 秒生效,不用走工单排期

  • 越权从根上堵住

    授权粒度收到 /32,“顺手给个 /24"这种事在门户上做不出来

  • 规则不再爆炸

    共享规则模型 + IP 归一,规则表从"没人敢动"变成"看得清”

  • 留痕可查

    谁什么时候提交了什么、撤销了什么,admin 一查就有

  • 可分批迁移

    legacy / active 双轨,不用停机切换

  • 技术栈很轻:FastAPI + SQLite 就够,一个人能维护

— — —

结尾 · 互动
#

你们那边的白名单、防火墙策略是怎么管的?直接通过CLI还是netconf实现?如果也在做类似的事,踩过什么坑,评论区聊聊。

📖 推荐阅读

拿假报告交差?GPU 集群网络验收我列了 6 个必测平面

NAT 回流:内网通过公网 IP 访问内网服务失败的原因与配置

3 个让我大幅减少重复劳动、每天早下班的 AI 工作流

相关文章