# Round 5V-7 — 旧客户端路径阻断与受管QA签署 日期:2026-10-15(Asia/Shanghai)。输入提交:`65c567152e4f57bd25af03da52cc7078ea264984`。 分支:`fix/iot-safety-hardening`。本轮只改归档工程的本地QA工具、工具测试、CI验证发现范围及文档。 没有修改原工程、实验工程、旧进程配置、数据库账号权限、路由、Tailscale或共享服务。 没有迁移、恢复、纠正sync_time、创建授权、发Mock业务控制命令或真实设备控制。 登录会正常产生自身认证审计;它不是零数据库写入,但没有授权/命令变更。 ## 1. 结论与边界 | 标识 | 结论 | 实际范围 | | --- | --- | --- | | SOFTWARE_FUNCTIONAL_QA_PASSED | YES | 保留11项真实Kingbase、86项选定回归、12项工具、Chrome15路由及住宿Mock闭环的历史通过;未重跑完整矩阵 | | SOFTWARE_FINAL_SIGNOFF | PASS_MANAGED_QA_SCOPE | 本轮受管隧道、旧端点拒绝守卫、新后端最小读冒烟、数据稳定观察和故障退出通过 | | REAL_HARDWARE_VERIFIED | NO | 真实门锁/MQTT/人脸/DMS均未放行,未做现场硬件验收 | 此签署是当前受管QA运行/退出工作流的可交付候选,不是生产上线、永久数据库访问控制或硬件签署。 脱离工具手工重开14321、修改旧进程配置或共享同一账号,仍可能恢复旧访问;这些不在通过范围。 不得把手工SSH隧道或未绑定租约的应用启动替代本流程。 ## 2. 旧进程和原访问路径的只读复核 - 旧Java PID51901,出生时间`2026-10-13 15:35:08`,cwd=`boot4-iot-fusion-test`; 实际JAR位于该工程的`RuoYi-Vue-master/ruoyi-admin/target/ruoyi-admin.jar`,不是归档工作树。 - 从进程环境只输出非秘密字段:DB_HOST=127.0.0.1、DB_PORT=14321、QA_DB_USER=fusion_qa_app。 实际运行JAR内application-druid.yml固定数据库`railwaysystem_fusion_qa_20261013`,默认Host/Port与环境一致。 - 另一Java PID53305,出生时间`2026-10-12 12:46:15`,属于另一工程;其JAR数据源模板是localhost:54321/iotlocks, 不是上述旧端点。本轮两个Java进程均未停止或修改。 - 开始时14321没有监听者,不存在可归属/可关闭的现有该端口隧道。其他既有SSH进程未发现14321转发参数,未操作它们。 - 旧任务`initialDelay=30000ms / fixedDelay=60000ms`,允许补偿时会按失败/待发状态扫描;失败分支可写sync_time。 实际调度间隔还包含数据库连接等待/失败处理,不能把60秒当作每分钟一定完成一次。 - 原归档`qa.py`不自动建14321隧道,但允许任意同名QA URL,且只检查新应用监听端口,未防止旧客户端借用新转发。 已证明的两条旧记录来源仍见[Round 5V-6](ROUND5V6_FINAL_SIGNOFF.md),不是正常Mock回执。 ## 3. 实际采用的最小隔离 新增`scripts/qa/qa_isolation.py`,正常前台运行,认证只走既有合法SSH入口、Agent/密钥或交互提示。 它不接受或保存SSH密码,不改SSH/Tailscale/系统代理配置,不依赖停止旧进程或修改账号。 | 客户端/审计 | 本轮端点 | 隔离行为 | | --- | --- | --- | | 旧PID51901及其他14321客户端 | 127.0.0.1:14321 | 本任务守卫独占,连接立即关闭;没有数据库协议响应、没有任何上游 | | 新归档后端PID35238 | 127.0.0.1:14327 | 仅归本任务SSH PID34187所有的loopback转发,经wzbmatebook到目标127.0.0.1:4321 | | 独立只读指纹核验 | 经诊断SSH执行容器本地ksql | 只读事务/ROLLBACK,不通过14321,不恢复备份、不执行DDL | 守卫owner PID34164;同一租约绑定Redis35236、后端35238、前端35269。 其PID/出生时间/cwd/命令、监听IP与归属、固定QA库、心跳及新端点Java客户端依赖都被核验。 未发现其他Java客户端依赖14327;实际TCP连接只见新后端与自建SSH,旧PID51901未连接它。 14321已有未知监听者、新端点冲突、PID重用、心跳过期或所有权不匹配均安全拒绝,不清理未知资源。 不是只换端口:旧14321被拒绝守卫占住,实际bind测试得到占用错误,实际连接不返回数据库响应; 新启动器同时拒绝14321 URL、没有活动租约的start以及与租约不匹配的数据源。 前端也必须绑定同租约后端及对应端口,不能用旧8096后端冒充本版本。 看门狗持续检查;临时隧道失效时仅清理同租约应用,先关自己的SSH,最后释放拒绝守卫。 退出后的账本保留审计,不自动重用旧账本或信号未知PID。 ### SSH继承配置的额外发现和修复 现有SSH目标和跳板配置均含与QA无关的RemoteForward17897。 首次受管试运行因该继承转发冲突失败,未启动应用;对应STOPPED账本保留。 本轮诊断会话也意外继承同一转发;单独cancel不足,因为后续mux命令客户端可能再次继承并申请转发。 已按确切归属退出本轮诊断ControlMaster,再以ClearAllForwardings和禁用ControlMaster的单次只读SSH复核:17897监听数为0。 没有修改持久SSH配置或取消其他会话的转发。 最终工具用独立目标配置和显式ProxyCommand复用既有跳板,跳板清除继承转发/本地命令; 目标只设置批准的HostName/User/22端口及唯一-L,StrictHostKeyChecking=yes,不复用ControlMaster,不发布远程端口。 此后正式运行没有继承无关转发。不要将失败的首次尝试隐去或算作成功启动。 ## 4. 实际验证及数据证据 证据根:受保护且Git忽略的`.qa-runtime/round5v7/`;所有业务行仅在数据库内计算排序完整行指纹,未导出人员资料。 浏览器截图位于`output/playwright/round5v7-*-headers.png`,数据行和头像遮罩。 - 新工具的29项定向本机测试通过(原12项工具测试及17项隔离测试),不连接真实服务或数据库。 覆盖无租约拒绝、禁止旧URL、PID/监听者/心跳/来源端点拒绝、非本租约进程不被停止、真实本机拒绝socket等。 其中28项在启动前通过,补充前端错误端口防护后最终29项通过;不假称重跑86项后端测试。 - 正式受管租约创建于2026-10-15 01:52:49;应用在01:53:12启动。 实测Java21.0.2 / Boot4.1.0,fusion_qa_app,数据源仅目标QA库,独立Redis16389,前端18088/后端18096均loopback。 强制CLI保持MQTT enabled=false/mock=true、real-device-write-enabled=false、空白名单、自动补偿关闭、 Face HTTP/OpenAPI/QA危险入口/DMS/Quartz关闭;实际日志出现MOCK-MQTT,未见08001/SQL错误。 - 实际Chrome155最小冒烟:管理员登录/getInfo/getRouters成功;Student查询与Auth查询均HTTP200/业务200,JS错误0。 Auth页实际组件和45条总数正确,不是登录页/404;没有点击授权、撤权、入住或回执操作。 - 隔离前、运行中、退出前后共四次真实Kingbase只读采样。前后窗口1432秒(约23分52秒), 是名义60秒补偿周期的多倍;两表完整数据指纹均不变: lock_auth45条:`af7e6a797bebef91a7d5570697265b5e`;lock_command83条:`271d15e2d0721015d3b020433c549c7c`。 包含所有字段,而不只是排除sync_time后的指纹。两表REAL行数均0。 - 两条脱敏旧记录sync_time分别保持`2026-10-14 16:51:29`与`16:51:30`,仍LEGACY/QUARANTINED/version0, sync_status3、status0,没有纠正性UPDATE;其余原始记录也包含在完整指纹中。 - 正式守卫累计拒绝507次连接(含一次明确的本机负向验证,不把全部次数硬归给单个PID)。 旧日志完整追加窗口读取约1.1MB,发现2个补偿失败事件、0个成功updateSyncStatus UPDATE;未复制原日志正文。 这证明旧任务仍可能运行,但在受管窗口内无法通过旧端点获得QA连接,不是把任务静默禁用。 ### 自建SSH异常退出演练 验证租约与PID身份后,仅向本轮自建SSH PID34187发送SIGTERM。 看门狗检测到监听者丢失,自动停止同租约前端/后端/Redis,随后关闭自己的资源; 终态STOPPED、cleanup_ok=true,故障检测按预期非零退出,退出证据保留。 14321、14327、18096、18088、16389均不再监听,旧两个Java的PID/出生时间不变。 退出后源QA只剩本次ksql只读会话,无fusion_qa_app残留连接,完整指纹仍一致。 随后实际`qa.py start`在无租约时拒绝,未连接数据库或再启动进程。 没有测试SIGKILL、主机断电或恶意绕过,也不把本测试写成这些保证。 ## 5. 归档状态和剩余风险 共享Kingbase/GitLab容器ID、2026-10-06启动时间、restart0/OOM=false均未变;GitLab healthy。 临时恢复容器仍停止,本轮未启动或修改它。没有共享部署或真实硬件操作。 本轮只读远端仍为`feat/boot4-iot-fusion@373921447fa4727c20aed7b28c5d1519fe26fa78`,修复分支远端不存在。 该融合基线是修复分支祖先;本地保留此前七笔提交,本轮再追加工具/文档提交,不改写历史。 GitLab使用默认CI文件,项目Hook=0、非项目Hook=0、相关活跃Integration=0。 CI仍仅显式web+RUN_FUSION_VALIDATION=true可运行,只有验证无部署;新增隔离测试已纳入工具测试发现范围。 没有Push、MR、Merge或触发Runner;不把静态配置审核写成已执行远程CI。 本轮对已有七笔提交和新增暂存范围合计142个blob/路径版本完成扫描,未检出已知本机凭据值、 私钥正文、Token形态高风险项或新增备份/日志/照片/二进制文件;通用赋值命中已区分环境变量、占位符、 合成测试及禁用账号哨兵,不将扫描写成对继承历史的绝对无秘密保证。 原始备份、0600凭据、运行账本/日志/截图未被跟踪,扫描摘要保存在受保护忽略目录。 继承的测试密钥素材、历史凭据轮换、既有账号过宽授权、Vue2依赖及长期Kingbase许可仍保留风险,未自动处置。 在**必须使用受管入口**的前提下,当前软件候选不再因旧端点隔离而挂起;本轮最后仅需用户决定GitLab归档。 可另行批准后推送`fix/iot-safety-hardening`的精确本地HEAD,不Force Push、不覆盖融合基线,再经MR评审合入。 这不放行部署/生产/真实硬件;若要永久关闭旧服务、改旧配置、撤销账号权限或允许手工转发,仍须对应批准。 对恶意同用户进程/管理员主动绕过不提供系统级隔离保证;如运行场景要求该等级,应维持该场景PENDING并另行设计权限隔离。