diff --git a/docs/maintenance/FREENODE.md b/docs/maintenance/FREENODE.md index 457a905e..846f10b5 100644 --- a/docs/maintenance/FREENODE.md +++ b/docs/maintenance/FREENODE.md @@ -121,7 +121,7 @@ merge 下仍有旧命名目录,不能据目录名推断当前站点归属。fn - 现有 NasaTestFnSubfile 主要验页面/文件 HTTP 状态,不解析节点协议或运行配置内核校验。FreenodeWatch 目前只是占位实现。 - 日期/token 参与现行链接生成;用户长期订阅地址的有效期、下游保留策略、缓存及更新响应尚未核实。不能把 master 上文件正确等同于用户更新成功。 -### 建议的重构范围与顺序(未实施) +### 研究阶段的重构建议(实施状态见下文 V2 入口) 建议重构 Freenode 业务链,保留 Laravel 管理、站点映射、既有文章/Telegram 入口;不因本次问题重写整个 master01 或直接改下游项目。 @@ -132,7 +132,7 @@ merge 下仍有旧命名目录,不能据目录名推断当前站点归属。fn 5. **新旧并行生成后再切换。** 先不分发新版,比较节点配置、来源覆盖、格式验证和兼容差异;用独立测试订阅做客户端导入/更新验收,再逐站切换。保持原链接契约,涉及链接调整时提供明确兼容/迁移方案。 6. **白色机测试点接入同一模型。** 本地格式与内核校验先完成,白色机承担真实连接检测;结果关联节点配置版本及批次,不用连通测试代替导入有效性检查。 -实施前仍需用户实际客户端名称/版本和一条失败订阅的安全定位信息(不写入文档的完整 token);服务端核查该链接的真实路径、接收文件、HTTP 响应及缓存链。当前研究足以确认生成链已有缺陷并划定重构范围,尚未确认用户每次更新失败的具体请求原因。 +客户端名称/版本及原失败链接的安全定位信息仍待用户提供,不能将固定内核检查当作所有GUI客户端验收。下文部署验收已覆盖服务端生成、运行路由及Nodehub落盘,但不代表公网CDN/浏览器下载链路均已测试。 ## V2 实现与运维入口 @@ -141,7 +141,7 @@ merge 下仍有旧命名目录,不能据目录名推断当前站点归属。fn - `app/Services/Freenode/Codec.php`:URI 结构先拆分再字段解码,BOM 清理、IPv6、VMess 节点级 Base64、独立 SNI、确定性身份及来源关联。未知输出传输明确排除。 - `Builder.php`:从各启用来源的 URI 与 Clash 输入独立建模,分别去重、保留多来源;Sing-box 从 URI 模型渲染,Clash 保留来源节点字段并沿用服务器现有 Clash 策略模板。当前没有声称已统一识别跨 URI/Clash 的同一物理节点。 - `Renderer.php`:Sing-box 采用现代配置(原生验收目标 1.14.3),保留私网/中国规则直连、其余代理的路由意图;不再用复制真实节点的方式制造宣传占位。旧版 Sing-box/Hiddify 的具体兼容性须按产品内核验收,不能承诺所有客户端版本。 -- `NativeValidator.php`:Sing-box/Mihomo 每种格式先整份检查;只有失败才二分隔离坏节点,再验整份。原生错误输出不进入日志或报告,报告只记录节点哈希及排除分类。不会启动内核代理服务或接管宿主路由。 +- `NativeValidator.php`:Sing-box/Mihomo 每种格式先整份检查;失败时优先按内核报错索引隔离坏节点,未知错误才二分定位,最后再验整份;整批原生校验限制240秒,超时保留旧产物。原生错误输出不进入日志或报告,报告只记录节点哈希及排除分类。不会启动内核代理服务或接管宿主路由。 - `ReleaseStore.php`:私有版本目录、SHA-256 清单、文件锁、数量骤减保护(默认低于上一版/旧产物的 50% 阻止发布)、逐文件原子替换兼容产物、原子切换当前清单。内部同步读取不可变版本,不能读半成品;兼容公开路径是逐文件原子更新,不能声称整个目录跨请求具备全局事务原子性。 - 首次发布前自动保留将被替换的旧产物版本。默认不迁移/删除数据库或旧代码,回滚代码和订阅产物是两个独立动作。 - 原时刻调度保留:采集后 :06 准备并原生校验,:09 不再重复旧合并,:12 发布准备批次,:15 按原接口分发。来源必须属于本轮六小时采集周期,失败则不覆盖上一份产物;准备批次超过 30 分钟不可发布。超过 24 小时的批次不继续自动推送。 @@ -152,14 +152,24 @@ merge 下仍有旧命名目录,不能据目录名推断当前站点归属。fn `php tools/freenode/manage.php status` 只显示引擎、批次/hash 元数据;`prepare` 读取来源并在 `storage/app/freenode-v2/versions/` 生成私有候选,不分发;`publish` 校验哈希和时效后更新产物;`rollback RELEASE_ID` 恢复指定产物,省略 ID 时使用 previous。 -官方内核由 `python3 tools/freenode/install_validators.py` 安装到 `/opt/master01-freenode/bin/`,仅支持 Linux amd64,固定官方压缩包 SHA-256:Sing-box 1.14.3、Mihomo 1.19.32。不会改现有代理或系统服务。可通过 FREENODE_SINGBOX_BINARY/FREENODE_MIHOMO_BINARY 指向其他已核验版本。 +官方内核由 `python3 tools/freenode/install_validators.py` 安装到 `/opt/master01-freenode/bin/`,仅支持 Linux amd64,固定官方压缩包 SHA-256:Sing-box 1.14.3、Mihomo 1.19.32;另固定Country.mmdb和geoip.metadb的SHA-256,校验目录使用离线GeoIP数据,避免每批自动下载。GeoIP下载入口虽然是latest,内容哈希仍严格固定,日后变化会拒绝安装,需重新核实摘要。不会改现有代理或系统服务。可通过 FREENODE_SINGBOX_BINARY/FREENODE_MIHOMO_BINARY 指向其他已核验版本。 运行目录需由实际 PHP/调度身份可写。发布前记录旧 Git 提交、并行修改、当前引擎配置及兼容文件哈希。切回旧链路须先停止/避开本轮生成发布,在配置中恢复 `FREENODE_ENGINE=legacy`,清除相应配置缓存,再恢复保留的旧产物;仅回退 Git 不会自动撤回已分发到 Nodehub/各站的文件,必要时按原接口再次同步旧产物。不能声称本地恢复等于全部下游已回滚。 -本地验证命令:`TEST_SINGBOX=/path/to/sing-box TEST_MIHOMO=/path/to/mihomo php -d error_reporting=22527 vendor/bin/phpunit tests/Unit/Freenode --do-not-cache-result`。当前 14 项、32 断言通过,含真实原生内核检查、坏节点隔离、参数完整性、数量骤减保护、清单篡改拒绝及旧产物恢复。未安装原生内核时该集成测试会跳过,不能把跳过当作原生验收通过。 +本地验证命令:`TEST_SINGBOX=/path/to/sing-box TEST_MIHOMO=/path/to/mihomo php -d error_reporting=22527 vendor/bin/phpunit tests/Unit/Freenode --do-not-cache-result`。当前 15 项、36 断言通过,含真实原生内核检查、坏节点隔离、参数完整性、数量骤减保护、清单篡改拒绝及旧产物恢复。未安装原生内核时该集成测试会跳过,不能把跳过当作原生验收通过。 -尚未完成:服务器内真实输入影子生成、生产切换、线上产物回滚演练、Nodehub 接收及用户客户端更新验收。白色机实际连通测试服务不包含在本次生成链切换中,尚未部署。 +已完成:服务器内真实输入影子生成、生产切换、16文件旧产物恢复演练、Nodehub四站10文件落盘校验及实际PHP-FPM内部请求验收。尚未完成:用户具体GUI客户端更新、公网下载/CDN链路验收。白色机每日实际连通测试服务不包含在本次生成链切换中,尚未部署。 本机合成规模验证:2000 个虚构 URI 节点及 2000 个虚构 Clash 节点,各格式输出 2000 条,整批生成及原生检查约 1.081 秒,PHP 峰值 24 MiB,原生内核检查 6 次,实际节点联网测试 0 次。此结果只代表本机合成输入,不代表生产实测或联网测速性能。 -当前发布状态:本地代码已提交;Git 推送尚未执行,自动审批要求用户确认现有 Gitea 仓库 `https://gitea.tomshell.com.de/tom/dd.git` 的具体推送及后续部署授权。生产仍为旧版本。另一次将完整生产节点配置导出到本机临时目录的操作被自动审批拒绝,未执行;后续真实数据验证改为服务器内影子生成,仅回传脱敏统计,不绕过 Git 上传代码。待上述推送授权后继续服务器内验证、回滚演练和切换,不把本地测试写成已上线。 +### 2026-10-18 上线验收 + +- 用户明确授权向现有Gitea仓库推送并继续部署。功能代码提交为 `7f657cb01792d548fd0e2356b179e7345f79fb0d`;后续维护记录提交不改变生成逻辑。生产分支 `codex/freenode-v2`,旧代码基线 `ddf104f158f4d7da970bdc0c936e650864c1b6e9` 保留在master。上线前原有已删除/未跟踪内容及服务器Clash模板保留,不覆盖并行修改。 +- 当前 `.env` 已启用 `FREENODE_ENGINE=v2`;上线时配置缓存不存在,未清空其他缓存、未重启服务、未修改数据库/凭据/网络/反代。 +- 运行身份www-data;私有批次根 `storage/app/freenode-v2/`;独立校验器及离线数据 `/opt/master01-freenode/`。完整节点原文只在服务器内处理,不导出到本机或写入报告。 +- 当前批次 `20261018114313-fe0b943ad776`;URI 2009、Clash 1830、Sing-box 1848。准备16个文件(含base、_admin和各站版本),通过固定版本原生校验。输入2个来源,9条无效URI输入被隔离,Sing-box转换阶段36条不支持的协议/传输被排除,原生校验进一步隔离Sing-box 125、Clash 29条;各分类不能相加当作跨格式唯一坏节点数。 +- 本轮真实输入最终校验160次内核调用、106.03秒、GNU time最大RSS 86228 KiB(约84.2 MiB;不是整机总峰值,也不等于并发总和)。初版二分策略2076次调用,已优化;该真实输入性能优先于上文合成样本结果。没有逐节点联网或测速。 +- 回滚演练:发布候选→恢复旧产物→逐一确认16文件SHA-256与发布前完全一致→重新发布候选。旧产物版本 `legacy-20261018114425-50ee6b49` 保留。恢复点与引擎原值元数据位于 `/var/backups/master01-freenode-20261018/`。这是产物恢复演练,不声称演练过全部下游代码/业务回滚。 +- 已按现有API分发到独立项目 [Nodehub的唯一档案](/Users/hellcat/Documents/GemDocs/AI版/10-项目/nodehub.md)。接收方代码未改,仍返回旧isDone结果,不提供批次/hash ACK;本次在接收服务器只读校验真实落盘文件,四站10文件全部匹配。URI与Sing-box逐字节匹配;Clash经接收端既有首尾空白处理后匹配(末尾换行差异),不声称其原始字节hash相同。未额外手工验收fn_a旧直推接口。 +- 实际PHP-FPM Unix socket请求 `/sub/clashfreenode.com/{v2ray,clash,singbox}`:均200,无stderr,返回MIME分别text/plain、application/yaml、application/json,响应体SHA-256与当前批次全部一致。此为服务器内部请求,不冒充公网TLS、CDN或GUI导入验收。 +- 本机和生产Linux/PHP 8.4.23均通过15项、36断言测试,含实际固定内核。部署后的正常定时任务下一轮执行尚未等待观察;原有调度时刻未变。