Skip to content


nginx用map获取X-Forwarded-For中的客户端ipv4/ipv6地址

网上搜搜连个像样的取ipv6代码也没有,这里写一个.如果有合法的http_x_forwarder_for就取第一或最后一个,没有则取直连IP.


$ForwardedFirstIp 容易伪造,但可以做流量控制用
$ForwardedLastIp 在前端代理可信情况下,可以做IP限制用

http
{

#获取左边第一个
map $http_x_forwarded_for $ForwardedFirstIp {
    default $remote_addr;
    ~^(?P<firstAddr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[0-9a-fA-F]+:[0-9a-fA-F:]+:[0-9a-fA-F\.]+),?.*$ $firstAddr;
}



#获取右边第一个
map $http_x_forwarded_for $ForwardedLastIp {
    default $remote_addr;
    ~,?(?P<lastAddr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[0-9a-fA-F]+:[0-9a-fA-F:]+:[0-9a-fA-F\.]+)$ $lastAddr;
}

}

支持ipv4;

支持ipv6缩写如 1080::8:800:200C:417A
支持正常ipv6如 2409:8907:a125:2e4d:c5d:9d59:c2d5:a13a
支技ipv4映射地址如 0:0:0:0:0:ffff:192.168.56.10
但不支持::简写回环等如 ::1 , ::192.168.56.10

2022/1/4更新
更严谨的正则语法
支持::1回环,支持 ::192.168.56.10
格式不正确返回空
没有forwared时取remote_addr

map $http_x_forwarded_for $ForwardedFirstIp {
    "" $remote_addr;
    "~(?<firstAddr>([0-9]{1,3}\.){3}[0-9]{1,3}|[0-9a-fA-F]{0,4}:[0-9a-fA-F:]{0,30}:[0-9a-fA-F\.]{1,15}),?.*$" $firstAddr;
}
map $http_x_forwarded_for $ForwardedLastIp {
    "" $remote_addr;
    "~,?\s?(?<lastAddr>([0-9]{1,3}\.){3}[0-9]{1,3}|[0-9a-fA-F]{0,4}:[0-9a-fA-F:]{0,30}:[0-9a-fA-F\.]{1,15})$" $lastAddr;
}

2022/1/13更新

支持[]包含的ipv6块



    map $http_x_forwarded_for $ForwardedFirstIp {
        default $remote_addr;
        "~\[?(?<firstAddr>([0-9]{1,3}\.){3}[0-9]{1,3}|[0-9a-fA-F]{0,4}:[0-9a-fA-F:]{0,30}:[0-9a-fA-F\.]{1,15})\]?,?.*$" $firstAddr;
    }
    map $http_x_forwarded_for $ForwardedLastIp {
        default $remote_addr;
        "~,?\s?\[?(?<lastAddr>([0-9]{1,3}\.){3}[0-9]{1,3}|[0-9a-fA-F]{0,4}:[0-9a-fA-F:]{0,30}:[0-9a-fA-F\.]{1,15})\]?$" $lastAddr;
    }

Posted in Nginx.


No Responses (yet)

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.