### [AZhai‑Sub阿宅二级域名分发系统|轻量化全开源私有二级域名管理平台](https://8maoku.com/article/3296) **Published:** 2026-09-21T10:31:49 **Author:** zenghe **Excerpt:** 在站长运维场景当中,二级域名分配管理一直是比较高频的需求,很多人希望拥有类似 us.kg 的自建二级域名服务,… 在站长运维场景当中,二级域名分配管理一直是比较高频的需求,很多人希望拥有类似 us.kg 的自建二级域名服务,不用搭建复杂NS服务器,就可以对外分配、托管大量子域名资源。今天给大家分享一套轻量化全开源项目——**AZhai‑Sub阿宅二级域名管理器**,这套系统可以直接复用自己已有的主域名资源,实现二级域名自助申请、审核、解析管控、SSL证书一键申请等全套业务,非常适合个人站长、小团队搭建自用或者小规模对外提供二级域名服务。 和市面上许多二次修改、功能臃肿的域名分发程序不一样,AZhai‑Sub主打轻量化路线,代码开源透明,没有多余加密组件,不需要部署独立DNS Nameserver。只要你手上持有一个主域名,就可以开放用户申请子域名。举个简单例子:你的主域为xxx.com,普通用户提交申请 you.xxx.com,系统就可以接管 \*.you.xxx.com 全部泛子域名的解析管控工作,大幅降低自建二级域名平台的门槛。 ## 一、系统核心功能概览 ### 1、二级域名全生命周期管控 系统完整覆盖从用户提交申请、管理员后台审核,到域名启用、暂停、销毁回收的整套流程。普通用户在前台提交二级域名申请,由管理员进行人工审核,审核通过之后方可使用该子域名资源,避免域名资源被恶意占用。同时支持对已经分配出去的域名随时暂停或者恢复解析,方便处理违规、闲置域名。 ### 2、多类型DNS解析记录管理 内置解析管理面板,支持 A、AAAA、CNAME、TXT 主流解析记录类型,用户可以在权限范围内自由修改解析指向。需要注意,根域名TXT验证记录无法由普通用户直接添加,需要提交申请之后由管理员手动操作完成,兼顾灵活性与安全风险控制。解析配置修改完成后,系统会自动同步到对接的第三方DNS服务商,无需人工登录云厂商控制台操作。 ### 3、SSL证书自助申请,支持HTTPS访问 为了解决子域名HTTPS部署麻烦的痛点,AZhai‑Sub内置SSL证书申请模块。分配得到二级域名的用户,可以直接在面板内发起证书申请,给自己的子域名配置HTTPS加密访问,省去手动去证书平台申请、下载、部署的繁琐步骤,让分配出去的子域名开箱即可支持加密访问。 ### 4、多厂商DNS服务商对接 系统并不强制绑定某一家DNS平台,目前原生支持 Cloudflare、阿里云DNS、腾讯云DNS、华为云DNS、西部数码DNS等主流服务商,只需要填入对应平台API密钥即可完成对接。后续版本还会持续扩充更多DNS服务商适配,方便站长根据自身域名托管位置灵活选择后端解析源。 ### 5、完整后台管理与OAuth登录拓展 - 管理员后台:集中管控用户账号、域名资源池、DNS服务商接口、全部操作日志记录,所有变更行为留有日志便于追溯排查问题。 - 阿宅OAuth登录:支持对接阿宅OAuth2.0账号中心,开启之后用户可以直接使用阿宅账号一键登录系统,不用重复注册本地账号,适合多系统统一账号体系的场景。 - 在线升级功能:后台内置系统更新检测,一键获取新版本并且完成升级,不需要手动下载源码覆盖上传,降低后期维护成本。 ## 二、运行环境要求 项目技术栈采用PHP8 + MySQL8组合,对服务器配置要求并不苛刻,普通云服务器、虚拟主机基本都可以满足条件。只需要确保服务器PHP版本不低于PHP8,数据库使用MySQL8版本,做好网站伪静态配置,即可正常运行整套业务系统。因为不需要自建DNS服务,省去了搭建BIND等DNS服务程序的复杂操作,新手上手难度大大降低。 ## 三、简易安装部署步骤 **步骤1:上传源码包**,将完整项目文件上传至网站运行目录并且解压。 **步骤2:数据库初始化**,在MySQL中新建数据库,把项目包内 database.sql 文件导入数据库完成数据表初始化。 **步骤3:修改配置文件**,编辑 config.php 配置文件,填入数据库地址、账号、库名、密码;如果计划启用阿宅OAuth登录,在此处填写申请得到的OAuth密钥参数。 **步骤4:登录管理后台**,后台访问地址为 `你的域名/admin`。默认管理员账号:azhai,默认密码:azhai123。**强烈建议首次登录后立刻修改默认管理员密码,避免站点被入侵风险。** **步骤5:后续配置**,登录后台之后,添加对应的DNS服务商API信息,导入主域名资源池,配置完成就可以开放用户提交二级域名申请使用。需要升级系统直接在后台“系统更新”模块检测更新一键升级。 ## 四、适用使用场景 - 个人站长自用:给自己、团队小伙伴批量分配二级域名,统一管理解析,省去反复登录云DNS控制台。 - 小型服务搭建:搭建私有二级域名分发服务,对内小范围开放子域名申请。 - 项目开发测试环境:给测试项目、演示站点快速分配独立子域名,统一管控生命周期。 - 搭配其他程序联动:依托OAuth能力,可以和其他自研站点打通统一账号登录体系。 ## 五、项目优缺点总结 相比网上很多开心版、二开版二级域名分发源码,AZhai‑Sub最大亮点就是**轻量化、全开源、不用自建NS服务器**,部署简单,解析依托各大云厂商成熟DNS服务,解析稳定性有保障。整套系统聚焦二级域名分配与解析管理核心需求,没有堆砌无关臃肿的商城、财务模块,代码干净适合进一步二次开发定制。 同时也要客观说明,系统需要依赖第三方DNS服务商开放API接口完成解析同步,需要你自己持有可以正常解析的主域名资源;TXT根记录需要管理员人工介入审核添加,在部分特殊验证场景会多一步操作。 总体来看,如果想要低成本搭建一套私有化二级域名分发管理平台,又不想折腾复杂DNS服务部署,这套AZhai‑Sub是非常值得尝试的轻量化开源方案。![](https://www.q0di.top/wp-content/uploads/2026/09/b7f2b16560-scaled.png) /\* ============================================================================= \* 源码安全检测报告 · 展示样式 \* 说明:本文件同时供两处使用—— \* 1. 客户端运行时插件组件(node/client/components/0/index.js) \* 2. WordPress 服务端正文注入(wordpress/plugin.php 内联打印) \* 因此类名与结构必须保持一致,改这里就等于同时改两边。 \* 尺寸统一用 em,随模块缩放设置联动;颜色优先取 element-plus / 瓜奇主题变量, \* 并带固定色兜底,保证脱离主题也不花屏。不使用 color-mix 等新特性。 \* ========================================================================== \*/ .gqssr { --gqssr-primary: var(--el-color-primary, #00c29a); --gqssr-high: #e5484d; --gqssr-medium: #d98a00; --gqssr-low: #3b82f6; --gqssr-info: #8b8fa3; --gqssr-clean: #16a34a; --gqssr-line: var(--el-border-color, #e4e7ed); --gqssr-fg: var(--el-text-color-primary, #1f2329); --gqssr-fg-2: var(--el-text-color-regular, #4e5969); --gqssr-fg-3: var(--el-text-color-secondary, #86909c); --gqssr-bg: var(--el-bg-color, #ffffff); --gqssr-bg-2: var(--el-fill-color-light, #f7f8fa); --gqssr-code-bg: var(--el-fill-color, #f0f1f3); --gqssr-mono: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, "Liberation Mono", monospace; box-sizing: border-box; display: flex; flex-direction: column; gap: 1em; width: 100%; max-width: 100%; min-width: 0; font-size: 1em; line-height: 1.6; color: var(--gqssr-fg); } .gqssr \*, .gqssr \*::before, .gqssr \*::after { box-sizing: border-box; } /\* ---------------------------------------------------------------- 头部 \*/ .gqssr-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75em 1em; padding-bottom: 0.875em; border-bottom: 1px solid var(--gqssr-line); } .gqssr-head-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; flex: 1 1 16em; min-width: 0; } .gqssr-title { margin: 0; padding: 0; border: 0; font-size: 1.0625em; font-weight: 600; line-height: 1.4; color: var(--gqssr-fg); } .gqssr-badge { display: inline-flex; align-items: center; flex: 0 0 auto; padding: 0.125em 0.5em; border-radius: 0.375em; font-size: 0.75em; font-weight: 600; line-height: 1.7; white-space: nowrap; color: #fff; background: var(--gqssr-info); } .gqssr-badge--high { background: var(--gqssr-high); } .gqssr-badge--medium { background: #d98a00; color: #fff; } .gqssr-badge--low { background: var(--gqssr-low); } .gqssr-badge--info { background: var(--gqssr-info); } .gqssr-badge--clean { background: var(--gqssr-clean); } .gqssr-chip { display: inline-flex; align-items: center; gap: 0.25em; flex: 0 0 auto; padding: 0.125em 0.5em; border-radius: 0.375em; font-size: 0.75em; font-weight: 600; line-height: 1.7; color: var(--gqssr-primary); background: var(--el-color-primary-light-9, rgba(0, 194, 154, 0.12)); border: 1px solid var(--el-color-primary-light-7, rgba(0, 194, 154, 0.34)); } .gqssr-meta { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 0.375em 1em; font-size: 0.8125em; color: var(--gqssr-fg-3); min-width: 0; } .gqssr-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; } .gqssr-meta b { font-weight: 600; color: var(--gqssr-fg-2); } /\* ---------------------------------------------------------------- 评分环 \*/ .gqssr-score { position: relative; flex: 0 0 auto; width: 4.5em; height: 4.5em; } .gqssr-score svg { display: block; width: 100%; height: 100%; transform: rotate(-90deg); } .gqssr-score .gqssr-ring-bg { fill: none; stroke: var(--el-fill-color, #eff0f1); stroke-width: 7; } .gqssr-score .gqssr-ring-fg { fill: none; stroke: var(--gqssr-info); stroke-width: 7; stroke-linecap: round; } .gqssr-score-inner { position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; } .gqssr-score-num { font-size: 1.375em; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--gqssr-fg); } .gqssr-score-unit { margin-top: 0.125em; font-size: 0.625em; color: var(--gqssr-fg-3); } .gqssr\[data-level="high"\] .gqssr-ring-fg { stroke: var(--gqssr-high); } .gqssr\[data-level="medium"\] .gqssr-ring-fg { stroke: var(--gqssr-medium); } .gqssr\[data-level="low"\] .gqssr-ring-fg { stroke: var(--gqssr-low); } .gqssr\[data-level="info"\] .gqssr-ring-fg { stroke: var(--gqssr-info); } .gqssr\[data-level="clean"\] .gqssr-ring-fg { stroke: var(--gqssr-clean); } /\* ---------------------------------------------------------------- 概览统计 \*/ .gqssr-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5em; } .gqssr-stat { display: flex; flex-direction: column; align-items: center; gap: 0.125em; padding: 0.625em 0.25em; border-radius: 0.5em; background: var(--gqssr-bg-2); border: 1px solid var(--gqssr-line); min-width: 0; } .gqssr-stat-num { font-size: 1.125em; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.2; } .gqssr-stat-label { font-size: 0.75em; color: var(--gqssr-fg-3); white-space: nowrap; } .gqssr-stat--high { border-color: rgba(229, 72, 77, 0.32); } .gqssr-stat--high .gqssr-stat-num { color: var(--gqssr-high); } .gqssr-stat--medium { border-color: rgba(217, 138, 0, 0.34); } .gqssr-stat--medium .gqssr-stat-num { color: var(--gqssr-medium); } .gqssr-stat--low { border-color: rgba(59, 130, 246, 0.32); } .gqssr-stat--low .gqssr-stat-num { color: var(--gqssr-low); } .gqssr-stat--info .gqssr-stat-num { color: var(--gqssr-info); } .gqssr-struct { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375em 0.75em; font-size: 0.8125em; color: var(--gqssr-fg-3); } .gqssr-struct b { font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-struct-label { font-weight: 600; color: var(--gqssr-fg-2); } /\* ---------------------------------------------------------------- 命中明细 \*/ .gqssr-findings { display: flex; flex-direction: column; gap: 0.5em; min-width: 0; } .gqssr-findings-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.625em; font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-findings-head em { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } /\* 区块标题:命中明细与后门特征排查共用(.gqssr-findings-head 是旧类名,保留兼容) \*/ .gqssr-sec-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.625em; font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-sec-head em { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } /\* ---------------------------------------------------------------- 按类别 \*/ /\* 把「风险项(参与评分)」与「加固建议 / 来源情报(不扣分)」分开摆, 报告读起来才是客观的 —— 后者不是缺陷,混在一起会让人以为问题很多。 \*/ .gqssr-cats { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375em 0.625em; font-size: 0.8125em; } .gqssr-cats-label { font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-cats-list { display: flex; flex-wrap: wrap; gap: 0.375em; min-width: 0; } .gqssr-cat { display: inline-flex; align-items: baseline; gap: 0.25em; padding: 0.125em 0.5em; border-radius: 0.375em; background: var(--gqssr-bg-2); border: 1px solid var(--gqssr-line); color: var(--gqssr-fg-2); white-space: nowrap; } .gqssr-cat b { font-weight: 700; font-variant-numeric: tabular-nums; } .gqssr-cat i { font-style: normal; font-size: 0.875em; color: var(--gqssr-fg-3); } .gqssr-cat--risk { border-color: rgba(229, 72, 77, 0.32); } .gqssr-cat--risk b { color: var(--gqssr-high); } .gqssr-cat--harden { border-color: rgba(217, 138, 0, 0.34); } .gqssr-cat--harden b { color: var(--gqssr-medium); } .gqssr-cat--intel { border-color: rgba(139, 143, 163, 0.34); } .gqssr-cat--intel b { color: var(--gqssr-info); } .gqssr-cat-groups { display: flex; flex-direction: column; gap: 0.75em; min-width: 0; } .gqssr-cat-group { display: flex; flex-direction: column; gap: 0.375em; min-width: 0; } .gqssr-cat-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.5em; font-size: 0.8125em; font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-cat-group-head i { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } .gqssr-cat-group--risk .gqssr-cat-group-head span { color: var(--gqssr-high); } .gqssr-cat-group--harden .gqssr-cat-group-head span { color: var(--gqssr-medium); } .gqssr-cat-group--intel .gqssr-cat-group-head span { color: var(--gqssr-info); } /\* ---------------------------------------------------------------- 后门特征排查 \*/ /\* 未命中项也要逐条写出来:只列命中项的报告,读的人无法分辨 是「查过没发现」还是「压根没查」。 \*/ .gqssr-backdoor { display: flex; flex-direction: column; gap: 0.5em; min-width: 0; } .gqssr-bd-list { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.375em 0.625em; } .gqssr-bd-item { display: flex; align-items: center; gap: 0.375em; padding: 0.375em 0.5em; border-radius: 0.375em; background: var(--gqssr-bg-2); border: 1px solid transparent; font-size: 0.8125em; min-width: 0; } .gqssr-bd-item--clear { border-color: rgba(22, 163, 74, 0.22); } .gqssr-bd-item--hit { border-color: rgba(229, 72, 77, 0.38); background: rgba(229, 72, 77, 0.07); } .gqssr-bd-mark { flex: 0 0 auto; width: 1.125em; height: 1.125em; fill: none; stroke: var(--gqssr-clean); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; } .gqssr-bd-mark path:first-child { fill: rgba(22, 163, 74, 0.14); } .gqssr-bd-item--hit .gqssr-bd-mark { stroke: var(--gqssr-high); } .gqssr-bd-item--hit .gqssr-bd-mark path:first-child { fill: rgba(229, 72, 77, 0.14); } .gqssr-bd-title { flex: 1 1 auto; min-width: 0; color: var(--gqssr-fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .gqssr-bd-state { flex: 0 0 auto; font-style: normal; font-size: 0.875em; color: var(--gqssr-clean); } .gqssr-bd-item--hit .gqssr-bd-state { color: var(--gqssr-high); font-weight: 600; } /\* 评分口径说明 \*/ .gqssr-basis { margin: 0; font-size: 0.75em; line-height: 1.6; color: var(--gqssr-fg-3); } .gqssr-hit-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.5em; } .gqssr-hit { position: relative; margin: 0; padding: 0.625em 0.75em 0.625em 1.125em; border-radius: 0.5em; background: var(--gqssr-bg-2); list-style: none; min-width: 0; overflow: hidden; } .gqssr-hit::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 3px; background: var(--gqssr-info); } .gqssr-hit--high::before { background: var(--gqssr-high); } .gqssr-hit--medium::before { background: var(--gqssr-medium); } .gqssr-hit--low::before { background: var(--gqssr-low); } .gqssr-hit--info::before { background: var(--gqssr-info); } .gqssr-hit-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25em 0.5em; min-width: 0; } .gqssr-hit-head strong { font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-hit-head code { font-family: var(--gqssr-mono); font-size: 0.75em; padding: 0.0625em 0.375em; border-radius: 0.25em; color: var(--gqssr-fg-2); background: var(--gqssr-code-bg); word-break: break-all; } .gqssr-tag { font-size: 0.6875em; font-weight: 600; padding: 0.0625em 0.375em; border-radius: 0.25em; color: var(--gqssr-high); background: rgba(229, 72, 77, 0.12); } .gqssr-hit-desc { margin: 0.25em 0 0; font-size: 0.8125em; color: var(--gqssr-fg-2); } .gqssr-hit-code { display: block; margin: 0.375em 0 0; padding: 0.375em 0.5em; border-radius: 0.375em; background: var(--gqssr-code-bg); font-family: var(--gqssr-mono); font-size: 0.75em; line-height: 1.5; color: var(--gqssr-fg-2); white-space: pre-wrap; word-break: break-all; overflow-x: auto; max-width: 100%; } .gqssr-hit-fix { margin: 0.375em 0 0; font-size: 0.8125em; color: var(--gqssr-fg-2); } .gqssr-hit-fix b { font-weight: 600; color: var(--gqssr-primary); } /\* ---------------------------------------------------------------- 页脚 \*/ .gqssr-foot { font-size: 0.75em; line-height: 1.6; color: var(--gqssr-fg-3); padding-top: 0.75em; border-top: 1px dashed var(--gqssr-line); } /\* ---------------------------------------------------------------- 窄屏 \*/ @media (max-width: 767px) { .gqssr-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } .gqssr-head { flex-direction: column; } .gqssr-score { align-self: flex-start; } /\* 窄屏下后门排查改成单列,8 项不至于挤成两行小字 \*/ .gqssr-bd-list { grid-template-columns: minmax(0, 1fr); } } 安全 ### 源码安全检测报告 已检测 80/100 检测引擎 **srcscan/1.3**报告编号 **SC-20260921-3076D2**检测时间 **2026-09-21 20:49:45**内容发布 **2026-09-21 18:31:49**AZhai‑Sub阿宅二级域名分发系统|轻量化全开源私有二级域名管理平台 2高危 10中危 3低危 5提示 结构概览文件 **63**体积 **21.4 MB**代码文件 **51**代码行 **27,573**含授权文件 按类别风险项 **4**_参与评分_部署加固建议 **3**_不扣分_来源情报 **3**_不扣分_ 后门特征排查_8 项特征全部未发现_ - 请求参数直接进入执行函数_未发现_ - 请求参数直接进入文件包含_未发现_ - 变量函数执行请求参数_未发现_ - 请求参数批量覆盖变量_未发现_ - 编码载荷后执行(混淆特征)_未发现_ - 回连裸 IP 地址_未发现_ - 配置预加载文件(隐蔽后门手法)_未发现_ - 向文件写入 PHP 代码_未发现_ 命中明细_共 20 项__仅展示前 12 项_ 风险项_参与评分_ - **远程升级 / 授权下发地址**`config.php:44` 配置中声明了远程检查更新或下载升级包的地址。若同时存在「下载 → 解压 → 覆盖站点文件」的逻辑,则厂商(或劫持该域名的人)可随时向你的站点写入任意 PHP 文件,属于可远程控制的交付通道。 ``` 'check_url' => 'https://update.azhai.de/api/check.php', ← 与「远程下发并覆盖站点文件」同源,仅作线索保留 ``` **建议:**核实域名归属:是不是作者自有域名?不是自有域名的升级/授权地址要特别警惕,建议直接移除或改成本地升级。 - **远程升级 / 授权下发地址**`config.php:46` 配置中声明了远程检查更新或下载升级包的地址。若同时存在「下载 → 解压 → 覆盖站点文件」的逻辑,则厂商(或劫持该域名的人)可随时向你的站点写入任意 PHP 文件,属于可远程控制的交付通道。 ``` 'download_url' => 'https://update.azhai.de/api/download.php', ← 与「远程下发并覆盖站点文件」同源,仅作线索保留 ``` **建议:**核实域名归属:是不是作者自有域名?不是自有域名的升级/授权地址要特别警惕,建议直接移除或改成本地升级。 - **硬编码的长令牌 / 密钥**`config.php:48` 配置里直接写入 32 位以上的真实令牌(非 CHANGE\_THIS 占位符)。这类凭据会随源码包一起分发,所有拿到包的人都持有同一枚密钥,等于共享口令;若厂商服务端做校验,还存在被冒用的风险。 ``` 'token' => 'a3896c4716bb19974e5f7563fbe1efe3095fe473f77a9ac365fadde289d31dad', ``` **建议:**把令牌移到配置项或环境变量里,并且立刻轮换这个已经外泄的值。 - **远程升级 / 授权下发地址**`config.php:62` 配置中声明了远程检查更新或下载升级包的地址。若同时存在「下载 → 解压 → 覆盖站点文件」的逻辑,则厂商(或劫持该域名的人)可随时向你的站点写入任意 PHP 文件,属于可远程控制的交付通道。 ``` 'authorize_url' => 'https://oauth.azhai.de/authorize.php', ← 与「远程下发并覆盖站点文件」同源,仅作线索保留 ``` **建议:**核实域名归属:是不是作者自有域名?不是自有域名的升级/授权地址要特别警惕,建议直接移除或改成本地升级。 - **X-Forwarded-For 无条件覆盖客户端 IP**`includes\database.php:46` 直接用 X-Forwarded-For 覆盖 REMOTE\_ADDR 且未校验来源是否为可信代理。该请求头由客户端自行发送、可任意伪造,会导致:IP 黑名单 / 限流被绕过、操作日志记录的 IP 全部失真(出事后无法溯源)。若站点确实在反向代理后,必须把代理 IP 列入白名单后再信任该头。 ``` $_SERVER['REMOTE_ADDR'] = trim($get_HTTP_X_FORWARDED_FOR[0]); ``` **建议:**只在明确可信的反向代理之后才解析 X-Forwarded-For,并且取最后一段可信 IP;其余情况一律用 REMOTE\_ADDR。 - **远程下发并覆盖站点文件(可远程控制通道)**`includes\updater.php:25` 该文件同时具备:从远程地址下载内容 + 解压/写入 + 覆盖站点目录。这构成一条厂商(或劫持者)可随时向你站点写入任意代码的通道。若下载内容未强制校验签名/哈希,风险等同预留后门;即便有哈希,也应视为「厂商保留的远程控制能力」并明确告知买家。 ``` 下载远程包 + ZipArchive 解压 + 覆盖 dirname(__DIR__) 站点目录 ``` **建议:**这是可远程控制站点文件的通道,强烈建议整段移除。短期无法移除时,至少加上下载包签名校验与下载域名白名单,并且不要覆盖站点根目录。 部署加固建议_不扣分_ - **疑似硬编码凭据**`config.php:33` 源码里写死的密码、密钥或令牌。买家拿到包就等于拿到凭据,建议改为配置文件并提示用户修改。 ``` 'app_key' => 'CHANGE_THIS_TO_A_RANDOM_64_CHARACTER_SECRET', ``` **建议:**先确认是不是占位符(例如 CHANGE\_THIS…)。如果是真实凭据,移出代码库并轮换;如果是示例值,注释里写明。 - **疑似硬编码凭据**`config.php:60` 源码里写死的密码、密钥或令牌。买家拿到包就等于拿到凭据,建议改为配置文件并提示用户修改。 ``` 'client_secret' => '去oauth.azhai.de申请阿宅登录', ``` **建议:**先确认是不是占位符(例如 CHANGE\_THIS…)。如果是真实凭据,移出代码库并轮换;如果是示例值,注释里写明。 - **数据库脚本内置默认管理员账号**`database.sql:42` 随包分发的 SQL 里带着可直接登录的后台管理员密码哈希。若安装后不修改,任何人都能用公开的默认口令进入后台,等于把后台交出去。 ``` INSERT INTO admin_users ... VALUES (... $2y$12$.rDJaZB3X0AyGOrhB0nMv.U.2Tu17Oj6zAxWKnM5IX3YuPmw0CW6G ...) ``` **建议:**删掉 SQL 里内置的默认管理员账号与密码哈希,改成安装时强制设置管理员。默认账号是被人拿着现成密码直接进后台的入口。 - **文件扩展名与实际内容不符**`assets\img\bg.jpg:1` 扩展名与文件真实格式不一致。多数情况只是命名不规范,但也可能是伪装——例如把脚本改名成图片以躲过检测。此处需确认该文件确实可正常解析。 ``` 扩展名 .jpg 但实际是 .png ``` **建议:**把文件扩展名改成与真实内容一致。扩展名与内容不符会绕过基于后缀的校验,也可能让服务器按错误类型解析。 来源情报_不扣分_ - **解码 / 解压函数**`includes\functions.php:186` 编码本身是中性的(缓存、序列化、压缩、XML-RPC 都会用),但与 eval 相邻时风险陡增。本项仅提示,需结合上下文判断。 ``` $raw = base64_decode( ``` **建议:**确认解码/解压的数据来源可信;尤其不要和 eval 之类组合出现,组合起来就是混淆执行。 - **解码 / 解压函数**`includes\dns\DnsManager.php:3450` 编码本身是中性的(缓存、序列化、压缩、XML-RPC 都会用),但与 eval 相邻时风险陡增。本项仅提示,需结合上下文判断。 ``` base64_decode( ``` **建议:**确认解码/解压的数据来源可信;尤其不要和 eval 之类组合出现,组合起来就是混淆执行。 本报告由 8号码库源码安全检测引擎(srcscan)静态扫描生成,用于上架前风险筛查,不构成安全保证。 **Tags:** 二级域名分发, 域名分发系统 **Categories:** PHP 源码, 源码下载 ---