wonderbeyond
2/6/2017 - 9:04 AM

IP 分组定义与管理

IP 分组定义与管理

local iputils = require("resty.iputils")
--iputils.enable_lrucache()

local group_defs = {
    localhost = {
        '127.0.0.1',
    },
    staff = {
        'x.x.x.x',
        '10.10.10.0/24',
    },
    waf = {
        'x.x.x.x/24',
    },
    slb = {
        'x.x.x.x',
    },
    all = {
        -- WARN: `0.0.0.0/0` isn't supported here!
        '0.0.0.0/1',
        '128.0.0.0/2',
        '192.0.0.0/3',
        '224.0.0.0/4',
    },
    banned = {
        '54.183.93.152',
        '117.135.144.51',
        '218.29.184.145',
    },
}

local group_alias = {
    aliyun = 'slb,waf',
}

function resolve_alias (input)
    -- e.g.
    -- Alias:
    --  Alias A=Ada
    --  Alias B=Bla
    --  Alias C=Cly
    --  Alias A_B=A,B
    --
    -- Resolve('A') => 'Ada'
    -- Resolve('A,B') => 'Ada,Bla'
    -- Resolve('A_B,C') => Resolve('A,B,Cly') => 'Ada,Bla,Cly'
    local resolved_parts = {}

    local it, err = ngx.re.gmatch(input, [=[[^\s\,]+]=])

    while true do
        local m = it()

        if not m then
            break
        end
        part = m[0]

        if group_alias[part] then
            part = resolve_alias(group_alias[part])
        end

        table.insert(resolved_parts, part)
    end

    return table.concat(resolved_parts, ',')
end

-- Store ip lists that are parsed to binary
local cidr_parsed_groups = {}

local exports = {
    get_all = function (self)
        return group_defs
    end,

    get_all_bin = function (self)
        return cidr_parsed_groups
    end,

    get = function (self, grps)
        local req_grps_name = grps

        grps = resolve_alias(grps)

        if group_defs[grps] then
            return group_defs[grps]
        end

        local it, err = ngx.re.gmatch(grps, [=[[^\s\,]+]=])
        local ip_set = {}
        local all_valid = true

        if not it then
            return nil
        end

        while true do
            local m = it()
            if not m then
                break
            end
            local grp_name = m[0]
            if group_defs[grp_name] then
                for _, ip_addr in pairs(group_defs[grp_name]) do
                    table.insert(ip_set, ip_addr)
                end
            else
                all_valid = false
                ngx.log(ngx.WARN, string.format('%s is an invalid IP group', grp_name))
            end
        end

        if all_valid and next(ip_set) then
            group_defs[req_grps_name] = ip_set
        end

        return ip_set
    end,

    get_parsed = function(self, grps)
        if cidr_parsed_groups[grps] then
            return cidr_parsed_groups[grps]
        end

        local raw_list = self:get(grps)
        local bin_list

        if raw_list then
            bin_list = iputils.parse_cidrs(raw_list)
            cidr_parsed_groups[grps] = bin_list
        end

        return bin_list
    end,
}

return exports