diff --git a/apisix/cli/ip.lua b/apisix/cli/ip.lua new file mode 100644 index 000000000000..182b824fe742 --- /dev/null +++ b/apisix/cli/ip.lua @@ -0,0 +1,66 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +--- IP match and verify module. +-- +-- @module cli.ip + +local mediador_ip = require("resty.mediador.ip") +local setmetatable = setmetatable + + +local _M = {} +local mt = { __index = _M } + + +--- +-- create a instance of module cli.ip +-- +-- @function cli.ip:new +-- @tparam string ip IP or CIDR. +-- @treturn instance of module if the given ip valid, nil and error message otherwise. +function _M.new(self, ip) + if not mediador_ip.valid(ip) then + return nil, "invalid ip" + end + + local _ip = mediador_ip.parse(ip) + + return setmetatable({ _ip = _ip }, mt) +end + + +--- +-- Is that the given ip loopback? +-- +-- @function cli.ip:is_loopback +-- @treturn boolean True if the given ip is the loopback, false otherwise. +function _M.is_loopback(self) + return self._ip and "loopback" == self._ip:range() +end + +--- +-- Is that the given ip unspecified? +-- +-- @function cli.ip:is_unspecified +-- @treturn boolean True if the given ip is all the unspecified, false otherwise. +function _M.is_unspecified(self) + return self._ip and "unspecified" == self._ip:range() +end + + +return _M diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua index 9a57cf4a9142..ae38a9dd5f7e 100644 --- a/apisix/cli/ops.lua +++ b/apisix/cli/ops.lua @@ -20,6 +20,7 @@ local util = require("apisix.cli.util") local file = require("apisix.cli.file") local schema = require("apisix.cli.schema") local ngx_tpl = require("apisix.cli.ngx_tpl") +local cli_ip = require("apisix.cli.ip") local profile = require("apisix.core.profile") local template = require("resty.template") local argparse = require("argparse") @@ -277,16 +278,16 @@ Please modify "admin_key" in conf/config.yaml . -- not disabled by the users if real_ip_from then for _, ip in ipairs(real_ip_from) do - -- TODO: handle cidr - if ip == "127.0.0.1" or ip == "0.0.0.0/0" then + local _ip = cli_ip:new(ip) + if _ip:is_loopback() or _ip:is_unspecified() then pass_real_client_ip = true end end end if not pass_real_client_ip then - util.die("missing '127.0.0.1' in the nginx_config.http.real_ip_from for plugin " .. - "batch-requests\n") + util.die("missing loopback or unspecified in the nginx_config.http.real_ip_from" .. + " for plugin batch-requests\n") end end diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index aa67ca73614c..e75c13e13eaa 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -76,7 +76,8 @@ dependencies = { "opentelemetry-lua = 0.1-3", "net-url = 0.9-1", "xml2lua = 1.5-2", - "nanoid = 0.1-1" + "nanoid = 0.1-1", + "lua-resty-mediador = 0.1.2-1" } build = { diff --git a/t/cli/test_validate_config.sh b/t/cli/test_validate_config.sh index 42cd2be4f10c..43bfd5293297 100755 --- a/t/cli/test_validate_config.sh +++ b/t/cli/test_validate_config.sh @@ -161,17 +161,41 @@ fi echo "passed: apisix test(failure scenario)" +# apisix plugin batch-requests real_ip_from invalid - failure scenario echo ' plugins: - batch-requests nginx_config: http: real_ip_from: - - "127.0.0.2" + - "128.0.0.2" ' > conf/config.yaml out=$(make init 2>&1 || true) -if ! echo "$out" | grep "missing '127.0.0.1' in the nginx_config.http.real_ip_from for plugin batch-requests"; then +if ! echo "$out" | grep "missing loopback or unspecified in the nginx_config.http.real_ip_from for plugin batch-requests"; then + echo "failed: should check the realip configuration for batch-requests" + exit 1 +fi + +echo "passed: apisix plugin batch-requests real_ip_from(failure scenario)" + +# apisix plugin batch-requests real_ip_from valid +echo ' +plugins: +- batch-requests +nginx_config: + http: + real_ip_from: + - "127.0.0.1" + - "127.0.0.2/8" + - "0.0.0.0" + - "0.0.0.0/0" + - "::" + - "::/0" +' > conf/config.yaml + +out=$(make init 2>&1 || true) +if echo "$out" | grep "missing loopback or unspecified in the nginx_config.http.real_ip_from for plugin batch-requests"; then echo "failed: should check the realip configuration for batch-requests" exit 1 fi