
本文目录:
0x01 概述
0x02 实验环境
0x03 实验开始
3.1 创建docker网络模拟内网环境
3.2 配置单域名的负载均衡
部署默认的Nginx应用
配置负载均衡服务器
单域名负载均衡效果
3.3 配置多域名的负载均衡
部署第二个web应用
第一台服务器web1
第二台服务器web2
第三台服务器web3
配置负载均衡服务器
多域名负载均衡效果
3.4 负载均衡策略
0x04 实验总结
0x01 概述
负载均衡,不管是红队蓝队、甲方乙方、踩点或者后渗透,多多少少都会遇到这个概念或者场景。而在大企业中,使用负载均衡可以说已经是常态。
本文主要利用Docker来模拟简单的多域名(多web应用)负载均衡。
0x02 实验环境
需求:为企业的两个web系统做负载均衡,一个是默认Nginx,一个是www.foxyu.cn
Nginx:使用ip访问:107.155.15.110
web目录:/usr/share/nginx/htmlwww.foxyu.cn:使用域名访问
web目录:/var/www/html
容器:
第一台服务器web1:172.20.0.2,部署在内网中,不对外网开放。
第一台服务器web2:172.20.0.3,部署在内网中,不对外网开放。
第一台服务器web3:172.20.0.4,部署在内网中,不对外网开放。
负载均衡服务器nginx:172.20.0.5,外网ip:107.155.15.110,部署在边界,只对外网开放80(Nginx应用)和81(foxyu域名应用)两个端口。
网络结构如下:

0x03 实验开始
物理机需要Docker环境。
我们直接使用Nginx官方镜像:docker pull nginx
3.1 创建docker网络模拟内网环境
1.首先创建一个新的docker网络:
docker network create -d bridge foxyu-net
参数说明:
-d:参数指定 Docker 网络类型,有 bridge、overlay。
2.创建容器并连接到创建的docker(foxyu-net)网络中:
docker run -dit --name web1 --network foxyu-net nginxdocker run -dit --name web2 --network foxyu-net nginxdocker run -dit --name web3 --network foxyu-net nginxdocker run -dit --name nginx --network foxyu-net -p 80:80 -p 81:81 nginx
其中只需要在负载均衡服务器:nginx(部署在边界)上面映射两个端口,相当于对外只开放两个端口,每个端口对应一个web应用。
其他三个web服务器不映射端口,模拟真实环境中的内网服务器。即外网无法直接访问。

可以通过容器名进行互相通信。也可以使用docker inspect 容器名
查看容器ip:

各容器IP如下:
web1:172.20.0.2
web2:172.20.0.3
web3:172.20.0.4
nginx:172.20.0.5
3.2 配置单域名的负载均衡
简单理解负载均衡:
假设有5台服务器,如果有5个访问请求,没有负载均衡时,可能5个请求都访问机器A,这样可能引致访问速度慢,A机器崩溃等问题,而有了负载均衡,就会将5个任务按照策略进行分发,可能5台机器每台负责处理一个任务就OK了。
Nginx的负载均衡,就是在Nginx代理服务器上配置upstream模块,通过调度算法实现各个服务器的合理的分压。
部署默认的Nginx应用
负载均衡服务器由于只是做代理转发,因此不用挂载,其他web1、web2、web3都是web服务器,实际环境中,这三台应该部署同一个web应用,才能做负载均衡。
先配置默认Nginx应用的负载均衡,这里为了等下可以观察到实际效果,我们分别在三个web服务器的Nginx默认页面上写入不同的内容:
docker exec -it web1 bash -c "echo 'Web server1,default nginx page.' > /usr/share/nginx/html/index.html"docker exec -it web2 bash -c "echo 'Web server2,default nginx page.' > /usr/share/nginx/html/index.html"docker exec -it web3 bash -c "echo 'Web server3,default nginx page.' > /usr/share/nginx/html/index.html"
查看是否写入成功:

配置负载均衡服务器
现在默认的Nginx应用就已经在三台web服务器上面部署完成,都是采用默认的80端口。接下来配置负载均衡。
进入容器负载均衡服务器:nginx
docker exec -it nginx /bin/bash
由于容器里面没有vim命令,我们需要先安装vim
apt-get updateapt-get install vim
首先查看我们的内网环境和三台web服务器是否正常运行:

使用内网IP可以请求到web页面,环境部署没问题。
接下来编辑/etc/nginx/nginx.conf
文件,在http{}中新增以下内容:
http {upstream default_nginx {server 172.20.0.2:80;server 172.20.0.3:80;server 172.20.0.4:80;}.....}

编辑/etc/nginx/conf.d/default.conf
文件,在server{}中新增以下内容:
server {}......location / {......proxy_pass http://default_nginx;proxy_connect_timeout 2s;}......}

因为我们这里使用默认的Nginx应用,因此这里的root,也就是web应用目录不需要改动。
执行以下命令检查配置文件,然后重新加载nginx配置文件:
nginx -tnginx -s reload

重启成功。
单域名负载均衡效果
由于没有多个域名,这里直接使用ip访问模拟一个域名了,使用下面命令查看负载效果:
sh -c "while true;do curl http://107.155.15.110;done;"

实验搭建成功,将我们的请求平均分配给后端的三台web服务器。
3.3 配置多域名的负载均衡
往往一个企业不止一个域名,可能会有多个域名多个web应用,那么在上面配置完单域名的负载均衡后,我们怎么添加多个域名的负载均衡呢?
部署第二个web应用
首先还是需要在三台web服务器上部署第二个web应用,为了查看效果,还是在页面内容中写入不同的内容:
第一台服务器web1
进入容器,安装vim:
docker exec -it web1 /bin/bashapt-get updateapt-get install vim
后面不再重复说明。
部署第二个web应用,这里参考Apache,部署在/var/www/html
目录下:
mkdir -p /var/www/htmlecho "Web server1,domain www.foxyu.cn!"> /var/www/html/index.html
部署完成之后,我们还需要配置一下Nginx。
进入/etc/nginx/conf.d/
目录下,复制一份默认的配置文件,重命名为域名.conf的格式。
如需部署第三个、第四个web应用,只需要在该目录下重新创建一个域名.conf的文件,修改其配置即可。
cp default.conf www.foxyu.cn.conf

编辑www.foxyu.cn.conf
文件,新增以下内容:
server {listen 81 default;listen [::]:81 default;server_name _;return 403;}server {listen 81;listen [::]:81;server_name www.foxyu.cn;#access_log /var/log/nginx/host.access.log main;location / {root /var/www/html;index index.html index.htm}......}

新增了一个server{},监听81端口,将除了域名访问的所有请求都返回403。
然后修改原来的server{},修改监听端口为81(80为默认的Nginx应用),设置虚拟主机为目标域名。也就是第二个web应用只允许通过域名进行访问。
修改location / {},将root也就是网站目录修改为上面创建的/var/www/html
目录。
修改完成后检查配置是否有问题:
nginx -tnginx -s reload

配置完成。
第二台服务器web2
同样部署第二个web应用:
docker exec -it web2 /bin/bashapt-get updateapt-get install vimmkdir -p /var/www/htmlecho "Web server2,domain www.foxyu.cn!"> /var/www/html/index.html
在/etc/nginx/conf.d/
目录下新建www.foxyu.cn.conf
文件,同样新增以下内容:
server {listen 81 default;listen [::]:81 default;server_name _;return 403;}server {listen 81;listen [::]:81;server_name www.foxyu.cn;#access_log /var/log/nginx/host.access.log main;location / {root /var/www/html;index index.html index.htm}......}

检查配置是否有问题并重启Nginx服务:

第三台服务器web3
部署第二个web应用:
docker exec -it web3 /bin/bashapt-get updateapt-get install vimmkdir -p /var/www/htmlecho "Web server3,domain www.foxyu.cn!"> /var/www/html/index.html
在/etc/nginx/conf.d/
目录下新建www.foxyu.cn.conf
文件,同样新增以下内容:
server {listen 81 default;listen [::]:81 default;server_name _;return 403;}server {listen 81;listen [::]:81;server_name www.foxyu.cn;#access_log /var/log/nginx/host.access.log main;location / {root /var/www/html;index index.html index.htm}......}

检查配置是否有问题并重启Nginx服务:

配置负载均衡服务器
现在第二个web应用也已经在三台web服务器上面部署完成,部署在81端口。接下来配置负载均衡。
进入容器负载均衡服务器:nginx
docker exec -it nginx /bin/bash
编辑/etc/nginx/nginx.conf
文件,在http{}中新增以下内容:
http {.....upstream foxyu_web {server 172.20.0.2:81;server 172.20.0.3:81;server 172.20.0.4:81;}.....}

进入/etc/nginx/conf.d/
目录下,同样新增一个www.foxyu.cn.conf
文件:

编辑www.foxyu.cn.conf
文件,在server{}中修改以下内容:
server {listen 81 default;listen [::]:81 default;server_name _;return 403;}server {listen 81;listen [::]:81;server_name www.foxyu.cn;#access_log /var/log/nginx/host.access.log main;......location / {proxy_pass http://foxyu_web;proxy_set_header Host $host;proxy_connect_timeout 2s;}......}

注意:这里由于我们负载均衡upstream{}中配置的是ip+端口形式,而三台web服务器又设置成只允许域名访问。因此这里在location / {}中需要添加一个proxy_set_header Host $host;
字段,再转发到后端三台web服务器的时候才会是以域名访问的形式。
此时后端服务器看到的来源IP都是负载均衡服务器的IP,如有需要得到真实的来源IP,可以再加上:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
配置完成后检查配置文件,然后重新加载nginx配置文件:

重启成功。
多域名负载均衡效果
1、测试 IP+端口 进行访问:
sh -c "while true;do curl http://107.155.15.110:81;done;"

可以看到直接以IP+端口的形式访问第二个web应用,返回都是403,也就是我们上面在www.foxyu.cn.conf
文件中配置的第一个server {}的作用。
2、测试 域名+端口 进行访问:
sh -c "while true;do curl http://www.foxyu.cn:81;done;"

成功得到第二个web应用的内容。
这里我们因为没有配置负载均衡策略,因此使用nginx默认的轮询策略进行负载,把每一个请求逐一分配到不同的server,如果分配到的server不可用,则分配到下一个,直到可用。
这个时候我们模拟一个服务器down掉了,停掉web1:

可以看到此时获取到的web页面就只有web2和web3的web页面了:

大大提高了企业网络的灵活性和可用性。
3.4 负载均衡策略
上面我们配置的负载均衡采用默认策略,但是,Nginx其实提供了多种负载均衡策略。
轮询
这是默认的策略,把每个请求逐一分配到不同的server,如果分配到的server不可用,则分配到下一个,直到可用:
upstream foxyu_web {server 172.20.0.2:81;server 172.20.0.3:81;server 172.20.0.4:81;}
最少连接
把请求分配到连接数最少的server
upstream foxyu_web {least_conn;server 172.20.0.2:81;server 172.20.0.3:81;server 172.20.0.4:81;}
权重
weight默认值为1,值越大则代表被访问的几率越大,如下配置,172.20.0.3
的访问数量是172.20.0.2
的2倍,172.20.0.4
的访问数量是172.20.0.2
的3倍。
upstream foxyu_web {server 172.20.0.2:81 weight=1;server 172.20.0.3:81 weight=2;server 172.20.0.4:81 weight=3;}
ip_hash
根据访问客户端IP的hash值分配,这样同一客户端的请求都会被分配到同一个server上,如果牵扯到session的问题,用这个是最好的选择
upstream foxyu_web {ip_hash;server 172.20.0.2:81;server 172.20.0.3:81;server 172.20.0.4:81;}
0x04 实验总结
本文通过Docker技术,模拟了一个小型企业实现多域名负载均衡的技术,在这之中了解了Nginx强大的功能,明白了Nginx的反向代理和负载均衡实现原理,还有负载均衡的几种策略。后续可能会再出一期针对Nginx的waf功能的实验,敬请期待!
如文章有错误不理解的地方,请在"公众号留言",欢迎各位师傅一起学习交流。




