HAProxy 1.4:如何用自定义 IP 替换 X-Forwarded-For
HAProxy 1.4: how to replace X-Forwarded-For with custom IP
我在 AWS ELB 后面有一个 HAProxy 1.4 服务器。逻辑上,ELB 在 X-Forwarded-For
header 中发送用户 IP。我的应用读取 header 并根据 IP(国家/地区)表现不同。
我想测试使用自定义 IP 覆盖 X-Forwarded-For
的行为,但 AWS ELB 将我的自定义值附加到我当前的 IP (X-Forwarded-For: 1.2.3.4, 200.1.130.2
)
我一直试图做的是发送另一个自定义 header X-Force-IP
,一旦它进入 HAproxy,删除 X-Forwarded-For
headers 并使用 reqirep
将名称 X-Force-IP
更改为 X-Forwarded-For
这是我的配置块的样子
acl custom-ip hdr_cnt(X-Force-IP) 1
reqidel ^X-Forwarded-For:.* if custom-ip
reqrep X-Force-IP X-Forwarded-For if custom-ip
但是当它进入我的应用程序时,应用程序服务器 (lighttpd) 以 "HTTP 400 Bad Request" 拒绝它,就好像它格式不正确一样。
[ec2-user@haproxy-stage]$ curl -I -H "X-Forwarded-For: 123.456.7.12" "http://www.example.com"
HTTP/1.1 200 OK
Set-Cookie: PHPSESSID=mcs0tqlsg31haiavqopdvm02i6; path=/; domain=www.example.com
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Date: Sun, 11 Jan 2015 02:57:34 GMT
Server: beta
[ec2-user@haproxy-stage]$ curl -I -H "X-Forwarded-For: 123.456.7.12" -H "X-Force-IP: 321.456.7.12" "http://www.example.com"
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Date: Sun, 11 Jan 2015 02:57:44 GMT
Server: beta
从之前的情况来看,ACL 似乎正在运行。
我在应用程序服务器中检查了 tcpdump,它似乎删除了 X-Forwarded-For
header 但也删除了 X-Force-IP
而不是替换它。
[ec2-user@beta ~]# sudo tcpdump -A -s 20240 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | egrep --line-buffered "^........(GET |HTTP\/|POST |HEAD )|^[A-Za-z0-9-]+: " | sed -r 's/^........(GET |HTTP\/|POST |HEAD )/\n/g'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 20240 bytes
GET / HTTP/1.1
User-Agent: curl/7.38.0
Host: www.example.com
Accept: */*
Connection: close
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
Date: Sun, 11 Jan 2015 02:56:50 GMT
Server: beta
前一个有X-Force-IP
,下一个没有
GET / HTTP/1.1
User-Agent: curl/7.38.0
Host: www.example.com
Accept: */*
X-Forwarded-For: 123.456.7.12
Connection: close
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.4
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Connection: close
Transfer-Encoding: chunked
Date: Sun, 11 Jan 2015 02:57:02 GMT
Server: beta
^C71 packets captured
71 packets received by filter
0 packets dropped by kernel
有什么帮助吗?
我期待 "X-Force-IP: 321.456.7.12" 转换为 "X-Forwarded-For: 321.456.7.12"
谢谢!
伊格纳西奥
此处提供的正则表达式匹配不进行简单替换。还是比较厉害的,一定要好好利用。
reqrep ^X-Force-IP:(.*) X-Forwarded-For: if custom-ip
reqrep
(区分大小写的请求正则表达式替换)和reqirep
(不区分大小写的请求正则表达式替换)指令在单个请求 header 级别运行,替换 header name and its value with the 2nd argument, if the 1st argument matches... 所以如果有你想保留的信息(比如值)你需要一个或多个捕获组,例如第一个参数中的 (.*)
,以及第二个参数中的占位符 </code>,以便保留数据。</p>
<p>您当前的配置确实通过创建 malformed/incomplete header 行使请求无效。</p>
<p>此外,您应该使用 <code>^
将模式固定在 header 名称的左侧。否则,表达式可能会匹配比预期更多的 header。
我在 AWS ELB 后面有一个 HAProxy 1.4 服务器。逻辑上,ELB 在 X-Forwarded-For
header 中发送用户 IP。我的应用读取 header 并根据 IP(国家/地区)表现不同。
我想测试使用自定义 IP 覆盖 X-Forwarded-For
的行为,但 AWS ELB 将我的自定义值附加到我当前的 IP (X-Forwarded-For: 1.2.3.4, 200.1.130.2
)
我一直试图做的是发送另一个自定义 header X-Force-IP
,一旦它进入 HAproxy,删除 X-Forwarded-For
headers 并使用 reqirep
将名称 X-Force-IP
更改为 X-Forwarded-For
这是我的配置块的样子
acl custom-ip hdr_cnt(X-Force-IP) 1
reqidel ^X-Forwarded-For:.* if custom-ip
reqrep X-Force-IP X-Forwarded-For if custom-ip
但是当它进入我的应用程序时,应用程序服务器 (lighttpd) 以 "HTTP 400 Bad Request" 拒绝它,就好像它格式不正确一样。
[ec2-user@haproxy-stage]$ curl -I -H "X-Forwarded-For: 123.456.7.12" "http://www.example.com"
HTTP/1.1 200 OK
Set-Cookie: PHPSESSID=mcs0tqlsg31haiavqopdvm02i6; path=/; domain=www.example.com
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Date: Sun, 11 Jan 2015 02:57:34 GMT
Server: beta
[ec2-user@haproxy-stage]$ curl -I -H "X-Forwarded-For: 123.456.7.12" -H "X-Force-IP: 321.456.7.12" "http://www.example.com"
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Date: Sun, 11 Jan 2015 02:57:44 GMT
Server: beta
从之前的情况来看,ACL 似乎正在运行。
我在应用程序服务器中检查了 tcpdump,它似乎删除了 X-Forwarded-For
header 但也删除了 X-Force-IP
而不是替换它。
[ec2-user@beta ~]# sudo tcpdump -A -s 20240 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | egrep --line-buffered "^........(GET |HTTP\/|POST |HEAD )|^[A-Za-z0-9-]+: " | sed -r 's/^........(GET |HTTP\/|POST |HEAD )/\n/g'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 20240 bytes
GET / HTTP/1.1
User-Agent: curl/7.38.0
Host: www.example.com
Accept: */*
Connection: close
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
Date: Sun, 11 Jan 2015 02:56:50 GMT
Server: beta
前一个有X-Force-IP
,下一个没有
GET / HTTP/1.1
User-Agent: curl/7.38.0
Host: www.example.com
Accept: */*
X-Forwarded-For: 123.456.7.12
Connection: close
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.4
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Connection: close
Transfer-Encoding: chunked
Date: Sun, 11 Jan 2015 02:57:02 GMT
Server: beta
^C71 packets captured
71 packets received by filter
0 packets dropped by kernel
有什么帮助吗? 我期待 "X-Force-IP: 321.456.7.12" 转换为 "X-Forwarded-For: 321.456.7.12"
谢谢! 伊格纳西奥
此处提供的正则表达式匹配不进行简单替换。还是比较厉害的,一定要好好利用。
reqrep ^X-Force-IP:(.*) X-Forwarded-For: if custom-ip
reqrep
(区分大小写的请求正则表达式替换)和reqirep
(不区分大小写的请求正则表达式替换)指令在单个请求 header 级别运行,替换 header name and its value with the 2nd argument, if the 1st argument matches... 所以如果有你想保留的信息(比如值)你需要一个或多个捕获组,例如第一个参数中的 (.*)
,以及第二个参数中的占位符 </code>,以便保留数据。</p>
<p>您当前的配置确实通过创建 malformed/incomplete header 行使请求无效。</p>
<p>此外,您应该使用 <code>^
将模式固定在 header 名称的左侧。否则,表达式可能会匹配比预期更多的 header。