Fixes for proxies to work behind istio-proxies 19/7919/1
authorBjornMagnussonXA <bjorn.magnusson@est.tech>
Thu, 10 Mar 2022 07:28:57 +0000 (08:28 +0100)
committerBjornMagnussonXA <bjorn.magnusson@est.tech>
Thu, 10 Mar 2022 07:29:08 +0000 (08:29 +0100)
Issue-ID: NONRTRIC-728
Signed-off-by: BjornMagnussonXA <bjorn.magnusson@est.tech>
Change-Id: I16e61111013bf60f1554bcfc7fb6d71eb7c9f44e

test/common/httpproxy_api_functions.sh
test/common/kubeproxy_api_functions.sh
test/common/testcase_common.sh
test/http-https-proxy/http_proxy.js

index e805264..ce7fcad 100644 (file)
@@ -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
+}
index 6448185..120fbb6 100644 (file)
@@ -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
+}
index d16ee6e..5ebc9d3 100755 (executable)
@@ -2996,6 +2996,7 @@ store_logs() {
 ## Generic curl
 ###############
 # Generic curl function, assumes all 200-codes are ok
+# Used proxy, set
 # args: <valid-curl-args-including full url>
 # returns: <returned response (without respose code)>  or "<no-response-from-server>" or "<not found, <http-code>>""
 # 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: <valid-curl-args-including full url>
+# returns: <returned response (without respose code)>  or "<no-response-from-server>" or "<not found, <http-code>>""
+# 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 "<no-response-from-server>"
+               return 1
+       fi
+       http_code="${res:${#res}-3}"
+       if [ ${#res} -eq 3 ]; then
+               if [ $http_code -lt 200 ] || [ $http_code -gt 299 ]; then
+                       echo "<no-response-from-server>"
+                       return 1
+               else
+                       return 0
+               fi
+       else
+               if [ $http_code -lt 200 ] || [ $http_code -gt 299 ]; then
+                       echo "<not found, resp:${http_code}>"
+                       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
 #######################################
index 4a98285..0bab052 100644 (file)
@@ -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);