From 573a070db03402470ca1375ae0531a2b3b9c0b17 Mon Sep 17 00:00:00 2001 From: An Tran Date: Thu, 27 Jun 2024 11:08:40 +1000 Subject: [PATCH] Prevent APIcast fallback to global proxy settings for direct connection With the newer version of lua-resty-http (0.7.1), if a proxy options is not provided when calling the connect() method, it will fall back to using the global proxy settings set by the "set_proxy_option" function (has no effect in previous versions of the library). This then causes unexpected behavior where the direct connection will now go through the proxy server. This PR explicitly sets the proxy options to an empty table to bypass global proxy settings when connecting directly. --- CHANGELOG.md | 6 +++++ gateway/src/resty/http/proxy.lua | 5 +++- t/http-proxy.t | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1236f9e25..8c219375c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed + +### Added + ## [3.15.0] 2024-04-04 ### Fixed @@ -49,6 +53,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Disable \_G write guard warning [PR #1454](https://github.com/3scale/APIcast/pull/1454) +- Fixed APIcast send request through proxy server even when `NO_PROXY` is used [PR #1478](https://github.com/3scale/APIcast/pull/1478) [THREESCALE-11128](https://issues.redhat.com/browse/THREESCALE-11128) + ### Added - Detect number of CPU shares when running on Cgroups V2 [PR #1410](https://github.com/3scale/apicast/pull/1410) [THREESCALE-10167](https://issues.redhat.com/browse/THREESCALE-10167) diff --git a/gateway/src/resty/http/proxy.lua b/gateway/src/resty/http/proxy.lua index 40ea28c88..637ed0e3e 100644 --- a/gateway/src/resty/http/proxy.lua +++ b/gateway/src/resty/http/proxy.lua @@ -57,10 +57,13 @@ local function connect(request) -- openresty treat nil as false, so we need to explicitly set ssl_verify to false if nil local ssl_verify = request.options and request.options.ssl and request.options.ssl.verify or false + -- We need to set proxy_opts to an empty table here otherwise, lua-resty-http will fallback + -- to the global proxy options local options = { scheme = scheme, host = host, - port = port + port = port, + proxy_opts = {} } if scheme == 'https' then options.ssl_server_name = host diff --git a/t/http-proxy.t b/t/http-proxy.t index de623f152..0e57c1010 100644 --- a/t/http-proxy.t +++ b/t/http-proxy.t @@ -2083,3 +2083,46 @@ qr/a client request body is buffered to a temporary file/ --- grep_error_log_out a client request body is buffered to a temporary file --- user_files fixture=tls.pl eval + + + +=== TEST 36: APIcast should not ingore NO_PROXY, when HTTP_PROXY and HTTPS_PROXY are also set +It connects directly to backened and forwards request to the upstream via proxy. +--- env random_port eval +( + 'http_proxy' => $ENV{TEST_NGINX_HTTP_PROXY}, + 'no_proxy' => '127.0.0.1,localhost,test_backend', +) +--- configuration +{ + "services": [ + { + "id": 42, + "backend_version": 1, + "proxy": { + "api_backend": "http://test-upstream.lvh.me:$TEST_NGINX_SERVER_PORT/", + "proxy_rules": [ + { "pattern": "/", "http_method": "GET", "metric_system_name": "hits", "delta": 2 } + ] + } + } + ] +} +--- backend + server_name test_backend.lvh.me; + location /transactions/authrep.xml { + content_by_lua_block { + ngx.exit(ngx.OK) + } + } +--- upstream + server_name test-upstream.lvh.me; + location / { + echo 'yay, api backend: $http_host'; + } +--- request +GET /?user_key=value +--- response_body env +yay, api backend: test-upstream.lvh.me:$TEST_NGINX_SERVER_PORT +--- error_code: 200 +--- no_error_log