点赞
评论
收藏
分享
举报
NGINX正向代理和反向代理实验记录
发表于2022-10-24 20:39

浏览 2.4k

NGINX正向代理和反向代理

实验记录


目录

1章 前言

2章 HTTP代理

2.1 HTTP正向代理

2.2 HTTP反向代理

2.2.1 基本测试

2.2.2 host效验测试

2.2.3 真实IP透传

2.2.3.1 验证验证场景:$remote_addr;

2.2.3.2 验证验证场景二:$proxy_add_x_forwarded_for;

2.2.3.3 验证验证场景三:ng_http_reali_module

3章 HTTPS代理

3.1 HTTPS 正向代理

3.1.1 SNI代理

3.1.2 CONNECT代理

3.1.3.1 创建需要代理访问的域名Pool

3.1.3.2 创建SSL SNI代理Policy

3.1.3.3 创建代理VS

3.1.3.4 SNI代理Policy编辑

3.2 HTTPS反向代理

3.2.1 基本测试

3.2.2 服务器再次加密代理

3.2.3 双向认证

3.2.4 IP多域名HTTPS代理

4章 TCP/UDP代理

4.1 基本测试


第1章 前言

        实验用NGINX版本

        NGINX-OSS NGINX version: NGINX/1.20.1

        NGINX-PlusNGINX version: NGINX/1.19.10 (NGINX-Plus-r24)

        什么是代理服务器?

        代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬盘中,再发送给客户机

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

        1)提高访问速度

        由于目标主机返回的数据会存放在代理服务器的硬盘中,因此下一次客户再访问相同的站点数据时,会直接从代理服务器的硬盘中读取,起到了缓存的作用,尤其对于热门站点能明显提高请求速度。

        2)防火墙作用

        由于所有的客户机请求都必须通过代理服务器访问远程站点,因此可在代理服务器上设限,过滤某些不安全信息。

        3)通过代理服务器访问不能访问的目标站点。

        什么是正向代理?

        正向代理,架设在客户机与目标主机之间,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中

        什么是反向代理?

        反向代理服务器架设在服务器端,通过缓冲经常被请求的页面来缓解服务器的工作量,将客户机请求转发给内部网络上的目标服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器与目标主机一起对外表现为一个服务器。

        NGINX通过ngx_http_proxy_module实现HTTP代理功能,参考官网文档地址如下:

        https://NGINX.org/en/docs/http/ngx_http_proxy_module.html

第2章 HTTP代理

        NGINXHTTP代理功能是通过“ngx_http_proxy_module”模块实现的,该模块会被默认构建,无须特殊配置参数。

2.1 HTTP正向代理

        配置示例如下:

测试验证:

通过curl -x 127.0.0.1:8090 http://www.hu.com”命令代理访问测试域名,访问成功,并能查看到正常的访问日志。

同时代理策略有header信息User-Agent配置,在被代理服务器抓包可以看到User-Agent已经由原始的curl更改DC-NGINX...

2.2 HTTP反向代理

2.2.1 基本测试

        HTTP反向代理可采用结合upstream配置方式和server 直接proxy配置方式,upstream下可配置多个server,用于负载均衡

        配置示例如下:

2.2.2 host效验测试

        在许多安全场景下,我们不允许用户直接通过IP地址或者伪造的域名访问到NGINX代理的服务器,需要实现对于客户端访问host名称的校验。

        Host效验配置示例如下:

        NGINXserver匹配采用的是从上往下匹配的方式,所以我们可以在最后设置一组default_server并对其进行限制访问的方式实现,如下图,当最后的匹配的其它非配置域名时访问时,NGINX返回403错误。


2.2.3 真实IP透传

        NGINX HTTP反向代理的真实IP透传或者叫IP朔源类似可采用多种方式实现真实。

        配置示例如下:


        为验证上图各种真实IP透传效果,我们按如下图搭建双层代理部署测试环境。

2.2.3.1 验证验证场景:$remote_addr;

        配置proxy_set_header X-real-ip  $remote_addrNGINX代理会在HTTP报头中插入一个叫X-real-ip的字段,并以访问来源IP作为透传地址写入X-real-ip中。

        参照下图:一二层代理均配置proxy_set_header X-real-ip  $remote_addr;


        测试验证:

        在二层代理服务器抓取请求报文,查看HTTP报文,可以看到由一层代理填加的X-real-ip字段,其IP地址为客户端实际地址:192.168.101.5


        Web服务器抓取请求报文,查看HTTP报文,可以看到二层代理修改后的的X-real-ip字段,其IP地址为一层代理请求地址:192.168.101.52


        同时测试发现X-real-ip字符其实是可以自定义的,参照下图,将一层代理X-real-ip更改为Hu-xiaotao,二层代理保持不变,并生效。



        再次在二层代理服务器抓取请求报文,查看HTTP报文,二层代理HTTP报头已经变为Hu-xiaotao


        再次在Web服务器抓取请求报文,查看HTTP报文,可以同时看到一层代理添加的Hu-xiaotao字段和二层代理添加的X-real-ip字段。


        将一二层代理X-real-ip更改为X-Forwarded-For,并生效。


        得到的结果同上

        二层代理服务器抓取请求报文


        Web服务器抓取请求报文


2.2.3.2 验证验证场景二:$proxy_add_x_forwarded_for;

        配置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forNGINX代理会在HTTP报头中插入一个叫X-Forwarded-For 的字段,并以访问来源IP作为透传地址写入X-Forwarded-For中,并且为持续增加模式,即每层代理服务器均添加自己的访问来源来IP,对上层代理添加的已经存在IP不做替换操作。

        参照下图:一二层代理均配置proxy_set_header X-real-ip  $proxy_add_x_forwarded_for;


        测试验证:

        在二层代理服务器抓取请求报文,查看HTTP报文,可以看到由一层代理填加的X-Forwarded-For字段,其IP地址为客户端实际地址:192.168.101.5


        Web服务器抓取请求报文,查看HTTP报文,可以看到二层代理继续添加后的X-Forwarded-For字段,其IP地址为一层代理请求地址:192.168.101.5192.168.101.52

2.2.3.3 验证验证场景三:ng_http_reali_module

        在很多场景下,我们的应用可能会经过多层代理,如CDNSSL卸载、负载均衡等等,这些代理如果都开启x-forwarded-for功能,那么x-forwarded-for字段中会存在着多个IP地址,这可能会导致内部或者WAF等安全设备或者应用本身无法识别真到真正的用户请求访问。

        当然在多级代理的场景下,最简单的方式就是只启用一级代理的x-forwarded-for功能,但是在实际的应用中,可能因为各种原因无法实现这一要求,这时可以采用ng_http_real_module模块对x-forwarded-for的字段进行过滤,以实现真正的客户端IP地址透传功能。

        为更好的测试验证,我们参照下图设置三层代理模式。



        测试验证:

        在一层代理和二层代理启用x-forwarded-for功能,三层代理采用默认配置,在web服务器上分别查看日志和抓取数据包查看,可以看到一二层代理分别插入的x-forwarded-forIP地址。



        在三层代理配置ng_http_real_module功能


        三层代理配置完成后,在web服务器上分别查看日志和抓取数据包查看,只能看到的真正的客户端的IP地址,并且仅有这一个IP地址,其它代理的IP地址已经被过滤。



第3章 HTTPS代理

        HTTPS由于其内容为加密流量,客户端访问内容代理服务器不可见,可采用SNI代理和CONNECT代理

        其中SNI代理NGINX-OSS和NGINX-Plus均由官方模块支持,CONNECT代理由第三方模块支持,NGINX-OSS可支持,NGINX-Plus无法支持。

3.1 HTTPS 正向代理

3.1.1 SNI代理

        SNI代理采用四层模式,使用“ngx_stream_ssl_preread_module”模块,其原理通过识别客户端的SNI信息中的请求域名后再进行加密的流量的代理转发。

        SNI (Server Name Indication)是用来改善服务器与客户端 SSL (Secure Socket Layer)TLS (Transport Layer Security) 的一个扩展,SNITLS扩展通过发送请示服务器的域名做为TSL协商的一部分,在Client Hello阶段,通过SNI扩展,将域名信息提前告诉服务器,服务器根据域名取得对应的证书返回给客户端完成校验过程,下图为Client Hello包中的SNI字段,可以看到客户端请示的Server Name为:www.163.com


        SNI代理完全依赖于客户端在SSL协商过程的SNI信息,如果客户端不支持或者未发送SNI字段信息,则SNI代理将会失败。

        配置示例如下:


测试验证:

修改测试终端的host文件,将网易、百度的主页host解析设置为NGINX代理服务器地址,并使用浏览器正常访问163和百度首页,访问成功,并能查看到浏览器实际访问的IP地址为NGINX代理服务器地址。




3.1.2 CONNECT代理

        CONNECT代理NGINX官方模块不支持, 需要采用第三方模块“ngx_http_proxy_connect_module”实现,其github地址如下:

        https://github.com/chobits/ngx_http_proxy_connect_module

整个过程可以参考HTTP权威指南中的图:

1、客户端给代理服务器发送HTTP CONNECT请求。

2、代理服务器利用HTTP CONNECT请求中的主机和端口与目的服务器建立TCP连接。

3、代理服务器给客户端返回HTTP 200响应。

4、客户端和代理服务器建立起HTTP CONNECT隧道,HTTPS流量到达代理服务器后,直接通过TCP透传给远端目的服务器。代理服务器的角色是透传HTTPS流量,并不需要解密HTTPS


        配置示例如下:

        由于ngx_http_proxy_connect_module”为第三方模块,在使用之前需要重新编译安装。

        编译安装完成后,即可使用,参照下图,基本配置后,即可进行使用。


测试验证:

设置客户端代理访问,并使用浏览器正常访问163和百度首页,访问成功,并能查看到浏览器实际访问的IP地址为NGINX代理服务器地址。




        NGINX上通过TCPDUMP抓包可以看到客户端到NGINX代理服务器采用的是CONNECTHTTP请求,NGINX代理服务器到外网开始SSL协商进行加密传输。



3.2 HTTPS反向代理

        HTTPS的反向代理即是咱们通常所说的的SSL卸载功能。

3.2.1 基本测试

        配置示例如下:


        基本配置,配置listenserverSSL的证书以及key文件目录,Location配置被代理的服务器即可。

        同时针对SSL协议以及SSL协商的算法,有现代兼容性、中级兼容性(默认)和旧的向后兼容性三种方式,分别如下:

1、现代兼容性

        对于不需要向后兼容性的服务。 此配置与 Windows 7EdgeOpera 17Safari 9Android 5.0 Java 8 上的 Firefox 27Chrome 30IE 11 兼容。

        配置参数如下:

        listen 443 ssl http2;

        ssl_protocols TLSv1.2;

        ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;

2、中级兼容性(默认)

        对于不需要与旧客户端(主要是 WinXP)兼容但仍需要支持各种客户端的服务,建议使用此配置。 它与 Firefox 1Chrome 1IE 7Opera 5 Safari 1 兼容。(推荐)

        listen 443 ssl http2;

        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;

        ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;

3、旧的向后兼容性

        这是旧的密码组件,它主要工作在 Windows XP / IE6 中,如果不是特别需要,建议放弃此配置。

        listen 443 ssl http2;

        ssl_protocols TLSv1.2 TLSv1.1 TLSv1 SSLv3;

ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;

3.2.2 服务器再次加密代理


        Location字段修改代理的服务器为https,同时加上proxy_ssl_xxx即可,Server字段的的ssl参数,在此加proxy_均可使用。

3.2.3 双向认证

        我们平时使用的HTTPS代理通常采用单向认证方式,即客户端验证通过服务端返回的信息验证服务器的合法性,双向认证则是客户端需要认证服务端以外,还增加了服务端对客户端的认证。



3.2.4 IP多域名HTTPS代理

        许多负载均衡上要实现单IP多域名的配置比较麻烦,在NGINX上就特点简单了,新建一个server就可以了,采用server_name区分不同域名。


第4章 TCP/UDP代理

        NGINX通过stream模块提供TCP/UDP代理。

4.1 基本测试

        配置示例如下:


已修改于2023-03-09 04:34
本作品系原创
创作不易,留下一份鼓励
葫芦娃

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
葫芦娃
这家伙很懒还未留下介绍~
2
文章
0
问答
4
粉丝
相关文章
WordPress 安装”的条目多达在这篇文章中,我们将试着就此给出解决办法。我们提供了在bash脚本,并详细解释了各部分的作用以及我们的考量取舍。(如果您是一名高级用户,则可跳过这篇文章,直接进入脚本部分,下载并根据您的环境进行修改。)最终的 NGINX Unit部署
点赞 0
浏览 7.2k
原文作者:Floyd Smith of F5原文链接:实现 10 倍应用性能提升的 10 个技巧转载来源:NGINX 官方网站Web 应用性能优化迫在眉睫。线上经济活动份额不断增长,发达世界的互联网经
点赞 0
浏览 2.5k
【版本更新】NGINX Unit 版本更新到 1.31.0 该版本隆重推出了 Unit WebAssembly (WASM)功能, 这是一个重要的里程碑,代表着 NGINX Unit 功能的重大飞跃。 此外还添加了发送响应请求头和控制响应请求头变量的能力,以及修复了一系列小 BUG。
点赞 0
浏览 552