HAProxy:将中间 IP 从 X-Forwarded-For 取到新的 header
HAProxy: Take the middle IP from X-Forwarded-For into a new header
在 haproxy.cfg
中,我试图从 x-forwarded-for header 中提取正确的 IP 地址到新的自定义 header。
我的输入请求 header 类似于
X-Forwarded-For: 1.2.3.4, 2.3.4.5, 3.4.5.6
我预期的新 header 会是这样的:
X-Custom-IP: 2.3.4.5
谢谢
原回答:
可以使用字段sample-fetcher转换关键字:
https://cbonte.github.io/haproxy-dconv/configuration-1.6.html#7.3.1-field
由于无法对当前 haproxy 中的字段进行计数,我将在 X-Forwarded-For header 上编写几个带有正则表达式的简单 ACL,检测 0、1、2、3、 4、5 个不同的 IP(或者实际上是逗号分隔符),并基于此,select 将适当的字段放入 X-Custom-IP.
例如(未测试)
acl x_forwarded_for_1_ips hdr(x-forwarded-for) -i (?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_2_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){1}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_3_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){2}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_4_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){3}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_5_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){4}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for)] if x_forwarded_for_1_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(2,\,)] if x_forwarded_for_2_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(2,\,)] if x_forwarded_for_3_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(3,\,)] if x_forwarded_for_4_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(3,\,)] if x_forwarded_for_5_ips
让我知道它是否适合您,或者您找到了其他更好的解决方案:)
编辑:有趣,我什至没花 5 分钟就找到了更好的解决方案。
使用 hdr_ip sample-fetcher:
https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#7.3.6-hdr_ip
您仍然需要 ACL 来计算 IP,但您可以使用 hdr_ip(x-forwarded-for,2) 和 hdr_ip(x-forwarded-for,3)直接,不需要Field()。
在 haproxy.cfg
中,我试图从 x-forwarded-for header 中提取正确的 IP 地址到新的自定义 header。
我的输入请求 header 类似于
X-Forwarded-For: 1.2.3.4, 2.3.4.5, 3.4.5.6
我预期的新 header 会是这样的:
X-Custom-IP: 2.3.4.5
谢谢
原回答:
可以使用字段sample-fetcher转换关键字: https://cbonte.github.io/haproxy-dconv/configuration-1.6.html#7.3.1-field
由于无法对当前 haproxy 中的字段进行计数,我将在 X-Forwarded-For header 上编写几个带有正则表达式的简单 ACL,检测 0、1、2、3、 4、5 个不同的 IP(或者实际上是逗号分隔符),并基于此,select 将适当的字段放入 X-Custom-IP.
例如(未测试)
acl x_forwarded_for_1_ips hdr(x-forwarded-for) -i (?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_2_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){1}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_3_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){2}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_4_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){3}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
acl x_forwarded_for_5_ips hdr(x-forwarded-for) -i ((?:[0-9]{1,3}\.){3}[0-9]{1,3},){4}(?:[0-9]{1,3}\.){3}[0-9]{1,3}
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for)] if x_forwarded_for_1_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(2,\,)] if x_forwarded_for_2_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(2,\,)] if x_forwarded_for_3_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(3,\,)] if x_forwarded_for_4_ips
http-request add-header X-Custom-Ip %[hdr(x-forwarded-for),field(3,\,)] if x_forwarded_for_5_ips
让我知道它是否适合您,或者您找到了其他更好的解决方案:)
编辑:有趣,我什至没花 5 分钟就找到了更好的解决方案。
使用 hdr_ip sample-fetcher: https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#7.3.6-hdr_ip
您仍然需要 ACL 来计算 IP,但您可以使用 hdr_ip(x-forwarded-for,2) 和 hdr_ip(x-forwarded-for,3)直接,不需要Field()。