Files
2026-07-13 12:32:21 +08:00

84 lines
2.3 KiB
Lua

---
-- Trusted IPs module.
--
-- This module can be used to determine whether or not a given IP address is
-- in the range of trusted IP addresses defined by the `trusted_ips` configuration
-- property.
--
-- Trusted IP addresses are those that are known to send correct replacement
-- addresses for clients (as per the chosen header field, for example
-- X-Forwarded-*).
--
-- See the [documentation on trusted IPs](https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips).
--
-- @module kong.ip
local is_valid_ip_or_cidr = require("kong.tools.ip").is_valid_ip_or_cidr
local ipmatcher = require "resty.ipmatcher"
---
-- Depending on the `trusted_ips` configuration property,
-- this function returns whether a given IP is trusted or not.
--
-- Both ipv4 and ipv6 are supported.
--
-- @function kong.ip.is_trusted
-- @phases init_worker, certificate, rewrite, access, header_filter, response, body_filter, log
-- @tparam string address A string representing an IP address.
-- @treturn boolean `true` if the IP is trusted, `false` otherwise.
-- @usage
-- if kong.ip.is_trusted("1.1.1.1") then
-- kong.log("The IP is trusted")
-- end
local function new(self)
local _IP = {}
local ips = self.configuration.trusted_ips or {}
local n_ips = #ips
local trusted_ips = self.table.new(n_ips, 0)
local trust_all_ipv4
local trust_all_ipv6
-- This is because we don't support unix: that the ngx_http_realip module
-- supports. Also as an optimization we will only compile trusted ips if
-- Kong is not run with the default 0.0.0.0/0, ::/0 aka trust all ip
-- addresses settings.
local idx = 1
for i = 1, n_ips do
local address = ips[i]
if is_valid_ip_or_cidr(address) then
trusted_ips[idx] = address
idx = idx + 1
if address == "0.0.0.0/0" then
trust_all_ipv4 = true
elseif address == "::/0" then
trust_all_ipv6 = true
end
end
end
if #trusted_ips == 0 then
_IP.is_trusted = function() return false end
elseif trust_all_ipv4 and trust_all_ipv6 then
_IP.is_trusted = function() return true end
else
-- do not load if not needed
local matcher = ipmatcher.new(trusted_ips)
_IP.is_trusted = function(ip)
return not not matcher:match(ip)
end
end
return _IP
end
return {
new = new,
}