在看haproxy的官方配置的时候,发现其中有一个使用use-server
的例子。可以根据https的域名来选择后端的server,从而实现根据域名将https的请求做负载。
想到之前也有一个类似的需求,好像因为当时没有找到解决方案就将功能放入了默认的后端server组里。
今天测试了一下,发现可以按照相似的思路实现根据https的域名做负载。
官方的示例
# intercept incoming TLS requests based on the SNI field
use-server www if { req_ssl_sni -i www.example.com }
server www 192.168.0.1:443 weight 0
use-server mail if { req_ssl_sni -i mail.example.com }
server mail 192.168.0.1:587 weight 0
use-server imap if { req_ssl_sni -i imap.example.com }
server imap 192.168.0.1:993 weight 0
# all the rest is forwarded to this server
server default 192.168.0.2:443 check
通过文档介绍可以看到,use-server仅仅可以用在 listen 和 backend。当有很多后端server组成一个集群的时候,这个方法不好用。
因此,想到既然use-server
不行,就换成use_backend
吧。这样不就可以了吗
自己的示例
frontend https
bind :443 ssl crt /etc/haproxy/ssl/site.pem crt /etc/haproxy/ssl/example.pem #①
use_backend site if { ssl_fc_sni -i www.site.com } #②
use_backend example if { ssl_fc_sni_end -i example.com } #③
backend site
mode http
option forwardfor
balance roundrobin
server myserver1 192.168.105.15:80 weight 1 check inter 10000
server myserver2 192.168.105.17:80 weight 1 check inter 10000
backend example
mode http
option forwardfor
balance roundrobin
server server1 192.168.105.14:80 weight 1
server server2 192.168.101.14:80 weight 1
① 配置了多个站点的ssl配置文件
② 使用ssl_fc_sni
获取https访问的情况下的host,类似于req.hdr(host)。-i表示忽略大小写
③ 除了使用ssl_fc_sni
做精准配置,还可以使用ssl_fc_sni_beg
和 `ssl_fc_end
做前缀和后缀的匹配
测试可以达到预期目的。