From 8c5fe95578614563e8d5905bb9cdecc299f32473 Mon Sep 17 00:00:00 2001 From: Ricardo Katz Date: Sun, 10 Sep 2023 23:18:08 +0000 Subject: [PATCH] Make it work with and without proxy protocol --- .../ingress/controller/template/template.go | 4 +- rootfs/etc/nginx/njs/passthrough.js | 69 ++++++++++++++----- rootfs/etc/nginx/template/nginx.tmpl | 9 +++ 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 31d46b279..8b10e5829 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -1555,9 +1555,9 @@ func httpsListener(addresses []string, co string, tc *config.TemplateConfig) []s lo = append(lo, fmt.Sprintf("%v:%v", address, tc.ListenPorts.SSLProxy)) } - if !strings.Contains(co, "proxy_protocol") { + /*if !strings.Contains(co, "proxy_protocol") { lo = append(lo, "proxy_protocol") - } + }*/ } else { if address == "" { lo = append(lo, fmt.Sprintf("%v", tc.ListenPorts.HTTPS)) diff --git a/rootfs/etc/nginx/njs/passthrough.js b/rootfs/etc/nginx/njs/passthrough.js index c2e367937..9239a8637 100644 --- a/rootfs/etc/nginx/njs/passthrough.js +++ b/rootfs/etc/nginx/njs/passthrough.js @@ -76,7 +76,7 @@ function configureWithData(configdata, s) { s.warn(`endpoint of ${key} is not string, skipping`) return; } - backends[key] = serviceitem.endpoint; + backends[key] = serviceitem; }); // Clear method is not working, we should verify with NGX folks @@ -90,30 +90,61 @@ function configureWithData(configdata, s) { } } +const PROXYSOCKET="unix:/var/run/nginxstreamproxy.sock"; // getBackend fetches the backend given a hostname sent via SNI function getBackend(s) { try { - var hostname = s.variables.ssl_preread_server_name; - if (hostname == null || hostname == "undefined" || hostname == "") { - throw("hostname was not provided") + const backendCfg = getBackendEndpoint(s); + if(backendCfg[1]) { + return PROXYSOCKET } - let backends = ngx.shared.ptbackends.get(KEYNAME) - if (backends == null || backends == "") { - throw('no entry on endpoint map') - } - const backendmap = JSON.parse(backends) - s.warn(JSON.stringify(backendmap)) - if (backendmap[hostname] == null || backendmap[hostname] == undefined) { - throw `no endpoint is configured for service ${hostname}"` - } - - return backendmap[hostname] - - } catch (e) { + return backendCfg[0] + } catch(e) { s.warn(`error occurred while getting the backend ` + - `sending to default backend: ${e}`) + `sending to default backend: ${e}`) + return "127.0.0.1:442" } } -export default {getConfigStatus, configBackends, getBackend}; +// getProxiedBackend fetches the backend given a hostname sent via SNI, to be used by proxy_protocol endpoint. +// An error here should be a final error +function getProxiedBackend(s) { + try { + const backend = getBackendEndpoint(s)[0]; + return backend; + + } catch(e) { + s.warn(`error occurred while getting the backend ` + + `sending to default backend: ${e}`) + s.deny() + } +} + +// getBackendEndpoint is the common function to return the endpoint and optinally if it should +// use proxy_protocol from the map +function getBackendEndpoint(s) { + var hostname = s.variables.ssl_preread_server_name; + if (hostname == null || hostname == "undefined" || hostname == "") { + throw("hostname was not provided") + } + + let backends = ngx.shared.ptbackends.get(KEYNAME) + if (backends == null || backends == "") { + throw('no entry on endpoint map') + } + const backendmap = JSON.parse(backends) + if (backendmap[hostname] == null || backendmap[hostname] == undefined || + backendmap[hostname].endpoint == null || backendmap[hostname].endpoint == undefined) { + throw `no endpoint is configured for service ${hostname}"` + } + + var isProxy = false + if (typeof backendmap[hostname].use_proxy == "boolean" && backendmap[hostname].use_proxy) { + isProxy = backendmap[hostname].use_proxy + } + + return [backendmap[hostname].endpoint, isProxy]; +} + +export default {getConfigStatus, configBackends, getBackend, getProxiedBackend}; diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 5803725bf..68a6c8323 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -848,6 +848,15 @@ stream { return $cfgreturn; } {{ if and $all.IsSSLPassthroughEnabled }} + # This server is here just for proxy protocol enabled passthroughs + server { + ssl_preread on; + listen unix:/var/run/nginxstreamproxy.sock; + js_set $proxyupstream passthrough.getProxiedBackend; + proxy_pass $proxyupstream; + proxy_protocol on; + } + server { # TODO: Remove Hardcode listen 443;