云原生(自定义错误界面 / 容灾兜底、全站加密、ACL 访问控制实验)
·
实验简介
实验一:自定义 HAProxy 错误界面
核心目标
实现业务故障时的 “兜底容灾”:先通过备用服务器(sorryserver)承接流量,若备用服务器也故障,则返回自定义错误页面(或重定向到指定网站),提升用户体验。
实验步骤与核心操作
- 配置 sorryserver(备用兜底服务器):
- 在 HAProxy 主机(或独立主机)部署 Apache,修改监听端口为 8080,编写兜底页面(如 “李哥在,没意外”);
- 在 HAProxy 配置中添加
backup标识的备用服务器(192.168.0.100:8080),仅当所有主服务器宕机时启用; - 测试:关闭所有主 Web 服务器后,访问 HAProxy 会返回备用服务器的兜底内容。
- 自定义错误页面:
- 当主服务器 + 备用服务器均宕机时,HAProxy 默认返回 503 页面,因此创建自定义 503 错误页面文件(自定义文案 “什么动物生气最安静 大猩猩!!”);
- 在 HAProxy 的
defaults块中通过errorfile 503指定自定义 503 页面路径,重启后验证访问返回自定义内容;
- 错误页面重定向到外部网站:
- 替换
errorfile为errorloc 503,指定重定向目标(如百度),实现故障时跳转到外部网站。
- 替换
关键价值
避免故障时返回默认生硬的错误页面,通过 “备用服务器 + 自定义错误页 / 重定向” 多层兜底,提升业务可用性和用户体验。
实验二:HAProxy ACL 访问控制
核心目标
基于 HAProxy 的 ACL(访问控制列表)功能,实现精细化的流量路由和访问权限管控。
实验步骤与核心操作
- 基础环境准备:
- 配置本地域名解析(如
www.timinglee.org、bbs.timinglee.org、www.lee.com等指向 HAProxy 服务器); - 配置 HAProxy 基础负载均衡,区分两个后端 Web 服务器(192.168.0.10/20)。
- 配置本地域名解析(如
- ACL 精细化路由示例:
- 域名后缀匹配:匹配
.com结尾的域名,路由到 web1;其他域名路由到 web2; - 域名前缀匹配:匹配
bbs.开头的域名,路由到 web1; - 访问路径匹配:匹配
/lee路径,路由到 web1;其他路径路由到 web2;
- 域名后缀匹配:匹配
- ACL 访问权限管控:
- 黑名单:配置 ACL 匹配指定 IP(172.25.254.1),通过
http-request deny拒绝该 IP 访问(返回 403); - 白名单:反向匹配 ACL,仅允许指定 IP 访问,拒绝其他所有 IP(注意语法:
! invalid_src表示 “非该 IP”)。
- 黑名单:配置 ACL 匹配指定 IP(172.25.254.1),通过
关键价值
实现 “按域名 / 路径 / IP” 的精细化流量调度和访问控制,满足业务多维度的路由、权限管控需求(如多域名分流、IP 黑白名单、路径级路由)。
实验三:HAProxy 全站加密
核心目标
实现 HTTP 请求自动重定向到 HTTPS,完成全站 HTTPS 加密,保障数据传输安全。
实验步骤与核心操作
- 制作自签名 SSL 证书:
- 创建证书存储目录,通过
openssl生成 RSA 2048 位的私钥和自签名证书,填写国家、省份、域名等信息(适配www.timinglee.org); - 将私钥和证书合并为 HAProxy 支持的 PEM 格式文件,便于配置加载。
- 创建证书存储目录,通过
- 配置 HAProxy 全站加密:
- 配置
frontend监听 80 端口,通过redirect scheme https if ! { ssl_fc }将所有非 HTTPS 请求强制重定向到 HTTPS; - 配置
listen块监听 443 端口,启用 SSL 并加载上述 PEM 证书,同时配置后端 Web 服务器(192.168.0.10/20)做负载均衡;
- 配置
- 测试验证:
- 通过
curl -v -k -L访问 80 端口,可观察到 302 重定向到 443 端口,且完成 TLS 握手、SSL 连接建立,最终返回后端 Web 服务器内容,验证全站加密生效。
- 通过
关键价值
解决 HTTP 明文传输的安全风险,实现业务流量的全链路加密,同时保留 HAProxy 的负载均衡能力。
自定义HAProxy 错误界面
sorryserver的设定
#在新主机中安装apache(可以用haproxy主机代替)
[root@haproxy yxs]# dnf install httpd -y
[root@haproxy yxs]# vim /etc/httpd/conf/httpd.conf
47 Listen 8080
[root@haproxy yxs]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@haproxy yxs]# echo "yxs" > /var/www/html/index.html
#配置sorryserver上线
[root@haproxy yxs]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode tcp
balance roundrobin
server haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1
server wuwu 192.168.0.100:8080 backup #sorryserver
[root@haproxy yxs]# systemctl restart haproxy.service
#测试
[root@test yxs]# curl 172.25.254.100 curl 172.25.254.100
webserver1 - 192.168.0.10
[root@test yxs]# curl 172.25.254.100 curl 172.25.254.100
webserver2 - 192.168.0.20
#关闭两台正常的业务主机
[root@webserver1 yxs]# systemctl stop httpd
[root@webserver2 yxs]# systemctl stop httpd
[root@test yxs]# curl 172.25.254.100 curl 172.25.254.100
yxs
自定义错误页面
#出现的错误页面
[root@webserver1 yxs]# systemctl stop httpd
[root@webserver2 yxs]# systemctl stop httpd
[root@haproxy yxs]# systemctl stop httpd
#所有后端web服务都宕机
[root@test yxs]# curl 172.25.254.100
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
[root@haproxy yxs]# vim /errorpage/html/503.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>
[root@haproxy yxs]# 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 503 /errorpage/html/503.http #error 页面
[root@haproxy yxs]# systemctl restart haproxy.service
#测试
[root@test yxs]# curl 172.25.254.100
<html><body><h1>什么动物生气最安静</h1>
大猩猩!!
</body></html>
重定向错误到指定网站
[root@haproxy yxs]# 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
errorloc 503 http://www.baidu.com #error 页面
[root@haproxy yxs]# systemctl restart haproxy.service
Haproxy ACL访问控制
实验环境
#在浏览器或者curl主机中设定本地解析
在windows中设定解析
#在Linux中设定解析
[root@test yxs]# vim /etc/hosts
172.25.254.100 www.timinglee.org bbs.timinglee.org news.timinglee.org login.timinglee.org www.lee.org www.lee.com
#测试
[root@test yxs]# ping bbs.timinglee.org
PING www.timinglee.org (172.25.254.100) 56(84) 比特的数据。
64 比特,来自 www.timinglee.org (172.25.254.100): icmp_seq=1 ttl=64 时间=0.441 毫秒
64 比特,来自 www.timinglee.org (172.25.254.100): icmp_seq=2 ttl=64 时间=0.309 毫秒
^Z
[5]+ 已停止 ping bbs.timinglee.org
设定基础的haproxy实验配置
[root@haproxy yxs]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
use_backend webserver-80-web1
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 yxs]# systemctl restart haproxy.service
基础acl示例
#在访问的网址中,所有以.com结尾的访问10,其他访问20
[root@haproxy yxs]# 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列表访问不匹配
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 yxs]# systemctl restart haproxy.service
#测试
[root@test yxs]# curl www.lee.com
webserver1 - 192.168.0.10
[root@test yxs]# curl www.lee.org
webserver1 - 192.168.0.20
#基于访问头部
[root@haproxy yxs]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl test hdr_end(host) -i .com #acl列表
acl head hdr_beg(host) -i bbs.
use_backend webserver-80-web1 if head
default_backend webserver-80-web2
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 yxs]# systemctl restart haproxy.service
#测试
[root@test yxs]# curl www.timinglee.org
webserver1 - 192.168.0.10
[root@test yxs]# curl bbs.timinglee.org
webserver1 - 192.168.0.20
#base参数acl
[root@haproxy yxs]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl pathdir base_dir -i /lee
use_backend webserver-80-web1 if pathdir
default_backend webserver-80-web2 #acl列表访问不匹配
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 yxs]# systemctl restart httpd.service
[root@webserver1 yxs]# mkdir -p /var/www/html/lee/
[root@webserver1 yxs]# mkdir -p /var/www/html/lee/test/
[root@webserver1 yxs]# echo lee - 192.168.0.10 > /var/www/html/lee/index.html
[root@webserver1 yxs]# echo lee/test - 192.168.0.10 > /var/www/html/lee/test/index.html
[root@webserver2 yxs]# mkdir -p /var/www/html/lee/
[root@webserver2 yxs]# mkdir -p /var/www/html/lee/test/
[root@webserver2 yxs]# echo lee - 192.168.0.20 > /var/www/html/lee/index.html
[root@webserver2 yxs]# echo lee/test - 192.168.0.10 > /var/www/html/lee/test/index.html
[root@webserver1 yxs]# systemctl restart httpd
[root@webserver2 yxs]# systemctl restart httpd
#测试
[root@test yxs]# curl 172.25.254.100/lee/
lee - 192.168.0.10
[root@test yxs]# curl 172.25.254.100/lee/test/
lee/test - 192.168.0.10
[root@test yxs]# curl 172.25.254.100/index.html
webserver1 - 192.168.0.20
#acl禁止列表黑名单
[root@haproxy yxs]# 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
http-request deny if invalid_src
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 yxs]# systemctl restart httpd.service
#测试
[root@test yxs]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
#禁止列表白名单
[root@haproxy yxs]# 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
http-request deny if ! invalid_src
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 yxs]# systemctl restart httpd.service
#测试
[root@test yxs]# curl 172.25.254.100
webserver1 - 192.168.0.20
[root@haproxy yxs]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
Haproxy全站加密
制作证书
[root@haproxy yxs]# mkdir /etc/haproxy/certs/
[root@haproxy yxs]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shanxi
Locality Name (eg, city) [Default City]:Xi'an
Organization Name (eg, company) [Default Company Ltd]:timinglee
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:www.timinglee.org
Email Address []:admin@timinglee.org
[root@haproxy yxs]# ls /etc/haproxy/certs/
timinglee.org.crt timinglee.org.key
[root@haproxy yxs]# cat /etc/haproxy/certs/timinglee.org.{key,crt} > /etc/haproxy/certs/timinglee.pem
全站加密
[root@haproxy yxs]# vim /etc/haproxy/haproxy.cfg
frontend webcluster-http
bind *:80
redirect scheme https if ! { ssl_fc }
listen webcluster-https
bind *:443 ssl crt /etc/haproxy/certs/timinglee.pem
mode http
balance roundrobin
server haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 1
server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1
[root@haproxy yxs]# systemctl restart httpd.service
#测试
[Administrator.DESKTOP-VJ307M3] ➤ curl -v -k -L http://172.25.254.100
* Trying 172.25.254.100:80...
* TCP_NODELAY set
* Connected to 172.25.254.100 (172.25.254.100) port 80 (#0)
> GET / HTTP/1.1
> Host: 172.25.254.100
> User-Agent: curl/7.65.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< content-length: 0
< location: https://172.25.254.100/ #转换信息体现
< cache-control: no-cache
<
* Connection #0 to host 172.25.254.100 left intact
* Issue another request to this URL: 'https://172.25.254.100/'
* Trying 172.25.254.100:443...
* TCP_NODELAY set
* Connected to 172.25.254.100 (172.25.254.100) port 443 (#1)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CN; ST=Shaanxi; L=Xi'an; O=timinglee; OU=linux; CN=www.timinglee.org; emailAddress=admin@timinglee.org
* start date: Jan 26 08:38:57 2026 GMT
* expire date: Jan 26 08:38:57 2027 GMT
* issuer: C=CN; ST=Shaanxi; L=Xi'an; O=timinglee; OU=linux; CN=www.timinglee.org; emailAddress=admin@timinglee.org
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: 172.25.254.100
> User-Agent: curl/7.65.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< date: Mon, 26 Jan 2026 08:48:34 GMT
< server: Apache/2.4.62 (Red Hat Enterprise Linux)
< last-modified: Fri, 23 Jan 2026 03:52:02 GMT
< etag: "1a-64906147d3d6a"
< accept-ranges: bytes
< content-length: 26
< content-type: text/html; charset=UTF-8
<
webserver2 - 192.168.0.20
* Connection #1 to host 172.25.254.100 left intact更多推荐
所有评论(0)