You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/07/02 00:56:39 UTC

[apisix] branch master updated: feat(ip-restriction): support user-defined configuration message (#4493)

This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new cd8afe6  feat(ip-restriction): support user-defined configuration message (#4493)
cd8afe6 is described below

commit cd8afe6ec4e043a188718c41fd5937d2cd88c59d
Author: Applenice <zx...@gmail.com>
AuthorDate: Fri Jul 2 08:56:30 2021 +0800

    feat(ip-restriction): support user-defined configuration message (#4493)
---
 apisix/plugins/ip-restriction.lua        |  49 ++++---
 docs/en/latest/plugins/ip-restriction.md |  19 ++-
 docs/zh/latest/plugins/ip-restriction.md |  16 +++
 t/plugin/ip-restriction.t                | 229 +++++++++++++++++++++++++++++--
 4 files changed, 275 insertions(+), 38 deletions(-)

diff --git a/apisix/plugins/ip-restriction.lua b/apisix/plugins/ip-restriction.lua
index 64a770b..8791429 100644
--- a/apisix/plugins/ip-restriction.lua
+++ b/apisix/plugins/ip-restriction.lua
@@ -27,32 +27,29 @@ local lrucache  = core.lrucache.new({
 
 local schema = {
     type = "object",
-    oneOf = {
-        {
-            title = "whitelist",
-            properties = {
-                whitelist = {
-                    type = "array",
-                    items = {anyOf = core.schema.ip_def},
-                    minItems = 1
-                },
-            },
-            required = {"whitelist"},
-            additionalProperties = false,
+    properties = {
+        message = {
+            type = "string",
+            minLength = 1,
+            maxLength = 1024,
+            default = "Your IP address is not allowed"
+        },
+        whitelist = {
+            type = "array",
+            items = {anyOf = core.schema.ip_def},
+            minItems = 1
         },
-        {
-            title = "blacklist",
-            properties = {
-                blacklist = {
-                    type = "array",
-                    items = {anyOf = core.schema.ip_def},
-                    minItems = 1
-                }
-            },
-            required = {"blacklist"},
-            additionalProperties = false,
-        }
-    }
+        blacklist = {
+            type = "array",
+            items = {anyOf = core.schema.ip_def},
+            minItems = 1
+        },
+    },
+    oneOf = {
+        {required = {"whitelist"}},
+        {required = {"blacklist"}},
+    },
+    additionalProperties = false,
 }
 
 
@@ -154,7 +151,7 @@ function _M.access(conf, ctx)
     end
 
     if block then
-        return 403, { message = "Your IP address is not allowed" }
+        return 403, { message = conf.message }
     end
 end
 
diff --git a/docs/en/latest/plugins/ip-restriction.md b/docs/en/latest/plugins/ip-restriction.md
index 82cee45..d915776 100644
--- a/docs/en/latest/plugins/ip-restriction.md
+++ b/docs/en/latest/plugins/ip-restriction.md
@@ -41,9 +41,10 @@ in CIDR notation like 10.10.10.0/24 can be used.
 | --------- | ------------- | ----------- | ------- | ----- | ---------------------------------------- |
 | whitelist | array[string] | optional    |         |       | List of IPs or CIDR ranges to whitelist. |
 | blacklist | array[string] | optional    |         |       | List of IPs or CIDR ranges to blacklist. |
+| message | string | optional    | Your IP address is not allowed. | [1, 1024] | Message returned in case IP access is not allowed. |
 
-One of `whitelist` or `blacklist` must be specified, and they can not work
-together.
+One of `whitelist` or `blacklist` must be specified, and they can not work together.
+The message can be user-defined.
 
 ## How To Enable
 
@@ -70,6 +71,20 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
 }'
 ```
 
+Default returns `{"message":"Your IP address is not allowed"}` when unallowed IP access. If you want to use a custom message, you can configure it in the plugin section.
+
+```json
+"plugins": {
+    "ip-restriction": {
+        "whitelist": [
+            "127.0.0.1",
+            "113.74.26.106/24"
+        ],
+        "message": "Do you want to do something bad?"
+    }
+}
+```
+
 ## Test Plugin
 
 Requests from `127.0.0.1`:
diff --git a/docs/zh/latest/plugins/ip-restriction.md b/docs/zh/latest/plugins/ip-restriction.md
index fffc112..dd09105 100644
--- a/docs/zh/latest/plugins/ip-restriction.md
+++ b/docs/zh/latest/plugins/ip-restriction.md
@@ -39,8 +39,10 @@ title: ip-restriction
 | --------- | ------------- | ------ | ------ | ------ | -------------------------------- |
 | whitelist | array[string] | 可选   |        |        | 加入白名单的 IP 地址或 CIDR 范围 |
 | blacklist | array[string] | 可选   |        |        | 加入黑名单的 IP 地址或 CIDR 范围 |
+| message | string | 可选   | Your IP address is not allowed. | [1, 1024] | 在未允许的IP访问的情况下返回的信息 |
 
 只能单独启用白名单或黑名单,两个不能一起使用。
+`message`可以由用户自定义。
 
 ## 如何启用
 
@@ -67,6 +69,20 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
 }'
 ```
 
+当未允许的IP访问时,默认返回`{"message":"Your IP address is not allowed"}`。如果你想使用自定义的`message`,可以在插件部分进行配置:
+
+```json
+"plugins": {
+    "ip-restriction": {
+        "whitelist": [
+            "127.0.0.1",
+            "113.74.26.106/24"
+        ],
+        "message": "Do you want to do something bad?"
+    }
+}
+```
+
 ## 测试插件
 
 通过 `127.0.0.1` 访问:
diff --git a/t/plugin/ip-restriction.t b/t/plugin/ip-restriction.t
index ce1e94e..dd20e0a 100644
--- a/t/plugin/ip-restriction.t
+++ b/t/plugin/ip-restriction.t
@@ -57,7 +57,7 @@ __DATA__
 --- request
 GET /t
 --- response_body
-{"whitelist":["10.255.254.0/24","192.168.0.0/16"]}
+{"message":"Your IP address is not allowed","whitelist":["10.255.254.0/24","192.168.0.0/16"]}
 --- no_error_log
 [error]
 
@@ -86,7 +86,7 @@ GET /t
 --- request
 GET /t
 --- response_body_like eval
-qr/value should match only one schema, but matches none/
+qr/failed to validate item 1: object matches none of the requireds/
 --- no_error_log
 [error]
 
@@ -115,7 +115,7 @@ qr/value should match only one schema, but matches none/
 --- request
 GET /t
 --- response_body_like eval
-qr/value should match only one schema, but matches none/
+qr/failed to validate item 1: object matches none of the requireds/
 --- no_error_log
 [error]
 
@@ -161,9 +161,8 @@ done
     }
 --- request
 GET /t
---- response_body
-value should match only one schema, but matches none
-done
+--- response_body_like eval
+qr/expect array to have at least 1 items/
 --- no_error_log
 [error]
 
@@ -185,7 +184,7 @@ done
 --- request
 GET /t
 --- response_body
-value should match only one schema, but matches none
+value should match only one schema, but matches both schemas 1 and 2
 done
 --- no_error_log
 [error]
@@ -567,9 +566,8 @@ GET /hello
     }
 --- request
 GET /t
---- response_body
-invalid ip address: ::1/129
-value should match only one schema, but matches none
+--- response_body_like eval
+qr/failed to validate item 1: object matches none of the requireds/
 --- no_error_log
 [error]
 
@@ -607,3 +605,214 @@ GET /t
 passed
 --- no_error_log
 [error]
+
+
+
+=== TEST 26: set blacklist and user-defined message
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "uri": "/hello",
+                        "upstream": {
+                            "type": "roundrobin",
+                            "nodes": {
+                                "127.0.0.1:1980": 1
+                            }
+                        },
+                        "plugins": {
+                            "ip-restriction": {
+                                 "blacklist": [
+                                     "127.0.0.0/24",
+                                     "113.74.26.106"
+                                 ],
+                                 "message": "Do you want to do something bad?"
+                            }
+                        }
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 27: hit route and ip cidr in the blacklist
+--- request
+GET /hello
+--- error_code: 403
+--- response_body
+{"message":"Do you want to do something bad?"}
+--- no_error_log
+[error]
+
+
+
+=== TEST 28: hit route and ip in the blacklist
+--- http_config
+set_real_ip_from 127.0.0.1;
+real_ip_header X-Forwarded-For;
+--- more_headers
+X-Forwarded-For: 113.74.26.106
+--- request
+GET /hello
+--- error_code: 403
+--- response_body
+{"message":"Do you want to do something bad?"}
+--- no_error_log
+[error]
+
+
+
+=== TEST 29: set whitelist and user-defined message
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "uri": "/hello",
+                        "upstream": {
+                            "type": "roundrobin",
+                            "nodes": {
+                                "127.0.0.1:1980": 1
+                            }
+                        },
+                        "plugins": {
+                            "ip-restriction": {
+                                 "whitelist": [
+                                     "127.0.0.0/24",
+                                     "113.74.26.106"
+                                 ],
+                                 "message": "Do you want to do something bad?"
+                            }
+                        }
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 30: hit route and ip not in the whitelist
+--- http_config
+set_real_ip_from 127.0.0.1;
+real_ip_header X-Forwarded-For;
+--- more_headers
+X-Forwarded-For: 114.114.114.114
+--- request
+GET /hello
+--- error_code: 403
+--- response_body
+{"message":"Do you want to do something bad?"}
+--- error_log
+ip-restriction exits with http status code 403
+--- no_error_log
+[error]
+
+
+
+=== TEST 31: message that do not reach the minimum range
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "uri": "/hello",
+                        "upstream": {
+                            "type": "roundrobin",
+                            "nodes": {
+                                "127.0.0.1:1980": 1
+                            }
+                        },
+                        "plugins": {
+                            "ip-restriction": {
+                                 "whitelist": [
+                                     "127.0.0.0/24",
+                                     "113.74.26.106"
+                                 ],
+                                 "message": ""
+                            }
+                        }
+                }]]
+                )
+
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body_like eval
+qr/string too short, expected at least 1, got 0/
+--- no_error_log
+[error]
+
+
+
+=== TEST 32: exceeds the maximum limit of message
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local json = require("toolkit.json")
+
+            local data = {
+                uri = "/hello",
+                upstream = {
+                    type = "roundrobin",
+                    nodes = {
+                        ["127.0.0.1:1980"] = 1,
+                    }
+                },
+                plugins = {
+                    ["ip-restriction"] = {
+                        ["whitelist"] = {
+                            "127.0.0.0/24",
+                            "113.74.26.106"
+                        },
+                        message = ("-1Aa#"):rep(205)
+                    }
+                }
+            }
+
+            local code, body = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                json.encode(data)
+            )
+
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body_like eval
+qr/string too long, expected at most 1024, got 1025/
+--- no_error_log
+[error]