目录
[一. 基于cookie的会话保持](#一. 基于cookie的会话保持)
[1.1 配合基于cookie的会话保持方法](#1.1 配合基于cookie的会话保持方法)
[二. HAProxy状态页](#二. HAProxy状态页)
[2.1 启用状态页](#2.1 启用状态页)
[2.2 开启自动刷新](#2.2 开启自动刷新)
[2.3 模拟设备下线](#2.3 模拟设备下线)
[三. IP透传](#三. IP透传)
[3.1 七层IP透传](#3.1 七层IP透传)
[3.2 四层IP透传](#3.2 四层IP透传)
[四. 四层负载](#四. 四层负载)
[4.1 环境设定](#4.1 环境设定)
[4.2 四层负载操作](#4.2 四层负载操作)
[4.3 backup参数](#4.3 backup参数)
[五. 自定义错误页面](#五. 自定义错误页面)
[5.2 自定义错误页面](#5.2 自定义错误页面)
[六. ACL 访问控制列表](#六. ACL 访问控制列表)
[6.1 实验素材](#6.1 实验素材)
[6.2 设定基础的haproxy实验配置](#6.2 设定基础的haproxy实验配置)
[6.3 基础acl示例](#6.3 基础acl示例)
[七. HAProxy https 实现](#七. HAProxy https 实现)
[7.1 制作证书](#7.1 制作证书)
[7.2 全站加密](#7.2 全站加密)
实验环境
环境流程图

实验环境

环境配置
具体环境配置已整理并发布到以下CSDN链接中,按需自行查看
一. 基于 cookie 的会话保持
HAProxy 基于 cookie 的会话保持是在 http 模式下,通过给客户端插入指定 cookie 值,让同一客户端同一浏览器的请求固定发往同一后端服务器(不同浏览器可分发至不同服务器),相比source地址 hash 粒度更精准,但会增加 HAProxy 负载且目前使用较少
注:不支持 tcp 模式,必须使用 http 模式。
配置语法
cookie name [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
配置项说明
-
name:用于实现持久连接的 Cookie 键名。
-
insert:插入新的 Cookie,默认不插入。
-
indirect:如果客户端已有 Cookie,则不会再发送 Cookie 信息。
-
nocache:当客户端与 HAProxy 之间存在缓存服务器(如 CDN)时,不允许中间缓存服务器缓存 Cookie,避免大量经同一 CDN 的请求被转发到同一台后端服务器。
1.1 配合基于cookie的会话保持方法
在haproxy上
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80 #监听所有网卡的 80 端口,接收客户端的 HTTP 请求
balance roundrobin #指定调度算法为动态权重轮询,支持运行时调整权重和服务器慢启动
hash-type consistent #设置哈希类型为一致性哈希,配合 Cookie 会话保持,减少后端服务器变动时的请求分发震荡
cookie WEBCOOKIE insert nocache indirect #开启 Cookie 会话保持,WEBCOOKIE 为 Cookie 键名;insert 指 HAProxy 自动插入 Cookie,nocache 禁止中间缓存服务器缓存 Cookie,indirect 指客户端已有该 Cookie 时 HAProxy 不再重复发送
server haha 192.168.221.10:80 cookie web1 check inter 3s fall 3 rise 5 weight 2
server hehe 192.168.221.20:80 cookie web2 check inter 3s fall 3 rise 5 weight 1
#cookie web1为该服务器绑定专属 Cookie 值,匹配到该值的请求会固定发往此服务器
[root@haproxy ~]# systemctl restart haproxy.service

测试
在浏览器上

二. HAProxy 状态页
HAProxy 状态页是通过 Web 界面展示运行状态的可视化工具,
可通过配置项启用:stats enable 开启状态页,stats hide-version 隐藏版本,stats refresh 设置自动刷新间隔,stats uri 自定义访问路径,stats auth 设置登录账号密码,stats admin 启用管理功能。
启用时需在配置中定义独立的 listen stats 块,指定 HTTP 模式、监听端口、访问 URI 和认证信息,重启服务后即可通过浏览器访问,查看实时运行数据。
2.1 启用状态页
在haproxy中
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen stats #定义一个名为stats的独立监听块,专门用于承载 HAProxy 状态页的请求与响应
mode http #指定该监听块工作在HTTP 七层模式,因为状态页是基于 HTTP 协议的 Web 可视化页面
bind 0.0.0.0:4321 #让状态页监听服务器所有网卡的 4321 端口,允许从任意网络地址访问该端口的状态页
stats enable #核心指令,启用 HAProxy 的 Web 状态页功能,开启后才能通过浏览器访问运行数据
log global #指定状态页的日志配置继承 HAProxy 的global全局日志规则,统一日志记录标准
# stats refresh
stats uri /status #自定义状态页的访问路径,即需通过IP:4321/status才能访问状态页,而非默认根路径
stats auth lee:lee #设置状态页的基础登录认证,限定用户名和密码均为lee,未通过认证无法查看状态页
[root@haproxy ~]# systemctl restart haproxy.service

登录测试
(访问192.168.35.100:4321/status)
- 访问地址含义 :
192.168.35.100是 HAProxy 服务器的 IP,4321是配置的监听端口,/status是自定义的访问路径,三者组合定位到状态页入口。 - 登录弹窗含义 :浏览器弹出身份验证窗口,验证
stats auth lee:lee配置是否生效,只有输入正确的lee/lee账号密码,才能进入状态页。

2.2 开启自动刷新
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind 0.0.0.0:4321
stats enable
log global
stats refresh 1 #设置状态页每 1 秒自动刷新一次,实时同步 HAProxy 的运行状态
stats uri /status
stats auth lee:lee
[root@haproxy ~]# systemctl restart haproxy.service

刷新测试
页面无需手动点击 "刷新",每 1 秒自动更新数据(如LastChk时间、连接数),证明stats refresh 1配置生效


2.3 模拟设备下线
下线:

重新上线:

三. IP 透传
HAProxy 的 IP 透传分为四层和七层:四层透传依赖send-proxy协议,后端 Nginx 需启用proxy_protocol并通过$proxy_protocol_addr记录真实 IP;七层透传通过option forwardfor在 HTTP 头中添加X-Forwarded-For字段,后端服务器(如 Nginx/Apache)可通过对应变量获取并记录客户端真实 IP,用于访问统计、安全防护等场景。
3.1 七层IP透传
1.实验环境
在haproxy中
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
balance roundrobin
server haha 192.168.221.10:80 check inter 3s fall 3 rise 5 weight 2
server hehe 192.168.221.20:80 check inter 3s fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service

2.测试环境
-
连续向 HAProxy(
192.168.35.100)发起 5 次 HTTP 请求,验证负载均衡是否按权重(haha权重 2,hehe权重 1)轮询分发请求。 -
输出显示
webserver1和webserver2交替出现,证明负载均衡配置生效。for i in {1..5}; do curl 192.168.35.100; done

3.在rs主机中默认是未开启透传功能的
- 查看 Apache 的访问日志,验证 IP 透传是否成功。
- 测试前 :日志中客户端 IP 显示为 HAProxy 的 IP(
192.168.221.100),因为默认情况下后端服务器看到的是代理服务器的 IP。 - 测试后 :日志中新增了
"192.168.35.1"字段,这是真实客户端的 IP,证明X-Forwarded-For透传和 Apache 日志配置生效。
在webserver2中
[root@webserver2 ~]# cat /etc/httpd/logs/access_log

4.开启ip透传的方式
在haproxy中
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
mode http:设置 HAProxy 工作在 HTTP 七层模式,这是option forwardfor生效的前提。option forwardfor except 127.0.0.0/8:在 HTTP 请求头中添加X-Forwarded-For字段,记录客户端真实 IP,但排除来自127.0.0.0/8(本机)的请求。

5.在rs中设定采集透传IP
[root@webserver1 ~]# vim /etc/httpd/conf/httpd.conf
201 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{X-Forwarded-For}i\" \"%{Referer}i\" \"%{User-Agent}i\"" combined
#定义新的日志格式combined,在日志中增加%{X-Forwarded-For}i字段,用于记录从 HAProxy 透传过来的客户端真实 IP。
[root@webserver1 ~]# systemctl restart httpd
[root@webserver2 ~]# vim /etc/httpd/conf/httpd.conf
201 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{X-Forwarded-For}i\" \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@webserver2 ~]# systemctl restart httpd

6.测试效果

3.2 四层IP透传
1.环境设置
#在RS中把apache停止
[root@webserver1 ~]# systemctl disable --now httpd
[root@webserver2 ~]# systemctl disable --now httpd
#在两台 webserver 上立即停止并禁用 Apache 服务,为部署 Nginx 腾出 80 端口。
部署nginx
[root@webserver1 ~]# dnf install nginx -y
[root@webserver2 ~]# dnf install nginx -y
[root@webserver1 ~]# echo RS1 - 192.168.221.10 > /usr/share/nginx/html/index.html
#在 webserver1 上创建 Nginx 默认首页,内容为RS1 - 192.168.221.10,用于区分后端服务器
[root@webserver2 ~]# echo RS2 - 192.168.221.20 > /usr/share/nginx/html/index.html
[root@webserver1 ~]# systemctl enable --now nginx
[root@webserver2 ~]# systemctl enable --now nginx
#立即启动并设置 Nginx 开机自启


测环境
- 连续向 HAProxy(
192.168.35.100)发起 5 次 HTTP 请求,验证四层负载均衡是否按权重轮询分发请求。 - 输出显示
RS1和RS2交替出现,证明四层负载均衡和 PROXY 协议配置生效。

2.启用nginx的四层访问控制
[root@webserver1 ~]# vim /etc/nginx/nginx.conf
server {
listen 80 proxy_protocol; #让 Nginx 在 80 端口启用 PROXY 协议解析,用于接收 HAProxy 透传的客户端真实 IP
listen [::]:80; #同时监听 IPv6 的 80 端口
server_name _; #匹配任意主机名
root /usr/share/nginx/html; #指定网站根目录为 Nginx 默认首页路径
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
}
[root@webserver2 ~]# vim /etc/nginx/nginx.conf
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;
error_page 404 /404.html;
location = /404.html {
}
[root@webserver1 ~]# systemctl restart nginx.service
[root@webserver2 ~]# systemctl restart nginx.service

测试:

3.设定haproxy访问4层
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode tcp #在四层 TCP 模式,这是 PROXY 协议生效的前提
balance roundrobin
server haha 192.168.221.10:80 send-proxy check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.221.20:80 send-proxy check inter 3s fall 3 rise 5 weight 1
#在转发请求时启用 PROXY 协议,向 Nginx 传递客户端真实 IP,配置健康检查,每 3 秒检查一次后端节点状态
[root@haproxy ~]# systemctl restart haproxy.service

测试:

4.设置4层ip透传
[root@webserver1&2 ~]# vim /etc/nginx/nginx.conf
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'"$proxy_protocol_addr"' #采集透传信息
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#定义新的日志格式main,新增$proxy_protocol_addr变量,用于记录从 PROXY 协议中获取的客户端真实 IP
[root@webserver1&2 ~]# systemctl restart nginx.service

测试:

- 查看 Nginx 的访问日志,验证四层 IP 透传是否成功。
- 测试前 :日志中客户端 IP 显示为 HAProxy 的 IP(
192.168.221.100)。 - 测试后 :日志中新增了
192.168.35.1字段,这是真实客户端的 IP,证明 PROXY 协议透传和 Nginx 日志配置生效。

四. 四层负载
HAProxy 针对 MySQL 等 TCP 协议服务实现四层负载均衡,需在配置中显式声明 mode tcp(拆分 frontend/backend 时需两端均配置),选用 leastconn 调度算法,后端 MySQL 节点需配置唯一 server-id 并授权通用访问账号,最终可通过访问 HAProxy 绑定端口并查询数据库特有标识(server-id/hostname)验证请求被分发至不同节点。
4.1 环境设定
1.部署mariadb数据库
[root@webserver1+2 ~]# dnf install mariadb-server mariadb -y
#在两台 webserver 上安装 MariaDB 服务端和客户端
[root@webserver1+2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf #编辑 MariaDB 主配置文件,用于设置唯一的 server_id 等核心参数
[mysqld]
server_id=10 #设定数据库所在主机的id标识,在20上设定id为20
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+2 ~]# systemctl restart mariadb


2.建立远程登录用户并授权
[root@webserver2+1 ~]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.5.27-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE USER 'lee'@'%' identified by 'lee'; #创建名为 lee 的用户,允许从任意主机(%)远程登录,密码为 lee
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> GRANT ALL ON *.* TO 'lee'@'%'; #授予 lee 用户对所有数据库和表(*.*)的全部操作权限
Query OK, 0 rows affected (0.000 sec)

测试:
[root@webserver2 ~]# mysql -ulee -plee -h 192.168.221.20
#测试10时修改ip即可,使用 lee 用户测试远程连接到 webserver2(192.168.221.20)的 MariaDB,验证授权是否生效

4.2 四层负载操作
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen mariadbcluster
bind *:6663 #HAProxy 监听所有网卡的 6663 端口,作为对外提供服务的入口
mode tcp
balance roundrobin
server haha 192.168.221.10:3306 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.221.20:3306 check inter 3s fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service

检测:
[root@haproxy ~]# netstat -antlupe | grep haproxy
#检查 HAProxy 监听的端口,确认 6663 端口已处于 LISTEN 状态。

测试:
多次连接返回 server_id=10,证明请求被分发到主节点 haha

mysql -ulee -plee -h192.168.35.100 -P 6663
#通过 HAProxy(192.168.35.100:6663)连接 MariaDB,验证四层负载均衡是否生效
SELECT @@server_id;
#查询当前连接的 MariaDB 实例的 server_id,判断请求被分发到哪个后端节点。

4.3 backup参数
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen mariadbcluster
bind *:6663
mode tcp
balance roundrobin
server haha 192.168.221.10:3306 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.221.20:3306 check inter 3s fall 3 rise 5 weight 1 backup
#在 server 行末尾添加 backup 标记,将 hehe(192.168.221.20)设为备份节点,仅当主节点 haha 故障时才会被启用。
[root@haproxy ~]# systemctl restart haproxy.service

测试:
mysql -ulee -plee -h192.168.35.100 -P 6663

关闭10的mariadb并等待1分钟
#关闭10的mariadb并等待1分钟
[root@webserver1+2 ~]# systemctl stop mariadb

[root@webserver1+2 ~]# systemctl restart mariadb
#再次连接 HAProxy,验证是否自动切换到备份节点 hehe

还原故障主机等待片刻
[root@webserver1 ~]# systemctl start mariadb
#恢复主节点 haha 的 MariaDB 服务。

五. 自定义错误页面
5.1.sorryserver的设定
正常的所有服务器如果出现宕机,那么客户将被定向到指定的主机中,这个当业务主机出问题时被临时访问的主机叫做sorryserver
1.在新主机中安装apache(可以用haproxy主机代替)
[root@haproxy ~]# dnf install httpd -y
#在 HAProxy 主机上安装 Apache(httpd)服务,用于作为故障时的临时 "道歉服务器"(sorryserver)。
[root@haproxy ~]# vim /etc/httpd/conf/httpd.conf #编辑 Apache 配置文件,修改监听端口以避免与 HAProxy 的 80 端口冲突。
47 Listen 8080 #将 Apache 的监听端口从默认的 80 改为 8080
[root@haproxy ~]# systemctl enable --now httpd #立即启动 Apache 服务
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@haproxy ~]# echo "李哥在,没意外" > /var/www/html/index.html
#创建 Apache 的默认首页,内容自定义,作为故障时的提示页面


2.配置sorryserver上线
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode tcp
balance roundrobin
server haha 192.168.221.10:80 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.221.20:80 check inter 3s fall 3 rise 5 weight 1
server wuwu 192.168.221.100:8080 backup #将 HAProxy 主机上的 Apache(192.168.221.100:8080)配置为备份节点,仅当所有主业务节点故障时才启用
[root@haproxy ~]# systemctl restart haproxy.service

测试
在业务节点正常时,访问 HAProxy,验证请求被正常分发到 RS1 和 RS2

3.关闭两台正常的业务主机
[root@webserver1+2 ~]# systemctl stop httpd
测试:
访问 HAProxy 主机的 8080 端口,验证 sorryserver 页面 "李哥在,没意外" 是否正常显示,证明故障时可提供临时服务。

5.2 自定义错误页面
当所有主机包括sorryserver都宕机了,那么haproxy会提供一个默认访问的错误页面,这个错误页面跟报错代码有关,这个页面可以通过定义来机型设置
1.出现的错误页面
[root@webserver1+2 ~]# systemctl stop httpd
[root@haproxy ~]# systemctl stop httpd
2.配置sorryserver上线
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
server haha 192.168.221.10:80 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.221.20:80 check inter 3s fall 3 rise 5 weight 1
# server wuwu 192.168.221.100:8080 backup
[root@haproxy ~]# systemctl restart haproxy.service

3.所有后端web服务都宕机

[root@haproxy ~]# mkdir /errorpage/html/ -p #创建目录 /errorpage/html/,用于存放自定义错误页面文件。
[root@haproxy ~]# vim /errorpage/html/502.http #创建自定义 502 错误页面文件
HTTP/1.0 502 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8
<html><body><h1>小狗怎么叫?</h1>
汪汪汪
</body></html>
#定义 HTTP 502 响应头和自定义 HTML 内容,用于替换 HAProxy 默认的 502 错误页面
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
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
errorfile 502 /errorpage/html/502.http #defaults 段中添加 errorfile 指令,将 502 错误码与自定义页面绑定
[root@haproxy ~]# systemctl restart haproxy.service


测试:
在所有后端服务(包括 sorryserver)宕机时,访问 HAProxy,验证返回的是自定义的 502 页面 "小狗怎么叫?汪汪汪",而非默认页面。

3.从定向错误到指定网站
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
errorloc 502 http://www.baidu.com
#将 502 错误码的响应方式从 "返回自定义页面" 改为 "重定向到百度首页"
[root@haproxy ~]# systemctl restart haproxy.service

4.在浏览器中访问
在浏览器中访问 192.168.35.100,验证当所有后端宕机时,页面自动跳转到百度首页,证明 502 错误重定向配置生效。
浏览器搜索ip192.168.35.100,回车自动跳转百度页面


六. ACL 访问控制列表
HAProxy 的 ACL(访问控制列表)是一种基于包过滤的访问控制技术,可根据请求的源地址、端口、URL、文件后缀、域名等报文信息,通过指定匹配模式(如大小写不敏感、前缀 / 后缀 / 子串匹配等)和逻辑组合(与 / 或 / 非)设定匹配条件,对经过服务器的数据包进行过滤匹配,进而执行允许通过、拒绝访问或转发至指定后端等操作,常见用于域名匹配、动静分离等场景。
6.1 实验素材
1.在浏览器或者curl主机中设定本地解析
notepad C:\Windows\System32\drivers\etc\hosts
#在 Windows 上用记事本打开 hosts 文件,用于配置本地域名解析。

Linux中会同步解析
[Administrator.DESKTOP-VJ307M3] ➤ vim /etc/hosts

测试:
测试域名解析是否生效,验证 bbs.timinglee.org 被解析到 192.168.35.100
ping bbs.timinglee.org

6.2 设定基础的haproxy实验配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster #定义处理 HTTP 请求的前端,监听 80 端口
bind *:80
mode http
use_backend webserver-80-web1 #默认将所有请求转发到 web1(192.168.221.10)
backend webserver-80-web1
server web1 192.168.221.10:80 check inter 3s fall 3 rise 5
backend webserver-80-web2
server web2 192.168.221.20:80 check inter 3s fall 3 rise 5
#定义两个后端服务器组,分别对应 webserver1 和 webserver2。
[root@haproxy ~]# systemctl restart haproxy.service

6.3 基础acl示例
1.在访问的网址中,所有以.com 结尾的访问10,其他访问20
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
# use_backend webserver-80-web1
acl test hdr_end(host) -i .com #acl列表:定义 ACL 规则 test,匹配以 .com 结尾的域名(不区分大小写)
use_backend webserver-80-web1 if test #acl列表访问匹配:如果匹配 test 规则,将请求转发到 web1
default_backend webserver-80-web2 #acl列表访问不匹配,默认转发到 web2
backend webserver-80-web1
server web1 192.168.221.10:80 check inter 3s fall 3 rise 5
backend webserver-80-web2
server web2 192.168.221.20:80 check inter 3s fall 3 rise 5
[root@haproxy ~]# systemctl restart haproxy.service

测试:

tips:测试前必须确保webserver1+2的httpd服务是开启状态,若没有开启,可通过
root@webserver1+2 \~\]# systemctl stop nginx \[root@webserver1+2\~\]# systemctl disable nginx Removed "/etc/systemd/system/multi-user.target.wants/nginx.service". \[root@webserver1+2 \~\]# systemctl enable --now httpd 来关闭nginx(因为nginx和http有冲突)之后再开启http服务
2..基于访问头部
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
# use_backend webserver-80-web1
acl test hdr_end(host) -i .com #acl列表
acl head hdr_beg(host) -i bbs. #定义 ACL 规则 head,匹配以 bbs. 开头的域名(不区分大小写)
use_backend webserver-80-web1 if head #如果匹配 head 规则,将请求转发到 web1
# use_backend webserver-80-web1 if test #acl列表访问匹配
default_backend webserver-80-web2 #acl列表访问不匹配
backend webserver-80-web1
server web1 192.168.221.10:80 check inter 3s fall 3 rise 5
backend webserver-80-web2
server web2 192.168.221.20:80 check inter 3s fall 3 rise 5
[root@haproxy ~]# systemctl restart haproxy.service

测试
访问 www.lee.com(不匹配 bbs. 开头),验证被转发到 web2。

3.base参数acl
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl pathdir base_dir -i /lee #定义 ACL 规则 pathdir,匹配访问路径中包含 /lee 目录的请求
use_backend webserver-80-web1 if pathdir #如果匹配 pathdir 规则,将请求转发到 web1
default_backend webserver-80-web2
backend webserver-80-web1
server web1 192.168.221.10:80 check inter 3s fall 3 rise 5
backend webserver-80-web2
server web2 192.168.221.20:80 check inter 3s fall 3 rise 5
[root@haproxy ~]# systemctl restart haproxy.service

[root@webserver1+2 ~]# mkdir -p /var/www/html/lee/
[root@webserver1+2 ~]# mkdir -p /var/www/html/lee/test/
#在两台 webserver 上创建 /lee 和 /lee/test 目录,用于存放测试页面。
[root@webserver1 ~]# echo lee - 192.168.0.10 > /var/www/html/lee/index.html
[root@webserver1 ~]# echo lee/test - 192.168.0.10 > /var/www/html/lee/test/index.html
[root@webserver2 ~]# echo lee - 192.168.0.20 > /var/www/html/lee/index.html
[root@webserver2 ~]# echo lee/test - 192.168.0.10 > /var/www/html/lee/test/index.html
#用于区分后端服务器


测试:
访问 /lee/ 路径,验证被转发到 web1。
访问根路径(不匹配 /lee),验证被转发到 web2。

4.acl禁止列表黑名单
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl test hdr_end(host) -i .com #acl列表
use_backend webserver-80-web1 if test #acl列表访问匹配
default_backend webserver-80-web2 #acl列表访问不匹配
acl invalid_src src 192.168.35.1 #定义 ACL 规则 invalid_src,匹配源 IP 为 192.168.35.1 的请求。
http-request deny if invalid_src #如果匹配 invalid_src 规则,直接拒绝该请求(返回 403 Forbidden)。
backend webserver-80-web1
server web1 192.168.221.10:80 check inter 3s fall 3 rise 5
backend webserver-80-web2
server web2 192.168.221.20:80 check inter 3s fall 3 rise 5
[root@haproxy ~]# systemctl restart haproxy.service

测试:
从 192.168.35.1 发起访问,验证被 HAProxy 拒绝;从其他 IP 发起访问,验证正常转发

5.禁止列表白名单
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl test hdr_end(host) -i .com #acl列表
use_backend webserver-80-web1 if test #acl列表访问匹配
default_backend webserver-80-web2 #acl列表访问不匹配
acl invalid_src src 172.25.254.1 #定义 ACL 规则 invalid_src,匹配源 IP 为 192.168.35.1 的请求
http-request deny if ! invalid_src #白名单逻辑,仅允许源 IP 为 192.168.35.1 的请求通过,其他所有源 IP 的请求都被拒绝(返回 403 Forbidden)
backend webserver-80-web1
server web1 192.168.0.10:80 check inter 3s fall 3 rise 5
backend webserver-80-web2
server web2 192.168.0.20:80 check inter 3s fall 3 rise 5
[root@haproxy ~]# systemctl restart haproxy.service

测试:
- 从源 IP
192.168.35.1发起访问:验证被允许通过,根据域名后缀规则转发到对应后端(如www.lee.com转发到 web1,www.lee.org转发到 web2)。 - 从其他源 IP(如 HAProxy 本机)发起访问:验证被拒绝,返回
403 Forbidden错误页面,证明白名单配置生效。


七. HAProxy https 实现
HAProxy 可以实现 HTTPS 卸载,即用户到 HAProxy 之间使用 HTTPS 加密通信,而 HAProxy 到后端服务器之间则使用 HTTP 以提升性能;在生产环境中,证书通常部署在后端服务器(如 Nginx),但也可在 HAProxy 上配置,通过bind *:443 ssl crt指令加载 PEM 格式证书(需合并证书与私钥),同时可配置 80 端口自动重定向到 443 端口,实现全站 HTTPS,后端仍通过 HTTP 转发请求。
7.1 制作证书
[root@haproxy ~]# mkdir /etc/haproxy/certs/
#创建目录,用于存放 HAProxy 的 HTTPS 证书和私钥文件。
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt
#使用 OpenSSL 生成一个自签名的 SSL 证书
[root@haproxy ~]# ls /etc/haproxy/certs/
timinglee.org.crt timinglee.org.key
列出 /etc/haproxy/certs/ 目录下的文件,确认私钥(.key)和证书(.crt)已生成
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.org.{key,crt} > /etc/haproxy/certs/timinglee.pem
将私钥和证书文件合并为一个 PEM 格式文件,供 HAProxy 加载
- 自签名的 SSL 证书
req -newkey rsa:2048:生成 2048 位 RSA 私钥-nodes:私钥不加密-sha256:使用 SHA256 哈希算法-keyout:将私钥保存到指定路径-x509 -days 365:生成有效期为 365 天的自签名 X.509 证书-out:将证书保存到指定路径


7.2 全站加密
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster-http #定义一个名为webcluster-http的前端,处理 HTTP 请求
bind *:80
redirect scheme https if ! { ssl_fc } #如果请求不是 HTTPS(!{ ssl_fc }),则将其重定向到 HTTPS 协议
listen webcluster-https #定义一个名为webcluster-https的监听块,同时处理前端和后端逻辑
bind *:443 ssl crt /etc/haproxy/certs/timinglee.pem #监听所有网卡的 443 端口,启用 SSL,并加载指定的 PEM 证书文件
mode http
balance roundrobin
server haha 192.168.221.10:80 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.221.20:80 check inter 3s fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service

测试:没出现就多测试几次
验证 HTTP(80 端口)是否被自动重定向到 HTTPS(443 端口),以及 HTTPS 连接是否正常
