Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions apisix/plugins/chaitin-waf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ local plugin_schema = {
type = "boolean",
default = false
},
allow_degradation = {
type = "boolean",
default = false
},
config = {
type = "object",
properties = {
Expand Down Expand Up @@ -314,6 +318,11 @@ local function do_access(conf, ctx)
extra_headers[HEADER_CHAITIN_WAF] = "unhealthy"
extra_headers[HEADER_CHAITIN_WAF_ERROR] = tostring(err)

if conf.allow_degradation then
core.log.warn("chaitin-waf: no healthy nodes, degradation enabled, passing request")
return nil, nil, extra_headers
end

return 500, nil, extra_headers
end

Expand Down Expand Up @@ -361,6 +370,11 @@ local function do_access(conf, ctx)
end
extra_headers[HEADER_CHAITIN_WAF_ERROR] = tostring(err)

if conf.allow_degradation then
core.log.warn("chaitin-waf: WAF error (", err_msg, "), degradation enabled, passing request")
return nil, nil, extra_headers
end

if mode == "monitor" then
core.log.warn("chaitin-waf monitor mode: detected waf error - ", err_msg)
return nil, nil, extra_headers
Expand Down
1 change: 1 addition & 0 deletions docs/en/latest/plugins/chaitin-waf.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ The Plugin can add the following response headers, depending on the configuratio
| match.vars | array[array] | false | | | An array of one or more matching conditions in the form of [lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list) to conditionally execute the plugin. |
| append_waf_resp_header | boolean | false | true | | If true, add response headers `X-APISIX-CHAITIN-WAF`, `X-APISIX-CHAITIN-WAF-TIME`, `X-APISIX-CHAITIN-WAF-ACTION`, and `X-APISIX-CHAITIN-WAF-STATUS`. |
| append_waf_debug_header | boolean | false | false | | If true, add debugging headers `X-APISIX-CHAITIN-WAF-ERROR` and `X-APISIX-CHAITIN-WAF-SERVER` to the response. Effective only when `append_waf_resp_header` is `true`. |
| allow_degradation | boolean | false | false | | If true, requests will be passed through instead of returning an error when the WAF service is unavailable (e.g., connection timeout, no healthy nodes). This prevents the WAF service from becoming a single point of failure. |
| config | object | false | | | Chaitin WAF service configurations. These settings override the corresponding metadata defaults when specified. |
| config.connect_timeout | integer | false | 1000 | | The connection timeout to the WAF service, in milliseconds. |
| config.send_timeout | integer | false | 1000 | | The sending timeout for transmitting data to the WAF service, in milliseconds. |
Expand Down
1 change: 1 addition & 0 deletions docs/zh/latest/plugins/chaitin-waf.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ description: chaitin-waf 插件与长亭雷池 WAF 集成,以检测和阻止
| match.vars | array[array] | 否 | | | 一个或多个匹配条件数组,使用 [lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list) 表达式来有条件地执行插件。 |
| append_waf_resp_header | boolean | 否 | true | | 若为 true,则在响应中添加 `X-APISIX-CHAITIN-WAF`、`X-APISIX-CHAITIN-WAF-TIME`、`X-APISIX-CHAITIN-WAF-ACTION` 和 `X-APISIX-CHAITIN-WAF-STATUS` 响应头。 |
| append_waf_debug_header | boolean | 否 | false | | 若为 true,则在响应中添加调试用响应头 `X-APISIX-CHAITIN-WAF-ERROR` 和 `X-APISIX-CHAITIN-WAF-SERVER`。仅当 `append_waf_resp_header` 为 true 时生效。 |
| allow_degradation | boolean | 否 | false | | 若为 true,当 WAF 服务不可用(如连接超时、无健康节点)时,请求将被放行而不是返回错误。这可以防止 WAF 服务成为单点故障。 |
| config | object | 否 | | | 长亭 WAF 服务配置。这些配置在指定时会覆盖对应的元数据默认值。 |
| config.connect_timeout | integer | 否 | 1000 | | 与 WAF 服务的连接超时时间,单位为毫秒。 |
| config.send_timeout | integer | 否 | 1000 | | 向 WAF 服务发送数据的超时时间,单位为毫秒。 |
Expand Down
95 changes: 95 additions & 0 deletions t/plugin/chaitin-waf-timeout.t
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,98 @@ hello world
X-APISIX-CHAITIN-WAF: timeout
--- response_headers_like
X-APISIX-CHAITIN-WAF-TIME:



=== TEST 3: allow_degradation=true on timeout
--- config
location /do {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"methods": ["GET"],
"plugins": {
"chaitin-waf": {
"mode": "block",
"allow_degradation": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed



=== TEST 4: timeout with allow_degradation=true, request passed
--- request
GET /hello
--- error_code: 200
--- response_body
hello world
--- error_log
degradation enabled, passing request
--- response_headers
X-APISIX-CHAITIN-WAF: timeout



=== TEST 5: allow_degradation=false on timeout (default behavior)
--- config
location /do {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"methods": ["GET"],
"plugins": {
"chaitin-waf": {
"mode": "block",
"allow_degradation": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed



=== TEST 6: timeout with allow_degradation=false, request blocked
--- request
GET /hello
--- error_code: 500
--- error_log
--- response_headers
X-APISIX-CHAITIN-WAF: timeout
Loading