问题背景
公司安全基建升级,计划上线堡垒机(JumpServer)实现「所有运维操作必须走堡垒机、所有服务器 SSH 必须走跳板、DB 账号密码统一托管」三收口。堡垒机上线后,运维团队把「服务器 SSH 登录」和「Web 管理界面」都切到了堡垒机,表面看收口完成。
但在一次生产变更中,DBA 误把「生产库 ALTER TABLE」脚本跑到了「核心业务库」,造成业务中断 40 分钟。事后复盘发现:虽然堡垒机已上线,但「DB 直连账号」和「跳板机白名单」仍存在历史遗留的直连通道,导致「堡垒机只是多了一层、不是唯一通道」。安全团队要求彻查「账号收口不彻底」的全链路。
故障现象
- 2026-08-30 02:17,DBA 小李在本地用
mysql -h core-db.prod.internal -u app_rw -p直连生产核心库,执行了ALTER TABLE order_items ADD COLUMN ext_json JSON。 - 02:19,核心业务接口开始报错「Unknown column ’ext_json’」,订单创建/支付全部失败。
- 02:21,监控告警「核心库 QPS 骤降 90%」,值班 SRE 发现「堡垒机会话日志里没有这条 ALTER 操作」。
- 02:25,DBA 意识到跑错库,紧急回滚,但
ext_json列已写入,需做pt-online-schema-change反向变更。 - 02:40,业务恢复,累计影响订单 1200+ 笔、支付失败 800+ 笔。
关键信号:堡垒机上线后,DB 直连仍可绕过堡垒机,且堡垒机会话审计完全缺失这条高危操作。
排查过程
第一步:确认堡垒机是否真正「收口」
堡垒机(JumpServer)已上线 3 周,SSH 登录必须走堡垒机、Web 管理必须走堡垒机。检查堡垒机「会话录像」和「命令审计」,08-30 02:17 没有任何 mysql 相关会话。
|
|
说明 DBA 不是通过堡垒机连的 DB。
第二步:检查跳板机白名单
跳板机(Bastion Host)是堡垒机的前置层,所有服务器 SSH 必须先登录跳板机,再从跳板机 ssh 到目标服务器。
|
|
PermitOpen any 允许 app_rw 从跳板机任意端口转发到任意目标,这意味着 app_rw 可以从本地 ssh -L 3306:core-db.prod.internal:3306 jumpbox 再用本地 3306 端口直连 DB,完全绕过堡垒机。
第三步:检查 DB 账号直连白名单
检查 MySQL mysql.user 表和 information_schema.processlist:
|
|
结果发现:
|
|
10.8.0.% 和 172.16.%.% 是办公网和开发网段,意味着「只要知道密码,任何开发机/办公 PC 都能直连生产 DB」,完全绕过堡垒机。
第四步:检查历史「直连脚本」与「跳板机配置漂移」
检查 DBA 本地 ~/.my.cnf 和团队 Wiki,发现:
- 旧脚本
prod-db-connect.sh仍使用直连方式(mysql -h core-db.prod.internal) - 跳板机白名单在 2026-07-15 曾因「紧急修复某业务连通性」临时放开
PermitOpen any,事后未收口 - 堡垒机上线 checklist 里「DB 账号收口」被标记「已完成」,但实际只做了「堡垒机 Web 管理界面托管密码」,没有做「DB 驱动层强制走堡垒机代理」
第五步:确认误操作路径
DBA 小李的本地操作:
|
|
这条连接没有经过堡垒机,也没有经过跳板机审计,完全「裸奔」。
解决方案
1. 立即止血:禁用直连账号、收紧跳板机白名单
|
|
跳板机配置收口:
|
|
2. DB 账号全面收口到堡垒机
- 所有生产 DB 账号(
app_rw、app_ro、backup)只保留bastion-01.internal一个 host 白名单 - 密码统一托管到堡垒机「数据库资产」,运维人员必须通过堡垒机 Web 界面或堡垒机代理端口连接
- 堡垒机开启「数据库会话录像」和「SQL 审计」
3. 跳板机白名单收口 + 堡垒机前置
- 跳板机
PermitOpen只允许转发到堡垒机 IP - 所有服务器 SSH 登录必须先登录堡垒机,再从堡垒机
ssh到目标(跳板机仅作为堡垒机后端,不再暴露给用户) - 堡垒机「资产」里所有服务器的「连接方式」统一改为「SSH → 堡垒机」
4. 建立「账号收口」验收门禁
- 新服务器上线 checklist 必须包含「堡垒机资产录入 + DB 账号收口验证」
- 每月做一次「直连白名单扫描」(脚本扫描
mysql.user的非堡垒机 host) - 堡垒机「会话缺失告警」:如果服务器上有登录但堡垒机无记录,立即告警
根因分析
根本原因:堡垒机上线 checklist 只做了「形式收口」(Web 管理界面托管密码),没有做「链路收口」(DB 驱动层、跳板机白名单、服务器 SSH 登录全部强制走堡垒机)。
直接原因:
- 跳板机
PermitOpen any未收口,允许本地端口转发直连 DB - MySQL
user.host白名单仍保留办公网/开发网段 - 堡垒机 checklist 把「DB 账号收口」标记「已完成」,但实际只托管了密码,没有切断直连
管理原因:安全团队和运维团队对「收口」的理解不一致——安全团队认为「必须走堡垒机」,运维团队认为「堡垒机上线了、密码托管了」就是收口,缺少「可验证的收口证据」。
预防措施
- 堡垒机 checklist 必须包含「链路验证」:不仅要托管密码,还要验证「直连是否失败」「堡垒机会话是否记录」
- 每月做一次「直连白名单扫描」:脚本扫描
mysql.user、redis.conf、mongo.conf等所有可能直连的配置,输出「非堡垒机 host」清单,纳入安全巡检 - 跳板机白名单收口 + 堡垒机前置:跳板机只允许转发到堡垒机,堡垒机作为唯一入口
- 建立「会话缺失告警」:服务器
/var/log/auth.log有登录但堡垒机无记录,立即告警 - DBA 工具链升级:所有 DB 连接必须走堡垒机代理(
mysql -h bastion-proxy.internal -P 33061),本地~/.my.cnf全部删除或指向代理
总结
堡垒机上线只是「安全收口」的起点,不是终点。真正的收口需要「链路验证 + 白名单收口 + 会话审计 + 门禁验收」四层保障。一次 MySQL 误操作暴露了「形式收口 vs 实质收口」的差距,也推动团队建立了「每月直连白名单扫描 + 会话缺失告警 + 堡垒机 checklist 链路验证」三道防线。安全基建不是「装个设备就完事」,而是「持续验证、持续收口、持续审计」。