From bbed20813aceed107f82f8d45fdd4e3628badf8e Mon Sep 17 00:00:00 2001 From: "Adrian A. Baumann" Date: Wed, 28 Jan 2026 08:55:19 +0100 Subject: [PATCH] Forward proxying and suppression of health checks in access logs --- argocd/configmap.yaml | 1 + argocd/deployment.yaml | 5 ++++ gunicorn.conf.py | 65 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 gunicorn.conf.py diff --git a/argocd/configmap.yaml b/argocd/configmap.yaml index 61dbbf0..a6f08ee 100644 --- a/argocd/configmap.yaml +++ b/argocd/configmap.yaml @@ -17,5 +17,6 @@ data: LOGIN_URL: "login" LOGIN_REDIRECT_URL: "index" LOGOUT_REDIRECT_URL: "login" + TRUSTED_PROXIES: "192.168.17.44,192.168.17.53" GUNICORN_OPTS: "--access-logfile -" IMAGE_TAG: "0.068" diff --git a/argocd/deployment.yaml b/argocd/deployment.yaml index 19b37fe..5e79294 100644 --- a/argocd/deployment.yaml +++ b/argocd/deployment.yaml @@ -102,6 +102,11 @@ spec: configMapKeyRef: name: django-config key: LOGOUT_REDIRECT_URL + - name: TRUSTED_PROXIES + valueFrom: + configMapKeyRef: + name: django-config + key: TRUSTED_PROXIES - name: GUNICORN_OPTS valueFrom: configMapKeyRef: diff --git a/gunicorn.conf.py b/gunicorn.conf.py new file mode 100644 index 0000000..de9a64a --- /dev/null +++ b/gunicorn.conf.py @@ -0,0 +1,65 @@ +import logging +import os + +from gunicorn.glogging import Logger + +TRUSTED_PROXIES = { + ip.strip() + for ip in os.environ.get("TRUSTED_PROXIES", "").split(",") + if ip.strip() +} + + +class HealthCheckFilter(logging.Filter): + def filter(self, record): + message = record.getMessage() + return "kube-probe" not in message + + +class CustomLogger(Logger): + def atoms(self, resp, req, environ, request_time): + atoms = super().atoms(resp, req, environ, request_time) + atoms["{client-ip}e"] = self._get_client_ip(environ) + return atoms + + @staticmethod + def _get_client_ip(environ): + remote_addr = environ.get("REMOTE_ADDR", "-") + xff = environ.get("HTTP_X_FORWARDED_FOR", "") + if not xff: + return remote_addr + # Walk the chain from right to left, skipping trusted proxies + ips = [ip.strip() for ip in xff.split(",")] + for ip in reversed(ips): + if ip not in TRUSTED_PROXIES: + return ip + # All IPs in the chain are trusted; fall back to the leftmost + return ips[0] + + +logger_class = CustomLogger +access_log_format = '%({client-ip}e)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' + +logconfig_dict = { + "version": 1, + "disable_existing_loggers": False, + "filters": { + "health_check": { + "()": HealthCheckFilter, + }, + }, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "filters": ["health_check"], + "stream": "ext://sys.stdout", + }, + }, + "loggers": { + "gunicorn.access": { + "handlers": ["console"], + "level": "INFO", + "propagate": False, + }, + }, +}