Haproxy -- 高级功能配置及实用案例

目录

实验环境

环境流程图

实验环境

环境配置

[一. 基于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.1.sorryserver的设定

[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链接中,按需自行查看

https://blog.csdn.net/2401_84184229/article/details/157808422https://blog.csdn.net/2401_84184229/article/details/157808422?sharetype=blogdetail&sharerId=157808422&sharerefer=PC&sharesource=2401_84184229&sharefrom=mp_from_link

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)轮询分发请求。

  • 输出显示webserver1webserver2交替出现,证明负载均衡配置生效。

    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 请求,验证四层负载均衡是否按权重轮询分发请求。
  • 输出显示RS1RS2交替出现,证明四层负载均衡和 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,验证请求被正常分发到 RS1RS2

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 连接是否正常

相关推荐
礼拜天没时间.1 小时前
Linux运维实战:巧用mv命令管理多版本Go环境,避免采坑
linux·运维·golang·centos
期待のcode2 小时前
Kubernetes与Minikube
运维·容器·kubernetes
鸠摩智首席音效师2 小时前
如何在 Ubuntu 上安装 phpMyAdmin ?
linux·运维·ubuntu
lihao lihao2 小时前
页面自动化常见函数重点说明
运维·自动化
Doro再努力2 小时前
【Linux操作系统16】Linux进程管理深度解析:从fork到内核链表设计
linux·运维·链表
iambooo2 小时前
基于日志的故障定位与自动化分析体系
运维·自动化
杨云龙UP2 小时前
Oracle ASM归档日志自动清理:RMAN+crontab一键闭环(生产可用)
linux·运维·服务器·数据库·oracle·centos·ux
love530love2 小时前
解决微软登录错误 0xCAA82EE2 & 身份验证故障排查指南
运维·人工智能·microsoft·onedrive·microsoft 365·teams·microsoftonline
A.A呐2 小时前
【Linux第八章】环境变量
linux