From a8128e2a8196750a9988dc86aacb8caeeab90703 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Wed, 14 Oct 2026 20:15:41 +0200 Subject: [PATCH] Bypass LAN addresses from anubis check --- README.md | 32 +++++++++++++++++++++++++++++--- anubis.yaml | 23 +++++++++++------------ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 81b6261..c9f8452 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,43 @@ on `code.brunner.ninja`. It uses a pinned container image, a Traefik `ForwardAuth` middleware, restricted Gitea Actions deployment credentials, and an out-of-repository signing key. -## Protected routes +## LAN and CI bypass + +Traefik sends clients in `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, +and `fc00::/7` directly to `legacy-gitea-service`, without Anubis middleware. +This priority-500 route covers every path, including Git HTTP, action downloads, +API requests and comparisons. The homelab Gitea runner uses this bypass too. + +The separate priority-400 route sends internet requests for `/.within.website` +to Anubis. Do not combine the LAN match with that route: doing so sends LAN +requests directly to Anubis instead of bypassing it. + +`ClientIP` matches the connection peer, not `X-Forwarded-For` or `X-Real-IP`. +Traefik's LoadBalancer must retain `externalTrafficPolicy: Local` to preserve +internet source addresses. The homelab's NAT loopback currently presents LAN +requests as `192.168.0.254`; internet clients retain their public address. +If a proxy or NAT configuration changes, repeat both checks below before +assuming this trust boundary still holds. + +From outside the homelab, verify the redirect to Anubis and then direct LAN +access (HTTP 200 with Gitea HTML, no Anubis challenge): + +```sh +curl -v https://code.brunner.ninja/papnkukn/qrcode-svg +ssh dahoam curl -v https://code.brunner.ninja/papnkukn/qrcode-svg +ssh dahoam git ls-remote https://code.brunner.ninja/actions/checkout.git refs/tags/v4 +``` + +## Protected internet routes Anubis is used for: - repository and API paths belonging to the current third-party mirror owners; - selected oversized public `feedc0de` forks (at least 512 MiB); -- the complete `EFeru` owner subtree, including the owner page itself; - comparison pages under every owner, including `feedc0de`. The existing catch-all Gitea route remains unprotected, so login, about, -explore, owner pages other than `EFeru`, and ordinary `feedc0de/*` +explore, owner pages, and ordinary `feedc0de/*` repositories remain unchanged outside their comparison pages. Proof-of-work difficulty is 5 and authorization cookies expire after one hour. diff --git a/anubis.yaml b/anubis.yaml index ea47c59..0ffcbf5 100644 --- a/anubis.yaml +++ b/anubis.yaml @@ -177,6 +177,17 @@ spec: entryPoints: - websecure routes: + # Trusted LAN, pod and container traffic goes directly to Gitea on every + # path. Match the TCP peer, never a client-supplied forwarded-IP header. + # This must outrank both the challenge endpoints and protected routes. + - kind: Rule + priority: 500 + match: Host(`code.brunner.ninja`) && (ClientIP(`10.0.0.0/8`) || ClientIP(`172.16.0.0/12`) || ClientIP(`192.168.0.0/16`) || ClientIP(`fc00::/7`)) + services: + - kind: Service + name: legacy-gitea-service + port: http + passHostHeader: true - kind: Rule priority: 400 match: Host(`code.brunner.ninja`) && PathPrefix(`/.within.website`) @@ -184,18 +195,6 @@ spec: - kind: Service name: gitea-anubis port: http - # EFeru is intentionally protected as a complete owner subtree, including - # the owner page itself rather than only its repositories. - - kind: Rule - priority: 250 - match: Host(`code.brunner.ninja`) && PathRegexp(`(?i)^/EFeru(/|$)`) - middlewares: - - name: gitea-anubis - services: - - kind: Service - name: legacy-gitea-service - port: http - passHostHeader: true - kind: Rule priority: 200 match: Host(`code.brunner.ninja`) && PathRegexp(`(?i)^/(Bodmer|DigiLive|EFeru|Ferdi265|HowardHinnant|Kistler-Group|Links2004|LogBlock|Makuna|PaulStoffregen|PostgreSQL-For-Wordpress|TartanLlama|TuxCoding|ValveSoftware|actions|adafruit|airgradienthq|arminwinkt|bblanchon|bbulkow|boostorg|catchorg|docker|dolphin-emu|espressif|fmtlib|getsentry|h2zero|hilch|home-assistant|jbagg|khoih-prog|lucianoforks|lucysrausch|me-no-dev|microsoft|moritzsternemann|mpusz|multimediamike|opentrafficmap|papnkukn|platformio|qt-creator|ramottamado|romixlab|rook|semaf|smarty-php|vikt0rm|wolfSSL|yath)/[^/]+(/|$)`)