From f70d4c6ca1a23390638a817cd4b1c264a6dba21f Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 8 Jul 2024 18:44:00 +1000 Subject: [PATCH] feat: support verification bypass on ingress --- README.md | 2 +- handlers/unidler/handler.go | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b049367..51e232a 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ To enable this functionality, set the following: - `--verify-secret=use-your-own-secret` or envvar `VERIFY_SECRET=use-your-own-secret` If the verification feature is enabled, and you need to unidle environments using tools that can't execute javascript, then it is possible to allow a namespace to override the feature by adding the following annotation to the namespace. Using the other allow/blocking mechanisms can then be used to restrict how the environment can unidle if required. -* `idling.amazee.io/disable-request-verification=true` - set this to disable the hmac verification on a namespace if Aergia has unidling request verification turned on. +* `idling.amazee.io/disable-request-verification=true` - set this to disable the hmac verification on a namespace if Aergia has unidling request verification turned on. This annotation is also supported on an ingress too, so that specific ingress can skip the verification requests. If you're using custom template overrides and enable this functionality, you will need to extend your `unidle.html` template with the additional changes to allow it to to perform the call back function or else environments will never unidle. See the bundled `unidle.html` file to see how this may differ from your custom templates. diff --git a/handlers/unidler/handler.go b/handlers/unidler/handler.go index c179910..02ed84b 100644 --- a/handlers/unidler/handler.go +++ b/handlers/unidler/handler.go @@ -70,8 +70,6 @@ func (h *Unidler) ingressHandler(path string) func(http.ResponseWriter, *http.Re opLog.Info(fmt.Sprintf("unable to get any namespaces: %v", err)) return } - // if hmac verification is enabled, perform the verification of the request - signedNamespace, verfied := h.verifyRequest(r, namespace) ingress := &networkv1.Ingress{} if err := h.Client.Get(ctx, types.NamespacedName{ Namespace: ns, @@ -82,6 +80,8 @@ func (h *Unidler) ingressHandler(path string) func(http.ResponseWriter, *http.Re h.setMetrics(r, start) return } + // if hmac verification is enabled, perform the verification of the request + signedNamespace, verfied := h.verifyRequest(r, namespace, ingress) xForwardedFor := strings.Split(r.Header.Get("X-Forwarded-For"), ",") trueClientIP := r.Header.Get("True-Client-IP") @@ -180,13 +180,21 @@ func (h *Unidler) genericError(w http.ResponseWriter, r *http.Request, opLog log } // handle verifying the namespace name is signed by our secret -func (h *Unidler) verifyRequest(r *http.Request, ns *corev1.Namespace) (string, bool) { +func (h *Unidler) verifyRequest(r *http.Request, ns *corev1.Namespace, ingress *networkv1.Ingress) (string, bool) { if h.VerifiedUnidling { + if val, ok := ingress.ObjectMeta.Annotations["idling.amazee.io/disable-request-verification"]; ok { + t, _ := strconv.ParseBool(val) + if t { + return "", true + } + // otherwise fall through to namespace check + } if val, ok := ns.ObjectMeta.Annotations["idling.amazee.io/disable-request-verification"]; ok { t, _ := strconv.ParseBool(val) - if t == true { + if t { return "", true } + // fall through to verify the request } // if hmac verification is enabled, perform the verification of the request signedNamespace := hmacSigner(ns.Name, []byte(h.VerifiedSecret))