Nginx正向代理模块详解-http-proxy-connect

Nginx正向代理模块详解-http-proxy-connect

1、模块简介

  • 官方REDEME:This module provides support for the CONNECT method request. This method is mainly used to tunnel SSL requests through proxy servers.

该模块为CONNECT方法请求提供支持。 此方法主要用于通过代理服务器转发SSL请求。

1.1、模块下载地址

https://github.com/chobits/ngx_http_proxy_connect_module

  • 目前支持版本支持如下(请前往如上地址实时查看):
nginx version enable REWRITE phase patch
1.4.x ~ 1.12.x NO proxy_connect.patch
1.4.x ~ 1.12.x YES proxy_connect_rewrite.patch
1.13.x ~ 1.14.x NO proxy_connect_1014.patch
1.13.x ~ 1.14.x YES proxy_connect_rewrite_1014.patch
1.15.2 YES proxy_connect_rewrite_1015.patch
1.15.4 ~ 1.16.x YES proxy_connect_rewrite_101504.patch
1.17.x YES proxy_connect_rewrite_101504.patch
OpenResty version enable REWRITE phase patch
1.13.6 NO proxy_connect_1014.patch
1.13.6 YES proxy_connect_rewrite_1014.patch
1.15.8 YES proxy_connect_rewrite_101504.patch

2、安装环境介绍

平台 IP NGINX版本 安装模块
CentOS 6.7 64Bit 192.168.1.219 NGINX-1.10.3 ngx_http_proxy_connect_module

3、模块安装

3.1、Build nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@test0002 soft]# tar xzvf nginx-1.10.3.tar.gz 
[root@test0002 soft]# tar xzvf nginx-sticky-module-ng-1.2.6.tar.gz
[root@test0002 soft]# tar xzvf ngx_http_proxy_connect_module-0.0.1.tar.gz
[root@test0002 nginx-1.10.3]# patch -p1 < /soft/ngx_http_proxy_connect_module-0.0.1/patch/proxy_connect.patch
[root@test0002 nginx-1.10.3]# useradd -s /sbin/nologin -M www
[root@test0002 nginx-1.10.3]# ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --add-module=/soft/ngx_http_proxy_connect_module-0.0.1/
[root@test0002 nginx-1.10.3]# make && make install
[root@test0002 nginx-1.10.3]# chmod a+x /etc/init.d/nginx
[root@test0002 nginx-1.10.3]# chkconfig --add nginx
[root@test0002 nginx-1.10.3]# chkconfig nginx on
[root@test0002 sbin]# ./nginx -V
nginx version: nginx/1.10.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --add-module=/soft/ngx_http_proxy_connect_module-0.0.1/

3.2、Config nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@test0002 vhost_conf]# vim proxy_9999.conf
server {
listen 3128;

# dns resolver used by forward proxying
resolver 8.8.8.8;

# forward proxy for CONNECT request
proxy_connect;
proxy_connect_allow 443 563;
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;
}
}

3.3、Error Log

  • This module logs its own error message beginning with "proxy_connect:" string.
    Some typical error logs are shown as following:The proxy_connect module tries to establish tunnel connection with backend server, but the TCP connection timeout occurs.
1
2019/08/07 17:27:20 [error] 19257#0: *1 proxy_connect: upstream connect timed out (peer:216.58.200.4:443) while connecting to upstream, client: 127.0.0.1, server: , request: "CONNECT www.google.com:443 HTTP/1.1", host: "www.google.com:443"

3.4、Directive

1
2
3
4
5
proxy_connect
- Syntax: proxy_connect
- Default: `none`
- Context: `server`
Enable "CONNECT" HTTP method support.
1
2
3
4
5
6
7
8
proxy_connect_allow
- Syntax: proxy_connect_allow `all | [port ...] | [port-range ...]`
- Default: `443 563`
- Context: `server`
The value `all` will allow all ports to proxy.
The value `port` will allow specified port to proxy.
The value `port-range` will allow specified range of port to proxy, for example:
proxy_connect_allow 1000-2000 3000-4000; # allow range of port from 1000 to 2000, from 3000 to 4000.
1
2
3
4
5
proxy_connect_connect_timeout
- Syntax: proxy_connect_connect_timeout `time`
- Default: `none`
- Context: `server`
Defines a timeout for establishing a connection with a proxied server.
1
2
3
4
5
6
7
proxy_connect_read_timeout
- Syntax: proxy_connect_read_timeout `time`
- Default: `60s`
- Context: `server`
Defines a timeout for reading a response from the proxied server.
The timeout is set only between two successive read operations, not for the transmission of the whole response.
If the proxied server does not transmit anything within this time, the connection is closed.
1
2
3
4
5
6
7
8
proxy_connect_send_timeout
- Syntax: proxy_connect_send_timeout `time`
- Default: `60s`
- Context: `server`

Sets a timeout for transmitting a request to the proxied server.
The timeout is set only between two successive write operations, not for the transmission of the whole request.
If the proxied server does not receive anything within this time, the connection is closed.
1
2
3
4
5
6
7
8
proxy_connect_address
- Syntax: proxy_connect_address `address | off`
- Default: `none`
- Context: `server`
Specifiy an IP address of the proxied server. The address can contain variables.
The special value off is equal to none, which uses the IP address resolved from host name of CONNECT request line.

NOTE: If using `set $<nginx variable>` and `proxy_connect_address $<nginx variable>` together, you should use `proxy_connect_rewrite.patch` instead, see [Install](#install) for more details.

3.5、Variables

1
2
$connect_host
- host name from CONNECT request line.
1
2
$connect_port
- port from CONNECT request line.
1
2
3
$connect_addr
- IP address and port of the remote host, e.g. "192.168.1.5:12345".
- IP address is resolved from host name of CONNECT request line.
1
2
$proxy_connect_connect_timeout
- Get or set timeout of [`proxy_connect_connect_timeout` directive](#proxy_connect_connect_timeout).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#For example:
# Set default value

proxy_connect_connect_timeout 10s;
proxy_connect_read_timeout 10s;
proxy_connect_send_timeout 10s;

# Overlap default value

if ($host = "test.com") {
set $proxy_connect_connect_timeout "10ms";
set $proxy_connect_read_timeout "10ms";
set $proxy_connect_send_timeout "10ms";
}
1
2
$proxy_connect_read_timeout
- Get or set a timeout of [`proxy_connect_read_timeout` directive](#proxy_connect_read_timeout).
1
2
$proxy_connect_send_timeout
- Get or set a timeout of [`proxy_connect_send_timeout` directive](#proxy_connect_send_timeout).

4、正向代理访问测试

4.1、Example for curl

  • With above configuration, you can get any https website via HTTP CONNECT tunnel. A simple test with command curl is as following:
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
[root@test0002 vhost_conf]# curl https://www.baidu.com/ -v -x 127.0.0.1:9999
* About to connect() to proxy 127.0.0.1 port 9999 (#0)
* Trying 127.0.0.1... connected
* Connected to 127.0.0.1 (127.0.0.1) port 9999 (#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.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> 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
* Server certificate:
* subject: CN=baidu.com,O="Beijing Baidu Netcom Science Technology Co., Ltd",OU=service operation department,L=beijing,ST=beijing,C=CN
* start date: 5月 09 01:22:02 2019 GMT
* expire date: 6月 25 05:31:02 2020 GMT
* common name: baidu.com
* issuer: CN=GlobalSign Organization Validation CA - SHA256 - G2,O=GlobalSign nv-sa,C=BE
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> 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: Mon, 28 Oct 2019 01:57:28 GMT
< Etag: "58860401-98b"
< Last-Modified: Mon, 23 Jan 2017 13:24:17 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/

4.2、Example for browser

  • You can configure your browser to use this nginx as PROXY server.

image_1do81jb5s1t8g61qfv13001bmd19.png-108.1kB

4.3、linux客户端测试

1
2
3
4
5
6
7
[root@test0002 ~]# vim /etc/profile
http_proxy=http://192.168.1.220:9999/
https_proxy=http://192.168.1.220:9999/
[root@test0002 ~]# export http_proxy https_proxy
[root@test0002 ~]# source /etc/profile
[root@test0002 ~]# echo $http_proxy $https_proxy
http://192.168.1.220:9999/ http://192.168.1.220:9999/
1
2
3
4
5
6
7
8
9
10
11
12
[root@test0002 ~]# curl -v https://www.baidu.com/
* About to connect() to proxy 192.168.1.220 port 9999 (#0)
* Trying 192.168.1.220... connected
* Connected to 192.168.1.220 (192.168.1.220) port 9999 (#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.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection Established
< Proxy-agent: nginx
-------------本文结束感谢您的阅读-------------
LiGuanCheng wechat
如有问题,请与我微信交流或通过右下角“daovoice”与我联系~。
请我喝一杯咖啡~