我在AWS ELB后面有一台HAProxy 1.4服务器。逻辑上,ELB在X-Forwarded-For
标头中发送用户IP。我的应用程序读取该标题,并根据IP(国家/地区)采取不同的行为。
我想测试用自定义IP覆盖X-Forwarded-For
的行为,但AWS ELB会将我的自定义值附加到我当前的IP(X-Forwarded-For: 1.2.3.4, 200.1.130.2
)
我一直尝试发送另一个自定义标头X-Force-IP
,一旦进入HAproxy,删除X-Forwarded-For
标头并使用reqirep
更改名称{{1} } X-Force-IP
这就是我的配置块看起来像
X-Forwarded-For
但当它进入我的应用程序时,应用程序服务器(lighttpd)拒绝它" HTTP 400 Bad Request"好像它是畸形的。
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
从前面开始看起来ACL正在运行。
我在应用服务器中检查了 tcpdump ,似乎已删除了[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
标题但删除了X-Forwarded-For
而不是替换它。
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\1/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
有任何帮助吗? 我原本期待&#34; X-Force-IP:321.456.7.12&#34;转换为&#34; X-Forwarded-For:321.456.7.12&#34;
谢谢! 伊格纳西奥
答案 0 :(得分:3)
此处提供的正则表达式匹配不会进行简单替换。它的功能相当强大,必须相应地使用。
reqrep ^X-Force-IP:(.*) X-Forwarded-For:\1 if custom-ip
reqrep
(区分大小写的请求正则表达式替换)和reqirep
(不区分大小写的请求正则表达式替换)指令在单个请求标头级别运行,替换标头名称及其值第二个参数,如果第一个参数匹配...那么如果你想要保留的信息(例如值),你需要在第一个arg中有一个或多个捕获组,例如(.*)
,和第二个arg中的占位符\1
,以便保存数据。
您当前的配置确实会通过创建格式错误/不完整的标题行来使请求无效。
此外,您应该使用^
将模式锚定到标题名称的左侧。否则,表达式可能会匹配比预期更多的标题。