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

浏览 7k

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
粉丝
相关文章
用户任务3: 阅读1篇优质好文,在该文评论区写下您的评论; l LV1用户等级权益: 社区官网个人主页精美V1等级勋章1个; 镜头盖和手机支架各1个; 获得LV 1等级权益还需要完成其他任务
点赞 0
浏览 2.7k
upstream-fair模块upstream-fair是比内建的负载均衡更加智能的负载均衡模块,一般google关键词nginx-upstream-fair可以找到相关资源和文章,这里不详述了。它采
点赞 0
浏览 4.2k
本期课程介绍了 NGINX 集群是怎么工作的,并对比 NGINX 官方和 Kubernetes 官方的两个 Ingress Controller 在运行时各自的特点以及性能上的差别。课程内容包括 Kubernetes 的网络流量场景,以及 NGINX 集群该如何管理,如何解决分布式集群中常见的高可用、容灾、扩容等问题。
点赞 1
浏览 3.4k