目录
一.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