From 82de58087905bbb024b6cc9332f786655948c983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ask=20Bj=C3=B8rn=20Hansen?= Date: Sun, 8 Mar 2026 18:31:44 -0700 Subject: [PATCH] feat(ekko): add WithTrustOptions for CDN IP trust configuration Allow callers to append additional echo.TrustOption values to the default IP extraction configuration. This enables trusting CDN IP ranges (e.g. Fastly) when extracting client IPs from X-Forwarded-For. --- ekko/ekko.go | 1 + ekko/options.go | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ekko/ekko.go b/ekko/ekko.go index 623a0b8..d3381f2 100644 --- a/ekko/ekko.go +++ b/ekko/ekko.go @@ -163,6 +163,7 @@ func (ek *Ekko) setup(ctx context.Context) (*echo.Echo, error) { echo.TrustLinkLocal(false), echo.TrustPrivateNet(true), } + trustOptions = append(trustOptions, ek.extraTrustOptions...) e.IPExtractor = echo.ExtractIPFromXFFHeader(trustOptions...) if ek.otelmiddleware == nil { diff --git a/ekko/options.go b/ekko/options.go index 82a83e3..45ff13d 100644 --- a/ekko/options.go +++ b/ekko/options.go @@ -13,13 +13,14 @@ import ( // It encapsulates server configuration, middleware options, and lifecycle management // for NTP Pool web services. Use New() with functional options to configure. type Ekko struct { - name string - prom prometheus.Registerer - port int - routeFn func(e *echo.Echo) error - logFilters []slogecho.Filter - otelmiddleware echo.MiddlewareFunc - gzipConfig *middleware.GzipConfig + name string + prom prometheus.Registerer + port int + routeFn func(e *echo.Echo) error + logFilters []slogecho.Filter + otelmiddleware echo.MiddlewareFunc + gzipConfig *middleware.GzipConfig + extraTrustOptions []echo.TrustOption writeTimeout time.Duration readHeaderTimeout time.Duration @@ -92,6 +93,16 @@ func WithReadHeaderTimeout(t time.Duration) func(*Ekko) { } } +// WithTrustOptions appends additional trust options to the default IP extraction +// configuration. These options are applied after the built-in trust settings +// (loopback trusted, link-local untrusted, private networks trusted) when +// extracting client IPs from the X-Forwarded-For header. +func WithTrustOptions(opts ...echo.TrustOption) func(*Ekko) { + return func(ek *Ekko) { + ek.extraTrustOptions = append(ek.extraTrustOptions, opts...) + } +} + // WithGzipConfig provides custom gzip compression configuration. // By default, gzip compression is enabled with standard settings. // Use this option to customize compression level, skip patterns, or disable compression.