HAProxy 中的动态服务器名称和 header
Dynamic server name and header in HAProxy
我正在寻找与下面这个后端代码块等效的请求 www.example.com 和 example.com。
http-response set-header X-Target example.com
server web-servers site.example.com:80 check
我将所有请求发送到 www.example.com,但我想使用 haproxy 将它们提供给站点。example.com。 example.com 有几种变体,所以我想要一个允许域的列表,然后如果允许它们,我想要一个后端代码块,如下所示,我可以在其中使用 %[req.hdr (Host)] 作为 http-response X-Target 语句中的值。
http-response set-header X-Target %[req.hdr(Host)]
server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check
HA-Proxy 版本 2.1.4-273103-54 2020/05/07 - https://haproxy.org/
当我尝试 haproxy -c -f haproxy.test
时出现此错误
[root@pm-prod-haproxy05 haproxy]# haproxy -c -f haproxy.test
[警报] 259/180932 (16116):解析 [haproxy.test:40]:'http-response set-header':此处可能无法可靠地使用样本提取,因为它需要 'HTTP 请求 headers' 此处不可用。
[警报] 259/180932 (16116):配置文件中发现错误:haproxy.test
[root@pm-prod-haproxy05 haproxy]#
我也试过这个:
http-request set-header X-Target %[req.hdr(Host)]
http-request set-header X-Hostname %[req.hdr(Host),regsub(^www.,site.,)]
http-request web-server do-lookup(hdr(X-Hostname))
server web-servers web-server:80 check
这是我的完整配置。
global
log 127.0.0.1 local2 debug
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
option httplog
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend frontend-http
bind *:80
bind *:443
acl redirect path_beg -i /rd
use_backend backend-tracking if redirect
default_backend backend-default
backend backend-default
option forwardfor
http-response set-header X-Publishing-system website
http-response set-header X-Target %[req.hdr(Host)]
server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check
backend backend-tracking
option forwardfor
http-response set-header X-Publishing-system redirect
http-request set-uri %[url,regsub(^/rd,/,)]
server web-hp www.trackingplatform.com:80 check
关于Header操纵
正如警报消息所说,您不能在响应中使用请求 header。您应该替换以下行。
线路错误
http-response set-header X-Target %[req.hdr(Host)]
右线
http-request set-header X-Target %[req.hdr(Host)]
Backend-Server 不应该删除此 header。如果您不想将 Backend-Server 发送给 'X-Target' 主机 header 那么您可以使用 session 变量来保存从请求到响应的主机 header相.
http-request set-var(txn.my_host) req.hdr(host),lower
http-response set-header X-Target %[var(txn.my_host)]
文档中对 set-var 和 set-header 指令进行了很好的解释。
http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-http-request
关于服务器操作
此行无法运行,因为 haproxy 会在启动时尝试解析目标服务器。
server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check
在较新版本的 haproxy 中。像2.1一样,你能动态解析和设置目标主机吗?
http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4.2-http-request%20do-resolve
我假设您想为使用正确虚拟服务器的目标服务器更改主机 header。
我对解决您的问题的建议是更改主机 header 并将服务器名称设置为可解析的地址。
backend backend-default
option forwardfor
http-response set-header X-Publishing-system website
http-request set-header X-Target %[req.hdr(Host)]
http-request replace-header Host ^www(.*) site.
http-request set-header X-NewTarget %[req.hdr(Host),regsub(^www.,,)]
server web-servers site.example.com:80 check
此后端配置仅进行语法检查。
关于动态后端服务器
server
应该动态解析。
对于该解决方案,至少需要 HAProxy 2.0。
我在此处复制了文档的某些部分 http-request do-resolve 作为此答案。
您需要在配置中添加一个部分 resolvers
resolvers mydns
# use here your prefered DNS Servers
nameserver local 127.0.0.53:53
nameserver google 8.8.8.8:53
timeout retry 1s
hold valid 10s
hold nx 3s
hold other 3s
hold obsolete 0s
accepted_payload_size 8192
frontend frontend-http
bind *:80
bind *:443
# define capture buffer for backend
declare capture request len 60
acl redirect path_beg -i /rd
use_backend backend-tracking if redirect
default_backend backend-default
# ... some more backends
backend backend-default
option forwardfor
http-response set-header X-Publishing-system website
http-request set-header X-Target %[req.hdr(Host)]
# replace www with site in host header
http-request replace-header Host ^www(.*) site.
# if necessary set X-NewTarget header
http-request set-header X-NewTarget %[req.hdr(Host),regsub(^www.,,)]
# do dynamic host resolving for dynamic
# server destination for
# the replaced Host Header above
http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),lower
# print the resolved IP in the log
http-request capture var(txn.myip) id 0
# rule to prevent HAProxy from reconnecting to services
# on the local network (forged DNS name used to scan the network)
# add the IP Range for the destination host here
http-request deny if { var(txn.myip) -m ip 127.0.0.0/8 10.0.0.0/8 }
http-request set-dst var(txn.myip)
server clear 0.0.0.0:0
请注意文档中的注释
注意:不要忘记设置 "protection" 规则以确保 HAProxy 不会被用于扫描网络或最坏的情况下不会在自身上循环...
我正在寻找与下面这个后端代码块等效的请求 www.example.com 和 example.com。
http-response set-header X-Target example.com
server web-servers site.example.com:80 check
我将所有请求发送到 www.example.com,但我想使用 haproxy 将它们提供给站点。example.com。 example.com 有几种变体,所以我想要一个允许域的列表,然后如果允许它们,我想要一个后端代码块,如下所示,我可以在其中使用 %[req.hdr (Host)] 作为 http-response X-Target 语句中的值。
http-response set-header X-Target %[req.hdr(Host)]
server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check
HA-Proxy 版本 2.1.4-273103-54 2020/05/07 - https://haproxy.org/
当我尝试 haproxy -c -f haproxy.test
时出现此错误[root@pm-prod-haproxy05 haproxy]# haproxy -c -f haproxy.test [警报] 259/180932 (16116):解析 [haproxy.test:40]:'http-response set-header':此处可能无法可靠地使用样本提取,因为它需要 'HTTP 请求 headers' 此处不可用。 [警报] 259/180932 (16116):配置文件中发现错误:haproxy.test [root@pm-prod-haproxy05 haproxy]#
我也试过这个:
http-request set-header X-Target %[req.hdr(Host)]
http-request set-header X-Hostname %[req.hdr(Host),regsub(^www.,site.,)]
http-request web-server do-lookup(hdr(X-Hostname))
server web-servers web-server:80 check
这是我的完整配置。
global
log 127.0.0.1 local2 debug
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
option httplog
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend frontend-http
bind *:80
bind *:443
acl redirect path_beg -i /rd
use_backend backend-tracking if redirect
default_backend backend-default
backend backend-default
option forwardfor
http-response set-header X-Publishing-system website
http-response set-header X-Target %[req.hdr(Host)]
server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check
backend backend-tracking
option forwardfor
http-response set-header X-Publishing-system redirect
http-request set-uri %[url,regsub(^/rd,/,)]
server web-hp www.trackingplatform.com:80 check
关于Header操纵
正如警报消息所说,您不能在响应中使用请求 header。您应该替换以下行。
线路错误
http-response set-header X-Target %[req.hdr(Host)]
右线
http-request set-header X-Target %[req.hdr(Host)]
Backend-Server 不应该删除此 header。如果您不想将 Backend-Server 发送给 'X-Target' 主机 header 那么您可以使用 session 变量来保存从请求到响应的主机 header相.
http-request set-var(txn.my_host) req.hdr(host),lower
http-response set-header X-Target %[var(txn.my_host)]
文档中对 set-var 和 set-header 指令进行了很好的解释。
http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-http-request
关于服务器操作
此行无法运行,因为 haproxy 会在启动时尝试解析目标服务器。
server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check
在较新版本的 haproxy 中。像2.1一样,你能动态解析和设置目标主机吗?
http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4.2-http-request%20do-resolve
我假设您想为使用正确虚拟服务器的目标服务器更改主机 header。
我对解决您的问题的建议是更改主机 header 并将服务器名称设置为可解析的地址。
backend backend-default
option forwardfor
http-response set-header X-Publishing-system website
http-request set-header X-Target %[req.hdr(Host)]
http-request replace-header Host ^www(.*) site.
http-request set-header X-NewTarget %[req.hdr(Host),regsub(^www.,,)]
server web-servers site.example.com:80 check
此后端配置仅进行语法检查。
关于动态后端服务器
server
应该动态解析。
对于该解决方案,至少需要 HAProxy 2.0。
我在此处复制了文档的某些部分 http-request do-resolve 作为此答案。
您需要在配置中添加一个部分 resolvers
resolvers mydns
# use here your prefered DNS Servers
nameserver local 127.0.0.53:53
nameserver google 8.8.8.8:53
timeout retry 1s
hold valid 10s
hold nx 3s
hold other 3s
hold obsolete 0s
accepted_payload_size 8192
frontend frontend-http
bind *:80
bind *:443
# define capture buffer for backend
declare capture request len 60
acl redirect path_beg -i /rd
use_backend backend-tracking if redirect
default_backend backend-default
# ... some more backends
backend backend-default
option forwardfor
http-response set-header X-Publishing-system website
http-request set-header X-Target %[req.hdr(Host)]
# replace www with site in host header
http-request replace-header Host ^www(.*) site.
# if necessary set X-NewTarget header
http-request set-header X-NewTarget %[req.hdr(Host),regsub(^www.,,)]
# do dynamic host resolving for dynamic
# server destination for
# the replaced Host Header above
http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),lower
# print the resolved IP in the log
http-request capture var(txn.myip) id 0
# rule to prevent HAProxy from reconnecting to services
# on the local network (forged DNS name used to scan the network)
# add the IP Range for the destination host here
http-request deny if { var(txn.myip) -m ip 127.0.0.0/8 10.0.0.0/8 }
http-request set-dst var(txn.myip)
server clear 0.0.0.0:0
请注意文档中的注释
注意:不要忘记设置 "protection" 规则以确保 HAProxy 不会被用于扫描网络或最坏的情况下不会在自身上循环...