一眼心动的HAProxy高级功能配置

目录

一.haproxy-基于cookie的会话保持

二.七层IP透传

三.四层IP透传

四.访问控制列表ACL

五.acl做动静分离访问控制

六.基于自定义的错误页面文件

七.HAProxy 四层负载

八.HAProxy https 实现

九.让文件编写更简单的方法


一.haproxy-基于cookie的会话保持

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

配置选项
name: #cookie 的 key名称,用于实现持久连接 
insert: #插入新的cookie,默认不插入cookie.
indirect: #如果客户端已经有cookie,则不会再发送cookie信息 nocache: #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie, #因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器
-------------------------------------------
vi  /etc/haproxy/haproxy.cfg 
listen webcluster          
bind *:80                   
mode http                      
balance  roundrobin       
cookie WEBCOOKIE insert nocahe 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 
验证:可以在浏览器输入172.25.254.100,或者
curl -b WEBCOOKIE=web1 172.25.254.100
curl -b WEBCOOKIE=web2 172.25.254.100

 验证成功图片:

二.七层IP透传

当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器

#nginx 日志格式:
$proxy_add_x_forwarded_for: 包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For: 只有客户端IP
vi /etc/nginx/nginx.conf
......
http {
    log_format  main  ' "$proxy_add_x_forwarded_for" $remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
.....
systemctl restart nginx
测试:在测试端curl 172.25.254.100,直到web2出现。web2:cat /var/log/nginx/access.log #在web2里面查看日志,是否有ip数据。应该是没有。之后在添加了内容后,在回到web2看看,是否有ip数据,大致是有的 "172.25.254.1, 172.25.254.100" 172.25.254.100 - - [10/Aug/2024:22:28:57 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.7.1" "172.25.254.1"
-------将web1的nginx服务改为Apache服务------
web1:
systemctl disable nginx
systemctl stop nginx.service
dnf install httpd -y
echo webserver1 - 172.25.254.10 > /var/www/html/index.html
systemctl enable --now httpd
在测试端:curl 172.25.254.100,直到web1出现。
cat /etc/httpd/logs/access_log  #然后查看日志,Apache默认没有设定。所以没有ip数据。
vi /etc/httpd/conf/httpd.conf
.....
    LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
systemctl restart httpd
测试:先在测试端curl了之后,在重新cat /etc/httpd/logs/access_log 就会出现ip:172.25.254.1 172.25.254.100 - - [10/Aug/2024:22:13:51 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.7.1"

三.四层IP透传

web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。能够实现高效的数据传输,减少中间设备对数据包的干预,从而降低延迟和提高性能。

修改haproxy配置文件
vim /etc/haproxy/haproxy.cfg
...
listen webserver_80
bind *:80
mode tcp
balance roundrobin
server  web1  172.25.254.10:80 send-proxy check inter 2 fall 3 rise 5 weight 1 
server  web2  172.25.254.20:80 send-proxy check inter 2 fall 3 rise 5 weight 1 
....
重启systemctl restart haproxy
---------------nginx配置--------------------
vim /etc/nginx/nginx.conf
.....
http {
    log_format  main  ' "$proxy_add_x_forwarded_for" $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;
.........
systemctl restart nginx
测试:先在测试端curl到web2,之后在web2输入:tail /var/log/nginx/access.log
 "172.25.254.1, 172.25.254.100" 172.25.254.100 - - [10/Aug/2024:22:41:44 +0800] "GET / HTTP/1.1"  "172.25.254.1"20027 "-" "curl/8.7.1" "172.25.254.1"
 ---Apache服务的四层透析一般不用,就没写----

四.访问控制列表ACL

是一种基于包过滤的访问控制技术 它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配)即对接收到的报文进行匹配和过 滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内 容进行匹配并执行进一步操作,比如允许其通过或丢弃。

ACL匹配模式:

-i 不区分大小写

-m 使用指定的正则表达式匹配方法

-n 不做DNS解析

-u 禁止acl重名,否则多个同名

ACL匹配或关系

多个ACL的逻辑处理

与:隐式(默认)使用

或:使用“or" 或 “||"表示

否定:使用 "!" 表示

修改haproxy配置文件
vim /etc/haproxy/haproxy.cfg
...
frontend webcluster
    bind *:80
    mode http
#选择一个及2个即可
acl domain hdr_beg(host) -i bbs
acl test path_sub -m sub lee
acl test path_sub -m sub lee   #检查请求的域名斜杆后面中是否包含子字符串 lee
acl test base_reg  -i lee/$  #在字符串里结尾有指定的字符 ,路径里面有指定的也行
acl test base_sub -m sub rhel   #使用正则表达式检查,在字符串里指定的字符 ,路径里面有指定的也行
acl test hdr_beg(host) -i bbs #请求的host结尾以 bbs开头,则匹配
acl test hdr_end(host) -i .org #请求的host结尾以 .org 结尾,则匹配
acl test hdr(host) -i www.rhel9.org  #检查请求头中的 host 字段,如果是 www.timinglee.org ,则匹配
#选择一个即可
use_backend webcluster-host if test  #如果匹配到上述定义的 test 相关的 ACL 条件,就使用名为 test_web 的后端。
use_backend webcluster-host if ! test  #否定
use_backend webcluster-host if test || domain  #或
use_backend webcluster-host if test  domain  #并且
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
#根据选择的在对于的web创建网页内容
[root@webserver1 ~]# mkdir /var/www/html/lee -p
[root@webserver1 ~]# echo 172.25.254.10 lee > /var/www/html/lee/index.html
[root@webserver1 ~]# curl 172.25.254.10/lee/
172.25.254.10 lee
[root@webserver2 ~]# mkdir /usr/share/nginx/html/lee -p
[root@webserver2 ~]# echo 172.25.254.20 lee > //usr/share/nginx/html/lee/index.html
[root@webserver2 ~]# systemctl restart nginx
#Windows本地加解析:C:Windows/System32/drivers/etc/hosts里面加入172.25.254.100  www.rhel9.org www.rhel9.com bbs.rhel9.org即可
测试:在Windows测试要先在Windows本地加解析才能访问域名curl www.rhel9.org

五.acl做动静分离访问控制

-------------基于域名的访问控制-----------------
修改haproxy配置文件
vim /etc/haproxy/haproxy.cfg
...
frontend webcluster
    bind *:80
    mode http
acl domain hdr_dom(host) -i www.rhel9.org
use_backend webcluster-host if domain 
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
-----------------------基于ip的访问控制-----------------------

...
frontend webcluster
    bind *:80
    mode http
acl ctrl_ip src 172.25.254.0/24  #也可以写-i www.rhel9.org,网段的一个主机,也可以加别的网段
use_backend webcluster-host if ctrl_ip
#http-request deny if ctrl_ip  #黑名单,拒绝名单里的主机访问
....
[root@haproxy ~]# systemctl restart haproxy
测试:可以在各个主机curl ip根据你写的内容。
-----------------------基于源地址的访问控制-----------------------
.....
acl web_host hdr_dom(host) www.timinglee.org
acl ip_test src 172.25.254.1 192.168.0.0/24
http-request deny if web_host
.......
#允许一个拒绝一个
[root@haproxy ~]# systemctl restart haproxy
-----------------------基于匹配浏览器的访问控制-----------------------
.....
acl badwebrowers hdr_sub(User-Agent) -i curl wget
http-request deny if badwebrowers
.....
[root@haproxy ~]# systemctl restart haproxy
测试:各个浏览器试试
---------------------基于文件后缀名实现动静分离-----------------------
[root@webserver1 ~]# dnf install php -y
[root@webserver1 ~]# systemctl restart httpd
[root@webserver1 ~]# cat /var/www/html/index.php
<?php
	phpinfo();
?>
测试:在浏览器访问172.25.254.10/index.php
修改haproxy配置文件
vim /etc/haproxy/haproxy.cfg
...
acl static path_end -i .html .jpg .png .css .js
acl php    path_end -i .php
use_backend webcluster-host if php
....
[root@haproxy ~]# systemctl restart haproxy
测试:在浏览器里面172.25.254.100和172.25.254.100/index.php;172.25.254.100/index.html。
---------------------基于匹配访问路径实现动静分离----------------------
[root@webserver1 ~]# mkdir -p /var/www/html/php
[root@webserver1 ~]# cp /var/www/html/index.php /var/www/html/php/
[root@webserver2 ~]# mkdir -p /usr/share/nginx/html/static
[root@webserver2 ~]# echo static - 172.25.254.20 > /usr/share/nginx/html/static/index.html
修改haproxy配置文件
vim /etc/haproxy/haproxy.cfg
...
acl static path_sub -m sub static
acl php    path_sub -m sub php
use_backend webcluster-host if php
....
[root@haproxy ~]# systemctl restart haproxy
测试:在浏览器里面172.25.254.100/static;172.25.254.100/php。不同的路径访问不同的页面。

六.基于自定义的错误页面文件

[root@webserver1 ~]# systemctl stop httpd
[root@webserver2 ~]# systemctl stop nginx
测试:访问172.25.254.100出现错误页面就对了。
vim /etc/haproxy/haproxy.cfg
.....
   timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 100000
errorfile 503 /etc/haproxy/errorpage/badpage.http
errorloc 503 https://www.baidu.com   #浏览器访问172.25.254.100 自动跳转到百度
.....
mkdir /haproxy/errorpage/ -p
vim /haproxy/errorpage/badpage.http
HTTP/1.0 503 Service Unavailable^M
Cache-Control: no-cache^M
Connection: close^M
Content-Type: text/html;charset=UTF-8^M
^M
<html><body><h1>shui si joker</h1>
si ni a hahahaha!!!!!
</body></html>
测试:
关闭后端的RS主机
然后用浏览器去访问172.25.254.100

七.HAProxy 四层负载

vim /etc/haproxy/haproxy.cfg
....
listen dbserver
bind *:3306
mode tcp
balance roundrobin
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
.....
#在后端服务器安装和配置mariadb服务
[root@haproxy ~]# yum install mariadb-server -y
[root@webserver1 ~]# yum install mariadb-server -y
[root@webserver2 ~]# yum install mariadb-server -y

[root@webserver1 ~]# vi /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=1 
[root@webserver2 ~]# vi /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=2 

[root@webserver1 ~]#  systemctl start mariadb
[root@webserver2 ~]#  systemctl start mariadb
[root@webserver1 ~]#  mysql
[root@webserver2 ~]#  mysql
MariaDB [(none)]> SELECT @@server_id
    -> ;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+
1 row in set (0.000 sec)
MariaDB [(none)]> SELECT @@server_id
    -> ;
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+
1 row in set (0.001 sec)

[root@webserver1 ~]#  mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
[root@webserver2 ~]#  mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
#测试
[root@haproxy ~]#  mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+
[root@haproxy ~]#  mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+

八.HAProxy https 实现

证书制作
[root@haproxy ~]# mkdir /etc/haproxy/certs/   #创一个文件放加密文件
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/rhel9.org.key -x509 -days 365 -out /etc/haproxy/certs/rhel9.org.crt    #生成密钥对
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shannxi
Locality Name (eg, city) [Default City]:Xi'An 
Organization Name (eg, company) [Default Company Ltd]:rhel9
Organizational Unit Name (eg, section) []:webserver
Common Name (eg, your name or your server's hostname) []:www.rhel9.org
Email Address []:admin@rhel9.org   
[root@haproxy ~]# ls /etc/haproxy/certs/
rhel9.org.crt  rhel9.org.key
[root@haproxy ~]# cat /etc/haproxy/certs/rhel9.org.key /etc/haproxy/certs/rhel9.org.crt > /etc/haproxy/certs/rhel9.pem
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg  #合并为一个文件
......
frontend webcluster
    bind *:80
    mode http
    redirect scheme https if !{ ssl_fc }    #全站加密
.....
listen web-https
bind *:443 ssl crt /etc/haproxy/certs/rhel9.pem   #加密
mode http 
balance  roundrobin
server   web1   172.25.254.10:80 check inter 2 fall 3 rise 5
server   web2   172.25.254.20:80 check inter 2 fall 3 rise 5
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
......
[root@haproxy ~]# systemctl restart haproxy
测试:在浏览器里输入172.25.254.100出现有风险就可以了。

九.让文件编写更简单的方法

[root@haproxy ~]# cd /etc/haproxy
[root@haproxy haproxy]# vi /etc/haproxy/conf.d  #创建并添加haproxy状态页的内容的子配置文件
listen stats
        bind *:9999
        mode http
        stats enable
        stats refresh 10
        stats uri /status
        stats auth lee:lee
[root@haproxy ~]# vi /lib/systemd/system/haproxy.service 
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "CFGDIR=/etc/haproxy/conf.d"  #添加子配置文件的路径,其实就是一个引用变量。
ExecStartPre=/usr/sbin/haproxy -f $CONFIG -f $CFGDIR -c -q $OPTIONS
ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -f $CFGDIR -p $PIDFILE $OPTIONS
ExecReload=/usr/sbin/haproxy -f $CONFIG -f $CFGDIR -c -q $OPTIONS   #添加子配置文件的变量。
[root@haproxy haproxy]# systemctl daemon-reload   #需要重启整个文件重新录入。
[root@haproxy haproxy]# systemctl restart haproxy
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值