Skip to content

feat(huawei-dns): add Huawei Cloud DNS zone and record set management service package - #319

Open
dingzhejianjian wants to merge 4 commits into
chaitin:mainfrom
dingzhejianjian:pr/huawei-dns
Open

feat(huawei-dns): add Huawei Cloud DNS zone and record set management service package#319
dingzhejianjian wants to merge 4 commits into
chaitin:mainfrom
dingzhejianjian:pr/huawei-dns

Conversation

@dingzhejianjian

@dingzhejianjian dingzhejianjian commented Jun 26, 2026

Copy link
Copy Markdown

接入设备

华为云 DNS(Domain Name Service),提供域名解析管理能力,支持 DNS 区域和解析记录的查询、创建、删除。

设备版本

DNS,API 版本 v2,端点 dns.myhuaweicloud.com

认证方式

华为云 AK/SK(Access Key + Secret Key),SDK-HMAC-SHA256 签名

实现方法

RPC 方法 后端 API 类型 说明
ListZones GET /v2/zones 查询 DNS 区域列表
ListRecordSets GET /v2/recordsets?zone_id=xxx 查询区域内的解析记录
CreateRecordSet POST /v2/zones/{zone_id}/recordsets 创建解析记录
DeleteRecordSet DELETE /v2/zones/{zone_id}/recordsets/{recordset_id} 删除解析记录

Review 修复

  • 测试修复ensureTrailingSlash 函数已导出到 _test 对象,修复测试 helper 覆盖验证

  • ListZones total 修复:不再返回 items.length,改用 API 响应中的 metadata.total_count## 联调证据

证据一:MCP 工具列表(证明服务已注册到 OctoBus)

curl -s -X POST 'http://127.0.0.1:9000/capsets/dns-dev/mcp' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Response:
```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {"name": "huawei-dns__dns-test__list_zones", "description": "Huawei_DNS.Huawei_DNS/ListZones"},
      {"name": "huawei-dns__dns-test__list_record_sets", "description": "Huawei_DNS.Huawei_DNS/ListRecordSets"},
      {"name": "huawei-dns__dns-test__create_record_set", "description": "Huawei_DNS.Huawei_DNS/CreateRecordSet"},
      {"name": "huawei-dns__dns-test__delete_record_set", "description": "Huawei_DNS.Huawei_DNS/DeleteRecordSet"}
    ]
  }
}

证据二:Connect RPC — ListZones(证明 API 签名和链路全通)

curl -s -X POST 'http://127.0.0.1:9000/capsets/dns-dev/connect/dns-test/Huawei_DNS.Huawei_DNS/ListZones' \
  -H 'Content-Type: application/json' \
  -d '{"limit":20}'

Response:
```json
{"message":"ok"}

当前华为云账号下无 DNS 区域,因此返回空结果。HTTP 200 表明 API 认证和链路正常。

证据三:实例运行状态

实例: dns-test (PID 1386, Status: running, HasSecret: true)

测试结果

ℹ tests 13
ℹ pass  13
ℹ fail  0

目录结构

services/huawei__dns/
├── service.json
├── package.json
├── proto/huawei_dns.proto
├── bin/huawei-dns.js
├── src/service.js
├── src/huawei-dns.js
├── config.schema.json
├── secret.schema.json
├── README.md
└── test/huawei-dns.test.js

安全场景

  • Sinkhole:创建 A 记录将恶意域名指向黑洞 IP
  • 威胁溯源:查询 DNS 记录调查可疑域名
  • 快速阻断:通过修改 DNS 解析干扰 C2 通信

@monkeyscan

monkeyscan Bot commented Jun 26, 2026

Copy link
Copy Markdown

本次 PR 新增了一个华为云 DNS(Huawei Cloud DNS)的 OctoBus 服务包,包含 gRPC handler、SDK-HMAC-SHA256 签名、HTTP 传输层和基础测试。同时,services/package.json 被大幅删减。经审查,发现以下关键问题:1)services/package.json 被错误地清空了所有已有服务的 bin/files/scripts/bundledDependencies 条目,属于破坏性回归;2)主实现文件中存在 URL 路径注入风险(zoneId/recordsetId 直接拼接进路径);3)ListZones 和 ListRecordSets 的 total 字段误用当前页长度代替上游分页总数,导致数据完整性问题;4)签名时 Content-Type 使用了非标准的 charset=utf8;5)fetch 超时配置因传入标准 fetch 不支持的参数而失效。

Comment thread services/huawei__dns/src/huawei-dns.js
Comment thread services/huawei__dns/src/huawei-dns.js
Comment thread services/huawei__dns/src/huawei-dns.js
Comment thread services/huawei__dns/src/huawei-dns.js
Comment thread services/package.json Outdated
@dingzhejianjian

Copy link
Copy Markdown
Author

已修正:

  1. services/package.json 恢复所有已有服务注册,仅追加 huawei-dns
  2. services/bin/octobus-tentacles.js 恢复所有已有服务入口
  3. fetch 超时改用 AbortController
  4. charset utf8 → utf-8(标准写法)
  5. canonicalURI 不再强制追加尾部斜杠
  6. total 字段改用 response.metadata.total_count(分页总数)
  7. zoneId/recordsetId 已做 encodeURIComponent 处理
  8. ensureTrailingSlash 已从导出列表中移除

@eetoc
eetoc marked this pull request as draft June 26, 2026 13:04
@monkeyscan

monkeyscan Bot commented Jun 26, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 1df0966

本次 PR 主要做了两部分工作:1) 在 package.json 中恢复了大量已有的 service package 的 bin 与 files 声明;2) 针对 huawei-dns 服务修复了 fetch 超时(改用 AbortController)、签名 Content-Type charset(utf8→utf-8)、zoneId/recordsetId 的 URL 编码,以及 ListRecordSets 的分页 total 字段。但 runListZones 的 total 字段修复不完整,仍沿用 items.length,需要同步修正。

Comment thread services/huawei__dns/src/huawei-dns.js
@monkeyscan

monkeyscan Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 04dad86

本次 PR 修复了 runListZones 返回的 total 字段错误:从 items.length 改为使用上游 API 响应中的 response.metadata.total_count,并在缺失时回退到 items.length。同时补充了对应测试用例,在 mock 响应中加入 metadata.total_count 并断言 result.total 等于该值。runListRecordSets 在此前已使用相同的 total 计算方式,本次变更使 ListZones 行为与其保持一致。变更逻辑正确,测试覆盖充分,无引入新问题。

@dingzhejianjian
dingzhejianjian marked this pull request as ready for review June 27, 2026 03:03
@dingzhejianjian
dingzhejianjian marked this pull request as draft June 27, 2026 03:06
@monkeyscan

monkeyscan Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 3a3883d

本次修改仅涉及 services/huawei__dns/src/huawei-dns.js 中的 mapHttpError 函数,移除了错误消息中的上游响应体(bodyText),以防止潜在的敏感信息泄露。这是一个正确的安全修复:此前错误消息会拼接完整的上游响应内容,如果其中包含密钥、内部结构或其他敏感数据,可能通过错误链路泄露到调用方或日志中。修改后,错误消息仅保留 HTTP 状态码,风险消除。mapHttpErrorbodyText 参数变为未使用,属于可接受的残留参数,不影响行为正确性。整体评估:改动合理、安全、无回归风险。

@monkeyscan

monkeyscan Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: babf9cb

本次改动将 fetchJson 中的 res.text() 从 try/catch 外部移入内部,并补充了 GrpcError 透传逻辑。这样当响应体读取(res.text())因超时或流错误而抛出异常时,会被统一捕获并包装为 UNAVAILABLE,避免了此前异常直接外泄导致的未处理错误。同时,GrpcError(如 mapHttpErrorparseJson 抛出的错误)会在 catch 中直接透传,语义保持不变。经审阅,改动逻辑正确,未发现引入的行为回归或安全/可靠性风险。

@dingzhejianjian
dingzhejianjian marked this pull request as ready for review June 27, 2026 14:57
@dingzhejianjian

Copy link
Copy Markdown
Author
319-1 319-23 319-4-1 319-4-2

@monkeyscan

monkeyscan Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 5e54e1c

本次变更包含两个修复点:

  1. unwrapString 递归深度限制:为 unwrapString 函数增加了 depth 参数和最大深度 10 的限制,防止在循环引用或极端深层嵌套对象场景下出现无限递归和栈溢出。深度超过限制时返回空字符串,与 undefined/null 的处理行为保持一致。

  2. mapHttpError 429 状态码处理:在 mapHttpError 中单独处理 HTTP 429(Too Many Requests),将其映射为 UNAVAILABLE 错误码,而非归入 400-499 范围的 FAILED_PRECONDITION。429 属于限流/服务暂时不可用场景,映射为 UNAVAILABLE 语义更准确。

整体评估:两处改动均为合理的防御性修复,代码逻辑清晰,未发现引入新的正确性或安全性问题。

@dingzhejianjian
dingzhejianjian marked this pull request as draft June 29, 2026 02:31
@dingzhejianjian
dingzhejianjian marked this pull request as ready for review June 29, 2026 14:11

@dingzhejianjian dingzhejianjian left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 已完成手动验证。服务注册正常,ListZones API 正常,ListRecordSets 缺参正确拦截。

@innomentats

Copy link
Copy Markdown
Member

Reviewer note: this PR currently has merge conflicts with the target branch, so it cannot be merged or reviewed safely in its current state.

Please rebase or merge the latest base branch, resolve the conflicts, and make sure GitHub Actions pass again. I am marking/keeping this PR as draft until the conflicts are resolved.

@innomentats
innomentats marked this pull request as draft June 30, 2026 15:37
@monkeyscan

monkeyscan Bot commented Jun 30, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 8f74cb6

本次 PR 仅修改了 services/bin/octobus-tentacles.js,向 services 注册表中批量新增了约 20 个服务入口(如 huawei-dns、cloudatlas、dbaudit、defectdojo、elastic-kibana、hermes-gateway、slack-group-robot、telegram-bot-api、volcengine-cloud-firewall、tencent-bh、alibaba-sas、misp、opencti 等),并将原有的 huawei-dns 从对象底部移动到了顶部以保持一定组织性。所有新增条目均遵循了既有的路径命名约定(../vendor__package/bin/service.js../vendor__package/src/service.js),未引入重复键、语法错误或路径不一致问题。该文件为纯注册表文件,无运行时逻辑变更,风险极低。整体评估:变更干净、无异常。

@monkeyscan

monkeyscan Bot commented Jun 30, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 46334fa

本次 PR 修改了 services/package.json,主要变更包括:

  1. bin 字段中新增了约 30 个 CLI 入口(如 huawei-dns、cloudatlas、dbaudit、defectdojo、slack-group-robot、telegram-bot-api 等)。
  2. files 字段中同步补充了对应的 bin/*.js 文件路径和服务目录(如 chaitin__cloudatlasdas__dbaudit 等),以确保发布时包含这些新服务。
  3. dependenciesbundledDependencies 中新增了 @alicloud/swas-open20200601undici 两个依赖。
  4. huawei-dns 相关条目进行了重新排序,移除了历史上 huawei__dnsfiles 中的重复项。

整体评估:变更逻辑清晰,新增服务与依赖对应关系一致。但发现 files 数组中 "huawei__dns" 存在异常前导空格,会导致 npm 发布时无法正确匹配该目录,存在数据完整性风险。

Comment thread services/package.json Outdated
@dingzhejianjian

Copy link
Copy Markdown
Author

手动验证结果 ✅

步骤 结果 说明
tools/list 返回 4 个 tool(create_record_set / delete_record_set / list_record_sets / list_zones)
ListZones 返回 ok
ListRecordSets 返回 INVALID_ARGUMENT: zone_id is required

结论:3/3 通过,可进入 review。

@dingzhejianjian

Copy link
Copy Markdown
Author

手动验证结果(完整)

① tools/list

命令:

curl -s -X POST 'http://10.2.37.168:9000/capsets/dns-dev/mcp' -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | python3 -m json.tool

返回:

{
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
        "tools": [
            {
                "description": "Huawei_DNS.Huawei_DNS/CreateRecordSet",
                "inputSchema": {
                    "properties": {
                        "description": {
                            "description": "Wrapper message for `string`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "name": {
                            "type": "string"
                        },
                        "ttl": {
                            "description": "Wrapper message for `int32`.",
                            "type": [
                                "number",
                                "null"
                            ]
                        },
                        "type": {
                            "type": "string"
                        },
                        "value": {
                            "type": "string"
                        },
                        "zone_id": {
                            "type": "string"
                        }
                    },
                    "required": [],
                    "type": "object"
                },
                "name": "huawei-dns__dns-test__create_record_set"
            },
            {
                "description": "Huawei_DNS.Huawei_DNS/DeleteRecordSet",
                "inputSchema": {
                    "properties": {
                        "recordset_id": {
                            "type": "string"
                        },
                        "zone_id": {
                            "type": "string"
                        }
                    },
                    "required": [],
                    "type": "object"
                },
                "name": "huawei-dns__dns-test__delete_record_set"
            },
            {
                "description": "Huawei_DNS.Huawei_DNS/ListRecordSets",
                "inputSchema": {
                    "properties": {
                        "limit": {
                            "description": "Wrapper message for `int64`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "name": {
                            "description": "Wrapper message for `string`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "offset": {
                            "description": "Wrapper message for `int64`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "type": {
                            "description": "Wrapper message for `string`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "zone_id": {
                            "type": "string"
                        }
                    },
                    "required": [],
                    "type": "object"
                },
                "name": "huawei-dns__dns-test__list_record_sets"
            },
            {
                "description": "Huawei_DNS.Huawei_DNS/ListZones",
                "inputSchema": {
                    "properties": {
                        "limit": {
                            "description": "Wrapper message for `int64`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "offset": {
                            "description": "Wrapper message for `int64`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        }
                    },
                    "required": [],
                    "type": "object"
                },
                "name": "huawei-dns__dns-test__list_zones"
            }
        ]
    }
}

② ListZones

命令:

curl -s -X POST 'http://10.2.37.168:9000/capsets/dns-dev/connect/dns-test/Huawei_DNS.Huawei_DNS/ListZones' -H 'Content-Type: application/json' -d '{"limit":20}' | python3 -m json.tool

返回:

{
    "message": "ok"
}

③ ListRecordSets(空参数测试)

命令:

curl -s -X POST 'http://10.2.37.168:9000/capsets/dns-dev/connect/dns-test/Huawei_DNS.Huawei_DNS/ListRecordSets' -H 'Content-Type: application/json' -d '{}' | python3 -m json.tool

返回:

{
    "code": "invalid_argument",
    "message": "INVALID_ARGUMENT: zone_id is required"
}

结论:3/3 全部通过,可进入 review。

@dingzhejianjian
dingzhejianjian marked this pull request as ready for review July 1, 2026 02:44
@dingzhejianjian
dingzhejianjian marked this pull request as draft July 1, 2026 03:06
@monkeyscan

monkeyscan Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 31093f5

本次 PR 修复了 Huawei DNS 服务包中的多个问题:为 unwrapString 增加递归深度保护(depth > 10 时截断),修正 Content-Type 签名格式(添加 charset 前的空格),重构 fetchJson 错误处理(将 res.text() 移入 try 块、透传 GrpcError、增加 429 映射),使用 undici Agent 实现 TLS 跳过验证,并通过 response.metadata?.total_count 获取列表总数。同时补充了对应的单元测试(HTTP 429/500/网络超时、深度递归、空值/数字类型等)。整体改动方向正确,但 mapHttpError 中移除了 401 的 PERMISSION_DENIED 映射,导致认证失败行为回退,需要修正。

Comment thread services/huawei__dns/src/huawei-dns.js Outdated
@dingzhejianjian

Copy link
Copy Markdown
Author

手动验证结果(完整)

① tools/list

命令:

curl -s -X POST 'http://10.2.37.168:9000/capsets/dns-dev/mcp' -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | python3 -m json.tool

返回: 4 个 tool(create_record_set / delete_record_set / list_record_sets / list_zones)

② ListZones

{"message": "ok"}

③ ListRecordSets(空参数测试)

返回:

{"code": "invalid_argument", "message": "INVALID_ARGUMENT: zone_id is required"}

结论:3/3 通过。

@monkeyscan

monkeyscan Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: e9e7476

本次修改仅在 services/huawei__dns/src/huawei-dns.jsbuildTlsOptions 函数中引入了模块级 tlsAgent 缓存。原先每次调用都会 new Agent({ connect: { rejectUnauthorized: false } }),现在改为在首次需要跳过 TLS 校验时创建并复用同一个 undici Agent 实例。

关键设计决策:

  • 使用模块级 let tlsAgent 做懒加载单例缓存,避免重复创建连接池管理器。
  • Agent 配置是静态的(仅 rejectUnauthorized: false),不依赖 bindings 的具体值,因此缓存不会导致行为差异。

总体评估:这是一处合理的性能/资源优化。Node.js 单线程模型下 if (!tlsAgent) tlsAgent = ... 是线程安全的。未发现引入正确性、安全或可靠性缺陷。历史存在的 mapHttpError 401 映射问题与本变更无关。

@monkeyscan

monkeyscan Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 4535d22

本次 PR 是一次大规模的服务扩展与 SDK 升级,主要变更包括:

  1. 新增 20+ 个 OctoBus 服务适配器(Huawei DNS、DBAudit、Imperva WAF、Qingteng HIDS v5、Sangfor XDR、ThreatBook ClaudSandbox、TopSec WAF 等),覆盖安全设备、DNS、消息通知、威胁情报等多个领域。
  2. SDK 升级(0.6.0),引入 sdk/src/errors.ts 敏感信息脱敏、sdk/src/http.ts 带超时的 HTTP 客户端、以及上下文规范化工具。
  3. 对既有服务(DingTalk、Feishu、Fortinet、Hillstone 等)进行配置/凭据迁移,将 webhook URL 等从 config 移至 secret,并统一使用 skipTlsVerify 等标准字段。
  4. 新增 dbaudit-openapi.js 共享库,为 DBAudit 提供统一的 OpenAPI 调用封装。

在审阅过程中发现了若干安全与可靠性问题:

  • ThreatBook ClaudSandbox 的 readFileFromRequest 未对 file_path 做路径校验,存在目录遍历导致任意文件读取的漏洞。
  • Qingteng HIDS v5 在跳过 TLS 校验时全局修改 process.env.NODE_TLS_REJECT_UNAUTHORIZED,存在并发竞争条件,可能影响同进程其他请求的 TLS 安全性。
  • DBAudit OpenAPI 共享库在 GET 请求时将认证参数(accessKeyId、accessSign)附加到 URL Query,存在 URL 日志泄露与重放风险。
  • Hermes Gateway 的 evidence 构建仅对请求头脱敏,未对上游响应头脱敏,可能导致 Set-Cookie 等敏感信息泄露。
  • TopSec WAF 的 aesEncrypt 将密钥同时作为 IV 使用,存在已知加密弱点;且全局 sessionCache 无 TTL/上限,长期运行下存在内存泄漏风险。

@dingzhejianjian
dingzhejianjian marked this pull request as ready for review July 1, 2026 12:43
- mapHttpError now handles 401 alongside 403 as PERMISSION_DENIED
- Added 401 test case to HTTP transport errors
- Fixes regression where 401 was incorrectly mapped to FAILED_PRECONDITION
@monkeyscan

monkeyscan Bot commented Jul 6, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-dns): add Huawei Cloud DNS zone and re...

Commit: 39b8011

本次 PR 修复了华为云 DNS 服务中 HTTP 401 状态码的错误映射问题。在之前的修改中,401 被从 PERMISSION_DENIED 映射中移除,导致认证失败被错误地归类为 FAILED_PRECONDITION。本变更将 mapHttpError 函数恢复为同时处理 401 和 403,统一映射为 PERMISSION_DENIED,并补充了针对 401 的单元测试。变更范围小、目标明确,测试覆盖充分,没有发现引入新的缺陷。

kiligertee and others added 2 commits July 27, 2026 14:58
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ices

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants