APISIX源码解析-插件-客户端IP【real-ip】

real-ip 客户端IP插件。

关键属性

在这里插入图片描述

源码解析

real-ip 插件用于动态改变传递到 APISIX 的客户端的 IP 和端口。

local function get_addr(conf, ctx)
    if conf.source == "http_x_forwarded_for" then
        -- use the last address from X-Forwarded-For header
        -- 用最后一个地址
        local addrs = core.request.header(ctx, "X-Forwarded-For")
        if not addrs then
            return nil
        end

        if type(addrs) == "table" then
            addrs = addrs[#addrs]
        end

        local idx = core.string.rfind_char(addrs, ",")
        if not idx then
            return addrs
        end

        for i = idx + 1, #addrs do
            if str_byte(addrs, i) == str_byte(" ") then
                idx = idx + 1
            else
                break
            end
        end

        return str_sub(addrs, idx + 1)
    end
    return ctx.var[conf.source]
end


function _M.rewrite(conf, ctx)
    if not is_apisix_or then
        core.log.error("need to build APISIX-OpenResty to support setting real ip")
        return 501
    end

    if conf.trusted_addresses then
        if not conf.matcher then
            conf.matcher = core.ip.create_ip_matcher(conf.trusted_addresses)
        end
        -- 校验是否在范围内
        local remote_addr = ctx.var.remote_addr
        local trusted = conf.matcher:match(remote_addr)
        if not trusted then
            return
        end
    end

    local addr = get_addr(conf, ctx)
    if not addr then
        core.log.warn("missing real address")
        return
    end

    local ip, port = core.utils.parse_addr(addr)
    if not ip or (not core.utils.parse_ipv4(ip) and not core.utils.parse_ipv6(ip)) then
        core.log.warn("bad address: ", addr)
        return
    end

    if str_byte(ip, 1, 1) == str_byte("[") then
        -- For IPv6, the `set_real_ip` accepts '::1' but not '[::1]'
        ip = str_sub(ip, 2, #ip - 1)
    end

    -- 端口范围正常时在 1到65535之间
    if port ~= nil and (port < 1 or port > 65535) then
        core.log.warn("bad port: ", port)
        return
    end

    core.log.info("set real ip: ", ip, ", port: ", port)

    local ok, err = client.set_real_ip(ip, port)
    if not ok then
        core.log.error("failed to set real ip: ", err)
        return
    end

    -- flush cached vars in APISIX
    ctx.var.remote_addr = nil
    ctx.var.remote_port = nil
    ctx.var.realip_remote_addr = nil
    ctx.var.realip_remote_port = nil
end
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值