环境: CentOS7、Nginx 1.16.0
在之前我们说到了Nginx的负载均衡,Nginx可以作为负载均衡器,分发客户端请求,其实,这就是Nginx的代理服务之一:反向代理
Nginx的代理服务分为两种:
正向代理是存在于客户端和服务器之间的代理人,需要客户端主动指定proxy,之后proxy会接受客户端的请求并发送给server,将得到的结果又回发给客户端,这一切对于server是透明的,它完全不知道这些请求时不同的人发起的。此时proxy代理的就是客户端,也就是正向代理。
反向代理与正向相反,这里proxy代理的是服务器,用户统一向proxy发送请求,而proxy将请求转发给其代理的server,将得到的结果再返回给客户端。这一切对于客户端来说是透明的,用户完全不知道自己的请求将会发送到哪个服务器,因此也不需要客户端做任何的设置,只需要把proxy当作server就行。
在配置上:
从用途上来区分:
从安全性来讲:
从上面的介绍也就可以猜出来正向代理的至少一个功能(科学上网),也即:
用户A无法访问facebook,但是能访问服务器B,而服务器B可以访问facebook。于是用户A访问服务器B,通过服务器B去访问facebook,,服务器B收到请求后,去访问facebook,facebook把响应信息返回给服务器B,服务器B再把响应信息返回给A。这样,通过代理服务器B,就实现了。
从上面的介绍也可以猜出来反向代理的至少一个功能——负载均衡。还有其他许多功能:
配置语法:
Syntax: proxy_pass URL;
Default: ——
Context: location, if in location, limit_except
URL可支持http、https、socket的写法
此时,在我的阿里服务器上,我在8080端口运行了一个server服务,但我的安全组并没有对外开放8080端口,也就是说,外界无法通过ip:8080访问到我的应用。但是这里可以通过Nginx做一次正向代理进行访问:
这里我通过443端口配置的https服务,把访问443的请求全部转发到了8080端口。可以看作,我的8080端口是google搜索,设置不对外开发,即好像我们在国内正常无法使用google一样,但是和他同处的443端口,相当于一台海外的服务器,它可以访问google,我们就通过它,实现了对google的访问。
再看一个例子:
这是一台服务器上Nginx的配置,这里通过匹配代理Ip进行访问控制
这里,这里设置了只允许http_x_forwarded_for带有116.62.103.228
的请求进行访问,其余的访问一律返回403。
那么接下来看一看116.62.103.228上Nginx的配置
这里配置起到的作用,就是将收到的所有请求都转发给自己,由这台代理服务器发出请求,返回响应。(resolver配置DNS解析,这里是google的8.8.8.8)
那么只需要在代理工具中选择该代理服务器,将自己的请求都发送到代理服务器上,就可以访问之前被限制的服务器了。
一些扩展配置:
除了proxy_pass一行,其余的都可以写在配置文件中,在.conf文件里include引入即可。
实现负载均衡:
通过报文中的IP地址和端口,再加上负载均衡设备所采用的负载均衡算法,最终确定选择后端哪台下游服务器。以TCP为例,客户端向负载均衡发送SYN请求建立第一次连接,通过配置的负载均衡算法选择一台后端服务器,并且将报文中的IP地址信息修改为后台服务器的IP地址信息,因此TCP三次握手连接是与后端服务器直接建立起来的。
也就是说,这是直接在传输层进行控制
七层负载均衡在应用层选择服务器,只能先与负载均衡设备进行TCP连接,然后负载均衡设备再与后端服务器建立另外一条TCP连接通道。就可以做到更多对于应用层信息的控制。Nginx实现的就是七层的负载均衡。
四层负载均衡与服务器直接建立起TCP连接,很容易遭受SYN Flood攻击。SYN Flood是一种广为人知的DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽的攻击方式。从技术实现原理上可以看出,四层负载均衡很容易将垃圾流量转发至后台服务器,而七层设备则可以过滤这些恶意并清洗这些流量,但要求设备本身具备很强的抗DDOS流量的能力。
配置语法:
Syntax: upstream name {...}
Default: ——
Context: http
我在==/etc/nginx/conf.d/==下新建了三个配置, server1.conf、server2.conf、server3.conf。它们分别监听8080、8081、8082端口,并且展示不同的首页。
如果nginx启动失败,并且error.log有如下错误,
可能是你并没有开放该端口。
首先通过如下命令查看开放的端口:
semanage port -l | grep http_port_t
再执行如下命令添加端口:
semanage port -a -t http_port_t -p tcp 8080
如果报错
改用:
semanage port -m -t http_port_t -p tcp 8080
可以启动nginx并访问了:
接下来创建80端口的配置文件upstream.conf,如下:
重启nginx,这次,不停刷新127.0.0.1,就可以看到原本在不同端口设置的页面了。
如果我们禁用掉其中一个端口,iptables -I INPUT -p tcp --dport 8081 -j DROP
即相当于其中一个server宕机,那么nginx会自动的排除,不再将请求转发给它。
最后,再补充一点upstream配置的细节
upstream xxx {
server xxx.com weight=5;//分配权重,即分配给该server的几率更大
server xxx.com:8080;//可指定服务器端口
server unix:/tmp/xxx;//支持socket
server xxx.com backup;//备份节点
}
down | 当前server暂时不参与负载均衡 |
---|---|
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails后,服务暂停的时间 |
max_conns | 限制最大的接受连接数 |
| :----------- | ------------------------------- |
| backup | 预留的备份服务器 |
| max_fails | 允许请求失败的次数 |
| fail_timeout | 经过max_fails后,服务暂停的时间 |
| max_conns | 限制最大的接受连接数 |