From f03b8a055b7da3102bc7274ab4e58e50fc8d33e6 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Wed, 11 Feb 2026 21:40:11 +0000 Subject: [PATCH] [ci skip] Fix rewrite-body plugin corrupting compressed responses The packruler/rewrite-body plugin (used for rybbit analytics injection) fails to decompress gzip responses with "flate: corrupt input before offset 5", corrupting the response body. This broke HA Companion app's external_auth flow and WebSocket connections on ha-sofia. Fix: add a strip-accept-encoding middleware that removes Accept-Encoding from requests when rybbit is active, forcing backends to send uncompressed responses that the plugin can safely process. Also add extra_middlewares variable to reverse_proxy factory for extensibility. --- modules/kubernetes/ingress_factory/main.tf | 1 + .../kubernetes/reverse_proxy/factory/main.tf | 9 ++++++-- modules/kubernetes/traefik/middleware.tf | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/modules/kubernetes/ingress_factory/main.tf b/modules/kubernetes/ingress_factory/main.tf index 8d2ed134..311789e5 100644 --- a/modules/kubernetes/ingress_factory/main.tf +++ b/modules/kubernetes/ingress_factory/main.tf @@ -111,6 +111,7 @@ resource "kubernetes_ingress_v1" "proxied-ingress" { var.exclude_crowdsec ? null : "traefik-crowdsec@kubernetescrd", var.protected ? "traefik-authentik-forward-auth@kubernetescrd" : null, var.allow_local_access_only ? "traefik-local-only@kubernetescrd" : null, + var.rybbit_site_id != null ? "traefik-strip-accept-encoding@kubernetescrd" : null, var.rybbit_site_id != null ? "${var.namespace}-rybbit-analytics-${var.name}@kubernetescrd" : null, var.custom_content_security_policy != null ? "${var.namespace}-custom-csp-${var.name}@kubernetescrd" : null, ], var.extra_middlewares))) diff --git a/modules/kubernetes/reverse_proxy/factory/main.tf b/modules/kubernetes/reverse_proxy/factory/main.tf index 371b2d47..1af42844 100644 --- a/modules/kubernetes/reverse_proxy/factory/main.tf +++ b/modules/kubernetes/reverse_proxy/factory/main.tf @@ -37,6 +37,10 @@ variable "strip_auth_headers" { type = bool default = false } +variable "extra_middlewares" { + type = list(string) + default = [] +} resource "kubernetes_service" "proxied-service" { @@ -66,15 +70,16 @@ resource "kubernetes_ingress_v1" "proxied-ingress" { name = var.name namespace = var.namespace annotations = merge({ - "traefik.ingress.kubernetes.io/router.middlewares" = join(",", compact([ + "traefik.ingress.kubernetes.io/router.middlewares" = join(",", compact(concat([ "traefik-rate-limit@kubernetescrd", var.custom_content_security_policy == null ? "traefik-csp-headers@kubernetescrd" : null, "traefik-crowdsec@kubernetescrd", var.protected ? "traefik-authentik-forward-auth@kubernetescrd" : null, var.strip_auth_headers ? "traefik-strip-auth-headers@kubernetescrd" : null, + var.rybbit_site_id != null ? "traefik-strip-accept-encoding@kubernetescrd" : null, var.rybbit_site_id != null ? "${var.namespace}-rybbit-analytics-${var.name}@kubernetescrd" : null, var.custom_content_security_policy != null ? "${var.namespace}-custom-csp-${var.name}@kubernetescrd" : null, - ])) + ], var.extra_middlewares))) "traefik.ingress.kubernetes.io/router.entrypoints" = "websecure" "traefik.ingress.kubernetes.io/service.serversscheme" = var.backend_protocol == "HTTPS" ? "https" : null "traefik.ingress.kubernetes.io/service.serverstransport" = var.backend_protocol == "HTTPS" ? "traefik-insecure-skip-verify@kubernetescrd" : null diff --git a/modules/kubernetes/traefik/middleware.tf b/modules/kubernetes/traefik/middleware.tf index f9508429..caffd6a2 100644 --- a/modules/kubernetes/traefik/middleware.tf +++ b/modules/kubernetes/traefik/middleware.tf @@ -218,3 +218,26 @@ resource "kubernetes_manifest" "middleware_immich_rate_limit" { depends_on = [helm_release.traefik] } + +# Strip Accept-Encoding header so backends send uncompressed responses. +# Used alongside rewrite-body plugin (rybbit analytics) which fails to +# decompress certain gzip responses (flate: corrupt input before offset 5). +resource "kubernetes_manifest" "middleware_strip_accept_encoding" { + manifest = { + apiVersion = "traefik.io/v1alpha1" + kind = "Middleware" + metadata = { + name = "strip-accept-encoding" + namespace = kubernetes_namespace.traefik.metadata[0].name + } + spec = { + headers = { + customRequestHeaders = { + "Accept-Encoding" = "" + } + } + } + } + + depends_on = [helm_release.traefik] +}