1、Nginx反向代理

主机IPV4地址版本
proxy (代理)192.168.110.31/24Rocky-Linux 8
web-01 (主机-01)192.168.110.32/24Rocky-Linux 8
client (客户端)192.168.110.35/24Rocky-Linux 8

1.1 概述

1.1.1 反向代理功能

  • Nginx 反向代理是一种服务,它接收客户端的请求,将请求转发到一个或多个后端服务器,获取响应,然后将服务器的响应返回给客户端。

应用场景描述
负载均衡Nginx 可以将客户端请求分发到多个后端服务器,以此提高性能、可扩展性和可靠性。
缓存作为反向代理,Nginx 可以缓存页面的预渲染版本,加速页面加载时间,减少对后端服务器的请求。
SSL 终止Nginx 处理客户端的 SSL 连接,进行解密,并加密发送到后端服务器的响应,减轻后端服务器的负担。
缓存服务器如果后端服务器未提供压缩的响应,Nginx 可以配置为在发送给客户端之前对响应进行压缩,节省带宽。
防御 DDoS 攻击Nginx 可以限制单个 IP 地址的请求和连接数量,通过限制正常用户值以上的行为来防御分布式拒绝服务攻击。此外,可以根据客户端的位置和请求头信息(如 "User-Agent" 和 "Referer")来阻止或限制访问。

1.1.2 为什么要使用代理服务器

作用描述
提高访问速度代理服务器可以缓存目标主机返回的数据,当客户再次访问相同站点时,数据直接从代理服务器的硬盘中读取,充当缓存,尤其对于热门站点可以显著提升请求速度。
防火墙作用所有客户机请求必须通过代理服务器访问远程站点,因此可以在代理服务器上设置限制,过滤掉某些不安全的信息,起到防火墙的作用。
访问受限站点当客户机访问受限时,可以通过互联网上开放的代理服务器访问原本受限的目标站点,因为代理服务器可能没有相应的访问限制。

1.1.3 Nginx反向代理流程

步骤描述
客户端请求客户端通过 HTTP 或 HTTPS 协议向 Nginx 发送请求。
请求接收与转发Nginx 接收到请求后,根据其配置的反向代理规则,将请求转发到一个或多个指定的后端服务器。
资源处理与响应后端服务器接收到来自 Nginx 的请求,处理该请求,并生成相应的资源响应。
响应返回客户端Nginx 从后端服务器接收到资源响应后,将其转发回原始请求的客户端,完成整个请求-响应周期。

image-20240420113807237

1.1.4 Nginx 反向代理的一些关键特点

特点描述
支持的协议Nginx 支持对 HTTP、HTTPS、TCP、WebSocket、gRPC、POP/IMAP 和 RTMP 等协议进行代理。
端口灵活性客户端使用的端口可以与后端服务器提供服务的端口不一致。
配置位置Nginx 反向代理的配置位于服务器块中的 location 模块。
反向代理语法使用 proxy_pass URL; 实现反向代理。
路径处理-当 proxy_pass 指定了具体 URL 后,location 中的路径会被取代。当未指定具体 URL 时,代理会保留客户端请求的格式或传递完整的标准化请求 URI。

1.2 Nginx 反向代理配置示例

1.2.1 Nginx反向代理基本配置

1、配置后端服务器
[root@web-01 ~]# mkdir -p /nginx/web1
[root@web-01 ~]# echo "This is web-01 IPV4:`hostname -I`" >> /nginx/web1/index.html
[root@web-01 ~]# vim /etc/nginx/conf.d/VirtualHost.conf
server {
        listen 192.168.110.32:80;
        server_name localhost;
​
        location /{
                root /nginx/web1;
                index index.html;
        }
}
​
[root@web-01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-01 ~]# nginx -s reload
​
2、配置代理服务器
[root@proxy ~]# vim /etc/nginx/conf.d/VirtualHost.conf
server {
        listen 192.168.110.31:80;
        server_name www.proxy.com;
​
        location / {
                proxy_pass http://192.168.110.32;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
​
3、客户端测试
[root@client ~]# echo '192.168.110.31 www.proxy.com' >> /etc/hosts 
[root@client ~]# curl http://www.proxy.com
This is web-01 IPV4:192.168.110.32 
​
4、查看web-01的访问日志
[root@web-01 ~]# tail -1 /var/log/nginx/access.log   #日志记录的ip为代理服务器
192.168.110.31 - - [20/Apr/2024:14:24:36 +0800] "GET / HTTP/1.0" 200 36 "-" "curl/7.61.1" "-"

1.2.2 反向代理重要参数

参数描述
proxy_pass http://server pools;该指令用于将客户端的请求转发到配置的 upstream 服务器组。server pools 是 upstream 中定义的一组后端服务器。
proxy_set_header Host $host;设置 Host 头部,确保后端服务器可以识别请求的原始 Host 头信息,这在后端服务器配置有多个虚拟主机时非常重要。
proxy_set_header X-Forwarded-For $remote_addr;设置 X-Forwarded-For 头部,添加客户端的真实 IP 地址。这样后端服务器的应用程序和日志可以记录客户端的真实 IP,而不是 Nginx 代理服务器的 IP。

注意:proxy_pass 后面的 URL 是上游服务器的地址,而 $host$remote_addr 是 Nginx 内置的变量,分别代表原始请求中的 Host 头和远程客户端的地址。

5.2.3 http proxy模块相关参数

参数说明
proxy_set_header设置 HTTP 请求头部信息,传递给后端服务器节点。例如,使用 X-Forwarded-For 可以让后端服务器获取访问客户端的真实 IP 地址。
client_body_buffer_size指定客户端请求主体的缓冲区大小。
proxy_connect_timeout反向代理后端节点服务器连接的超时时间,即发起握手到等候响应的超时时间。
proxy_send_timeout代理后端服务器的数据回传时间,即在规定时间内后端服务器必须传完所有数据,否则 Nginx 将断开连接。
proxy_read_timeout设置 Nginx 从代理的后端服务器获取信息的时间,也就是 Nginx 等待后端服务器响应的时间。
proxy_buffer_size设置缓冲区大小,默认等于 proxy_buffers 设置的大小。
proxy_buffers设置缓冲区的数量和大小,用于缓存从代理的后端服务器获取的响应信息。
proxy_busy_buffers_size设置高负荷下可以使用的 proxy_buffers 大小,官方推荐为 proxy_buffers 的两倍。
proxy_temp_file_write_size指定 proxy 缓存临时文件的大小。

1.3 location配置详解

1.3.1 常见示例

在Nginx中配置反向代理时,locationproxy_pass的配置对于URL的转发路径确实有很大的影响。以下是您提供的示例配置,以及它们对应的转发路径,我已经将IP地址替换为www.location.com

  • location /test/ { proxy_pass http://www.proxy.com/; }

    • 最终转发路径http://www.proxy.com/index.html

    • 解释:由于location使用了尾部斜杠/test/,Nginx会将匹配到的路径/test/以及其后的所有内容(例如index.html)作为内部请求的一部分传递给代理服务器。但是,由于proxy_pass也包含了一个尾部斜杠/,Nginx会将/test/这部分路径去掉,只保留后面的index.html,导致最终请求的是http://www.proxy.com/index.html

  • location /test/ { proxy_pass http://www.proxy.com; }

    • 最终转发路径http://www.proxy.com/test/index.html

    • 解释:这里的proxy_pass没有尾部斜杠,因此Nginx不会去掉location匹配到的路径部分,而是将其原样传递给代理服务器。

  • location /test { proxy_pass http://www.proxy.com/; }

    • 最终转发路径http://www.proxy.com//index.html

    • 解释location没有使用尾部斜杠,这意味着它会匹配到/test及其后面的任意内容。然而,proxy_pass有一个尾部斜杠,所以Nginx会将匹配到的路径视为一个单独的内部路径,并在代理请求中添加一个额外的斜杠。

  • location /test { proxy_pass http://www.proxy.com; }

    • 最终转发路径http://www.proxy.com/test/index.html

    • 解释:与第二个示例相同,proxy_pass没有尾部斜杠,因此会将location匹配到的完整路径传递给代理服务器。

1.3.2 location不同配置测试

1.3.2.1 后端主机配置
[root@web-01 ~]# rm -f /nginx/web1/index.html   #删除之前的页面
[root@web-01 ~]# mkdir /nginx/web1/test   #创建测试目录
[root@web-01 ~]# echo "This is web-01 directory is /nginx/web1/test IP:`hostname -I`" >> /nginx/web1/test/index.html #创建测试页
[root@web-01 ~]# sed -i 's/listen/#listen/g' /etc/nginx/nginx.conf  #将默认的监听端口注释
[root@web-01 ~]# sed -i 's/root/#root/' /etc/nginx/nginx.conf  #默认访问路径注释
[root@web-01 ~]# vim /etc/nginx/conf.d/VirtualHost.conf  #配置虚拟主机
server {
        root /nginx/web1;
​
        location /{
                index index.html;
        }
}
​
[root@web-01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-01 ~]# nginx -s reload 
[root@web-01 ~]# curl http://localhost/test/   #测试确保可以访问
This is web-01 directory is /nginx/web1/test IP:192.168.110.32 
1.3.2.2 路径后有"/",URL后无"/"
1、环境准备
[root@proxy ~]# sed -i 's/listen/#listen/g' /etc/nginx/nginx.conf  #将默认的监听端口注释
[root@proxy ~]# sed -i 's/root/#root/' /etc/nginx/nginx.conf   #默认访问路径注释
2、peoxy配置
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
        server_name www.proxy.com;
        location /test/ {
        proxy_pass http://192.168.110.32;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
3、客户端访问测试
[root@client ~]# curl http://www.proxy.com/test/
This is web-01 directory is /nginx/web1/test IP:192.168.110.32 
1.3.2.3 路径后有"/",URL也有"/"
1、后端服务器配置
[root@web-01 ~]# echo 'This is web-01 directory is /nginx/web1/ 注意:不包含/test目录' >> /nginx/web1/index.html
[root@web-01 ~]# curl http://localhost
This is web-01 directory is /nginx/web1/ 注意:不包含/test目录
注意:配置文件不用改
2、proxy配置
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
        server_name www.proxy.com;
        location /test/ {
        proxy_pass http://192.168.110.32/;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
3、客户端访问测试
[root@client ~]# curl http://www.proxy.com/test/
This is web-01 directory is /nginx/web1/ 注意:不包含/test目录
1.3.2.4 路径后无/,URL后有/
1、proxy配置
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
        server_name www.proxy.com;
        location /test { 
        proxy_pass http://192.168.110.32/; 
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
2、客户端访问
[root@client ~]# curl http://www.proxy.com/test/
This is web-01 directory is /nginx/web1/ 注意:不包含/test目录
1.3.2.5 前后都没有"/"
1、proxy配置
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
        server_name www.proxy.com;
        location /test { 
        proxy_pass http://192.168.110.32; 
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
2、客户端访问测试
[root@client ~]# curl http://www.proxy.com/test/
This is web-01 directory is /nginx/web1/test IP:192.168.110.32 
1.3.2.6 路径后有"/",URL后跟路径
1、后端主机配置
[root@web-01 ~]# mkdir /nginx/web1/yoozoo
[root@web-01 ~]# echo "This is web-01 dir=/nginx/web1/yoozoo IP:`hostname -I`" >> /nginx/web1/yoozoo/index.html
2、proxy配置
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
        server_name www.proxy.com;
        location /test/ { 
        proxy_pass http://192.168.110.32/yoozoo/; 
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
3、客户端访问
[root@client ~]# curl http://www.proxy.com/test/   #注意最后test后面加了/
This is web-01 dir=/nginx/web1/yoozoo IP:192.168.110.32 
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐