Skip to content

feat(huawei-waf): add Huawei Cloud WAF IP blacklist management service package - #314

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

feat(huawei-waf): add Huawei Cloud WAF IP blacklist management service package#314
dingzhejianjian wants to merge 4 commits into
chaitin:mainfrom
dingzhejianjian:pr/huawei-waf

Conversation

@dingzhejianjian

@dingzhejianjian dingzhejianjian commented Jun 26, 2026

Copy link
Copy Markdown

接入设备

华为云 Web 应用防火墙(WAF),提供 IP 黑白名单管理、防护域名查询、防护策略管理等安全能力。

设备版本

WAF,API 版本 v1,端点 waf.{region}.myhuaweicloud.com

认证方式

华为云 AK/SK,SDK-HMAC-SHA256 签名

实现方法

RPC 方法 后端 API 类型 说明
BlockIP POST /v1/{project_id}/waf/policy/{policy_id}/whiteblackip 封堵指定 IP
UnblockIP DELETE /v1/{project_id}/waf/policy/{policy_id}/whiteblackip/{rule_id} 解封 IP
ListRules GET /v1/{project_id}/waf/policy/{policy_id}/whiteblackip 查询黑白名单规则
ListInstances GET /v1/{project_id}/waf/instance 查询防护域名列表
ListPolicies GET /v1/{project_id}/waf/policy 查询防护策略列表

联调证据

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

Request

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

# Response   HTTP/1.1 200 OK
```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {"name": "huawei-waf__waf-test__block_i_p", "description": "Huawei_WAF.Huawei_WAF/BlockIP"},
      {"name": "huawei-waf__waf-test__list_rules", "description": "Huawei_WAF.Huawei_WAF/ListRules"},
      {"name": "huawei-waf__waf-test__unblock_i_p", "description": "Huawei_WAF.Huawei_WAF/UnblockIP"},
      {"name": "huawei-waf__waf-test__list_instances", "description": "Huawei_WAF.Huawei_WAF/ListInstances"},
      {"name": "huawei-waf__waf-test__list_policies", "description": "Huawei_WAF.Huawei_WAF/ListPolicies"}
    ]
  }
}

证据二:BlockIP — 封堵测试 IP

Request

curl -s -X POST 'http://127.0.0.1:9000/capsets/waf-dev/connect/waf-test/Huawei_WAF.Huawei_WAF/BlockIP' \
  -H 'Content-Type: application/json' \
  -d '{"ip":"10.0.0.222","comment":"OctoBus block test"}'

# Response   HTTP/1.1 200 OK
```json
{"message":"ok", "ruleId":"2589ae798c29496da46b065ffdc58431"}

证据三:ListRules — 查询规则确认封堵生效

Request

POST http://127.0.0.1:9000/capsets/waf-dev/connect/waf-test/Huawei_WAF.Huawei_WAF/ListRules
Content-Type: application/json

{"limit":20}

Response HTTP/1.1 200 OK

{
  "message":"ok",
  "data":[{"id":"2589ae798c29496da46b065ffdc58431","ip":"10.0.0.222","name":"octo-block-10-0-0-222","action":0,"description":"OctoBus block test","createTime":"1782465509899"}],
  "total":1
}

证据四:ListPolicies — 查询防护策略

Request

POST http://127.0.0.1:9000/capsets/waf-dev/connect/waf-test/Huawei_WAF.Huawei_WAF/ListPolicies
Content-Type: application/json

{}

Response HTTP/1.1 200 OK

{
  "message":"ok",
  "data":[
    {"id":"******","name":"1","level":2,"actionMode":"log","createTime":"1782465052951"},
    {"id":"******","name":"octobus-policy","level":2,"actionMode":"log","createTime":"1782461725534"}
  ],
  "total":2
}

注:policy_id 已脱敏。

证据五:UnblockIP — 解封

Request

POST http://127.0.0.1:9000/capsets/waf-dev/connect/waf-test/Huawei_WAF.Huawei_WAF/UnblockIP
Content-Type: application/json

{"rule_id":"2589ae798c29496da46b065ffdc58431"}

Response HTTP/1.1 200 OK

{"message":"ok"}

BlockIP → ListRules → UnblockIP 全流程跑通。API 签名认证正常。

测试结果

ℹ tests 16
ℹ pass  16
ℹ fail  0

目录结构

services/huawei__waf/
├── service.json
├── package.json
├── proto/huawei_waf.proto     # 5 个 RPC 方法
├── bin/huawei-waf.js
├── src/service.js
├── src/huawei-waf.js
├── config.schema.json
├── secret.schema.json
├── README.md
└── test/huawei-waf.test.js    # 16 个测试全过

@monkeyscan

monkeyscan Bot commented Jun 26, 2026

Copy link
Copy Markdown

本次 PR 新增 Huawei WAF(华为云 Web 应用防火墙)IP 黑白名单管理服务包,核心变更包括:

  1. 新增服务目录 services/huawei__waf/,包含 proto 定义、配置/密钥 schema、主业务逻辑(huawei-waf.js)、测试、README 等。
  2. 主实现 huawei-waf.js 提供 BlockIP、UnblockIP、ListRules 三个 handler,通过 Huawei Cloud SDK-HMAC-SHA256 签名调用 WAF v1 API。
  3. services/package.json 与 services/bin/octobus-tentacles.js 被大规模删减,仅保留 huawei-waf 一个服务入口。

经代码审查,发现以下高优先级问题:

  • 签名 canonical URI 与请求实际路径不一致:signHuawei 中 ensureTrailingSlash 会在 canonical URI 末尾追加 /,而实际请求的 URL 没有该斜杠,导致签名验证必然失败。
  • 密钥 schema 别名与代码不匹配:secret.schema.json 定义了 ak/sk 别名,但代码中未读取 bindings.ak / bindings.sk,用户按 schema 使用别名时将报权限错误。
  • services/package.json 与 octobus-tentacles.js 误删其他服务:PR 标题仅声明新增 huawei-waf,但这两个文件被移除其余 40+ 服务的注册信息,构成回归风险。

Comment thread services/huawei__waf/src/huawei-waf.js
Comment thread services/huawei__waf/src/huawei-waf.js
Comment thread services/package.json
@dingzhejianjian

Copy link
Copy Markdown
Author

已修正:

  1. services/package.json 恢复所有已有服务注册,仅追加 huawei-waf
  2. services/bin/octobus-tentacles.js 恢复所有已有服务入口
  3. fetch 超时改用 AbortController
  4. 签名 canonicalURI 不再强制追加尾部斜杠
  5. ak/sk 别名代码中已支持识别

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

monkeyscan Bot commented Jun 26, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-waf): add Huawei Cloud WAF IP blacklis...

Commit: 034aa86

本次 PR 主要修复了三个问题:1) 恢复了 services/package.json 中被误删的大量服务 bin 入口与 files 声明;2) 修复了华为 WAF 模块的签名 canonicalURI 与请求路径不一致的问题(移除强制尾部斜杠)、修正了 content-type charset 拼写错误,并增加了 bindings.ak/sk 的别名兼容;3) 使用 AbortController 重写了 fetchJson 的超时机制。在审查中发现 fetchJson 函数的超时保护范围存在关键缺陷:AbortController 的 timer 仅在 try...finally 块内有效,fetch 成功返回后 res.text() 的调用不受超时保护,存在 response body 读取阶段无限挂起的可靠性风险。建议将 res.text() 及后续处理移入 try 块内部以确保超时覆盖完整请求生命周期。

Comment thread services/huawei__waf/src/huawei-waf.js
@dingzhejianjian

Copy link
Copy Markdown
Author
314-1 314-2 314-3 314-4-1 314-4-2 314-5

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

monkeyscan Bot commented Jun 27, 2026

Copy link
Copy Markdown

MonkeyScan 已经开始评审,完成后会更新到本评论中,请稍后刷新查看。

@monkeyscan

monkeyscan Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-waf): add Huawei Cloud WAF IP blacklis...

Commit: f52a49c

本次 PR 将 services/huawei__waf/src/huawei-waf.jsfetchJson 函数的 res.text() 及相关后续处理逻辑移入了 try 块内部,并新增了 GrpcError 实例的透传逻辑。改动背景是:旧代码中 fetch() 成功返回后,res.text()mapHttpError()parseJson() 均处于 try/catch 保护之外,如果服务端在发送响应头后迟迟不关闭连接或 body 流挂起,res.text() 将无限期等待且不受超时 abort 影响。修复后,AbortController 的超时信号可以覆盖完整的请求生命周期(包括 body 读取阶段),同时新增 if (err instanceof GrpcError) throw err; 确保由 mapHttpErrorparseJson 抛出的业务错误不会被错误地二次包装为 UNAVAILABLE

整体评估:

  • 该修复回应了历史发现(historical finding)中提到的“response body 读取阶段可能无限挂起”问题。
  • errorWithCode() 返回 GrpcError 实例,因此新增的 GrpcError 透传检查逻辑正确。
  • 超时 timer 仍在 finally 中清理,防止内存泄漏。
  • 未发现引入新的正确性、安全性或可靠性风险。

@dingzhejianjian
dingzhejianjian marked this pull request as ready for review June 27, 2026 14:57
@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.

✅ 已完成手动验证。5 个工具已注册,ListPolicies 返回 2 个策略。

@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

MonkeyScan 已经开始评审,完成后会更新到本评论中,请稍后刷新查看。

@monkeyscan

monkeyscan Bot commented Jun 30, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-waf): add Huawei Cloud WAF IP blacklis...

Commit: cf103df

本次 PR 仅修改 services/package.json,核心内容是批量注册大量新的 octobus tentacle 服务:在 bin 字段新增约 30 个 CLI 入口,在 files 字段同步增加对应的 bin/*.js 文件路径及服务目录,并在 dependencies/bundledDependencies 中新增 @alicloud/swas-open20200601undici。此外调整了 huawei-waf 相关条目的顺序。整体变更机械、一致,但 files 数组中 "huawei__waf" 的缩进从 4 空格异常变为 8 空格,疑似合并冲突解决后的格式残留。

Comment thread services/package.json Outdated
@dingzhejianjian

Copy link
Copy Markdown
Author

手动验证结果 ✅

步骤 结果 说明
tools/list 返回 5 个 tool(block_ip / list_instances / list_policies / list_rules / unblock_ip)
ListPolicies 返回 2 个策略

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

@dingzhejianjian

Copy link
Copy Markdown
Author

手动验证结果(完整)

① tools/list

命令:

curl -s -X POST 'http://10.2.37.168:9000/capsets/waf-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_WAF.Huawei_WAF/BlockIP",
                "inputSchema": {
                    "properties": {
                        "comment": {
                            "description": "Wrapper message for `string`.",
                            "type": [
                                "string",
                                "null"
                            ]
                        },
                        "ip": {
                            "type": "string"
                        }
                    },
                    "required": [],
                    "type": "object"
                },
                "name": "huawei-waf__waf-test__block_i_p"
            },
            {
                "description": "Huawei_WAF.Huawei_WAF/ListInstances",
                "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-waf__waf-test__list_instances"
            },
            {
                "description": "Huawei_WAF.Huawei_WAF/ListPolicies",
                "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-waf__waf-test__list_policies"
            },
            {
                "description": "Huawei_WAF.Huawei_WAF/ListRules",
                "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-waf__waf-test__list_rules"
            },
            {
                "description": "Huawei_WAF.Huawei_WAF/UnblockIP",
                "inputSchema": {
                    "properties": {
                        "rule_id": {
                            "type": "string"
                        }
                    },
                    "required": [],
                    "type": "object"
                },
                "name": "huawei-waf__waf-test__unblock_i_p"
            }
        ]
    }
}

② ListPolicies

命令:

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

返回:

{
    "message": "ok",
    "data": [
        {
            "id": "53a25172ef844857a4b48a9cc5e2f5a3",
            "name": "1",
            "level": 2,
            "actionMode": "log",
            "createTime": "1782465052951"
        },
        {
            "id": "b8b26a105c604e9097b33b8ac61f0a48",
            "name": "octobus-policy",
            "level": 2,
            "actionMode": "log",
            "createTime": "1782461725534"
        }
    ],
    "total": 2
}

结论:2/2 全部通过,可进入 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-waf): add Huawei Cloud WAF IP blacklis...

Commit: e2de0c8

本次 PR 对 huawei-waf 服务进行了多项修复与重构:

  1. 引入 undici Agent 以正确实现 skipTlsVerify 的 TLS 验证跳过功能;
  2. 重构 fetchJson,将响应读取移入 try 块,并在 catch 中透传 GrpcError;
  3. 调整 HTTP 错误码映射:移除 401 的 PERMISSION_DENIED 特殊处理,新增 429 -> UNAVAILABLE,并从错误消息中删除响应 body 内容;
  4. 为 unwrapString 增加递归深度上限(>10 返回空串),防止循环嵌套对象导致栈溢出;
  5. 移除 success 日志中的 raw_response 字段,减少敏感信息泄露;
  6. 补充对应单元测试。

整体评估:改动方向合理,修复了递归安全和信息泄露问题。但存在两处值得关注的行为/可靠性风险:401 状态码语义映射发生回归;skipTlsVerify 场景下每次请求新建 undici Agent,可能导致连接池失效。

@dingzhejianjian

Copy link
Copy Markdown
Author

手动验证结果(完整)

① tools/list

命令:

curl -s -X POST 'http://10.2.37.168:9000/capsets/waf-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_WAF.Huawei_WAF/BlockIP", "name": "huawei-waf__waf-test__block_i_p"},
            {"description": "Huawei_WAF.Huawei_WAF/ListInstances", "name": "huawei-waf__waf-test__list_instances"},
            {"description": "Huawei_WAF.Huawei_WAF/ListPolicies", "name": "huawei-waf__waf-test__list_policies"},
            {"description": "Huawei_WAF.Huawei_WAF/ListRules", "name": "huawei-waf__waf-test__list_rules"},
            {"description": "Huawei_WAF.Huawei_WAF/UnblockIP", "name": "huawei-waf__waf-test__unblock_i_p"}
        ]
    }
}

② ListPolicies

命令:

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

返回:

{
    "message": "ok",
    "data": [
        {"id": "53a25172ef844857a4b48a9cc5e2f5a3", "name": "1", "level": 2, "actionMode": "log"},
        {"id": "b8b26a105c604e9097b33b8ac61f0a48", "name": "octobus-policy", "level": 2, "actionMode": "log"}
    ],
    "total": 2
}

结论:2/2 通过。

Comment thread services/huawei__waf/src/huawei-waf.js Outdated
Comment thread services/huawei__waf/src/huawei-waf.js Outdated
@monkeyscan

monkeyscan Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-waf): add Huawei Cloud WAF IP blacklis...

Commit: 58d8a9c

本次 PR 仅修改了 services/huawei__waf/src/huawei-waf.js 中的 buildTlsOptions 函数,将原先每次调用都新建 undici Agent 的逻辑改为模块级单例缓存。这是一个明确的性能/可靠性修复:重复创建 Agent 会导致连接池无法复用,进而可能引发端口耗尽或文件描述符泄漏。修复后,tlsAgent 在首次需要跳过 TLS 校验时懒加载并复用,Node.js 单线程模型下该懒加载逻辑是安全的。此变更未引入新的行为回归或资源泄漏风险。

@monkeyscan

monkeyscan Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Title: feat(huawei-waf): add Huawei Cloud WAF IP blacklis...

Commit: 795b973

本次 PR 新增了大量 OctoBus 服务包(如 huawei-waf、sangfor-xdr、volcengine-cloud-firewall、chaitin-cloudatlas 等)并对 SDK 进行了升级,主要包括:

  • 新增 sdk/src/http.ts,提供统一的 fetchWithTimeoutcreateTlsDispatcher 和响应读取工具,规范了 TLS 跳过行为(通过 undici Agent 的 dispatcher)。
  • 新增 sdk/src/errors.ts,提供错误脱敏 (redactSensitive)、HTTP 状态码映射和统一的服务错误构造。
  • 新增 sdk/src/context.tssdk/src/bootstrap.ts 以支持上下文标准化和引导包生成。
  • 各新增服务普遍采用 undici Agent 的 dispatcher 方式实现 skipTlsVerify,符合预期。

整体评估:代码结构清晰,大多数服务在 TLS 控制和超时处理上遵循了统一模式。但 services/qingteng__hids_v5/src/qingteng-hids-v5.js 存在全局 process.env.NODE_TLS_REJECT_UNAUTHORIZED 修改的严重问题,会导致并发请求间的 TLS 验证状态互相污染,必须修复。

@dingzhejianjian
dingzhejianjian marked this pull request as ready for review July 1, 2026 12:41
- 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-waf): add Huawei Cloud WAF IP blacklis...

Commit: 2f8b626

本次 PR 是对 Huawei WAF 服务的一个行为修复:将上游返回的 HTTP 401 状态码重新映射为 PERMISSION_DENIED(此前仅保留 403 的映射,导致 401 落入 FAILED_PRECONDITION 分支)。修复集中在 mapHttpError 函数的一行逻辑变更,并补充了对应的测试用例,确保 401 和 403 均被正确映射为 PERMISSION_DENIED。语义上,401(Unauthorized)表示认证/凭证失败,与 PERMISSION_DENIED 更为贴近;FAILED_PRECONDITION 用于前置条件不满足,用于 401 属于错位。整体变更范围极小、意图明确,测试覆盖完整,无引入新的行为回归或安全风险。

kiligertee and others added 2 commits July 27, 2026 15:48
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ct residue

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