文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

阿里云国际版使用Nginx作为HTTPS转发代理服务器的处理方法

2024-04-02 19:55

关注

NGINX最初被设计为反向代理服务器。但是,随着不断发展,NGINX也可以作为实现转发代理的选项之一。转发代理本身并不复杂,它解决的关键问题是如何加密HTTPS流量。本文介绍了使用NGINX作为HTTPS流量转发代理的两种方法,以及它们的应用场景和主要问题。

今天87cloud详谈下阿里云国际如何使用NGINX作为HTTPS转发代理服务器

HTTP/HTTPS 转发代理的分类

首先,让我们仔细看看转发代理的分类。

分类依据:代理对客户是否透明

分类依据:代理是否加密HTTPS

注意:在这种情况下,客户端在TLS握手过程中实际获取了代理服务器的自签名证书,默认情况下证书链的验证不成功。代理自签名证书中的根 CA 证书必须在客户端上受信任。因此,客户端知道此过程中的代理。如果将自签名根 CA 证书推送到客户端(在企业的内部环境中实现),则可实现透明代理。

转发代理处理 HTTPS 流量时需要特殊处理

在充当反向代理时,代理服务器通常会终止 HTTPS 加密流量并将其转发到后端实例。HTTPS 流量的加密、解密和身份验证发生在客户端和反向代理服务器之间。

另一方面,当充当转发代理并处理客户端发送的流量时,代理服务器不会在客户端请求的URL中看到目标域名,因为HTTP流量已加密并封装在TLS / SSL中,如下图所示。因此,与 HTTP 流量不同,HTTPS 流量在代理实现期间需要一些特殊处理。

NGINX解决方案

根据前面几节中的分类,当NGINX用作HTTPS代理时,代理是透明的传输(隧道)代理,既不解密也不感知上层流量。具体来说,有两种NGINX解决方案可用:第7层(L7)和第4层(L4)。以下各节详细介绍了这些解决方案。

HTTP 连接隧道 (L7 解决方案)

历史背景

早在1998年TLS还没有正式上市的时候,推广SSL协议的网景就提出使用Web代理进行SSL流量的隧道。核心思想是使用HTTP CONNECT请求在客户端和代理之间建立HTTP CONNECT隧道。CONNECT 请求必须指定客户端需要访问的目标主机和端口。互联网草案中的原始图表如下:

有关整个过程的详细信息,请参阅 HTTP:权威指南中的图表。以下步骤简要概述了该过程。

1) 客户端向代理服务器发送 HTTP CONNECT 请求。
2) 代理服务器使用 HTTP CONNECT 请求中的主机和端口信息与目标服务器建立 TCP 连接。
3) 代理服务器向客户端返回 HTTP 200 响应。
4) 客户端与代理服务器建立 HTTP CONNECT 隧道。在 HTTPS 流量到达代理服务器后,代理服务器通过 TCP 连接透明地将 HTTPS 流量传输到远程目标服务器。代理服务器仅透明地传输 HTTPS 流量,不解密 HTTPS 流量。

 

ngx_http_proxy_connect_module

作为反向代理服务器,NGINX并不正式支持HTTP CONNECT方法。但是,由于NGINX的模块化和可扩展功能,阿里巴巴@chobits提供了连接模块(中文内容)来支持HTTP CONNECT方法,以扩展NGINX作为转发代理。ngx_http_proxy_connect_module

环境建设

以 CentOS 7 環境為例,讓我們詳細看看這過程。

1) 环境安装

对于新环境安装,请参阅安装连接模块的常见安装步骤(中文内容)。ngx_http_proxy_connect_module

安装相应版本的修补程序,并在“configure”命令下添加参数,如以下示例所示。--add-module=/path/to/ngx_http_proxy_connect_module

./configure \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-threads \
--add-module=/root/src/ngx_http_proxy_connect_module

此外,为现有环境添加,如下所示。ngx_http_proxy_connect_module

# 停止NGINX服务
# systemctl stop nginx
# 备份原执行文件
# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
# 在源代码路径重新编译
# cd /usr/local/src/nginx-1.16.0
./configure \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-threads \
--add-module=/root/src/ngx_http_proxy_connect_module
# make
# 不要make install
# 将新生成的可执行文件拷贝覆盖原来的nginx执行文件
# cp objs/nginx /usr/local/nginx/sbin/nginx
# /usr/bin/nginx -V
nginx version: nginx/1.16.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-threads --add-module=/root/src/ngx_http_proxy_connect_module

2) 配置 nginx.conf 文件

执行以下命令以配置文件。nginx.conf

server {
     listen  443;
    
     # dns resolver used by forward proxying
     resolver  114.114.114.114;
     # forward proxy for CONNECT request
     proxy_connect;
     proxy_connect_allow            443;
     proxy_connect_connect_timeout  10s;
     proxy_connect_read_timeout     10s;
     proxy_connect_send_timeout     10s;
     # forward proxy for non-CONNECT request
     location / {
         proxy_pass http://$host;
         proxy_set_header Host $host;
     }
 }

应用场景

在 L7 解决方案中,HTTP CONNECT 请求必须建立隧道,因此,代理服务器是客户端必须感知的公共代理。在客户端上手动配置 HTTP(S) 代理服务器的 IP 地址和端口。使用 cURL 的“-x”参数访问客户端,如下所示。

# curl https://www.baidu.com -svo /dev/null -x 39.105.196.164:443
* About to connect() to proxy 39.105.196.164 port 443 (#0)
*   Trying 39.105.196.164...
* Connected to 39.105.196.164 (39.105.196.164) port 443 (#0)
* Establish HTTP proxy tunnel to www.baidu.com:443
> CONNECT www.baidu.com:443 HTTP/1.1
> Host: www.baidu.com:443
> User-Agent: curl/7.29.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection Established
< Proxy-agent: nginx
<
* Proxy replied OK to CONNECT request
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*     subject: CN=baidu.com,O="Beijing Baidu Netcom Science Technology Co., Ltd",OU=service operation department,L=beijing,ST=beijing,C=CN
...
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.baidu.com
> Accept: **
>
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Connection: Keep-Alive
< Content-Length: 2443
< Content-Type: text/html
< Date: Fri, 21 Jun 2019 05:46:07 GMT
< Etag: "5886041d-98b"
< Last-Modified: Mon, 23 Jan 2017 13:24:45 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<
{ [data not shown]
* Connection #0 to host www.baidu.com left intact

常见问题

现在,让我们快速看一下有关L4解决方案的关键问题。

1) 由于客户端上的手动代理设置,访问尝试失败。

L4 转发代理透明地传输上层 HTTPS 流量,不需要 HTTP CONNECT 即可建立隧道。因此,没有必要在客户端上设置 HTTP(S) 代理。关键问题是,在客户端上手动设置 HTTP(S) 代理是否可确保访问尝试成功。使用 cURL 的“-x”参数设置转发代理服务器并测试对此服务器的访问。以下代码段显示了结果。

# curl https://www.baidu.com -svo /dev/null -x 39.105.196.164:443
* About to connect() to proxy 39.105.196.164 port 443 (#0)
*   Trying 39.105.196.164...
* Connected to 39.105.196.164 (39.105.196.164) port 443 (#0)
* Establish HTTP proxy tunnel to www.baidu.com:443
> CONNECT www.baidu.com:443 HTTP/1.1
> Host: www.baidu.com:443
> User-Agent: curl/7.29.0
> Proxy-Connection: Keep-Alive
>
* Proxy CONNECT aborted
* Connection #0 to host 39.105.196.164 left intact

结果指示客户端尝试在 NGINX 之前建立 HTTP CONNECT 隧道。但是,由于NGINX透明地传输流量,因此CONNECT请求直接转发到目标服务器。目标服务器不接受 CONNECT 方法。因此,“代理连接中止”反映在上面的代码段中,导致访问失败。

2) 访问尝试失败,因为客户端在 ClientHello 数据包中不包含 SNI。

如前所述,当NGINX流用作转发代理时,使用从ClientHello中提取SNI字段至关重要。如果客户端在 ClientHello 数据包中未包含 SNI,则代理服务器将不知道目标域名,从而导致访问失败。ngx_stream_ssl_preread_module

在透明代理模式(由手动绑定主机模拟)下,使用 OpenSSL 在客户端上进行模拟。


# openssl s_client -connect www.baidu.com:443 -msg
CONNECTED(00000003)
>>> TLS 1.2  [length 0005]
    16 03 01 01 1c
>>> TLS 1.2 Handshake [length 011c], ClientHello
    01 00 01 18 03 03 6b 2e 75 86 52 6c d5 a5 80 d7
    a4 61 65 6d 72 53 33 fb 33 f0 43 a3 aa c2 4a e3
    47 84 9f 69 8b d6 00 00 ac c0 30 c0 2c c0 28 c0
    24 c0 14 c0 0a 00 a5 00 a3 00 a1 00 9f 00 6b 00
    6a 00 69 00 68 00 39 00 38 00 37 00 36 00 88 00
    87 00 86 00 85 c0 32 c0 2e c0 2a c0 26 c0 0f c0
    05 00 9d 00 3d 00 35 00 84 c0 2f c0 2b c0 27 c0
    23 c0 13 c0 09 00 a4 00 a2 00 a0 00 9e 00 67 00
    40 00 3f 00 3e 00 33 00 32 00 31 00 30 00 9a 00
    99 00 98 00 97 00 45 00 44 00 43 00 42 c0 31 c0
    2d c0 29 c0 25 c0 0e c0 04 00 9c 00 3c 00 2f 00
    96 00 41 c0 12 c0 08 00 16 00 13 00 10 00 0d c0
    0d c0 03 00 0a 00 07 c0 11 c0 07 c0 0c c0 02 00
    05 00 04 00 ff 01 00 00 43 00 0b 00 04 03 00 01
    02 00 0a 00 0a 00 08 00 17 00 19 00 18 00 16 00
    23 00 00 00 0d 00 20 00 1e 06 01 06 02 06 03 05
    01 05 02 05 03 04 01 04 02 04 03 03 01 03 02 03
    03 02 01 02 02 02 03 00 0f 00 01 01
140285606590352:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 289 bytes
⋯

默认情况下,OpenSSL 不包括 SNI。如代码段所示,在发送 ClientHello 后,前面的请求将在 TLS/SSL 握手阶段终止。发生这种情况是因为代理服务器不知道应将 ClientHello 转发到的目标域名。s_client

使用带有“服务器名称”参数的 OpenSSL 来指定 SNI,将产生成功的访问。

# openssl s_client -connect www.baidu.com:443 -servername www.baidu.com

结论

本文介绍了使用NGINX作为HTTPS流量转发代理的两种方法。它总结了NGINX使用HTTP CONNECT隧道和NGINX流充当HTTPS转发代理的解决方案的原则,环境构建要求,应用场景和关键问题。本文在各种情况下使用NGINX作为转发代理时用作参考,具体情况参考www.87cloud.com

到此这篇关于阿里云国际版使用Nginx作为HTTPS转发代理服务器的处理方法的文章就介绍到这了,更多相关Nginx作为HTTPS转发代理服务器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯