【HAProxy10】企业级反向代理HAProxy高级功能之四层负载与Https 实现
HAProxy 高级功能
介绍 HAProxy 高级配置及实用案例
HAProxy 四层负载
针对除HTTP以外的TCP协议应用服务访问的应用场景
MySQL
Redis
Memcached
RabbitMQ
问题: 后端服务器到底是与haproxy还是和客户端建立三次握手呢?
四层负载示例
注意:如果使用frontend和backend,一定在 frontend 和 backend 段中都指定mode tcp
listen redis-port
bind 10.0.0.7:6379
mode tcp
balance leastconn
server server1 10.0.0.17:6379 check
server server2 10.0.0.27:6379 check backup
范例:对 MySQL 服务实现四层负载
[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg
listen wang_mysql
bind 10.0.0.7:3306
mode tcp
balance leastconn
server mysql1 10.0.0.17:3306 check
server mysql2 10.0.0.27:3306 check #如果不写端口号,可以转发,但无法check状态
#或者使用frontend和backend实现
frontend mysql
bind :3306
mode tcp #必须指定tcp模式
default_backend mysqlsrvs
backend mysqlsrvs
mode tcp #必须指定tcp模式
balance leastconn
server mysql1 10.0.0.17:3306
server mysql2 10.0.0.27:3306
[root@centos7 ~]#systemctl restart haproxy
#在后端服务器安装和配置mariadb服务
[root@centos7 ~]#yum -y install mariadb-server
[root@centos7 ~]#mysql -e "grant all on *.* to test@'10.0.0.%' identified by '123456'"
[root@centos7 ~]#vim /etc/my.cnf
[mysqld]
server-id=17 #在另一台主机为27
[root@centos7 ~]#systemctl start mariadb
#测试
[root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'"
+---------------+--------------------------+
| Variable_name | Value |
+---------------+--------------------------+
| hostname | centos17.wangxiaochu.com |
+---------------+--------------------------+
[root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'"
+---------------+--------------------------+
| Variable_name | Value |
+---------------+--------------------------+
| hostname | centos27.wangxiaochu.com |
+---------------+--------------------------+
[root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id'
+-------------+
| @@server_id |
+-------------+
|
17 |
+-------------+
[root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id'
+-------------+
| @@server_id |
+-------------+
|
27 |
+-------------+
ACL示例-四层访问控制
frontend web_host
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl static_path path_beg -i /static /images /javascript
acl invalid_src src 192.168.1.0/24 10.0.0.8
###################### acl hosts #################################
use_backend static_path_host if HTTP_1.1 TRUE static_path
tcp-request connection reject if invalid_src #四层ACL控制
default_backend default_web
################### backend hosts ################################
backend php_server_host
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend static_path_host
mode http
server web1 10.0.0.27 check inter 2000 fall 3 rise 5
backend default_web
mode http
server web1 10.0.0.37:80 check inter 2000 fall 3 rise 5
HAProxy Https 实现
haproxy支持https,基于性能考虑,证书是在后端服务器比如nginx上实现,即用户到haproxy利用tcp模式 再到后端服务器
范例: 基于tcp 模式实现
listen web_http
bind 192.168.10.100:80
redirect scheme https if !{ ssl_fc }
mode http
log global
server web1 10.0.0.8:80 check
server web2 10.0.0.18:80 check
listen web_https
bind 192.168.10.100:443
mode tcp
log global
server web1 10.0.0.8:443 check
server web2 10.0.0.18:443 check
Haproxy 可以实现 Https 的证书安全,即从用户到haproxy为https,从haproxy到后端服务器用http通信
#配置HAProxy支持https协议,支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥
cat demo.key demo.crt > demo.pem
#把80端口的请求利用302重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
#向后端传递用户请求的协议和端口(frontend或backend)
http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Proto https if { ssl_fc }
证书制作
使用方法1
#方法1
[root@haproxy certs]#mkdir /etc/haproxy/certs/
[root@haproxy certs]#cd /etc/haproxy/certs/
[root@haproxy certs]#openssl genrsa -out haproxy.key 2048
[root@haproxy certs]#openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.web01.com" -days 355
[root@centos7 certs]#cat haproxy.key haproxy.crt > haproxy.pem
[root@centos7 certs]#openssl x509 -in haproxy.pem -noout -text
#方法2
[root@centos7 ~]#mkdir /etc/haproxy/certs/
[oot@centos7 ~]#cd /etc/pki/tls/certs
[root@centos7 certs]#make /etc/haproxy/certs/haproxy.pem
umask 77 ; \
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365 -out $PEM2 ; \
cat $PEM1 > /etc/haproxy/certs/haproxy.pem ; \
echo ""
#查看证书
>> /etc/haproxy/certs/haproxy.pem ; \
cat $PEM2 >> /etc/haproxy/certs/haproxy.pem ; \
rm -f $PEM1 $PEM2
Generating a 2048 bit RSA private key
.+++
..............................................+++
writing new private key to '/tmp/openssl.x8hOA8'----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:wang
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:www.wang.org
Email Address []:
[root@centos7 certs]#ll /etc/haproxy/certs/
total 4-rw------- 1 root root 3027 Apr 4 10:35 haproxy.pem
Https 配置示例
[root@centos7 ~]#cat /etc/haproxy/conf.d/test.cfg
frontend wang_http_port
bind 10.0.0.7:80
###################### https setting ##############################
bind 10.0.0.7:443 ssl crt /etc/haproxy/certs/haproxy.pem
redirect scheme https if !{ ssl_fc }
# 注意{ }内的空格
http-request set-header X-forwarded-Port %[dst_port]
http-request add-header X-forwarded-Proto https if { ssl_fc }
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl mobile_domain hdr_dom(host) -i mobile.wang.org
###################### acl hosts #################################
default_backend pc_hosts
################### backend hosts #################################
backend mobile_hosts
mode http
server web1 10.0.0.17:80 check inter 2000 fall 3 rise 5
backend pc_hosts
mode http
#http-request set-header X-forwarded-Port %[dst_port] 也可加在此处
#http-request add-header X-forwarded-Proto https if { ssl_fc }
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
修改后端服务器的日志格式
[root@centos27 ~]#vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{XForwarded-Port}i\" \"%{X-Forwarded-Proto}i\"" combined
验证 Https
[root@master-db ~]#curl -IkL 172.16.1.211
HTTP/1.1 302 Found
content-length: 0
location: https://172.16.1.211/
cache-control: no-cache
HTTP/1.1 200 OK
server: nginx/1.22.1
date: Wed, 13 Nov 2024 15:21:30 GMT
content-type: text/html
content-length: 29
last-modified: Tue, 05 Nov 2024 14:33:04 GMT
etag: "672a2ca0-1d"
accept-ranges: bytes
set-cookie: WEBSRV=web01; path=/
cache-control: private