用于CONNECT请求处理的前向代理模块

・10 分钟阅读

  • 源代码名称: ngx_http_proxy_connect_module
  • 源代码网址: https://www.github.com/chobits/ngx_http_proxy_connect_module
  • ngx_http_proxy_connect_module的文档
  • ngx_http_proxy_connect_module的源代码下载
  • Git URL:
    git://www.github.com/chobits/ngx_http_proxy_connect_module.git
  • Git Clone代码到本地:
    git clone https://www.github.com/chobits/ngx_http_proxy_connect_module
  • Subversion代码到本地:
    $ svn co --depth empty https://www.github.com/chobits/ngx_http_proxy_connect_module
                              Checked out revision 1.
                              $ cd repo
                              $ svn up trunk
              
  • 名称

    此模块为"CONNECT "HTTP方法提供支持。
    此方法主要用于通过代理服务器隧道传递SSL请求。

    目录例子
    
     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;
    
    
     }
    
    
     }
    
    
    
    

    通过以上配置,你可以通过HTTP CONNECT隧道获取任何https网站。带有命令curl的简单测试如下所示:

    
    $ curl https://github.com/ -v -x 127.0.0.1:3128
    
    
    * Trying 127.0.0.1... -.
    
    
    * Connected to 127.0.0.1 (127.0.0.1) port 3128 (#0) | curl creates TCP connection with nginx (with proxy_connect module).
    
    
    * Establish HTTP proxy tunnel to github.com:443 -'
    
    
    > CONNECT github.com:443 HTTP/1.1 -.
    
    
    > Host: github.com:443 (1) | curl sends CONNECT request to create tunnel.
    
    
    > User-Agent: curl/7.43.0 |
    
    
    > Proxy-Connection: Keep-Alive -'
    
    
    >
    
    
    < HTTP/1.0 200 Connection Established .- nginx replies 200 that tunnel is established.
    
    
    < Proxy-agent: nginx (2)| (The client is now being proxied to the remote host. Any data sent
    
    
    < '- to nginx is now forwarded, unmodified, to the remote host)
    
    
    
    * Proxy replied OK to CONNECT request
    
    
    * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -.
    
    
    * Server certificate: github.com |
    
    
    * Server certificate: DigiCert SHA2 Extended Validation Server CA | curl sends"https://github.com" request via tunnel,
    
    
    * Server certificate: DigiCert High Assurance EV Root CA | proxy_connect module will proxy data to remote host (github.com).
    
    
    > GET / HTTP/1.1 |
    
    
    > Host: github.com (3) |
    
    
    > User-Agent: curl/7.43.0 |
    
    
    > Accept: */* -'
    
    
    >
    
    
    < HTTP/1.1 200 OK .-
    
    
    < Date: Fri, 11 Aug 2017 04:13:57 GMT |
    
    
    < Content-Type: text/html; charset=utf-8 | Any data received from remote host will be sent to client
    
    
    < Transfer-Encoding: chunked | by proxy_connect module.
    
    
    < Server: GitHub.com (4)|
    
    
    < Status: 200 OK |
    
    
    < Cache-Control: no-cache |
    
    
    < Vary: X-PJAX |
    
    
    ... |
    
    
    ... <other response headers & response body> ... |
    
    
    ... '-
    
    
    
    

    上述例子的顺序图如下所示:

    
     curl nginx (proxy_connect) github.com
    
    
     | | |
    
    
    (1) |-- CONNECT github.com:443 -->| |
    
    
     | | |
    
    
    (2) |<- HTTP/1.1 200 ---| |
    
    
     | Connection Established | |
    
    
     | | |
    
    
     ~~ CONNECT tunnel has ~~ |
    
    
     ~~ been establesied. ~~ |
    
    
     | | |
    
    
     | | |
    
    
     | [ SSL stream ] | |
    
    
    (3) |---[ GET / HTTP/1.1 ]----->| [ SSL stream ] |
    
    
     | [ Host: github.com ] |---[ GET / HTTP/1.1 ]-->.
    
    
     | | [ Host: github.com ] |
    
    
     | | |
    
    
     | | |
    
    
     | | |
    
    
     | | [ SSL stream ] |
    
    
     | [ SSL stream ] |<--[ HTTP/1.1 200 OK ]---'
    
    
    (4) |<--[ HTTP/1.1 200 OK ]------| [ < html page > ] |
    
    
     | [ < html page > ] | |
    
    
     | | |
    
    
    
    

    你也可以配置你的浏览器使用这个nginx作为PROXY服务器(例如。Google Chrome HTTP代理设置)。

    以下是如何在SSL层(对于supporing Google Chrome HTTPS代理设置)下配置这个模块的指南和配置

    安装
    • 选择适合构建的补丁:
    Nginx版本启用REWRITE 补丁
    1.4 .x ~1.12 .x不是proxy_connect.patch
    1.4 .x ~1.12 .x是的proxy_connect_rewrite.patch
    1.13 .x ~1.14 .x不是proxy_connect_1014.patch
    1.13 .x ~1.14 .x是的proxy_connect_rewrite_1014.patch

    proxy_connect,patch includes logic in macro ngx_http_rpoxy_connect,and config script will enable this macro automatically,

    默认情况下,此模块禁用连接请求的Nginx REWRITE ,这意味着不能使用if,set,rewrite_by_lua和其他REWRITE指令,要启用这些功能,你应该使用proxy_connect_rewrite.patch而不是proxy_connect.patch ,(TODO:将两个补丁合并为一个。)

    • 从源代码安装此模块:
    
    $ wget http://nginx.org/download/nginx-1.9.2.tar.gz
    
    
    $ tar -xzvf nginx-1.9.2.tar.gz
    
    
    $ cd nginx-1.9.2/
    
    
    $ patch -p1 < /path/to/ngx_http_proxy_connect_module/patch/proxy_connect.patch
    
    
    $ ./configure --add-module=/path/to/ngx_http_proxy_connect_module
    
    
    $ make && make install
    
    
    
    
    指令

    proxy_connect

    语法:proxy_connect
    默认值:none
    上下文:server

    启用"CONNECT "HTTP方法支持。

    proxy_connect_allow

    语法:proxy_connect_allowall | [port ...] | [port-range ...]
    默认值:443 563
    上下文:server

    此指令指定代理连接方法可以连接的端口号或范围的列表,
    默认情况下仅启用默认的https端口443和默认的snews端口563.
    使用此指令将覆盖此默认值,并允许仅连接到所列端口。

    all将允许所有端口代理。

    port将允许指定的端口代理。

    port-range将允许指定的端口范围进行代理,例如:

    
    proxy_connect_allow 1000-2000 3000-4000; # allow range of port from 1000 to 2000, from 3000 to 4000.
    
    
    
    

    proxy_connect_connect_timeout

    语法:代理连接超时time
    默认值:none
    上下文:server

    定义与已代理服务器建立连接的超时时间。

    proxy_connect_read_timeout

    语法:proxy_connect_read_timeout time strong >
    默认值:60s
    上下文:server

    定义从代理服务器读取响应的超时时间,
    超时是在两个连续读操作之间设置的,而不是整个响应的传输,
    如果代理服务器在此时间内没有传输任何内容,则关闭连接。

    proxy_connect_write_timeout

    语法:proxy_connect_write_timeout time strong >
    默认值:60s
    上下文:server

    设置向代理服务器发送请求的超时时间,
    超时设置只在两个连续的写操作之间设置,而不是整个请求的传输,
    如果代理服务器在这一次没有收到任何消息,则关闭连接。

    proxy_connect_address

    语法:proxy_connect_addressaddress [transparent] | off
    默认值:none
    上下文:server

    指定代理服务器的IP地址,地址可以包含变量,
    特殊值等于none,它使用从连接请求行主机名解析的IP地址。

    注:如果使用set $<nginx variable>proxy_connect_address $<nginx variable> 同时,你应该使用proxy_connect_rewrite.patch,查看安装了解更多细节。

    proxy_connect_bind

    语法:proxy_connect_bind address_off >
    默认值:none
    上下文:server

    向代理服务器发出传出连接来自有可选端口的指定本地IP地址,
    参数值可以包含变量,特殊值等于none,这允许系统自动分配本地IP地址和端口。

    透明参数允许与代理服务器的传出连接来源于非本地IP地址,例如,从客户端的实际IP地址:

    
    proxy_connect_bind $remote_addr transparent;
    
    
    
    
    

    注:如果使用set $<nginx variable>proxy_connect_bind $<nginx variable> 同时,你应该使用proxy_connect_rewrite.patch,查看安装了解更多细节。

    变量

    $connect_host

    CONNECT请求行中的主机名。

    $connect_port

    来自CONNECT请求行的端口。

    $connect_addr

    远程主机的IP地址和端口,例如,"192.168.1.5:12345 ", IP地址从CONNECT请求行的主机名解析。

    Nginx兼容性

    最新的模块与以下版本的Nginx兼容:

    • 1.14.0(稳定版1.14 .x)
    • 1.12.1(稳定版1.12 .x)
    • 1.10.3(稳定版1.10 .x)
    • 1.8.1(稳定版1.8 .x)
    • 1.6.3(稳定版1.6 .x)
    • 1.4.7(稳定版1.4 .x)
    Tengine兼容性

    此模块将很快合并到Tengine中,请参阅this pull request,请求 。

    作者
    • 彭琦 :原始作者,他将此模块提供给了TEngine pull request ,
    • xiaochen Wang :当前维护者为Nginx重新构建此模块,
    许可证

    有关详细信息,请参阅LICENSE

    讨论
    Fansisi profile image