haproxy高级

haproxy高级配置及案例

1、基于cookie的会话保持


cookie value :为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy 负载,目前此模式使用较少, 已经被 session 共享服务器代替

cookie会话保持明显不支持 tcp mode ,使用 http mode


配置选项

cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [
preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name : #cookie 的 key 名称,用于实现持久连接
insert : # 插入新的 cookie, 默认不插入 cookie
indirect : # 如果客户端已经有 cookie, 则不会再发送 cookie 信息
nocache:  # 当 client 和 hapoxy 之间有缓存服务器(如: CDN )时,不允许中间缓存器缓存 cookie , #因为这会导致很多经过同一个 CDN 的请求都发送到同一台后端服务器
配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
......
listen webserver_80
bind 172.25.254.100:80
option forwardfor
mode http
balance roundrobin
cookie WEBCOOKIE insert nocache indirect
server webserver1 192.168.0.10:80 cookie web1 weight 1 check inter 3s fall
3 rise 5
server webserver2 192.168.0.20:80 cookie web2 weight 1 check inter 3s fall
3 rise 5
.....

2、IP透传


P 透传(IP Transparency)指的是在代理服务器处理请求和响应的过程中,能够将客户端的真实 IP 地址传递到后端服务器,使得后端服务器能够获取到客户端的原始 IP 而不是代理服务器的 IP 地址。

在web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。

IP透传分为四层和七层:tcp协议为四层,httpd协议为七层

2.1、四层代理

开启透传四层代理
[root@rs1 ~]# vim /etc/nginx/nginx.conf
。。。。。。
http {
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"';
。。。内容省略。。。
server {
listen 80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理
访问
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
。。。。。。
}
}
修改haproxy
haproxy ~]# vim /etc/haproxy/haproxy.cfg
......
listen webserver_80
bind 172.25.254.100:80
mode tcp
balance roundrobin
server webserver1 192.168.0.10:80 send-proxy weight 1 check inter 3s fall 3
rise 5
......
查看日志内容
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
192.168.0.10 - - [10/aug/2024:15:21:00 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"
192.168.0.10 - - [10/aug/2024:15:26:11 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"
192.168.0.10 - - [10/aug/2024:15:41:56 +0800] "GET / HTTP/1.1" "172.25.254.10"200
18 "-" "curl/7.29.0"

七层代理

修改haproxy
haproxy ~]# vim /etc/haproxy/haproxy.cfg
......
listen webserver_80
option forwardfor
bind 172.25.254.100:80
mode http
balance roundrobin
server webserver1 192.168.0.10:80 send-proxy weight 1 check inter 3s fall 3
rise 5
server webserver1 192.168.0.20:80 weight 1 check inter 3s fall 3 rise 5
配置web服务日志格式
#nginx 日志格式:
$proxy_add_x_forwarded_for: #包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For: #只有客户端IP
log_format main '"$proxy_add_x_forwarded_for" - $remote_user [$time_local]
"$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_For';
查看日志
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
"172.25.254.10, 192.168.0.10" 192.168.0.10 - - [10/aug/2024:16:15:00 +0800] "GET
/ HTTP/1.1"200 18 "-" "curl/7.29.0" "172.25.254.10"
[root@rs2 ~]# tail -n 3 /etc/httpd/logs/access_log
172.25.254.10 192.168.0.10 - - [11/aug/2024:00:15:00 +0800] "GET / HTTP/1.1" 200
27 "-" "curl/7.29.0"

HAProxy 中的 ACL(访问控制列表)详解

1. ACL 概述

1.1 基本概念

ACL(Access Control List)是 HAProxy 中用于实现基于请求报文的首部、响应报文的内容或其他环境状态信息来做出转发决策的一种机制。ACL 可以根据不同的条件来过滤流量,并据此执行特定的动作,如阻止请求、转发到特定的后端服务器等。

1.2 作用

  • 智能路由:根据客户端请求的特性(如 IP 地址、请求方法、URL 等)将流量导向特定的后端服务器。
  • 访问控制:限制或允许特定客户端的访问,提高系统的安全性。
  • 负载均衡:根据服务器的负载情况和其他条件智能地分配请求。
  • 故障恢复:在服务器出现故障时,可以自动将请求重新定向到健康的服务器。

2. ACL 配置

2.1 ACL 语法格式

ACL 的配置通常遵循以下格式:

acl <aclname> <criterion> [flags] [operator] <value>
  • <calname>:定义 ACL 的名称,必须是唯一的,且只能包含字母、数字和连字符。
  • [flags]:可选的标志位,例如 -i 表示忽略大小写。
  • [operator]:可选的操作符,例如 eq 表示等于。
  • <value>:定义测试条件的具体值。

2.2 ACL 示例

  • ACL-criterion 匹配规范
 提取http报文首部
hdr string,提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出
现次数
hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的dom(host)
hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径
hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配 模糊匹配c 报文中a/b/c也会匹
配
 首部指定内容
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.zheng.org
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn

acl bad_agent hdr_sub(User-Agent) -i curl wget
http-request deny if bad_agent
#有些功能是类似的,比如以下几个都是匹配用户请求报文中host的开头是不是www
acl short_form hdr_beg(host) www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2 hdr_dom(host) -m beg www.
acl alternate3 hdr(host) -m beg www.

base:string
ACL-operator 具体操作符
整数比较:eq、ge、gt、le、lt
字符比较:
- exact match (-m str) :字符串必须完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
- suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行
匹配
- subdir match (-m dir) :查看提取出来的用斜线分隔(“/")的字符串,如其中任一个匹配,则ACL
进行匹配
- domain match (-m dom) :查找提取的用点(“.")分隔字符串,如果其中任何一个匹配,则ACL进行
匹配
ACL-value 操作对象
The ACL engine can match these types against patterns of the following types :
- Boolean #布尔值
- integer or integer range #整数或整数范围,比如用于匹配端口范围
- IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.timinglee.org
exact #精确比较
substring #子串
suffix #后缀比较
prefix #前缀比较
subdir #路径, /wp-includes/js/jquery/jquery.js
domain #域名,www.timinglee.org
- regular expression #正则表达式
- hex block #16进制

  • 基于客户端 IP 地址

    acl ip100 src 192.168.1.100
    acl ip100 src 192.168.1.100/24
    
  • 基于请求的 URL

    acl api-uri path_beg /api
    acl api-uri path -i /api
    
  • 基于 HTTP 方法

    acl get-method req.meth eq GET
    acl post-method req.meth eq POST
    
  • 基于 HTTP 用户代理

    acl chrome-user-agent hdr(User-Agent) -i chrome
    

2.3 使用 ACL

一旦定义了 ACL,就可以在 HAProxy 的配置中使用它们来执行各种操作,例如:

  • 转发到特定后端

    use_backend servers if api-uri
    
  • 拒绝请求

    http-request deny if ip100
    
  • 重定向

    http-request redirect code 302 if api-uri location /new-api-url
    

3. 实际应用场景

3.1 基于 IP 的访问控制

假设我们需要限制来自特定 IP 地址的访问,可以使用如下配置:

frontend http-in
    bind *:80
    mode http
    default_backend servers

backend servers
    balance roundrobin
    server server1 192.168.0.10:80 check
    server server2 192.168.0.20:80 check

    acl block-ip src 192.168.0.100
    http-request deny if block-ip

3.2 基于 URL 的路由

假设我们需要将所有以 /api/ 开头的请求路由到一组专门处理 API 请求的后端服务器,可以使用如下配置:

frontend http-in
    bind *:80
    mode http
    default_backend servers

backend servers
    balance roundrobin
    server server1 192.168.0.10:80 check
    server server2 192.168.0.20:80 check

backend api-servers
    balance roundrobin
    server server3 192.168.0.11:80 check
    server server4 192.168.0.21:80 check

    acl api-uri path_beg /api
    use_backend api-servers if api-uri

3.3 基于 HTTP 方法的重定向

假设我们需要将所有 POST 请求重定向到一个特定的 URL,可以使用如下配置:

frontend http-in
    bind *:80
    mode http
    default_backend servers

backend servers
    balance roundrobin
    server server1 192.168.1.10:80 check
    server server2 192.168.1.11:80 check

    acl post-method req.meth eq POST
    http-request redirect code 302 if post-method location /post-handler

 3.4 匹配访问路径实现动静分离

假设我们需要将php与static静态界面的资源分别存放于指定的服务器,通过匹配访问路径访问动静态资源,可用以下配置:

frontend testacl
bind :80
mode http

########### ACL settings #######################

acl url_static path_end -i .jpg .png .css .js .html
acl url_static path_end -m sub /static /images /javascript
acl acl_app path_beg -m sub /api

########### host ###########################

use_backend static_host if url_static
use_backend api_host if acl_app

########### default server ###################

default_backend default_webserver
backend static_host
mode http
server web2 192.168.0.101:80 check weight 1 inter 3s fall 3 rise 5
backend api_host
mode http
server web1 192.168.0.102:80 check weight 1 inter 3s fall 3 rise 5
backend default_webserver
mode http
server web1 172.25.254.10:80 check weight 1 inter 3s fall 3 rise 5

创建相关文件
[root@rs1 ~]# mkdir /usr/share/nginx/html/static
[root@rs1 ~]# echo static 192.168.0.10 > /usr/share/nginx/html/static/index.html
[root@rs2 ~]# mkdir /var/www/html/php/
[root@rs2 ~]# vim /var/www/html/php/index.php
<?php
      phpinfo();
?>
 测试访问

自定义haproxy错误页面

 配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
......
defaults

mode http
......

timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 1000000
errorfile 503 /haproxy/errorpages/503page.http

[root@haproxy ~]# mkdir /haproxy/errorpages/ -p
[root@haproxy ~]# cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
[root@haproxy ~]# vim /haproxy/errorpages/503page.http
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8

<html><body><h1>易如反掌易如反掌</h1>

</body></html
测试

haproxy四层负载

对于haproxy还存在除http外的tcp协议应用服务访问的应用场景,比如mysql

配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
......
listen mysql_port
bind :3306       #mysql服务使用的端口
mode tcp
balance leastconn
server mysql1 192.168.0.101:3306 check
server mysql2 192.168.0.102:3306 check       #或者使用frontend和backend实现
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
......
frontend mysql_port
bind :3306
mode tcp
use_backend mysql_rs
backend mysql_rs
mode tcp
balance leastconn
server mysql1 192.168.0.101:3306 check
server mysql2 192.168.0.102:3306 check
[root@haproxy ~]# systemctl restart haproxy.service
在rs1,rs2安装mysql服务
 yum install mariadb-server -y
vim /etc/my.cnf
[mysqld]
server-id=1 
 测试

  • 29
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值