我想使用 HAproxy 配置简单重定向。
期望行为:HAProxy 收到对 example.com 的请求或https://example.com并从服务器列表中返回 https webserver 起始页,将自身排除在链之外。我尝试过 redirect location https://web1.com code 301 if example_acl
,它适用于单个服务器,但我需要重定向后的 5 个服务器,包括 web1.com、web2.com ... 和循环。也许后端部分有一些特定的配置?请帮忙
我当前的配置是
-#------------------- GLOBAL SETTINGS ---------------------------
...
-#------------------- FRONTEND HTTP ---------------------------
frontend http_in
mode http
option httplog
bind *:80
stats enable
redirect scheme https if { hdr(Host) -i example.com }
-#------------------- FRONTEND TCP ---------------------------
frontend tcp_in
mode tcp
option tcplog
bind *:443
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
acl example_acl req.ssl_sni -i example.com
use_backend special_example if example_acl
-#------------------- Server Farms ---------------------------
backend special_example
mode tcp
balance roundrobin
?
答案1
我同意评论者的观点,这似乎是一个不寻常的应用程序,但尽管如此,HAProxy 还是成功了。
我在测试代理上创建了一个 hosts 文件条目,以便 example.com 实际上指向 127.0.0.1,所以下面的测试是来自代理的实际响应。
假设我想通过example.com
重定向到四台服务器中的一台。external-1.example.com
external-4.example.com
这是一行代码——所有内容都在一行上,但为了清晰起见,这里显示为多行。
这进入 本frontend
节。
http-request redirect code 301
location http://external-%[rand(4),add(1)].%[req.hdr(host)]%[url]
if { req.hdr(host) -m str example.com }
{ req.hdr(host) -m str example.com }
是启用重定向的匿名 ACL,if
它与当前请求匹配。正在location
使用rand(n)
取样,生成一个介于 0 和 n-1 之间的随机数;然后将其值传递给add(x)
转换器,它将 x 添加到值中——在本例中,我们取 0 到 (4 - 1) 之间的可能值并加 1,这样表达式的%[rand(4),add(1)]
计算结果就是 1 到 4 之间的数字,并隐式转换为字符串。我们将http://external-
这个整数、一个点、传入的主机标头%[req.hdr(host)]
和 url连接起来%[url]
,其中包括路径和查询字符串。
测试 1:
$ curl -v http://example.com
* Rebuilt URL to: http://example.com/
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: example.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: http://external-4.example.com/
< Connection: close
测试2:
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: http://external-2.example.com/
< Connection: close
是的,正在起作用。
如果你需要重定向到一组未按顺序编号的主机名,解决方案会类似,但你会使用http-request set-var
将随机数存储在事务变量中,然后是一系列重定向语句,每个主机一个,每个语句都有自己的匿名 ACL,将评估随机值是否与与该主机匹配的整数相等,如果变量包含该值则重定向。
该rand()
提取不是加密质量的随机数生成器,但对于这种用例来说肯定足够了。