利用haproxy复用443端口同时使用tcp和http协议
Janz Lv4

最近买了一台aws的新加坡的机器,对三网的网络都很不错,遂想好好的利用一下这台机器的网络,做梯子有点大材小用了,同时可以用这台机器给我的主力机做网络代理。

为什么用Haproxy?

梯子一般用网络协议为tcp,而反代其他网站或者自己的网站是http协议的,而haproxy刚好可以利用sni很好的处理tcp和http协议,这就配置起来简单容易了很多,实际上我的nginx前端也是haproxy的。

什么是Haproxy(AI)?

HAProxy(High Availability Proxy)是一款开源的负载均衡器和代理服务器,常用于提高网络和应用程序的性能与可靠性。它通常部署在客户端与服务器之间,以分发客户端请求到多个后端服务器,从而实现负载均衡、故障转移、SSL 终止等功能。

主要特性:

  1. 负载均衡:HAProxy 可以在多个后端服务器之间分配请求,支持多种负载均衡算法(如轮询、最少连接、源地址哈希等)。
  2. 高可用性:HAProxy 支持对后端服务器的健康检查,可以在检测到某个服务器故障时自动停止向其发送请求。
  3. SSL/TLS 终止:HAProxy 能够处理和终止 SSL/TLS 连接,将加密流量解密后再转发给后端服务器,从而减轻后端服务器的负担。
  4. 内容重写:能够根据请求的内容对请求或响应进行重写,例如修改 URL 或插入 HTTP 头。
  5. HTTP/2 和 WebSocket 支持:支持现代的传输协议和技术,能够处理实时 Web 应用的连接。
  6. 丰富的监控与统计:提供详细的实时监控和日志功能,可以帮助运维人员了解流量情况和系统性能。

使用场景:

  • 网站负载均衡:将来自用户的请求均匀地分配到多台 Web 服务器上。
  • API 网关:在微服务架构中,HAProxy 可以作为 API 网关,管理不同服务之间的流量。
  • 高可用架构:用于确保关键应用和服务的高可用性,防止单点故障。

总结:

HAProxy 是一个灵活、强大且广泛使用的工具,适用于需要高性能、高可靠性的网络架构。其广泛的功能和配置选项,适合从中小型企业到大型互联网公司在内的各种场景。

使用场景

通用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#配置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

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
# 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证书,会加密转发到后端服务器,劣势是无法修改请求头,各有优势。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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证书,优势在于可以修改请求,并能隐藏后端服务器信息。

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
# 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

备忘自己使用的配置

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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分流真好呀。

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep