nginx反向代理
nginx反向代理服务器总结
什么是代理
# 代理
代理(英语:Proxy)也称网络代理,是一种特殊的网络服务,允许一个网络终端(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击。
提供代理服务的电脑系统或其它类型的网络终端称为代理服务器(英文:Proxy Server)。一个完整的代理请求过程为:客户端首先与代理服务器创建连接,接着根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或者获得目标服务器的指定资源(如:文件)。在后一种情况中,代理服务器可能对目标服务器的资源下载至本地缓存,如果客户端所要获取的资源在代理服务器的缓存之中,则代理服务器并不会向目标服务器发送请求,而是直接传回已缓存的资源。一些代理协议允许代理服务器改变客户端的原始请求、目标服务器的原始响应,以满足代理协议的需要。代理服务器的选项和设置在计算机程序中,通常包括一个“防火墙”,允许用户输入代理地址,它会遮盖他们的网络活动,可以允许绕过互联网过滤实现网络访问。
# 1.正向代理和反向代理的区别:
反向代理在电脑网络中是代理服务器的一种。服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器集群的存在。
与正向代理不同,正向代理作为客户端的代理,将从互联网上获取的资源返回给一个或多个的客户端,服务端(如Web服务器)只知道代理的IP地址而不知道客户端的IP地址;而反向代理是作为服务器端(如Web服务器)的代理使用,而不是客户端。客户端借由正向代理可以间接访问很多不同互联网服务器(集群)的资源,而反向代理是供很多客户端都通过它间接访问不同后端服务器上的资源,而不需要知道这些后端服务器的存在,而以为所有资源都来自于这个反向代理服务器。
正向代理:由内向外。代替,效率低,代替局域网内pc,请求外部应用服务,代理对象为客户端,为客户端服务
反向代理:由外向内,代替,效率低,代替外部的用户请求内部的应用服务器,代理对象对服务端,为服务端服务
# 2.反向代理的主要作用为:
·对客户端隐藏服务器(集群)的IP地址
·安全:作为应用层防火墙,为网站提供对基于Web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等
·为后端服务器(集群)统一提供加密和SSL加速(如SSL终端代理)
·负载均衡,若服务器集群中有负荷较高者,反向代理通过URL重写,根据连线请求从负荷较低者获取与所需相同的资源或备援
·对于静态内容及短时间内有大量访问请求的动态内容提供缓存服务
·对一些内容进行压缩,以节约带宽或为网络带宽不佳的网络提供服务
·减速上传
·为在私有网络下(如局域网)的服务器集群提供NAT穿透及外网发布服务
·提供HTTP访问认证
·突破互联网封锁(不常用,因为反向代理与客户端之间的连线不一定是加密连线,非加密连线仍有遭内容审查进而遭封禁的风险;此外面对针对域名的关键字过滤、DNS缓存污染/投毒攻击乃至深度数据包检测也无能为力)
3.常见反向代理软件
Nginx、Tengine
Apache HTTP Server
Varnish cache
Squid Cache
Traffic Server
HAProxy
YXORP
Polipo
Privoxy
IIS
-
正向代理(图一)
-
反向代理(图二)
代理支持协议
-
支持协议
-
常用协议
- 反向代理模式与Nginx代理模块总结如表格所示
反向代理模式 | Nginx配置模块 |
---|---|
http、websocket、https | ngx_http_proxy_module |
fastcgi | ngx_http_fastcgi_module |
uwsgi | ngx_http_uwsgi_module |
grpc | ngx_http_v2_module |
Nginx反向代理配置
配置示例
# 语法
Syntax: proxy_redirect default;
proxy_redirect off;proxy_redirect redirect replacement;
Default: proxy_redirect default;
Context: http, server, location
# 官方推荐配置示例:
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 注意:
官方推荐中的 proxy_set_header X-Real-IP $remote_addr;不建议使用,此模块主要用于后端服务器记录客户端源ip使用,但多层代理时,使用此模块会将多次代理服务器当成客户端ip,所以无法准确记录客户端地址。此处推荐使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;此模块
# 代理模块优化介绍
-------------代理到后端的TCP连接,响应,返回等超时时间
//nginx代理与后端服务器连接超时时间(代理连接超时)
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
//nginx代理等待后端服务器的响应时间
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
//后端服务器数据回传给nginx代理超时时间
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
--------------proxy_burrer代理缓冲区
//nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
//设置nginx代理保存用户头信息的缓冲区大小
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location
//proxy_buffers 缓冲区
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
--------------常用优化配置
· 代理配置location时调用方便后续多个location重复使用,直接使用include包含,将优化配置写入/etc/nginx/下命名为XXX_params。如下操作:
[root@web01 /etc/nginx]# vim proxy_params # 优化模块写入文件
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
[root@lb01 /etc/nginx/conf.d]# vim wp.lb.conf
server {
listen 80; # 代理端口
server_name www.wp.com; # 代理域名
location / {
proxy_pass http://172.16.1.7:80; # 代理web服务器ip端口
include proxy_params; # 包含文件为/etc/nginx/目录下文件,自定义
}
}
- 代理服务器基本配置
# 下载nginx
[root@lb01 ~]# yum install -y nginx
# 编辑配置文件
[root@m01 /etc/nginx/conf.d]# vim lb.conf
server {
listen 80;
server_name www.zh.com;
location / {
# 代理后端服务器ip端口
proxy_pass http://10.0.0.7:80;
# 用户请求host值是www.zh.com,那么代理服务器会像后端传递请求还是www.zh.com。如不书写此行,将以ip传递
proxy_set_header Host $host;
# 客户端通过代理服务器访问后端服务,后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
配置案例
- 配置需求:
web01服务器,配置一个网站,监听在8080此时仅172网段的用户能访问
[root@web01 ~]# cd /etc/nginx/conf.d/
[root@web01 conf.d]# vim web.conf
server {
listen 8080;
server_name nginx.oldboy.com;
location / {
root /code_8080;
index index.html;
deny 10.0.0.0/24;
allow all;
}
}
[root@web01 conf.d]# mkdir /code_8080
[root@web01 conf.d]# echo "web01-7...." >/code_8080/index.html
[root@web01 conf.d]# systemctl restart nginx
- 配置需求:
proxy代理服务,配置监听eth0的80端口,使10.0.0.0网段的用户,能够通过代理服务器访问到后端的172.16.1.7的8080端口站点内容
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# cat proxy_web_node1.conf
server {
listen 80;
server_name nginx.oldboy.com;
location / {
proxy_pass http://172.16.1.7:8080;
}
}
[root@lb01 conf.d]# systemctl enable nginx
[root@lb01 conf.d]# systemctl start nginx
- 存在问题
从图中可以看出,当我们只用
proxy_pass
代理的时候,会发现如下问题:10.0.0.1请求10.0.0.5的时候使用的是域名10.0.0.5请求10.0.0.7的时候使用的是IP:port之前课程中讲到,当访问80端口的时候,没有域名的情况下,默认会去找排在最上面的那个配置文件。所以我们需要解决这个问题,保留住最开始的请求头部信息。proxy_set_header`,这个模块可以帮我们解决这个问题
- 修改配置文件如下:
[root@lb01 conf.d]# cat proxy_web_node1.conf
server {
listen 80;
server_name nginx.oldboy.com;
location / {
proxy_pass http://172.16.1.7:8080;
proxy_set_header Host $http_host; # 将请求头信息转发给后端web
proxy_http_version 1.1; # 使用http 1.1协议
}
}
- 记住客户端来源ip
在生产环境中,我们必须要记录客户端的来源IP,如果所有的访问日志,全都来源于代理,那么我们根本不知道都有哪些地区的用户访问了我们什么页面。还是使用
proxy_set_header
[root@lb01 conf.d]# cat proxy_web_node1.conf
server {
listen 80;
server_name nginx.oldboy.com;
location / {
proxy_pass http://172.16.1.7:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
}