Skip to content
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

proxy_connect ignoring location blocks #318

Open
markgargan opened this issue Aug 8, 2024 · 5 comments
Open

proxy_connect ignoring location blocks #318

markgargan opened this issue Aug 8, 2024 · 5 comments

Comments

@markgargan
Copy link

0. Before Your ASK

  1. Try to find an answer by reading a FAQ.

Ⅰ. Issue Description

I've tried the following configuration as provided in the README.md

server {
    listen                         3128;

    # dns resolver used by forward proxying
    resolver                       8.8.8.8;

    # forward proxy for CONNECT requests
    proxy_connect;
    proxy_connect_allow            443 563;
    proxy_connect_connect_timeout  10s;
    proxy_connect_data_timeout     10s;

    # defined by yourself for non-CONNECT requests
    # Example: reverse proxy for non-CONNECT requests
    location / {
         return 403 "Non-CONNECT requests are forbidden";
    }
}

fully expecting proxy_connect to handle the CONNECT and then the location block to then reject the GET with a 403.

curl --proxy http://localhost:8889 https://kong.mycomp.com:8445

Ⅱ. Describe what happened

The GET request succeeds returning the HTML.

Ⅲ. Describe what you expected to happen

The GET request should return a 403 from the proxy

Ⅳ. How to reproduce it (as minimally and precisely as possible)

I'm building nginx in a docker RHEL8 container using

RUN wget https://nginx.com/download/nginx-1.20.1.tar.gz
&& tar -zxvf nginx-1.20.1.tar.gz
&& cd nginx-1.20.1
&& git clone https://github.com/openresty/echo-nginx-module.git
&& git clone https://github.com/chobits/ngx_http_proxy_connect_module.git
&& patch -p1 < ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_1018.patch
&& ./configure --add-module=./ngx_http_proxy_connect_module --add-module=./echo-nginx-module
&& make
&& make install

Ⅴ. Anything else we need to know?

  1. If applicable, add nginx debug log.

Ⅵ. Environment:

Nginx with the echo-nginx-module and ngx_http_proxy_connect_module

  1. Tengine/Nginx/OpenResty version (use sbin/nginx -v):
  2. Which patch do you use?
@markgargan
Copy link
Author

2 weeks since this bug in the readme was highlighted? Any ideas @chobits ?

@andarg
Copy link

andarg commented Sep 7, 2024

same issue

@chobits
Copy link
Owner

chobits commented Sep 8, 2024

When you run this command curl --proxy http://localhost:8889 https://kong.mycomp.com:8445, the curl command will establish a CONNECT tunnel to your localhost 's port 8889, then all the data sent by curl will be handled by proxy_connect module, proxy_connect will not process the internal data flow inside the CONNECT tunnel, it just proxied it to the backend destination kong.mycomp.com:8445. So the localtion / { return 403 .. } will not work for this CONNECT data flow.

So what you observed is as expected.

  • curl command:
$ curl --proxy localhost:8889 https://kong.mycomp.com:8445 -sv
*   Trying [::1]:8889...
* connect to ::1 port 8889 failed: Connection refused
*   Trying 127.0.0.1:8889...
* Connected to localhost (127.0.0.1) port 8889
* CONNECT tunnel: HTTP/1.1 negotiated
* allocate connect buffer
* Establish HTTP proxy tunnel to kong.mycomp.com:8445
> CONNECT kong.mycomp.com:8445 HTTP/1.1
> Host: kong.mycomp.com:8445
> User-Agent: curl/8.4.0
> Proxy-Connection: Keep-Alive
>
...
  • simulated local nginx+proxy_connect server that listened on port :8889
$ nc -l 8889
CONNECT kong.mycomp.com:8445 HTTP/1.1
Host: kong.mycomp.com:8445
User-Agent: curl/8.4.0
Proxy-Connection: Keep-Alive

^------- then proxy_connect will handle this tcp connection and its internal data flow includeing 
CONNECT request and the following SSL requests, so `location / { return 403 ...}` block 
will not work for this scenario.

@markgargan
Copy link
Author

Thanks a lot for getting back to us @chobits. I guess what myself and I believe @andarg may be trying as well is to create a form of MITM forwarding proxy. In fiddler there is an autoresponder tab that allows you to intercept calls coming through fiddler and return different responses for application coding testing and chaos testing. So instead of going to the real host it would intercept the call and return say a 400 or a 502 for the gateway being down. Also it can introduce delays which Id hoped to achieve using the echo module in nginx.

It appears the problem you have solved is that up until this point nginx couldn't handle CONNECT requests? The Get and Post sent through a CONNECT tunnel isn't interceptible? Am I right in saying that?

The 'location /' block you've provided that returns the 403 is only for GET POST requests that weren't established with a CONNECT request first. They don't go down the CONNECT tunnel.

Thanks
Mark.

@chobits
Copy link
Owner

chobits commented Sep 9, 2024

It appears the problem you have solved is that up until this point nginx couldn't handle CONNECT requests? The Get and Post sent through a CONNECT tunnel isn't interceptible? Am I right in saying that?

Yes. Because The design of the CONNECT tunnel protocol is overly simple, as the proxy server cannot obtain information beyond the destination address. Therefore, it cannot determine what protocol the data stream is using unless the server makes a guess. Moreover, if it’s SSL traffic, the server cannot decrypt it without the private key of the destination address.

The 'location /' block you've provided that returns the 403 is only for GET POST requests that weren't established with a CONNECT request first. They don't go down the CONNECT tunnel.

Yes. This location / block is reserved for users to define by theirselves to handle the HTTP requests that are not inside the tunnel.

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

No branches or pull requests

3 participants