Nginx

Nginx环境搭建

Nginx安装步骤

首先创建Nginx的目录并进入:

[root@localhost]# mkdir /soft && mkdir /soft/nginx/
[root@localhost]# cd /soft/nginx/

下载Nginx的安装包,可以通过FTP工具上传离线环境包,也可通过wget命令在线获取安装包:

[root@localhost]# wget https://nginx.org/download/nginx-1.21.6.tar.gz

没有wget命令的可通过yum命令安装:

[root@localhost]# yum -y install wget

解压Nginx的压缩包:

[root@localhost]# tar -xvzf nginx-1.21.6.tar.gz

下载并安装Nginx所需的依赖库和包:

[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ gcc-c++
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ pcre pcre-devel4
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ zlib zlib-devel
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ openssl openssl-devel

也可以通过yum命令一键下载(推荐上面哪种方式):

[root@localhost]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

执行完成后,然后ls查看目录文件,会看一大堆依赖:

nginx各版本漏洞从哪里看出来_Nginx

[root@localhost]# rpm -ivh --nodeps *.rpm

 进入解压后的nginx目录,然后执行Nginx的配置脚本,为后续的安装提前配置好环境,默认位于/usr/local/nginx/目录下(可自定义目录):

[root@localhost]# cd nginx-1.21.6
[root@localhost]# ./configure --prefix=/soft/nginx/

编译并安装Nginx

[root@localhost]# make && make install

最后回到前面的/soft/nginx/目录,输入ls即可看见安装nginx完成后生成的文件。

修改安装后生成的conf目录下的nginx.conf配置文件:

[root@localhost]# vi conf/nginx.conf
    修改端口号:listen    80;
	修改IP地址:server_name  你当前机器的本地IP(线上配置域名);

制定配置文件并启动Nginx

[root@localhost]# sbin/nginx -c conf/nginx.conf
[root@localhost]# ps aux | grep nginx

Nginx其他操作命令:

sbin/nginx -t -c conf/nginx.conf # 检测配置文件是否正常
sbin/nginx -s reload -c conf/nginx.conf # 修改配置后平滑重启
sbin/nginx -s quit # 优雅关闭Nginx,会在执行完当前的任务后再退出
sbin/nginx -s stop # 强制终止Nginx,不管当前是否有任务在执行

Windows/Mac的浏览器中,直接输入刚刚配置的IP地址访问Nginx

配置完成

welcome to nginx !

Nginx负载均衡与反向代理

负载均衡

 实现Nginx负载均衡的组件

Nginx http功能模块

模块说明

ngx_http_proxy_module

proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池。

ngx_http_upstream_module

负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查。

upstream模块

Nginx的负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等。

ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体写法为“proxy_pass http://www_server_pools”,其中www_server_pools就是一个Upstream节点服务器组的名字。upstream模块官方地址:http://nginx.org/en/docs/http/ngx_http_upstream_module.htm

upstream配置案例    
    upstream www_server_pool {
    server 10.0.0.7 weight=5;
    server 10.0.0.16 weight=10;
}

upstream完整的配置案例
  
upstream www_server_pool {
    server 10.0.0.5;   #<==这一行标签和下一行是等价的
server 10.0.0.6:80 weight=1 max_fails=1 fails_timeout=10s; #<==此行标签为默认配置
server 10.0.0.7:80 weight=1 max_fails=2  fails_timeout=10s backup;
server 10.0.0.8:80 weight=1 max_fails=3 fails_timeout=20s backup;
}

1、upstream是关键字必须要有,后面的www_server_pool为一个Upstream集群组的名字,可以自定义;

2、server是关键字固定,后面可以接域名或IP。如果不指定端口,默认是80。结尾有分号。

3、weight代表权重,数值越大分配的请求就越多。

upstream模块功能说明

upstream模块的内容应放于nginx.conf配置的http{}标签内,其默认调度节点算法是wrr(权重轮询weighted round-robin)。下表为内部server标签部分参数说明:

server标签

参数说明

server 10.0.0.6:80

负载均衡后面的RS配置,可以是IP或域名,如果不写端口,默认是80端口。高并发场景下,IP可换成域名,通过DNS做负载均衡。

weight=1

代表服务器的权重,默认值是1。权重数字越大表示接受的请求比例越大。

max_fails=1

Nginx尝试连接后端主机失败的次数,这个数值是配置proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream三个参数来使用的,当Nginx接受后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503。max_fails的默认值是1;企业场景:建议2-3次。

backup

热备配置(RS)节点的高可用,当期面激活的RS都失败后会自动启用热备RS。这标志着这个服务器作为备份服务器,若主服务器全部宕机了,就会向他转发请求;注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

fail_timeout=10s

在max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s;如果max_fails是5,他就检测5次。如果5次都是502,那么他就会根据fail_timeout的值,等待10s再去检查,还是只检查一次,如果持续502,在不重新加载nginx配置的情况下,每隔10s都只检测一次。常规业务:2-3秒比较合理。

down

这标识着服务器永远不可用,这个参数可配合ip_hash使用。

反向代理

相关了解
反向代理

说到代理,首先我们要明确一个概念,所谓代理就是一个代表、一个渠道;

此时就设计到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称为代理操作过程;如同生活中的专卖店~客人到adidas专卖店买了一双鞋,这个专卖店就是代理,被代理角色就是adidas厂家,目标角色就是用户

明白了什么是正向代理,我们继续看关于反向代理的处理方式,举例如我大天朝的某宝网站,每天同时连接到网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望了,此时就出现了一个大家耳熟能详的名词:分布式部署;也就是通过部署多台服务器来解决访问人数限制的问题;某宝网站中大部分功能也是直接使用nginx进行反向代理实现的,并且通过封装nginx和其他的组件之后起了个高大上的名字:Tengine
那么反向代理具体是通过什么样的方式实现的分布式的集群操作呢,我们先看一个示意图:

nginx各版本漏洞从哪里看出来_Nginx_02

那么接下来,nginx扮演了反向代理服务器的角色,它是以依据什么样的规则进行请求分发的呢?不用的项目应用场景,分发的规则是否可以控制呢?

这里提到的客户端发送的、nginx反向代理服务器接收到的请求数量,就是我们说的负载量

请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则

所以~将服务器接收到的请求按照规则分发的过程,称为负载均衡。

负载均衡在实际项目操作过程中,有硬件负载均衡和软件负载均衡两种,硬件负载均衡也称为硬负载,如F5负载均衡,相对造价昂贵成本较高,但是数据的稳定性安全性等等有非常好的保障,如中国移动中国联通这样的公司才会选择硬负载进行操作;更多的公司考虑到成本原因,会选择使用软件负载均衡,软件负载均衡是利用现有的技术结合主机硬件实现的一种消息队列分发机制

proxy模块

proxy是实现反向代理的模块,具体配置相关参数如下:

proxy模块相关参数

参数说明

proxy_set_header

设置http请求header项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址。

client_body_buffer_size

用于指定客户端请求主体缓冲区大小(http请求报文)

proxy_connect_timeout

表示反向代理与后端节点服务器连接的超时时间,即发起握手等候响应的超时时间。

proxy_send_timeout

表示代理后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,Nginx将断开这个连接。

proxy_buffer_size

设置缓冲区大小,默认该缓冲区大小等于指令proxy_buffers设置的大小

proxy_buffers

设置缓冲区的数量和大小。nginx从代理的后端服务器获取的响应信息,会放置到缓冲区。

proxy_busy_buffers_size

用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐为proxy_buffers*2。

proxy_temp_file_write_size

指定proxy缓存临时文件的大小

配置
upstream nginx_boot{
   # 30s内检查心跳发送两次包,未回复就代表该机器宕机,请求分发权重比为1:2
       server 192.168.164.1:80 weight=100 max_fails=2 fail_timeout=30s;
       server 192.168.164.10:80 weight=200 max_fails=2 fail_timeout=30s;
   # 这里的IP请配置成你WEB服务所在的机器IP以及端口
             }
 
    server {
        listen       80;
        server_name  192.168.164.8;
 
 
        location / {
            proxy_set_header Host $host;    
            #将原始请求的Host头信息传递给后端服务器
            proxy_set_header X-Real-IP $remote_addr;
            #将客户端的真实 IP 地址传递给后端服务器
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #这个配置指令用于构建一个包含了客户端 IP 地址的 HTTP 头部。每经过一个代理服务器,代 
            #理服务器会将自己的 IP 地址添加到这个头部的值中,以表示请求经过的路径。
            proxy_pass http://nginx_boot/test/web.php;
            #请求交给名为nginx_boot的upstream上
            
        }

区别

严格的说,Nginx仅仅是作为Nginx Proxy反向代理使用的。普通的负载均衡软件,例如LVS,其实现的功能只是对请求数据包的转发(也可能会改写数据包)、传递,其中DR模式明显的特征是从负载均衡下面的节点服务器来看,接收到的请求还是来自访问负载均衡的客户端的真实用户。而反向代理不一样,反向代理接收访问用户的请求后,会代理用户重新发起请求代理下的节点服务器,最后把数据返回给客户端用,在节点服务器看来,访问的节点服务器的客户端就是反向代理服务器了,而非真是的网络用户。 注: LVS等负载均衡是转发用户请求的数据包,而Nginx反向代理是接收用户的请求然后重新发起请求去请求后面的节点。

Nginx配置漏洞

docker环境

1.docker环境搭建
1.安装docker

yum install docker.io

2.下载并解压docker环境Nginx配置漏洞安装包

链接:https://pan.baidu.com/s/1OFAY7TzHk6Qem78pdM_UEg?pwd=8s6c 
提取码:8s6c 

cd到对应目录下,docker启容器

unzip vulhub-master.zip
cd /root/vulhub-master/nginx/insecure-configuration
docker-compose up -d

安装好后,用docker ps -a查看容器运行情况

nginx各版本漏洞从哪里看出来_nginx_03

如果要进入容器,键入docker exec -it ************(这里写你的容器ID) /bin/bash命令

CRLF(carriage return/line feed)注入漏洞

这个漏洞产生的原因是请求重定向的错误配置,导致在url中输入回车换行符可以控制http响应头部

Nginx会将$uri进行解码,导致传入%0d%0a即可引入换行符,造成CRLF注入漏洞。

错误的配置文件示例(原本的目的是为了让http的请求跳转到https上):

原本的目的是为了让http的请求跳转到https上

但是$uri参数是不包含查询参数的,于是当我们在url中输入%0d%0a时,$uri参数不会将回车换行符传入,这就导致用户可以控制http响应头部

访问http://ip:8080,使用bp抓包,构造反射性xss

%0d%0a%0d%0a<img src=1 οnerrοr=alert(1)>

修复方法:把$url改为$request-uri,这个参数会传入完整的原始url请求,也就是说用户输入的所有内容都会被当做参数传入Location字段

目录穿越

Nginx在配置别名(Alias)的时候,如果忘记加/,将造成一个目录穿越漏洞。

错误的配置文件示例:

nginx各版本漏洞从哪里看出来_linux_04

 原本的目的是想用户输入/files会跳转到/home目录下,但是/files并没有以"/"结尾,所以我们可以输入/files../,此时/files匹配上了,替换为/home/..,造成目录穿越

修复方法:将/files改为/files/,这样就算输入/files../也不会匹配上/files/

nginx各版本漏洞从哪里看出来_nginx各版本漏洞从哪里看出来_05

add_header覆盖

Nginx配置文件子块(server、location、if)中的add_header,将会覆盖父块中的add_header添加的HTTP头,造成一些安全隐患。

这个漏洞产生的原因是Location子块中又添加了add_header参数,覆盖了父块中的参数,导致失效



这个配置本意是想在子块中再添加一个参数,结果覆盖父块,导致父块参数全部失效

bp抓包发现父块添加的参数消失,只有子块里的参数

修复方法:删除子块中的add_header参数,或者添加到父块中