haproxy
-
- [1 haproxy简介](#1 haproxy简介)
-
- [1.1 定义](#1.1 定义)
- [1.2 原理讲解](#1.2 原理讲解)
- [1.3 HAProxy的优点:](#1.3 HAProxy的优点:)
- [2. haproxy的基本部署](#2. haproxy的基本部署)
-
- [2.1 实验环境](#2.1 实验环境)
-
- [2.1.2 haproxy主机配置](#2.1.2 haproxy主机配置)
- [2.1.3 webserver1配置](#2.1.3 webserver1配置)
- [2.1.4 webserver2配置](#2.1.4 webserver2配置)
- [3. haproxy的全局配置](#3. haproxy的全局配置)
- [4. haproxy代理参数](#4. haproxy代理参数)
- [5. haporxy的热处理](#5. haporxy的热处理)
- 6.haproxy的算法
-
- [6.1 静态算法](#6.1 静态算法)
- [6.2 动态算法](#6.2 动态算法)
-
- 6.2.1roundrobin
- [6.2.2 leastconn](#6.2.2 leastconn)
- [6.3 其他算法](#6.3 其他算法)
-
- [6.3.1 source](#6.3.1 source)
- [6.3.2 uri](#6.3.2 uri)
- [7. haproxy的状态页](#7. haproxy的状态页)
- [8. 基于cookie的会话保持](#8. 基于cookie的会话保持)
- [9. ip透传](#9. ip透传)
-
- [9.1 七层透传(mode=http)nginx](#9.1 七层透传(mode=http)nginx)
-
- [9.1.1 主机操作](#9.1.1 主机操作)
- [9.1.2 web主机操作](#9.1.2 web主机操作)
- [9.2 四层透传(mode=tcp)nginx](#9.2 四层透传(mode=tcp)nginx)
- [10. haproxy的acl基本访问控制](#10. haproxy的acl基本访问控制)
-
- [10.1 主机操作](#10.1 主机操作)
- [10.2 client测试](#10.2 client测试)
- [11. haproxy的acl一些常用限制](#11. haproxy的acl一些常用限制)
-
- [11.1 基于ip的访问控制](#11.1 基于ip的访问控制)
- [11.2 基于ip的访问控制之黑名单](#11.2 基于ip的访问控制之黑名单)
- [11.3 基于浏览器的访问控制](#11.3 基于浏览器的访问控制)
- [11.3 基于文件后缀名实现动静分离](#11.3 基于文件后缀名实现动静分离)
- [12. haproxy自定义错误页面](#12. haproxy自定义错误页面)
- [13. haproxy四层负载数据库](#13. haproxy四层负载数据库)
- [14. haproxy之https网站加密](#14. haproxy之https网站加密)
- [15. haproxy之https网站强制全站加密](#15. haproxy之https网站强制全站加密)
1 haproxy简介
1.1 定义
HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性 、负载均衡 ,以及基于TCP和HTTP的应用程序代理。
HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
包括 GitHub、Bitbucket、Stack Overflow、Reddit、Tumblr、Twitter和 Tuenti在内的知名网站,及亚马逊网络服务系统都使用了HAProxy。
1.2 原理讲解
负载均衡集群
负载均衡集群运行时,一般是通过一个或多个前端负载均衡器将客户访问请求分发到后端的一组服务器上,从而达到整个系统的高性能和高可用性。一般高可用性集群和负载均衡集群会使用类似的技术,或同时具有高可用性与负载均衡的特点。
HAProxy是基于四层和七层技术,可提供TCP和HTTP应用的负载均衡综合解决方案。
1.3 HAProxy的优点:
1)可靠性和稳定性非常好,可以与硬件的F5相媲美
2)最高可以同时维护40000--50000个并发连接,单位时间内处理的最大请求数为20000个,最大数据处理能力可达10Gbps
3)支持多于8种负载均衡算法 ,同时也支持session保持
4)支持虚拟主机功能从HAProxy 1.3版本后开始支持连接拒绝、全透明代理等功能
5)HAProxy拥有一个功能强大的服务器状态监控页面
6)HAProxy拥有功能强大的ACL支持
2. haproxy的基本部署
2.1 实验环境
功能 | ip |
---|---|
haproxy | eth0:172.25.254.100 |
RS1 | eth0:172.25.254.10 |
RS2 | eth0:172.25.254.20 |
2.1.2 haproxy主机配置
c
[root@haproxy ~]# dnf install haproxy -y
[root@haproxy ~]# rpm -qc haproxy
/etc/haproxy/haproxy.cfg
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
# 修改内容如下
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend webcluster
bind *:80
mode http
use_backend webcluster-host
backend webcluster-host
balance roundrobin
server web1 172.25.254.10:80
server web2 172.25.254.20:80
或者
c
listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80
server web2 172.25.254.20:80
c
[root@haproxy ~]# systemctl restart haproxy.service
c
# 测试
[root@haproxy ~]# for i in {1..10}
> do
> curl 172.25.254.100
> done
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
2.1.3 webserver1配置
c
[root@webserver1 ~]# dnf install nginx -y
[root@webserver1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index.html
[root@webserver1 ~]# systemctl enable --now nginx.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
2.1.4 webserver2配置
c
[root@webserver2 ~]# dnf install -y nginx
[root@webserver2 ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index.html
[root@webserver2 ~]# systemctl enable --now nginx.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
3. haproxy的全局配置
c
#多进程
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
nbproc 2
cpu-map 1 0
cpu-map 2 1
[root@haproxy ~]# systemctl restart haproxy.service
c
#查看多进程信息
[root@haproxy ~]# pstree -p | grep haproxy
|-haproxy(31828)-+-haproxy(31831)
| `-haproxy(31832)
c
# 启用多线程
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
nbthread 2
c
#定义日志
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
log 127.0.0.1 local2
[root@haproxy ~]# systemctl restart haproxy.service
[root@haproxy ~]# vim /etc/rsyslog.conf
module(load="lmudp") #udp的这个打开
input(type="imudp" port="514")
local2.* /var/log/haproxy.log
#查看多线程信息
[root@haproxy ~]# pstree -p | grep haproxy
|-haproxy(31841)---haproxy(31843)---{haproxy}(31844)
4. haproxy代理参数
c
#关掉webserver1\2的,可以访问100的
[root@webserver1 ~]# systemctl stop nginx.service
[root@webserver2 ~]# systemctl stop nginx.service
[root@haproxy ~]# dnf install httpd -y
[root@haproxy ~]# vim /etc/httpd/conf/httpd.conf
#backup --sorryserver 的端口
Listen 8080
[root@haproxy ~]# systemctl enable --now httpd
[root@haproxy ~]# echo sorry > /var/www/html/index.html
[root@haproxy ~]# curl 172.25.254.100
sorry
#如果是开启的话,需在文件里注释掉
[root@webserver1 ~]# systemctl start nginx.service
[root@webserver2 ~]# systemctl start nginx.service
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
#server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
#server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
server web_sorry 172.25.254.100:8080 backup
c
[root@haproxy ~]# systemctl restart haproxy.service
测试
c
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver1 - 172.25.254.20
webserver1 - 172.25.254.10
webserver1 - 172.25.254.20
c
#下线指定realserver
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2 disabled
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
server web_sorry 172.25.254.100:8080 backup
[root@haproxy ~]# systemctl restart haproxy.service
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.20
webserver1 - 172.25.254.20
c
#网页重定向
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
redirect prefix http://www.baidu.com/
#server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
#server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
#server web_sorry 172.25.254.100:8080 backup
[root@haproxy ~]# systemctl restart haproxy.service
5. haporxy的热处理
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
# 开启socker热处理,并且以root账户的身份去处理
stats socket /var/lib/haproxy/stats mode 600 level admin
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTE
c
[root@haproxy ~]# systemctl restart haproxy.service
# 下载socat工具
[root@haproxy ~]# dnf install socat-1.7.4.1-5.el9.x86_64 -y
[root@haproxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats
2 (initial 2)
[root@haproxy ~]# echo "get weight webcluster/web2" | socat stdio /var/lib/haproxy/stats
1 (initial 1)
[root@haproxy ~]# echo "set weight webcluster/web1 1" | socat stdio /var/lib/haproxy/stats
[root@haproxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats
1 (initial 2)
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats
1
# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
2 webcluster 1 web1 172.25.254.10 2 0 1 2 218 6 0 7 7 0 0 0 - 80 - 0 0 - - 0
2 webcluster 2 web2 172.25.254.20 2 0 1 1 103 6 0 7 7 0 0 0 - 80 - 0 0 - - 0
4 static 1 static 127.0.0.1 0 0 1 1 217 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0
5 app 1 app1 127.0.0.1 0 0 1 1 217 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0
5 app 2 app2 127.0.0.1 0 0 1 1 217 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0
5 app 3 app3 127.0.0.1 0 0 1 1 217 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0
5 app 4 app4 127.0.0.1 0 0 1 1 216 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0
c
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 2.4.17-9f97155
Release_date: 2022/05/13
Nbthread: 2
Nbproc: 1
Process_num: 1
Pid: 2634
Uptime: 0d 0h05m04s
Uptime_sec: 304
Memmax_MB: 0
PoolAlloc_MB: 0
PoolUsed_MB: 0
PoolFailed: 0
Ulimit-n: 8037
Maxsock: 8037
Maxconn: 4000
Hard_maxconn: 4000
CurrConns: 0
CumConns: 40675
CumReq: 13
MaxSslConns: 0
CurrSslConns: 0
CumSslConns: 0
Maxpipes: 0
PipesUsed: 0
PipesFree: 0
ConnRate: 0
ConnRateLimit: 0
MaxConnRate: 0
SessRate: 0
SessRateLimit: 0
MaxSessRate: 0
SslRate: 0
haproxy多进程如何热处理
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
# turn on stats unix socket
# 为每一个进程独立建立一个控制文件
stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
# 开启多进程
nbproc 2
cpu-map 1 0
cpu-map 2 1
[root@haproxy ~]# systemctl restart haproxy.service
[root@haproxy ~]# ll /var/lib/haproxy/
总用量 0
srw------- 1 root root 0 8月 9 11:39 stats
srw------- 1 root root 0 8月 9 11:50 stats1
srw------- 1 root root 0 8月 9 11:50 stats2
6.haproxy的算法
HAProxy通过固定参数 balance 指明对后端服务器的调度算法
balance参数可以配置在listen或backend选项中。
HAProxy的调度算法分为静态和动态调度算法
有些算法可以根据参数在静态和动态算法中相互转换。
6.1 静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
6.1.1static-rr:基于权重的轮询调度
- 不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
- 不支持端服务器慢启动
- 其后端主机数量没有限制,相当于LVS中的 wrr
慢启动是指在服务器刚刚启动上不会把他所应该承担的访问压力全部给它,而是先给一部分,当没问题后在给一部分
c
# 不要多进程
stats socket /var/lib/haproxy/stats mode 600 level admin
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
#balance roundrobin
balance static-rr
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
# 测试
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.102、first
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
#balance roundrobin
#balance static-rr
balance first
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
# 测试: 多台主机执行死循环,可看到
[root@webserver1 ~]# while true ; do curl 172.25.254.100; sleep 0.1 ; done
[root@webserver2 ~]# while true ; do curl 172.25.254.100; sleep 0.1 ; done
6.2 动态算法
动态算法
基于后端服务器状态进行调度适当调整, 新请求将优先调度至当前负载较低的服务器 权重可以在haproxy运行时动态调整无需重启
6.2.1roundrobin
- 基于权重的轮询动态调度算法,
- 支持权重的运行时调整,不同于lvs中的rr轮训模式,
- HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数), 4. 其每个后端backend中最多支持4095个real server,
- 支持对real server权重动态调整,
- roundrobin为默认调度算法,此算法使用广泛
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
#balance static-rr
#balance first
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
#测试
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
6.2.2 leastconn
leastconn加权的最少连接的动态
- 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户
端连接) - 比较适合长连接的场景使用,比如:MySQL等场景。
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
#balance static-rr
#balance first
#balance roundrobin
balance leastconn
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
#测试
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
6.3 其他算法
其它算法即可作为静态算法,又可以通过选项成为动态算法
6.3.1 source
源地址hash,基于用户源地址hash并将请求转发到后端服务器 ,后续同一个源地址请求将被转发至同一 个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCP 模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性 ,适用于session会话保持但不支持 cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法 和一致性hash
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
#balance static-rr
#balance first
#balance roundrobin
#balance leastconn
balance source
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
#测试
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
6.3.2 uri
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后
根据最终结果将请求转发到后端指定服务器
适用于后端是缓存服务器场景
默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性 hash
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
c
#webserver1上
[root@webserver1 ~]# echo 172.25.254.10 - index1.html > /usr/share/nginx/html/index1.html
[root@webserver1 ~]# echo 172.25.254.10 - index2.html > /usr/share/nginx/html/index2.html
[root@webserver1 ~]# echo 172.25.254.10 - index3.html > /usr/share/nginx/html/index3.html
#webserver2
[root@webserver2 ~]# echo 172.25.254.20 - index1.html > /usr/share/nginx/html/index1.html
[root@webserver2 ~]# echo 172.25.254.20 - index2.html > /usr/share/nginx/html/index2.html
[root@webserver2 ~]# echo 172.25.254.20 - index3.html > /usr/share/nginx/html/index3.html
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
#balance roundrobin
#balance leastconn
#balance static-rr
#balance first
#balance source
balance uri
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
#测试
[root@haproxy ~]# curl 172.25.254.100/index1.html
172.25.254.10 - index1.html
[root@haproxy ~]# curl 172.25.254.100/index2.html
172.25.254.20 - index2.html
[root@haproxy ~]# curl 172.25.254.100/index3.html
172.25.254.10 - index3.html
7. haproxy的状态页
通过web界面,显示当前HAPROXY的运行状态
c
root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind *:9999
stats enable
stats refresh 3
stats uri /status
stats auth shanxin:shanxin
[root@haproxy ~]# systemctl restart haproxy.service
登陆状态页
8. 基于cookie的会话保持
在一个浏览器访问后,会记住选择,之后刷新一直是该后端主机,另一个浏览器访问则是另一个后端主机
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
#redirect prefix http://www.baidu.com/
#server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
#server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
#server web_sorry 172.25.254.100:8080 backup
# 添加cookie功能
cookie WEBCOOKIE insert nocache indirect
server web1 172.25.254.10:80 cookie lee1 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 cookie lee2 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
# 访问测速
[root@haproxy ~]# curl -b WEBCOOKIE=lee1 172.25.254.100
webserver1 - 172.25.254.10
[root@haproxy ~]# curl -b WEBCOOKIE=lee1 172.25.254.100
webserver1 - 172.25.254.10
[root@haproxy ~]# curl -b WEBCOOKIE=lee2 172.25.254.100
webserver2 - 172.25.254.20
[root@haproxy ~]# curl -b WEBCOOKIE=lee2 172.25.254.100
webserver2 - 172.25.254.20
[root@haproxy ~]# curl -b WEBCOOKIE=lee2 172.25.254.100
webserver2 - 172.25.254.20
9. ip透传
9.1 七层透传(mode=http)nginx
IP透传的用途:web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
9.1.1 主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
# IP透传的参数,需要保持开启
option forwardfor except 127.0.0.0/8
[root@haproxy ~]# systemctl restart haproxy.service
9.1.2 web主机操作
c
[root@webserver2 ~]# > /var/log/nginx/access.log
[root@webserver2 ~]# cat /var/log/nginx/access.log
# 此时这里显示了真实访问主机的IP,透传成功
172.25.254.100 - - [10/Aug/2024:10:34:36 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/7.76.1" "172.25.254.200"
9.2 四层透传(mode=tcp)nginx
haproxy主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
# 这里需要更改为tcp
mode tcp
balance roundrobin
#redirect prefix http://www.baidu.com/
#server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
#server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
#server web_sorry 172.25.254.100:8080 backup
#cookie WEBCOOKIE insert nocache indirect
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
# 这里需要加上send-proxy
server web2 172.25.254.20:80 send-proxy check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
c
[root@webserver2 ~]# vim /etc/nginx/nginx.conf
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
# 在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP
' "$proxy_protocol_addr"'
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80 proxy_protocol; # 需要添加这个,才可以通过四层代理访问此网站
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
[root@webserver2 ~]# systemctl restart nginx.service
# 测试
[root@webserver2 ~]# tail -n 3 /var/log/nginx/access.log
[root@webserver1 ~]# tail -n 3 /etc/httpd/logs/access_log
再次访问后,查看日志可以看到地址
10. haproxy的acl基本访问控制
10.1 主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
# 进行一下配置文件的编写
frontend webcluster
bind *:80
mode http
acl test hdr_end(host) -i .org
use_backend webcluster-host if test
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
10.2 client测试
c
[root@client ~]# vim /etc/hosts
[root@client ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.200 client.shanxin.org
172.25.254.10 www.shanxin.org
172.25.254.20 www.shanxin.com
# 测试成功
[root@client ~]# curl www.shanxin.org
webserver1 - 172.25.254.10
[root@client ~]# curl www.shanxin.com
webserver2 - 172.25.254.20
11. haproxy的acl一些常用限制
11.1 基于ip的访问控制
主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl ctrl_ip src 172.25.254.200 172.25.254.20 192.168.0.0/24
use_backend webcluster-host if ctrl_ip
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
client主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl ctrl_ip src 172.25.254.200 172.25.254.20 192.168.0.0/24
use_backend webcluster-host if ctrl_ip
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
测试
c
[root@haproxy ~]# curl 172.25.254.100
webserver2 - 172.25.254.20
11.2 基于ip的访问控制之黑名单
主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl ctrl_ip src 172.25.254.200 172.25.254.20 192.168.0.0/24
# use_backend webcluster-host if ctrl_ip
http-request deny if ctrl_ip
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
client主机操作
c
[root@client ~]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
11.3 基于浏览器的访问控制
主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl badwebrowers hdr_sub(User-Agent) -i curl wget
http-request deny if badwebrowers
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
client主机操作
c
[root@client ~]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
测试
11.3 基于文件后缀名实现动静分离
主机操作
c
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl static path_end -i .html .jpg .png .css .js
acl php path_end -i .php
use_backend webcluster-host if php
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
webserver1操作
c
[root@webserver1 ~]# dnf install php -y
[root@webserver1 ~]# systemctl disable --now nginx.service
[root@webserver1 ~]# systemctl restart httpd.service
[root@webserver1 ~]# vim /var/www/html/index.php
[root@webserver1 ~]# cat /var/www/html/index.php
<?php
phpinfo();
?>
client主机操作
c
[root@client ~]# curl 172.25.254.100
webserver2 - 172.25.254.20
浏览器访问测试
12. haproxy自定义错误页面
主机操作
c
# 查看错误页面文件的存储路径
[root@haproxy ~]# rpm -ql haproxy | grep http
/usr/share/doc/haproxy/design-thoughts/http2.txt
/usr/share/doc/haproxy/design-thoughts/http_load_time.url
/usr/share/doc/haproxy/internals/http-cookies.txt
/usr/share/doc/haproxy/internals/http-docs.txt
/usr/share/doc/haproxy/internals/http-parsing.txt
/usr/share/doc/haproxy/option-http_proxy.cfg
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http
[root@haproxy ~]# mkdir /etc/haproxy/errorpage/
[root@haproxy ~]# cp /usr/share/haproxy/503.http /etc/haproxy/errorpage/503.http
[root@haproxy ~]# vim /etc/haproxy/errorpage/503.http
# 修改内容如下
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>errrrrrrrrrrrr</h1>
No server is available to handle this request.
</body></html>
# 配置haproxy主配置文件
[root@haproxy conf.d]# vim /etc/haproxy/haproxy.cfg
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# 这条语句要放在default里面
errorfile 503 /etc/haproxy/errorpage/503.http
[root@haproxy conf.d]# systemctl restart haproxy.service
webserver主机操作
c
[root@webserver1 ~]# systemctl stop httpd.service
[root@webserver2 static]# systemctl stop nginx.service
client主机操作
c
[root@client ~]# curl 172.25.254.100
<html><body><h1>errrrrrrrrrrrr</h1>
No server is available to handle this request.
</body></html>
[root@client ~]# curl 172.25.254.10
curl: (7) Failed to connect to 172.25.254.10 port 80: 拒绝连接
[root@client ~]# curl 172.25.254.20
curl: (7) Failed to connect to 172.25.254.20 port 80: 拒绝连接
浏览器访问测试
haproxy报错后跳转指定网站
c
[root@haproxy conf.d]# vim /etc/haproxy/haproxy.cfg
#errorfile 503 /etc/haproxy/errorpage/503.http
# 也是在defualt语句块中
errorloc 503 https://www.baidu.com
[root@haproxy conf.d]# systemctl restart haproxy.service
13. haproxy四层负载数据库
主机操作
c
# 在haproxy的子配置文件中配置
[root@haproxy conf.d]# vim /etc/haproxy/conf.d/web.cfg
[root@haproxy conf.d]# cat /etc/haproxy/conf.d/web.cfg
listen dbserver
bind *:3306
mode tcp
balance static-rr
server db1 172.25.254.10:3306 check inter 2 fall 2 rise 5
server db2 172.25.254.20:3306 check inter 2 fall 2 rise 5
[root@haproxy conf.d]# systemctl restart haproxy.service
webserver1/2主机操作
c
[root@webserver1 ~]# dnf install mariadb-server -y
[root@webserver1 ~]# systemctl enable --now mariadb
[root@webserver1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=1
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid
[root@webserver1 ~]# systemctl restart mariadb.service
[root@webserver1 ~]# mysql
# 建立普通用户lee,并授予权限,为了之后的远程登录测试
MariaDB [(none)]> create user lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> grant all on *.* to lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> quit
Bye
[root@webserver2 ~]# dnf install mariadb-server -y
[root@webserver2 ~]# systemctl enable --now mariadb
[root@webserver2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=2 # server-id=1 # 设置数据库的id为了在之后的测试方便
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid
[root@webserver2 ~]# systemctl restart mariadb.service
[root@webserver2 ~]# mysql
MariaDB [(none)]> create user lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> grant all on *.* to lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> quit
Bye
client主机操作
c
[root@client ~]# mysql -ulee -plee -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 1 |
+-------------+
1 row in set (0.001 sec)
MariaDB [(none)]> quit
Bye
[root@client ~]# mysql -ulee -plee -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 2 |
+-------------+
1 row in set (0.001 sec)
MariaDB [(none)]> quit
Bye
[root@client ~]# mysql -ulee -plee -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 1 |
+-------------+
1 row in set (0.001 sec)
MariaDB [(none)]> quit
Bye
[root@client ~]# mysql -ulee -plee -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 2 |
+-------------+
1 row in set (0.001 sec)
14. haproxy之https网站加密
主机操作
c
# 建立证书以及密钥的存储目录
[root@haproxy ~]# mkdir -p /etc/haproxy/certs
# 生成证书以及密钥
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/shanxin.org.key -x509 -days 365 -out /etc/haproxy/certs/shanxin.org.crt
[root@haproxy ~]# ll /etc/haproxy/certs/
总用量 8
-rw-r--r-- 1 root root 1415 8月 10 17:19 shanxin.org.crt
-rw------- 1 root root 1708 8月 10 17:18 shanxin.org.key
# 将证书以及密钥文件都存储在配置默认路径中
[root@haproxy ~]# cat /etc/haproxy/certs/shanxin.org.key /etc/haproxy/certs/shanxin.org.crt > /etc/haproxy/certs/shanxin.org.pem
[root@haproxy ~]# ll /etc/haproxy/certs/shanxin.org.pem
-rw-r--r-- 1 root root 3123 8月 10 17:21 /etc/haproxy/certs/shanxin.org.pem
[root@haproxy ~]# vim /etc/haproxy/conf.d/web.cfg
listen web-https
bind *:443 ssl crt /etc/haproxy/certs/shanxin.org.pem
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5 # 这里实际上是对haproxy主机进行了https加密,真实的服务器还是80端口,未加密
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
webserver主机操作
c
[root@webserver1 ~]# systemctl start httpd.service
//
[root@webserver2 ~]# systemctl start nginx.service
15. haproxy之https网站强制全站加密
c
[root@haproxy ~]# vim /etc/haproxy/conf.d/web.cfg
listen webcluster
bind *:80
mode http
redirect scheme https if !{ ssl_fc }
n
[root@haproxy ~]# systemctl restart haproxy.service
浏览器访问测试