chobits / ngx_http_proxy_connect_module

A forward proxy module for CONNECT request handling
BSD 2-Clause "Simplified" License
1.84k stars 498 forks source link

How to proxy requests to http servers that hosted by same nginx #296

Open chen-chao opened 10 months ago

chen-chao commented 10 months ago

Hi, I've been using the module for almost one week and it works quite well. Thanks for the good job!

But there's one use case that I'm concerned: the request to the other http servers that hosted by the same nginx cannot be proxied. So I'm here to seek help for any workaround.

Repro steps:

  1. Run nginx (built with this module) with nginx.conf that has multiple http servers (distinguished by the host field):
    
    user  nginx;
    worker_processes  auto;

http {

http directives are omitted...

server { listen 443 ssl; listen [::]:443 ssl; server_name proxy.example.com;

    # ...SSL settings are omitted...

    resolver 1.1.1.1 ipv6=off;
    proxy_connect;
    proxy_connect_allow            443 563;
    proxy_connect_connect_timeout  10s;
    proxy_connect_data_timeout     10s;

    location / {
        return 403 "Non-CONNECT requests are forbidden";
    }

}

server { listen 443 ssl; listen [::]:443 ssl; server_name app.example.com;

    # ...SSL settings are omitted...

    keepalive_timeout 70;

    location / {
        proxy_pass http://app.internal.site
    }

} }

2. Use `curl` to send request `app.example.com` via `proxy.example.com`: `curl -v -L -x https://proxy.example.com https://app.example.com`.

```log
*   Trying <redacted-ip>:443...
* Connected to (nil) (<redacted-ip>) port 443 (#0)
* <redacted-ssl-handshake>
* allocate connect buffer!
* Establish HTTP proxy tunnel to app.example.com:443
* <redacted-ssl-handshake>
> CONNECT app.example.com:443 HTTP/1.1
> Host: app.example.com:443    <-- Host is `app.example.com`!
> User-Agent: curl/7.81.0
> Proxy-Connection: Keep-Alive
* <redacted-ssl-handshake>
< HTTP/1.1 405 Not Allowed
< Server: nginx/1.24.0
< Date: <redacted>
< Content-Type: text/html
< Content-Length: 157
< Connection: keep-alive
<
* Received HTTP code 405 from proxy after CONNECT
* CONNECT phase completed!
* Closing connection 0
* <redacted-ssl-handshake>
curl: (56) Received HTTP code 405 from proxy after CONNECT

I guess nginx dispatches the subsequent request CONNECT app.example.com:443 HTTP/1.1 to server app.example.com, according to the Host field. The other server doesn't have the proxy_connect directive hence raise a 405 for the connection.

Is there any workaround to overcome this?

chobits commented 8 months ago

I guess nginx dispatches the subsequent request CONNECT app.example.com:443 HTTP/1.1 to server app.example.com, according to the Host field. The other server doesn't have the proxy_connect directive hence raise a 405 for the connection.

It seems as what you guessed here, but I'm not sure. I need some time to figure it out. Or you can enable and check the nginx debug log with your configuration.