8000 HTTP CONNECT proxy. by arut · Pull Request #707 · nginx/nginx · GitHub
[go: up one dir, main page]

Skip to content

HTTP CONNECT proxy. #707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

HTTP CONNECT proxy. #707

wants to merge 1 commit into from

Conversation

arut
Copy link
Contributor
@arut arut commented May 25, 2025

HTTP CONNECT method is now supported in HTTP/1 connections. It's disabled in all currently existing standard modules. A new variable $port is added that contains the port passed by client in HTTP CONNECT. The $host variable contains the host part.

A new module ngx_http_tunnel module is added which establishes a tunnel to a backend. It supports the newly added HTTP CONNECT method and can be used to set up an HTTP CONNECT proxy.

As recommended by RFC 9110, proxy target should be restricted to ensure safe proxying:

: Proxies that support CONNECT SHOULD restrict its use to a limited set : of known ports or a configurable list of safe request targets.

Example config:

    server {
        listen 8000;

        resolver dns.example.com;

        map $port $tun_port {
            80             1;
            443            1;
        }

        map $host $tun_host {
            hostnames;

            example.com    1;
            *.example.org  1;
        }

        map $tun_port$tun_host $tun {
            11             $host:$port;
        }

        location / {
            tunnel_pass $tun;
        }
    }

Request:

    $ curl -px 127.0.0.1:8000 http://example.com

@jo-carter
Copy link
jo-carter commented May 25, 2025

@arut should limit_except be adjusted to include CONNECT, as part of this changeset?

Also was performing virtual server lookup using the destination's host/ip component intended?

HTTP CONNECT method is now supported in HTTP/1 connections.  It's disabled
in all currently existing standard modules.  A new variable $port is added
that contains the port passed by client in HTTP CONNECT.  The $host
variable contains the host part.

A new module ngx_http_tunnel module is added which establishes a tunnel
to a backend.  It supports the newly added HTTP CONNECT method and can be
used to set up an HTTP CONNECT proxy.

As recommended by RFC 9110, proxy target should be restricted to ensure
safe proxying:

: Proxies that support CONNECT SHOULD restrict its use to a limited set
: of known ports or a configurable list of safe request targets.

Example config:

    server {
        listen 8000;

        resolver dns.example.com;

        map $port $tun_port {
            80             1;
            443            1;
        }

        map $host $tun_host {
            hostnames;

            example.com    1;
            *.example.org  1;
        }

        map $tun_port$tun_host $tun {
            11             $host:$port;
        }

        location / {
            tunnel_pass $tun;
        }
    }

Request:

    $ curl -px 127.0.0.1:8000 http://example.com
@arut
Copy link
Contributor Author
arut commented May 25, 2025

@arut should limit_except be adjusted to include CONNECT, as part of this changeset?

Yes, thanks. Added.

Also was performing virtual server lookup using the destination's host/ip component intended?

I thought about disabling the lookup for CONNECT completely. However it's just more code, and it seems like there's actually a use case for that, which is to restrict proxying to a predefined set of hosts. And it's not host+ip, it's just host, as usual.

An example which restricts proxying to just 2 servers (port 80 hardcoded). More server-specific settings can be added.

    server {                                                                     
        listen 8000;
        return 502;
    }

    server {                                                                     
        listen 8000;                                                                                                                       
        server_name nginx.com;                                                      
                                                          
A84E
                       
        location / {                                                             
            tunnel_pass nginx.com:80;                                               
        }                                                                        
    } 
    server {                                                                     
        listen 8000;                                                                                                                                     
        server_name f5.com;                                                      
                                                                                 
        location / {                                                             
            tunnel_pass f5.com:80;                                               
        }                                                                        
    } 

@nginx-discourse-bot
Copy link

This pull request has been mentioned on NGINX Community Forum. There might be relevant details there:

https://community.nginx.org/t/web-client-nginx-proxy-server-target-web-server/5100/2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0