chaitin-waf

描述

在启用 chaitin-waf 插件后,流量将被转发给长亭 WAF 服务,用以检测和防止各种 Web 应用程序攻击,以保护应用程序和用户数据的安全。

响应头

根据插件配置,可以选择是否附加额外的响应头。

响应头的信息如下:

  • X-APISIX-CHAITIN-WAF:APISIX 是否将请求转发给 WAF 服务器。
    • yes:转发
    • no:不转发
    • unhealthy:符合匹配条件,但没有可用的 WAF 服务器
    • err:插件执行过程中出错。此时会附带 X-APISIX-CHAITIN-WAF-ERROR 请求头
    • waf-err:与 WAF 服务器交互时出错。此时会附带 X-APISIX-CHAITIN-WAF-ERROR 请求头
    • timeout:与 WAF 服务器的交互超时
  • X-APISIX-CHAITIN-WAF-ERROR:调试用响应头。APISIX 与 WAF 交互时的错误信息。
  • X-APISIX-CHAITIN-WAF-TIME:APISIX 与 WAF 交互所耗费的时间,单位是毫秒。
  • X-APISIX-CHAITIN-WAF-STATUS:WAF 服务器返回给 APISIX 的状态码。
  • X-APISIX-CHAITIN-WAF-ACTION:WAF 服务器返回给 APISIX 的处理结果。
    • pass:请求合法
    • reject:请求被 WAF 服务器拒绝
  • X-APISIX-CHAITIN-WAF-SERVER:调试用响应头。所使用的 WAF 服务器。

插件元数据

名称类型必选项默认值描述
nodesarray(object)必选长亭 WAF 的地址列表。
nodes[0].hoststring必选长亭 WAF 的地址,支持 IPV4、IPV6、Unix Socket 等配置方式。
nodes[0].portstring可选80长亭 WAF 的端口。
configobject长亭 WAF 服务的配置参数值。当路由没有配置时将使用这里所配置的参数。
config.connect_timeoutinteger1000connect timeout, 毫秒
config.send_timeoutinteger1000send timeout, 毫秒
config.read_timeoutinteger1000read timeout, 毫秒
config.req_body_sizeinteger1024请求体大小,单位为 KB
config.keepalive_sizeinteger256长亭 WAF 服务的最大并发空闲连接数
config.keepalive_timeoutinteger60000空闲链接超时,毫秒

一个典型的示例配置如下:

chaitin-waf - 图1note

您可以这样从 config.yaml 中获取 admin_key 并存入环境变量:

  1. admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
  1. curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/chaitin-waf -H "X-API-KEY: $admin_key" -X PUT -d '
  2. {
  3. "nodes":[
  4. {
  5. "host": "unix:/path/to/safeline/resources/detector/snserver.sock",
  6. "port": 8000
  7. }
  8. ]
  9. }'

属性

名称类型必选项默认值描述
matcharray[object]匹配规则列表,默认为空且规则将被无条件执行。
match.varsarray[array]由一个或多个 {var, operator, val} 元素组成的列表,例如:{“arg_name”, “==”, “json”},表示当前请求参数 namejson。这里的 var 与 NGINX 内部自身变量命名是保持一致,所以也可以使用 request_urihost 等;对于已支持的运算符,具体用法请参考 lua-resty-exproperator-list 部分。
append_waf_resp_headerbooltrue是否添加响应头
append_waf_debug_headerboolfalse是否添加调试用响应头,add_headertrue 时才生效
configobject长亭 WAF 服务的配置参数值。当路由没有配置时将使用元数据里所配置的参数。
config.connect_timeoutintegerconnect timeout, 毫秒
config.send_timeoutintegersend timeout, 毫秒
config.read_timeoutintegerread timeout, 毫秒
config.req_body_sizeinteger请求体大小,单位为 KB
config.keepalive_sizeinteger长亭 WAF 服务的最大并发空闲连接数
config.keepalive_timeoutinteger空闲链接超时,毫秒

一个典型的示例配置如下,这里使用 httpbun.org 作为示例后端,可以按需替换:

  1. curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
  2. {
  3. "uri": "/*",
  4. "plugins": {
  5. "chaitin-waf": {
  6. "match": [
  7. {
  8. "vars": [
  9. ["http_waf","==","true"]
  10. ]
  11. }
  12. ]
  13. }
  14. },
  15. "upstream": {
  16. "type": "roundrobin",
  17. "nodes": {
  18. "httpbun.org:80": 1
  19. }
  20. }
  21. }'

测试插件

以上述的示例配置为例进行测试。

不满足匹配条件时,请求可以正常触达:

  1. curl -H "Host: httpbun.org" http://127.0.0.1:9080/get -i
  2. HTTP/1.1 200 OK
  3. Content-Type: application/json
  4. Content-Length: 408
  5. Connection: keep-alive
  6. X-APISIX-CHAITIN-WAF: no
  7. Date: Wed, 19 Jul 2023 09:30:42 GMT
  8. X-Powered-By: httpbun/3c0dc05883dd9212ac38b04705037d50b02f2596
  9. Server: APISIX/3.3.0
  10. {
  11. "args": {},
  12. "headers": {
  13. "Accept": "*/*",
  14. "Connection": "close",
  15. "Host": "httpbun.org",
  16. "User-Agent": "curl/8.1.2",
  17. "X-Forwarded-For": "127.0.0.1",
  18. "X-Forwarded-Host": "httpbun.org",
  19. "X-Forwarded-Port": "9080",
  20. "X-Forwarded-Proto": "http",
  21. "X-Real-Ip": "127.0.0.1"
  22. },
  23. "method": "GET",
  24. "origin": "127.0.0.1, 122.231.76.178",
  25. "url": "http://httpbun.org/get"
  26. }

面对潜在的注入请求也原样转发并遇到 404 错误:

  1. curl -H "Host: httpbun.org" http://127.0.0.1:9080/getid=1%20AND%201=1 -i
  2. HTTP/1.1 404 Not Found
  3. Content-Type: text/plain; charset=utf-8
  4. Content-Length: 19
  5. Connection: keep-alive
  6. X-APISIX-CHAITIN-WAF: no
  7. Date: Wed, 19 Jul 2023 09:30:28 GMT
  8. X-Content-Type-Options: nosniff
  9. X-Powered-By: httpbun/3c0dc05883dd9212ac38b04705037d50b02f2596
  10. Server: APISIX/3.3.0
  11. 404 page not found

当满足匹配条件时,正常请求依然可以触达上游:

  1. curl -H "Host: httpbun.org" -H "waf: true" http://127.0.0.1:9080/get -i
  2. HTTP/1.1 200 OK
  3. Content-Type: application/json
  4. Content-Length: 427
  5. Connection: keep-alive
  6. X-APISIX-CHAITIN-WAF-TIME: 2
  7. X-APISIX-CHAITIN-WAF-STATUS: 200
  8. X-APISIX-CHAITIN-WAF: yes
  9. X-APISIX-CHAITIN-WAF-ACTION: pass
  10. Date: Wed, 19 Jul 2023 09:29:58 GMT
  11. X-Powered-By: httpbun/3c0dc05883dd9212ac38b04705037d50b02f2596
  12. Server: APISIX/3.3.0
  13. {
  14. "args": {},
  15. "headers": {
  16. "Accept": "*/*",
  17. "Connection": "close",
  18. "Host": "httpbun.org",
  19. "User-Agent": "curl/8.1.2",
  20. "Waf": "true",
  21. "X-Forwarded-For": "127.0.0.1",
  22. "X-Forwarded-Host": "httpbun.org",
  23. "X-Forwarded-Port": "9080",
  24. "X-Forwarded-Proto": "http",
  25. "X-Real-Ip": "127.0.0.1"
  26. },
  27. "method": "GET",
  28. "origin": "127.0.0.1, 122.231.76.178",
  29. "url": "http://httpbun.org/get"
  30. }

而潜在的攻击请求将会被拦截并返回 403 错误:

  1. curl -H "Host: httpbun.org" -H "waf: true" http://127.0.0.1:9080/getid=1%20AND%201=1 -i
  2. HTTP/1.1 403 Forbidden
  3. Date: Wed, 19 Jul 2023 09:29:06 GMT
  4. Content-Type: text/plain; charset=utf-8
  5. Transfer-Encoding: chunked
  6. Connection: keep-alive
  7. X-APISIX-CHAITIN-WAF: yes
  8. X-APISIX-CHAITIN-WAF-TIME: 2
  9. X-APISIX-CHAITIN-WAF-ACTION: reject
  10. X-APISIX-CHAITIN-WAF-STATUS: 403
  11. Server: APISIX/3.3.0
  12. Set-Cookie: sl-session=UdywdGL+uGS7q8xMfnJlbQ==; Domain=; Path=/; Max-Age=86400
  13. {"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "51a268653f2c4189bfa3ec66afbcb26d"}

删除插件

当你需要删除该插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务:

  1. $ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
  2. {
  3. "uri": "/*",
  4. "upstream": {
  5. "type": "roundrobin",
  6. "nodes": {
  7. "httpbun.org:80": 1
  8. }
  9. }
  10. }'