nginx正向代理https网站的实现

1. 缘起

最近碰到了一个麻烦事情,就是公司的centos测试服务器放在内网环境,而且不能直接上外网,导致无法通过yum安装软件,非常捉急。

幸好,内网还是有可以可以访问外网的机器,所以就想到应该可以利用nginx搭建一个代理服务器,然后centos通过这个nginx来访问外网。当然,如果只是代理http还是很简单的,而要代理https还是需要稍费周折,因为nginx本身不能部署被代理的网站的证书,不能部署成https终结点来,因此与被代理客户端之间不能用ssl协议通讯,因此需要通过http协议中的CONNECT请求打通和外网的连接,然后客户端到nginx走明文,nginx到外网走https协议。这里需要用到ngx_http_proxy_connect_module模块来实现CONNECT的代理功能。

2. 部署nginx

步骤1:从nginx官网下载nginx源码包

步骤2:因为nginx原生是不支持CONNECT请求的,需要安装一个扩展插件,即ngx_http_proxy_connect_module,从github下载ngx_http_proxy_connect_module,另外还要下载一个nginx内核补丁

步骤3: 解压nginx源码包,进入nginx源码目录,创建modules目录(mkdir modules)。

步骤4: 将ngx_http_proxy_connect_module源码目录放到modules目录中。

步骤5: 将nginx内核补丁放到nginx源码目录,姑且名字叫p1.patch

步骤6: 在nginx源码目录,执行以下命令给nginx内核打上补丁:

1
patch -p 1

步骤7:编译nginx,这里假设nginx安装到/opt/nginx目录中(在编译前确认pcre、zlib、openssl的库是否已经正常安装),编译命令如下:

1
2
./configure --prefix=/opt/nginx --with-http_ssl_module -add-module=./modules/ngx_http_proxy_connect_module
make & make install

步骤8:配置nginx

配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#user  nobody;
worker_processes  1;
 
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
 
#pid        logs/nginx.pid;
 
 
events {
    worker_connections  1024;
}
 
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 
    #access_log  logs/access.log  main;
 
    sendfile        on;
    keepalive_timeout  65;
 
 
  server {
        # 代理端口
        listen 8080;
        server_name  localhost;
         
        # 解析被代理网站域名的dns服务器,根据实际情况自行配置
        resolver  114.114.114.114;
         
        # 开启proxy connect功能
        proxy_connect;
         
        # 设置允许代理的目标端口为443,即https的默认端口
        proxy_connect_allow 443 80;
 
        location / {
         
            # 正向代理配置,根据请求地址自动解析出目标网站地址并进行代理
            proxy_pass $scheme://$host$request_uri;
             
            # 发送到被代理网站的请求需要添加host头
            proxy_set_header Host $http_host;
         
            proxy_buffers 256 4k;
            proxy_max_temp_file_size 0;
            proxy_connect_timeout 30;
        }
    }
}

以上配置完成后,通过nginx的8080端口,既可以代理普通http的请求,也可以代理https的请求。

步骤9:启动nginx

执行/opt/nginx/sbin/nginx,启动nginx

3. 测试

3.1 http测试

1
curl "http://www.baidu.com/" -x 127.0.0.1:8080 -v

响应内容:

1
2
3
4
5
6
7
8
9
10
11
12
*   Trying 127.0.0.1:8080...
* Connected to (nil) (127.0.0.1) port 8080 (#0)
> GET http://www.baidu.com/ HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.81.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Mark bundle as not supporting multiuse
 
<title>百度一下,你就知道</title><div id="wrapper"> <div id="head"> <div class="head_wrapper"> <div class="s_form"> <div class="s_form_wrapper"> <div id="lg"> <img decoding="async" src="https://www.2it.club/wp-content/uploads/2024/06/frc-5f8dcf06d74b796a51269303a0d2e07b.png">
</div>  <span class="bg s_ipt_wr"></span><span class="bg s_btn_wr"></span>  </div> </div> <div id="u1"> <a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a> <a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a> <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a>  <a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login" class="lb">登录</a>  document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === " rel="external nofollow" name="tj_login" class="lb">登录');</a><a href="//www.baidu.com/more/" name="tj_briicon" class="bri">更多产品</a> </div> </div> </div> <div id="ftCon"> <div id="ftConw"> <p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p> <p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度前必读</a>  <a href="http://jianyi.baidu.com/" class="cp-feedback">意见反馈</a> 京ICP证030173号  <img decoding="async" src="https://www.2it.club/wp-content/uploads/2024/06/frc-00d1288894417d1a3f3c7ca18fdbac65.gif"></p> </div> </div> </div> 

通过以上的输出可以看到http代理是没有通过CONNECT请求进行连接的,响应正常。

3.2 https测试

1
curl "https://www.baidu.com/" -x 127.0.0.1:8080 -v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
*   Trying 127.0.0.1:8080...
* Connected to (nil) (127.0.0.1) port 8080 (#0)
* allocate connect buffer!
* 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.81.0
> Proxy-Connection: Keep-Alive
>
 GET / HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
 
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
 <title>百度一下,你就知道</title><div id="wrapper"> <div id="head"> <div class="head_wrapper"> <div class="s_form"> <div class="s_form_wrapper"> <div id="lg"> <img decoding="async" src="https://www.2it.club/wp-content/uploads/2024/06/frc-5f8dcf06d74b796a51269303a0d2e07b.png">
</div>  <span class="bg s_ipt_wr"></span><span class="bg s_btn_wr"></span>  </div> </div> <div id="u1"> <a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a> <a href="https://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a> <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a>  <a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login" class="lb">登录</a>  document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === " rel="external nofollow" name="tj_login" class="lb">登录');
                </a><a href="//www.baidu.com/more/" name="tj_briicon" class="bri">更多产品</a> </div> </div> </div> <div id="ftCon"> <div id="ftConw"> <p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p> <p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度前必读</a>  <a href="http://jianyi.baidu.com/" class="cp-feedback">意见反馈</a> 京ICP证030173号  <img decoding="async" src="https://www.2it.club/wp-content/uploads/2024/06/frc-00d1288894417d1a3f3c7ca18fdbac65.gif"></p> </div> </div> </div> 

通过以上的输出可以看到https代理是通过CONNECT请求进行连接的,中间有发生ssl的握手过程,也已经正常进行了响应。

4 给centos设置代理访问外网

给centos服务器设置两个http_proxy和https_proxy环境变量,假设nginx服务器的ip为192.168.0.1,那么在命令行执行以下两条命令,即:

1
2
export http_proxy="http://192.168.0.1:8080"
export https_proxy="https://192.168.0.1:8080"

然后就可以顺畅地进行yum了。当然,如果可以的话,就将以上两条命令配置到bash.rc中,这样子免得每次登录都需要敲命令。

到此这篇关于nginx正向代理https网站的实现的文章就介绍到这了,更多相关nginx正向代理https内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/server/nginx/12138.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部