HAPROXY博主也使用了很长时间了,从对端口转发有需求之后早期接触到的就是haproxy
,后来逐渐接触到了负载均衡、后端检查、SNI转发这些功能,趁着有空对它们的配置文件做一个简单的记录。
HAPROXY的安装非常简便,直接使用apt install haproxy
/yum install haproxy
即可,相应的配置文件位于/etc/haproxy/haproxy.cfg
。实现TCP转发和SNI Proxy,Socat和NGINX Stream同样可以做到。相比Socat,HAPROXY功能更丰富一些,使用配置文件运行的方式更加直观;相比NGINX,HAPROXY是一个额外的轻量化软件,也可以保留博主之前单纯Web Server认知。
一、TCP端口转发
HAPROXY配置文件中frontend
与backend
需要严格一一对应,以下的几个配置文件部分内容也是互通的,可以按照自己的需求进行修改。这样做端口转发是有不足的,它并不能实现UDP转发,现在博主的纯端口转发工具更倾向于基于Rust构建的realm
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#--------------------------------------------------------------------- # 全局设定部分 #--------------------------------------------------------------------- global defaults log global mode tcp option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 #--------------------------------------------------------------------- # TCP端口转发 #--------------------------------------------------------------------- frontend swas-in bind *:443 # 监听IPv6及同时监听的写法 #bind [::]:443 #bind :::443 v4v6 maxconn 20000 default_backend swas-out backend swas-out server HKG-1 104.19.20.20:443 maxconn 20480 |
二、负载均衡
负载均衡功能,是博主前两年爬取数据时用于均衡节点地址和反代ao3时用到的。本段插入了一段开启HAPROXY状态页面的参数,可以通过这个页面观察到HAPROXY的工作状况。
后端检查博主只用到了一个TCP Check,相应的HAPROXY还支持GET、HEAD Check,在此仅作记录不做过多赘述,更多关于后端检查的内容可以查看官方博客的介绍。
https://www.haproxy.com/blog/how-to-enable-health-checks-in-haproxy/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#--------------------------------------------------------------------- # 全局设定部分 #--------------------------------------------------------------------- global defaults log global mode tcp option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 #--------------------------------------------------------------------- # HAPROXY状态页面 #--------------------------------------------------------------------- listen admin_stats stats enable # 监听端口 bind *:12345 mode http option httplog log global maxconn 10 # 刷新间隔 stats refresh 30s # 页面路径 stats uri / stats realm haproxy # 访问认证 stats auth admin:password stats hide-version #--------------------------------------------------------------------- # TCP转发及负载均衡及简单TCP可用性校验 # weight权重;check inter检测频率;rise 1一次可用恢复;fall 2两次失败降级 #--------------------------------------------------------------------- frontend cf-in bind *:10000 maxconn 20000 default_backend cf-out backend cf-out #使用HTTP对URI路径可用性进行检测 #option httpchk #http-check send meth GET uri /check.html #http-check expect status 200 server HKG-1 104.16.157.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 server HKG-2 104.19.235.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 server HKG-3 162.159.251.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 server KIX-1 104.18.54.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 server KIX-2 104.19.74.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 server SIN-1 104.24.104.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 server SIN-2 162.159.210.86:443 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 |
三、SNI转发
SNI转发是在TCP转发的基础上识别SNI并将流量以四层转发的形式送往源站,好处就是作为中间节点可以直接转发任意站点的流量而不涉及SSL证书的部署。例如博主的go.moelty.cn
,相比于直接无法控制的TCP端口转发,SNI的存在可以控制访客不能随意使用博主对CF的转发,并且具有同样高的效率和更多源站的支持。更加详细的配置请参考以下的HAProxy SNI Example。
https://gist.github.com/mbentley/0e887c2af7863a562146ee23b121fb33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#--------------------------------------------------------------------- # 全局设定部分 #--------------------------------------------------------------------- global defaults 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 #--------------------------------------------------------------------- # 接管HTTP流量实现301跳转HTTPS #--------------------------------------------------------------------- frontend http bind :80 mode http redirect scheme https code 301 if { hdr(Host) -i site1.example.com } !{ ssl_fc } redirect scheme https code 301 if { hdr(Host) -i site2.example.com } !{ ssl_fc } #--------------------------------------------------------------------- # 通过SNI Proxy对HTTPS流量实现四层转发 #--------------------------------------------------------------------- frontend https_proxy mode tcp bind :443 tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } acl is_site1.example.com req_ssl_sni -i site1.example.com acl is_site2.example.com req_ssl_sni -i site2.example.com use_backend site1.example.com if is_site1.example.com use_backend site2.example.com if is_site2.example.com backend site1.example.com server web1 104.18.10.10:443 backend site2.example.com server web1 104.18.10.12:443 |
补充一个使用DDNS的写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#--------------------------------------------------------------------- # 定义DNS解析器 #--------------------------------------------------------------------- resolvers dns1 nameserver internal-dns 1.1.1.1:53 resolve_retries 3 timeout resolve 10s timeout retry 10s hold other 30s hold refused 30s hold nx 30s hold timeout 30s # 对有效的DNS响应保存和使用10秒 hold valid 10s hold obsolete 30s #--------------------------------------------------------------------- # 将解析器应用于源站设置 #--------------------------------------------------------------------- frontend https_proxy mode tcp bind :443 tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } acl is_example.com req_ssl_sni -i example.com use_backend example.com if is_example.com backend example.com server ddns-1 ddns.example.com:8080 resolvers dns1 resolve-prefer ipv4 |
四、存在问题
1、经过SNI Proxy后访客真实IP被隐藏,只能通过Proxy Protocol获取,会导致如CloudFlare WAF功能部分失效。使用时建议在CloudFlare WAF中为你的节点设置白名单,具有Pro及以上套餐的朋友请额外在托管规则中关闭Fake Baidu Bot
等条目以避免对SEO的影响。
2、多个网站相同源站的情况下,若开启HTTP2长连接,SNI Proxy可能会导致后访问的站点复用之前的连接进入错误的网站。建议对于每一个站点选择不同的源站以避免这种情况。
五、结语
写这篇文章之前CloudFlare在中国大陆地区受到干扰日益加重,网络波动也是时常的事,博主不得不考虑一些中转的方案。使用SNI Proxy实现四层TCP转发相比反代可以免去维护证书这一步骤,转发效率也非常可观。基于这个原理可以在内网中实现对一些站点的直接转发加速,而不影响站点中的数据。
HAPROXY是一个功能非常强大而复杂的软件,在生产中有大量的参数可以设置进行调优,可以从51cto
这篇文章中略知一二(点击前往)。此外,通过apt
/yum
库安装的HAPROXY版本较旧,若有对新功能的需求建议自行编译较新的版本使用。
博主近段时间接触的新东西很少,希望这篇文章能够对你有所帮助,也希望熟练使用HAPROXY的朋友能够共同分享您宝贵的经验指正博主的不足~
*手记文章,转载无需注明出处
请问如何使用Haproxy代理后端cloudflare域名?我cloudflare域名开启CDN后就不通了。
这个方法能实现tcp代理经过cloudflare流量进行加速吗
现在想使用cloudflare对国外服务器10000端口加速有什么办法吗?
找了很久,学到了!
一直在用, 现在cf干扰比较严重, v6好些。 不过haproxy的一个问题是只有tcp, 现在udp的quic似乎更快, 查了下可以试试 gost负载
又开始整活了