From 0a882454d203e62e18f55ed1d3d5b3790801169b Mon Sep 17 00:00:00 2001 From: BjornMagnussonXA Date: Thu, 10 Mar 2022 08:28:57 +0100 Subject: [PATCH] Fixes for proxies to work behind istio-proxies Issue-ID: NONRTRIC-728 Signed-off-by: BjornMagnussonXA Change-Id: I16e61111013bf60f1554bcfc7fb6d71eb7c9f44e --- test/common/httpproxy_api_functions.sh | 26 ++++++++++++--- test/common/kubeproxy_api_functions.sh | 15 +++++++++ test/common/testcase_common.sh | 41 +++++++++++++++++++++++ test/http-https-proxy/http_proxy.js | 59 ++++++++++++++++++++++++++++++---- 4 files changed, 130 insertions(+), 11 deletions(-) diff --git a/test/common/httpproxy_api_functions.sh b/test/common/httpproxy_api_functions.sh index e8052641..ce7fcada 100644 --- a/test/common/httpproxy_api_functions.sh +++ b/test/common/httpproxy_api_functions.sh @@ -130,14 +130,14 @@ __HTTPPROXY_test_requirements() { # args: - # (Function for test scripts) use_http_proxy_http() { - __http_proxy_set_protocoll "http" $HTTP_PROXY_INTERNAL_PORT $HTTP_PROXY_EXTERNAL_PORT + __http_proxy_set_protocoll "http" $HTTP_PROXY_INTERNAL_PORT $HTTP_PROXY_EXTERNAL_PORT $HTTP_PROXY_WEB_INTERNAL_PORT $HTTP_PROXY_WEB_EXTERNAL_PORT } # Set https as the protocol to use for all communication to the http proxy # args: - # (Function for test scripts) use_http_proxy_https() { - __http_proxy_set_protocoll "https" $HTTP_PROXY_INTERNAL_SECURE_PORT $HTTP_PROXY_EXTERNAL_SECURE_PORT + __http_proxy_set_protocoll "https" $HTTP_PROXY_INTERNAL_SECURE_PORT $HTTP_PROXY_EXTERNAL_SECURE_PORT $HTTP_PROXY_WEB_INTERNAL_SECURE_PORT $HTTP_PROXY_WEB_EXTERNAL_SECURE_PORT } # Setup paths to svc/container for internal and external access @@ -150,12 +150,14 @@ __http_proxy_set_protocoll() { ## HTTP_PROXY_CONFIG_HOST_NAME and HTTP_PROXY_CONFIG_PORT used by apps as config for proxy host and port HTTP_PROXY_SERVICE_PATH=$1"://"$HTTP_PROXY_APP_NAME":"$2 # docker access, container->container and script->container via proxy + HTTP_PROXY_WEB_PATH=$1"://"$HTTP_PROXY_APP_NAME":"$4 HTTP_PROXY_CONFIG_HOST_NAME=$HTTP_PROXY_APP_NAME HTTP_PROXY_CONFIG_PORT=$2 if [ $RUNMODE == "KUBE" ]; then HTTP_PROXY_CONFIG_HOST_NAME=$HTTP_PROXY_APP_NAME"."$KUBE_SIM_NAMESPACE HTTP_PROXY_CONFIG_PORT=$3 HTTP_PROXY_SERVICE_PATH=$1"://"$HTTP_PROXY_APP_NAME.$KUBE_SIM_NAMESPACE":"$3 # kube access, pod->svc and script->svc via proxy + HTTP_PROXY_WEB_PATH=$1"://"$HTTP_PROXY_APP_NAME.$KUBE_SIM_NAMESPACE":"$5 fi echo "" @@ -237,7 +239,7 @@ start_http_proxy() { fi - __check_service_start $HTTP_PROXY_APP_NAME $HTTP_PROXY_SERVICE_PATH$HTTP_PROXY_ALIVE_URL + __check_service_start $HTTP_PROXY_APP_NAME $HTTP_PROXY_WEB_PATH$HTTP_PROXY_ALIVE_URL else # Check if docker app shall be fully managed by the test script @@ -252,7 +254,23 @@ start_http_proxy() { __start_container $HTTP_PROXY_COMPOSE_DIR "" NODOCKERARGS 1 $HTTP_PROXY_APP_NAME - __check_service_start $HTTP_PROXY_APP_NAME $HTTP_PROXY_SERVICE_PATH$HTTP_PROXY_ALIVE_URL + __check_service_start $HTTP_PROXY_APP_NAME $HTTP_PROXY_WEB_PATH$HTTP_PROXY_ALIVE_URL fi echo "" } + +# Turn on debug logging in httpproxy +# args: - +# (Function for test scripts) +set_httpproxy_debug() { + echo -e $BOLD"Setting httpproxy debug logging"$EBOLD + curlString="$HTTP_PROXY_WEB_PATH/debug -X PUT" + result=$(__do_curl "$curlString") + if [ $? -ne 0 ]; then + __print_err "could not set debug logging" $@ + ((RES_CONF_FAIL++)) + return 1 + fi + echo "" + return 0 +} diff --git a/test/common/kubeproxy_api_functions.sh b/test/common/kubeproxy_api_functions.sh index 6448185b..120fbb6a 100644 --- a/test/common/kubeproxy_api_functions.sh +++ b/test/common/kubeproxy_api_functions.sh @@ -378,3 +378,18 @@ start_kube_proxy() { } +# Turn on debug logging in kubeproxy +# args: - +# (Function for test scripts) +set_kubeproxy_debug() { + echo -e $BOLD"Setting kubeproxy debug logging"$EBOLD + curlString="$KUBE_PROXY_WEB_PATH/debug -X PUT" + result=$(__do_curl_no_proxy "$curlString") + if [ $? -ne 0 ]; then + __print_err "could not set debug logging" $@ + ((RES_CONF_FAIL++)) + return 1 + fi + echo "" + return 0 +} diff --git a/test/common/testcase_common.sh b/test/common/testcase_common.sh index d16ee6ec..5ebc9d3a 100755 --- a/test/common/testcase_common.sh +++ b/test/common/testcase_common.sh @@ -2996,6 +2996,7 @@ store_logs() { ## Generic curl ############### # Generic curl function, assumes all 200-codes are ok +# Used proxy, set # args: # returns: or "" or ">"" # returns: The return code is 0 for ok and 1 for not ok @@ -3042,6 +3043,46 @@ __do_curl() { fi } +# Generic curl function, assumes all 200-codes are ok +# Uses no proxy, even if it is set +# args: +# returns: or "" or ">"" +# returns: The return code is 0 for ok and 1 for not ok +__do_curl_no_proxy() { + echo ${FUNCNAME[1]} "line: "${BASH_LINENO[1]} >> $HTTPLOG + curlString="curl -skw %{http_code} $@" + echo " CMD: $curlString" >> $HTTPLOG + res=$($curlString) + retcode=$? + echo " RESP: $res" >> $HTTPLOG + echo " RETCODE: $retcode" >> $HTTPLOG + if [ $retcode -ne 0 ]; then + echo "" + return 1 + fi + http_code="${res:${#res}-3}" + if [ ${#res} -eq 3 ]; then + if [ $http_code -lt 200 ] || [ $http_code -gt 299 ]; then + echo "" + return 1 + else + return 0 + fi + else + if [ $http_code -lt 200 ] || [ $http_code -gt 299 ]; then + echo "" + return 1 + fi + if [ $# -eq 2 ]; then + echo "${res:0:${#res}-3}" | xargs + else + echo "${res:0:${#res}-3}" + fi + + return 0 + fi +} + ####################################### ### Basic helper function for test cases ####################################### diff --git a/test/http-https-proxy/http_proxy.js b/test/http-https-proxy/http_proxy.js index 4a982856..0bab0523 100644 --- a/test/http-https-proxy/http_proxy.js +++ b/test/http-https-proxy/http_proxy.js @@ -38,6 +38,8 @@ const aliveporthttps = 8434; // Default https destination port const defaulthttpsport = "443"; +var debug = false; + // Certs etc for https const httpsoptions = { key: fs.readFileSync('cert/key.crt'), @@ -56,13 +58,34 @@ const stats = { function httpclientrequest(clientrequest, clientresponse) { stats['http-requests-initiated']++; - if (clientrequest.url == "/" ) { - console.log("Catch bad url in http request: "+clientrequest.url) + // Extract destination information + var crurl=clientrequest.url; + var crhost=clientrequest.headers['host']; + var crproto=clientrequest.headers['x-forwarded-proto']; + + if (debug) { + console.log("crurl: "+crurl) + console.log("crhost: "+crhost) + console.log("crproto: "+crproto) + } + + // If this server is running behind a proxy (like istio envoy proxy) then the 'clientrequest.url' + // only contains the path component (i.e /test ). The host name and port is included in the + // 'host' header and the protocol (http/https) is in the header 'x-forwarded-proto'. + // In case of istio - https to a pod over mTLS does not seem to work. Only http. + // Othewise, if no front proxy, the full url is included in the 'clientrequest.url' + if (crproto != undefined) { + crurl=crproto+"://"+crhost+crurl + if (debug) { + console.log(" Constructed ulr: "+crurl) + } + } else if (crurl.startsWith('/')) { + console.log("Catched bad url in http request: "+crurl) clientresponse.end(); return; } - // Extract destination information - const clientrequesturl = new URL(clientrequest.url); + + const clientrequesturl = new URL(crurl); var proxyrequestoptions = { 'host': clientrequesturl.hostname, @@ -111,7 +134,9 @@ function addhttpsconnect(httpserver) { 'connect', function (request, socketrequest, bodyhead) { - + if (debug) { + console.log("Received 'connect' for: "+request['url']) + } stats['https-requests-initiated']++; // Extract destination information var res = request['url'].split(":") @@ -166,8 +191,28 @@ function addhttpsconnect(httpserver) { function main() { // -------------------- Alive server ---------------------------------- - // Responde with '200' and statistics for any path on the alive address + // Responde with '200' and statistics for any path (except for GET|PUT|DELETE on /debug) on the alive address const alivelistener = function (req, res) { + if (req.url == "/debug") { + if (req.method == "GET") { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write(""+debug) + res.end() + return + } else if (req.method == "PUT") { + debug=true + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write("OK") + res.end() + return + } else if (req.method == "DELETE") { + debug=false + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write("OK") + res.end() + return + } + } console.log(stats) res.writeHead(200, { 'Content-Type': 'application/json' }); res.write(JSON.stringify(stats)) @@ -206,7 +251,7 @@ function main() { const proxyserverhttps = https.createServer(httpsoptions, httpclientrequest).listen(proxyporthttps); console.log('http/https proxy for https proxy calls on port ' + proxyporthttps); console.log(' example: curl --proxy-insecure --proxy https://localhost:8433 http://100.110.120.130:1234') - console.log(' example: curl --proxy-insecure --proxy https://localhost:8433 https://100.110.120.130:5678') + console.log(' example: curl -k --proxy-insecure --proxy https://localhost:8433 https://100.110.120.130:5678') // handle a https proxy request - https listener addhttpsconnect(proxyserverhttps); -- 2.16.6