利用haproxy复用443端口同时使用tcp和http协议
编辑
80
2024-11-04
最近买了一台aws的新加坡的机器,对三网的网络都很不错,遂想好好的利用一下这台机器的网络,做梯子有点大材小用了,同时可以用这台机器给我的主力机做网络代理。
为什么用Haproxy?
梯子一般用网络协议为tcp,而反代其他网站或者自己的网站是http协议的,而haproxy刚好可以利用sni很好的处理tcp和http协议,这就配置起来简单容易了很多,实际上我的nginx前端也是haproxy的。
什么是Haproxy(AI)?
HAProxy(High Availability Proxy)是一款开源的负载均衡器和代理服务器,常用于提高网络和应用程序的性能与可靠性。它通常部署在客户端与服务器之间,以分发客户端请求到多个后端服务器,从而实现负载均衡、故障转移、SSL 终止等功能。
主要特性:
- 负载均衡:HAProxy 可以在多个后端服务器之间分配请求,支持多种负载均衡算法(如轮询、最少连接、源地址哈希等)。
- 高可用性:HAProxy 支持对后端服务器的健康检查,可以在检测到某个服务器故障时自动停止向其发送请求。
- SSL/TLS 终止:HAProxy 能够处理和终止 SSL/TLS 连接,将加密流量解密后再转发给后端服务器,从而减轻后端服务器的负担。
- 内容重写:能够根据请求的内容对请求或响应进行重写,例如修改 URL 或插入 HTTP 头。
- HTTP/2 和 WebSocket 支持:支持现代的传输协议和技术,能够处理实时 Web 应用的连接。
- 丰富的监控与统计:提供详细的实时监控和日志功能,可以帮助运维人员了解流量情况和系统性能。
使用场景:
- 网站负载均衡:将来自用户的请求均匀地分配到多台 Web 服务器上。
- API 网关:在微服务架构中,HAProxy 可以作为 API 网关,管理不同服务之间的流量。
- 高可用架构:用于确保关键应用和服务的高可用性,防止单点故障。
总结:
HAProxy 是一个灵活、强大且广泛使用的工具,适用于需要高性能、高可靠性的网络架构。其广泛的功能和配置选项,适合从中小型企业到大型互联网公司在内的各种场景。
使用场景
通用配置
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 24h
timeout client 24h
timeout server 24h
转发tcp流量给后端的Trojan Sever
#配置tcp入站,主要复用443端口
frontend tcp_in
mode tcp
bind *:443
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
# <sni_domin> Trojan sni domain
acl host_trojan req_ssl_sni -i <sni_domain>
# 2. tcp 转发后端处理
use_backend trojan_backend if host_trojan
# Trojan 后端配置,转发给本地的9000端口
backend trojan_backend
mode tcp
server trojan_server 127.0.0.1:9000 check
反代本地web网站并配置https
# http转https
frontend http_in
mode http
bind *:80
http-request redirect scheme https
# 配置http入站
frontend https_in
## 配置acme.sh申请证书
# export DEPLOY_HAPROXY_PEM_PATH=/usr/local/etc/haproxy/cert/
# export DEPLOY_HAPROXY_RELOAD="/bin/systemctl restart haproxy"
# acme.sh --deploy -d <domain> --deploy-hook haproxy
##
mode http
bind *:443 ssl crt /usr/local/etc/haproxy/cert alpn h2,http/1.1
# 配置日志
option httplog
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
# 捕获更多请求信息
capture request header Host len 40
capture request header User-Agent len 100
capture request header X-Forwarded-For len 15
# <web_domain> Web Sni Doamin
## hdr(host): 匹配域名
## hdr_end(host): 匹配子域名
acl host_web hdr(host) -i <web_domain>
use_backend nginx_server if host_web
# 未匹配转发
default_backend default_backend
# web后端,不传递其他Header信息
backend nginx_server
mode http
server nginx_server 127.0.0.1:8443 check
# 默认后端
backend default_backend
mode http
http-request deny
利用ssl透传反代其他服务器的web服务
优势在于不用在本机部署ssl证书,会加密转发到后端服务器,劣势是无法修改请求头,各有优势。
# ssl透传需要走tcp协议
frontend tcp_in
mode tcp
bind *:443
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
# 域名匹配规则
## 1. ssl透传
## tcp协议不能用hdr,需要使用req_ssl_sni
## -i:匹配域名
## -m sub:匹配子域名和自身
acl host_app req_ssl_sni -m <backend_web_domain>
# 1. ssl穿透,由后端服务器负责处理ssl,负载均衡服务器只负责加密转发,适合原域名转发的情况
use_backend forward_backend if host_app
# ssl穿透
backend forward_backend
mode tcp
#balance roundrobin
option ssl-hello-chk
server blog_server IP:443 weight 1 check inter 2000 rise 2 fall 4
本机终端ssl后转发到后端web服务器
接近cdn的原理,优势和劣势和上面的反过来,需要配置ssl证书,优势在于可以修改请求,并能隐藏后端服务器信息。
# http转https
frontend http_in
mode http
bind *:80
http-request redirect scheme https
# 配置http入站
frontend https_in
## 配置acme.sh申请证书
# export DEPLOY_HAPROXY_PEM_PATH=/usr/local/etc/haproxy/cert/
# export DEPLOY_HAPROXY_RELOAD="/bin/systemctl restart haproxy"
# acme.sh --deploy -d <domain> --deploy-hook haproxy
##
mode http
bind *:443 ssl crt /usr/local/etc/haproxy/cert alpn h2,http/1.1
# 配置日志
option httplog
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
# 捕获更多请求信息
capture request header Host len 40
capture request header User-Agent len 100
capture request header X-Forwarded-For len 15
# <web_domain> Web Sni Doamin
## hdr(host): 匹配域名
## hdr_end(host): 匹配子域名
acl host_backend_web hdr(host) -i <web_domain>
use_backend blog_backend if host_backend_web
# web后端,sni转发到其他服务器
backend blog_backend
mode http
option forwardfor
option http-server-close
# 保持客户端真实IP
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Real-IP %[src]
http-request set-header Host <backend_web_domain>
# 转发到远程nginx服务器
server nginx_server IP:443 ssl check verify none check-sni <backend_web_domain> sni str(<backend_web_domain>) inter 2000 rise 2 fall 4
备忘自己使用的配置
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 24h
timeout client 24h
timeout server 24h
# http转https
frontend http_in
mode http
bind *:80
http-request redirect scheme https
#配置tcp入站,主要复用443端口
frontend tcp_in
mode tcp
bind *:443
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
# 域名匹配规则
## 1. ssl透传
acl host_app req_ssl_sni -m <backend_web_domain>
## 2. 复用443 tcp代理
acl host_trojan req_ssl_sni -i <trojan_sni_domain>
# 1. ssl穿透,由后端服务器负责处理ssl,负载均衡服务器只负责加密转发,适合原域名转发的情况
use_backend forward_backend if host_app
# 2. tcp 转发后端处理
use_backend trojan_backend if host_trojan
# 配置http入站
frontend https_in
# export DEPLOY_HAPROXY_PEM_PATH=/usr/local/etc/haproxy/cert/
# export DEPLOY_HAPROXY_RELOAD="/bin/systemctl restart haproxy"
# acme.sh --deploy -d <domain> --deploy-hook haproxy
mode http
bind *:443 ssl crt /usr/local/etc/haproxy/cert alpn h2,http/1.1
# 配置日志
option httplog
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
# 捕获更多请求信息
capture request header Host len 40
capture request header User-Agent len 100
capture request header X-Forwarded-For len 15
# 处理web流量转发给后端
acl host_blog hdr(host) -i <web_domain>
use_backend blog_backend if host_blog
default_backend default_backend
# web后端,sni转发到其他服务器
backend blog_backend
mode http
option forwardfor
option http-server-close
# 保持客户端真实IP
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Real-IP %[src]
http-request set-header Host <backend_web_domain>
# 转发到远程nginx服务器
server nginx_server IP:443 ssl check verify none check-sni <backend_web_domain> sni str(<backend_web_domain>) inter 2000 rise 2 fall 4
# ssl穿透
backend forward_backend
mode tcp
#balance roundrobin
option ssl-hello-chk
server blog_server IP:443 weight 1 check inter 2000 rise 2 fall 4
# Trojan 后端配置
backend trojan_backend
mode tcp
server trojan_server 127.0.0.1:9000 check
# 默认后端
backend default_backend
mode http
http-request deny
后记
Haproxy做这个事情我觉得比Nginx要好不少,利用SNI分流真好呀。
- 0
- 0
-
分享