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

Encounter a strange issue when using rewrite_by_lua_block to authoriacate connect request. #264

Open
lifei opened this issue May 9, 2023 · 3 comments

Comments

@lifei
Copy link

lifei commented May 9, 2023

Dear developer,

I am using ngx_http_proxy_connect_module to proxy requests from https to http server. However, I encountered a strange issue that lacks logic and I hope you can take a deep look into it and investigate the possible reasons and solutions.

The symptom of the problem is that

  1. the following code is not work
    rewrite_by_lua_block {
        if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
            ngx.status = ngx.HTTP_FORBIDDEN
        end
    }

i had hoped that i would get a 403. but what i got is good request.
"CONNECT www.google.com:443 HTTP/1.1" 200 22173 "-" "curl/7.74.0" "-"
2. the following code is not work

    rewrite_by_lua_block {
        if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
            ngx.var.proxy_connect_response = string.format("HTTP/1.1 403 Forbidden\\r\\nServer: openresty/%sP\\r\\n\\r\\n", ngx.var.nginx_version)
        end
    }

i had hoped that i would get a 403. but i got 200 without html body and hanging.
3. the following code is not work

    rewrite_by_lua_block {
        if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
            ngx.say("<h1>PROXY WAS DISABLED IN THIS SITE, PLEASE DO NOT TRY!</h1>")
            ngx.exit(403)
        end
    }

i had hoped that i would get a 403. but i got 200 without html body and not hanging.

i found some code is good:
1.

    rewrite_by_lua_block {
        if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
            ngx.status = ngx.HTTP_FORBIDDEN
            ngx.say("<h1>PROXY WAS DISABLED IN THIS SITE, PLEASE DO NOT TRY!</h1>")
        end
    }
    rewrite_by_lua_block {
        if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
            ngx.exit(403)
        end
    }

but i can not set html body for them.

I have tried to investigate this issue myself but I failed to find any clue about it. I wonder if you could provide some guidance on how to debug this issue, or if there is any configuration or parameter I should set to prevent this issue from happening again.

Thank you very much for your help in advance.

Best regards,

L. Fee

@chobits
Copy link
Owner

chobits commented May 12, 2023

For the cases of (1.), if proxy_connect module is enabled to handle the CONNECT request, the response of CONNECT request will be generated individually by this module, skipping the nginx output header / response filter. As a result, you cannot modify the response via the nginx header/response filter module, such as ngx.status primitive of the ngx-lua-module.

However there is an exception for nginx REWRITE module including return directive or ngx.exit of the ngx-lua-module. The rewrite module can work before proxy_connect module. For example of my test case: https://github.com/chobits/ngx_http_proxy_connect_module/blob/master/t/http_proxy_connect.t#L323

        if ($host = "get-default-response.com") {
            return 403;
        }

or return response directly in lua-nginx-module rewrite phase

        rewrite_by_lua_block {
            if ngx.var.request_method == "CONNECT" then
               ngx.exit(402)
            end
        }

@chobits
Copy link
Owner

chobits commented May 12, 2023

For case (2.), pls ensure you are correctly encapsulating the HTTP response. The code you provided is incorrect and should be replaced with \r\n instead of \\r\\n.

  • your orignal code
ngx.var.proxy_connect_response = string.format("HTTP/1.1 403 Forbidden\\r\\nServer: openresty/%sP\\r\\n\\r\\n", ngx.var.nginx_version)
  • right code

image


After debugging your original code, I found that the response was invalid, see the following tcpdump log

image


log of my debugging with righ lua code

    server {
        listen 8888;
        resolver 223.5.5.5;
        proxy_connect;
        proxy_connect_allow 443 563;
        proxy_connect_connect_timeout 10s;
        proxy_connect_read_timeout 100ms;
        proxy_connect_send_timeout 10s;
#access_log logs/host.access.log main;
#proxy_ignore_client_abort on;
        client_body_timeout 3600s;

        proxy_read_timeout 10ms;

        ## rewrite_by_lua_block {
        ## if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
        ##     ngx.var.proxy_connect_response = "HTTP/1.1 200 CE\r\n\r\n"
        ##     ngx.status = ngx.HTTP_FORBIDDEN
        ## end
        ## }
        rewrite_by_lua_block {
        if ngx.var.request_method == "CONNECT" and ngx.var.http_proxy_authorization ~= "Basic XXXXXXXXXXXXXXXXX" then
            ngx.var.proxy_connect_response = string.format("HTTP/1.1 403 Forbidden\r\nServer: openresty/%sP\r\n\r\n", ngx.var.nginx_version)
        end
    }
  • testing
xc output $ curl https://baidu.com -x localhost:8888 -sv -o /dev/null
*   Trying 127.0.0.1:8888...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8888 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to baidu.com:443
> CONNECT baidu.com:443 HTTP/1.1
> Host: baidu.com:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 403 Forbidden
< Server: openresty/1.22.1P
<
* Received HTTP code 403 from proxy after CONNECT
* CONNECT phase completed!
* Closing connection 0
  • tcpdump log:
xc output $ sudo tcpdump -i any -n -A port 8888
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
19:30:27.261926 IP 127.0.0.1.46474 > 127.0.0.1.8888: Flags [S], seq 587633994, win 65495, options [mss 65495,sackOK,TS val 200265004 ecr 0,nop,wscale 7], length 0
E..<.B@[email protected]..........".#..J.........0.........
...,........
19:30:27.261934 IP 127.0.0.1.8888 > 127.0.0.1.46474: Flags [S.], seq 1754985367, ack 587633995, win 65483, options [mss 65495,sackOK,TS val 200265004 ecr 200265004,nop,wscale 7], length 0
E..<..@.@.<........."...h...#..K.....0.........
...,...,....
19:30:27.261942 IP 127.0.0.1.46474 > 127.0.0.1.8888: Flags [.], ack 1, win 512, options [nop,nop,TS val 200265004 ecr 200265004], length 0
E..4.C@.@..~..........".#..Kh........(.....
...,...,
19:30:27.261996 IP 127.0.0.1.46474 > 127.0.0.1.8888: Flags [P.], seq 1:111, ack 1, win 512, options [nop,nop,TS val 200265004 ecr 200265004], length 110
E....D@.@.............".#..Kh..............
...,...,CONNECT baidu.com:443 HTTP/1.1
Host: baidu.com:443
User-Agent: curl/7.68.0
Proxy-Connection: Keep-Alive


19:30:27.296154 IP 127.0.0.1.8888 > 127.0.0.1.46474: Flags [P.], seq 1:54, ack 111, win 512, options [nop,nop,TS val 200265038 ecr 200265004], length 53
E..i!.@.@..........."...h...#........].....
...N...,HTTP/1.1 403 Forbidden
Server: openresty/1.22.1P


1

@chobits
Copy link
Owner

chobits commented May 12, 2023

And also note that if the proxy_connect module fails to resolve the proxied backend (DNS resolve), you may receive a 503 status code as a response. In such cases, the $proxy_connect_response configuration will be ignored.

To see my test for a non-existent proxied backend domain, please refer to the following.

image

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

2 participants