immich-frame: LAN-only access via home-lans-only allowlist + dns_type=internal
Some checks failed
ci/woodpecker/push/default Pipeline failed
Some checks failed
ci/woodpecker/push/default Pipeline failed
Viktor asked to tighten who can see the immich-frame deployments: make them not public while keeping the two Meta Portals working as frames. The Portal app bakes the URL into the APK, so the same hostnames must keep loading from the home networks with zero device or router changes. - New shared Traefik middleware home-lans-only (Sofia/London/Valchedrym LANs + 10/8 + internal v6) — separate from local-only so the remote LANs don't inherit access to admin surfaces. - New ingress_factory dns_type="internal": publicly-resolvable A record carrying the internal Traefik LB IP (10.0.20.203). Outsiders resolve but can't route; WG spokes policy-route 10/8 down the tunnel. Never combine the allowlist with proxied DNS (cloudflared pod IPs are in 10/8 and would bypass it). - Both frame ingresses: dns_type internal + allowlist attached + external_monitor=false (drop the doomed [External] monitors). - rybbit worker: highlights-immich route/site removed (off Cloudflare). - Docs: CLAUDE.md/AGENTS.md ingress tiers, networking.md DNS categories, design doc docs/plans/2026-07-04-immich-frame-lan-only-design.md. Pre-verified: London router DNS returns RFC1918 answers unfiltered; Technitium already CNAMEs both hosts to the LB; no public wildcard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
114a7743ac
commit
8bac9914ec
10 changed files with 241 additions and 32 deletions
File diff suppressed because one or more lines are too long
|
|
@ -95,7 +95,7 @@ Terragrunt-based homelab managing a Kubernetes cluster (5 nodes, v1.34.2) on Pro
|
|||
## Key Paths
|
||||
- `stacks/<service>/main.tf` — service definition
|
||||
- `stacks/platform/modules/<service>/` — core infra modules
|
||||
- `modules/kubernetes/ingress_factory/` — standardized ingress with auth, rate limiting, anti-AI, and auto Cloudflare DNS (`dns_type = "proxied"` or `"non-proxied"`)
|
||||
- `modules/kubernetes/ingress_factory/` — standardized ingress with auth, rate limiting, anti-AI, and auto Cloudflare DNS (`dns_type = "proxied"`, `"non-proxied"`, or `"internal"` — a public A record carrying the internal Traefik LB IP for household-only services; pair with the `home-lans-only` ipAllowList middleware, never with `"proxied"`)
|
||||
- `modules/kubernetes/nfs_volume/` — NFS volume module (CSI-backed, soft mount)
|
||||
- `config.tfvars` — non-secret configuration (plaintext)
|
||||
- `secrets.sops.json` — all secrets (SOPS-encrypted JSON)
|
||||
|
|
|
|||
|
|
@ -232,6 +232,8 @@ VMs tag traffic on vmbr1 to isolate workloads. pfSense bridges VLAN 20 to the up
|
|||
- blog, hackmd, privatebin, url, echo, f1tv, excalidraw, send, audiobookshelf, jsoncrack, ntfy, cyberchef, homepage, linkwarden, changedetection, tandoor, n8n, stirling-pdf, dashy, city-guesser, travel, netbox
|
||||
- **Non-proxied domains** (grey cloud, direct IP resolution):
|
||||
- mail, wg, headscale, immich, calibre, vaultwarden, and other services requiring direct connections
|
||||
- **Internal-IP domains** (grey cloud, A → `10.0.20.203` Traefik LB, `ingress_factory` `dns_type = "internal"`):
|
||||
- highlights-immich, highlights-immich-emo — publicly *resolvable* but only *routable* from home LANs / WG sites / VPN (spokes policy-route `10.0.0.0/8` down the tunnel, so kiosk devices with baked-in URLs need no per-site DNS overrides). The record is reachability, not a gate — enforcement is the `home-lans-only` Traefik ipAllowList (Sofia/London/Valchedrym LANs + 10/8) on the ingress. See `docs/plans/2026-07-04-immich-frame-lan-only-design.md`.
|
||||
- CNAME records for proxied domains point to Cloudflared tunnel FQDNs
|
||||
|
||||
### Ingress Flow
|
||||
|
|
|
|||
123
docs/plans/2026-07-04-immich-frame-lan-only-design.md
Normal file
123
docs/plans/2026-07-04-immich-frame-lan-only-design.md
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# immich-frame: LAN-only access, Portals untouched (2026-07-04)
|
||||
|
||||
## Goal
|
||||
|
||||
Strangers must no longer be able to view `highlights-immich.viktorbarzin.me`
|
||||
(Viktor's London Portal Plus frame) or `highlights-immich-emo.viktorbarzin.me`
|
||||
(Emo's Sofia Portal Mini frame) — pages or ImmichFrame API. Both were
|
||||
`auth = "none"`, Cloudflare-proxied, fully public.
|
||||
|
||||
Who keeps access (per Viktor, this session): the two Portals plus **any
|
||||
household device on the Sofia, London, or Valchedrym home networks**. No
|
||||
public access, no tailnet requirement. Hard constraint: the Portal app is a
|
||||
WebView with the URL **baked in at APK build time** (`portal-immich-frame`,
|
||||
`-PframeUrl`), so the exact URLs must keep loading from where the Portals sit
|
||||
— zero app rebuilds, zero device touches, zero router changes.
|
||||
|
||||
## Design
|
||||
|
||||
Two cooperating pieces — the gate and the reachability pointer:
|
||||
|
||||
1. **The gate — `home-lans-only` Traefik middleware** (traefik stack, next to
|
||||
`local-only`): `ipAllowList` of `192.168.1.0/24` (Sofia LAN), `10.0.0.0/8`
|
||||
(VLANs, K8s pods `10.10.0.0/16`, services `10.96.0.0/12`, WG tunnel
|
||||
`10.3.2.0/24`), `192.168.8.0/24` (London LAN), `192.168.0.0/24`
|
||||
(Valchedrym LAN), `fc00::/7`, `fe80::/10`. Attached to both frame
|
||||
ingresses via `extra_middlewares`. Everyone else gets a Traefik 403 —
|
||||
including direct-to-WAN-IP requests carrying the right SNI, which DNS
|
||||
changes alone cannot stop. A **separate** middleware rather than a widened
|
||||
`local-only`, because widening would silently grant the remote LANs access
|
||||
to the 9 admin surfaces using it (Prometheus, iDRAC, Loki, …).
|
||||
|
||||
2. **The pointer — `dns_type = "internal"`** (new `ingress_factory` tier,
|
||||
Viktor's idea): a **non-proxied public A record → `10.0.20.203`** (module
|
||||
var `internal_lb_ip`). Outsiders resolve it but get an unroutable RFC1918
|
||||
address; every household resolver path delivers a working answer with no
|
||||
config anywhere: Sofia LAN already gets the internal CNAME from Technitium,
|
||||
London/Valchedrym resolve the public record via any upstream and
|
||||
policy-route `10.0.0.0/8` down the WireGuard tunnel. IPv4-only (spokes
|
||||
route no internal v6 range).
|
||||
|
||||
Interlock (the reason both flip together): with a *proxied* record, public
|
||||
traffic arrives from cloudflared **pod IPs inside 10/8** and would sail
|
||||
through the allowlist. `internal` removes the Cloudflare path entirely (CF
|
||||
edge stops serving the hostname), so every request reaches Traefik with its
|
||||
real source IP (ETP=Local). Verified: no wildcard `*.viktorbarzin.me` record
|
||||
exists to resurrect public resolution.
|
||||
|
||||
`auth` stays `"none"` — there is still no *user* auth by design (kiosk
|
||||
WebView; forward-auth would 302 the device to a login it can't complete, and
|
||||
emo's Google-only account can't log in inside a WebView at all); the
|
||||
convention comment now names the ipAllowList as the gate.
|
||||
|
||||
### Resulting flows
|
||||
|
||||
| Client | Path | Result |
|
||||
|---|---|---|
|
||||
| Emo's Portal Mini (Sofia LAN) | Technitium CNAME → `.203` direct (unchanged) | allowed (`192.168.1.x`) |
|
||||
| Viktor's Portal Plus (London LAN) | public A → `10.0.20.203` → WG tunnel | allowed (`192.168.8.x`) |
|
||||
| Household browsers (any of the 3 LANs) | same as above | allowed |
|
||||
| In-cluster checks (`homelab browser`, blackbox) | CoreDNS → Technitium → `.203` | allowed (pod IP in 10/8) |
|
||||
| Stranger, resolves hostname | gets `10.0.20.203` | unroutable |
|
||||
| Stranger, hits WAN IP with SNI | pfSense NAT → Traefik (real source IP) | **403** |
|
||||
| Stranger, via Cloudflare | no proxied record | CF edge won't serve the host |
|
||||
|
||||
### Rejected alternatives
|
||||
|
||||
- **ImmichFrame `AuthenticationSecret`** (supported upstream: web input field
|
||||
or `?authsecret=` param + bearer API): real auth from anywhere, but family
|
||||
browsers would face a secret prompt (fails "household devices just work"),
|
||||
the secret leaks into URLs/analytics/APK, and robust rollout needs APK
|
||||
rebuild + USB-adb sideload on both Portals (the Sofia one is high-friction).
|
||||
- **Authentik forward-auth / `auth = "public"`**: WebView can't complete SSO
|
||||
(Google blocks WebView logins; session expiry silently bricks an appliance);
|
||||
the anonymous outpost is an audit trail, not a gate.
|
||||
- **Remove DNS + London router AdGuardHome rewrites**: works, but adds an
|
||||
out-of-band, un-IaC'd router dependency the internal-IP record makes
|
||||
unnecessary. Kept as documented fallback if resolver-side private-IP
|
||||
filtering ever appears in the London path.
|
||||
|
||||
## Pre-verified facts (2026-07-04)
|
||||
|
||||
- London Flint 2 DNS chain returns RFC1918 answers unfiltered
|
||||
(`nslookup 10.0.20.203.nip.io 127.0.0.1` on the router → `10.0.20.203`;
|
||||
dnsmasq `rebind_protection '0'`, no AdGuardHome rebind filtering).
|
||||
- Technitium already CNAMEs both hostnames → apex → `10.0.20.203`
|
||||
(`technitium-ingress-dns-sync` is ingress-driven, not DNS-record-driven, so
|
||||
the internal answer survives the Cloudflare record swap).
|
||||
- Pod CIDR `10.10.0.0/16`, service CIDR `10.96.0.0/12` — inside `10.0.0.0/8`.
|
||||
- No public wildcard record in the zone.
|
||||
|
||||
## Blast radius & cleanups
|
||||
|
||||
- `external_monitor = false` set explicitly on both ingresses: the
|
||||
external-monitor-sync default opt-in would otherwise keep the now-doomed
|
||||
`[External] highlights-immich*` uptime-kuma monitors alive and red. Verify
|
||||
the sync drops them post-apply.
|
||||
- rybbit CF worker: `highlights-immich` removed from `SITE_IDS` (`index.js`)
|
||||
and `wrangler.toml` routes — off Cloudflare the route can never fire.
|
||||
Requires a `wrangler deploy` to take effect (route removal is hygiene, not
|
||||
functional).
|
||||
- Homepage dashboard link keeps working from LANs (hostname unchanged).
|
||||
- Docs updated in the same change: `.claude/CLAUDE.md` (DNS tier +
|
||||
external-monitor mechanism), `AGENTS.md`, `docs/architecture/networking.md`
|
||||
(Internal-IP domains category). The `portal-immich-frame` repo's glossary
|
||||
("public, login-less URL") updated separately in that repo.
|
||||
|
||||
## Failure-mode delta
|
||||
|
||||
London frame now depends on the WG tunnel instead of Cloudflare+cloudflared
|
||||
(the app self-heals with 5s retries; tunnel-flap modes documented in
|
||||
`docs/architecture/vpn.md`). A Traefik LB renumber must update
|
||||
`internal_lb_ip` in the module alongside the split-horizon apex record.
|
||||
Cutover window: cached proxied answers keep working ≤ ~5 min TTL, then the
|
||||
WebView's own retry picks up the new path.
|
||||
|
||||
## Verification & rollback
|
||||
|
||||
Verify: public dig → `10.0.20.203` (both hosts); Technitium dig → `.203`;
|
||||
curl from devvm (10/8) → 200; external vantage (WebFetch/cloud) → unreachable
|
||||
or 403; middleware attached on both ingresses; Emo's frame renders via
|
||||
`homelab browser`; London Portal image fetches visible in Traefik access logs
|
||||
from `192.168.8.x`. Rollback: `git revert` + apply traefik/immich — records
|
||||
and middleware chain restore (`allow_overwrite = true` re-adopts the records).
|
||||
|
|
@ -127,20 +127,29 @@ variable "anti_ai_scraping" {
|
|||
variable "dns_type" {
|
||||
type = string
|
||||
default = "none"
|
||||
description = "Cloudflare DNS: 'proxied' (CNAME to tunnel), 'non-proxied' (A/AAAA to public IP), or 'none'"
|
||||
description = <<-EOT
|
||||
Cloudflare DNS: 'proxied' (CNAME to tunnel), 'non-proxied' (A/AAAA to
|
||||
public IP), 'internal' (A to the internal Traefik LB IP — resolvable from
|
||||
any resolver but only ROUTABLE from home LANs / WG sites / VPN; the record
|
||||
is a reachability pointer, NOT a gate: pair it with an ipAllowList via
|
||||
extra_middlewares, e.g. traefik-home-lans-only@kubernetescrd, because
|
||||
direct-to-WAN-IP requests with the right SNI still hit Traefik), or 'none'.
|
||||
EOT
|
||||
validation {
|
||||
condition = contains(["proxied", "non-proxied", "none"], var.dns_type)
|
||||
error_message = "dns_type must be 'proxied', 'non-proxied', or 'none'."
|
||||
condition = contains(["proxied", "non-proxied", "internal", "none"], var.dns_type)
|
||||
error_message = "dns_type must be 'proxied', 'non-proxied', 'internal', or 'none'."
|
||||
}
|
||||
}
|
||||
|
||||
# Uptime Kuma external monitor: when true, annotate the ingress so the
|
||||
# external-monitor-sync CronJob creates a `[External] <name>` monitor pointing
|
||||
# at https://<host>. Null means "follow dns_type" — enabled when proxied.
|
||||
# at https://<host>. Null means "follow dns_type" — enabled when the ingress
|
||||
# has a PUBLIC DNS record (proxied or non-proxied; 'internal' records are not
|
||||
# externally reachable, so no external monitor).
|
||||
variable "external_monitor" {
|
||||
type = bool
|
||||
default = null
|
||||
description = "Enable Uptime Kuma external monitor. null = auto (enabled when dns_type == 'proxied')."
|
||||
description = "Enable Uptime Kuma external monitor. null = auto (enabled when dns_type is 'proxied' or 'non-proxied')."
|
||||
}
|
||||
|
||||
variable "external_monitor_name" {
|
||||
|
|
@ -171,6 +180,15 @@ variable "public_ipv6" {
|
|||
default = "2001:470:6e:43d::2"
|
||||
}
|
||||
|
||||
# Internal Traefik LB IP used by dns_type = "internal" records. Tracks the
|
||||
# dedicated MetalLB IP from stacks/traefik (ETP=Local). A future LB renumber
|
||||
# must update this default alongside the split-horizon apex record — see
|
||||
# docs/plans/2026-05-30-traefik-dedicated-ip-etp-local-*.
|
||||
variable "internal_lb_ip" {
|
||||
type = string
|
||||
default = "10.0.20.203"
|
||||
}
|
||||
|
||||
variable "homepage_group" {
|
||||
type = string
|
||||
default = null # auto-detect from namespace
|
||||
|
|
@ -201,8 +219,10 @@ locals {
|
|||
)
|
||||
|
||||
# External monitor enabled by default when the ingress has a public DNS
|
||||
# record (either CF-proxied or direct A/AAAA). Explicit bool overrides.
|
||||
effective_external_monitor = var.external_monitor != null ? var.external_monitor : (var.dns_type != "none")
|
||||
# record (either CF-proxied or direct A/AAAA). 'internal' records resolve
|
||||
# publicly but are unroutable from outside, so they get no external monitor.
|
||||
# Explicit bool overrides.
|
||||
effective_external_monitor = var.external_monitor != null ? var.external_monitor : (var.dns_type == "proxied" || var.dns_type == "non-proxied")
|
||||
|
||||
# Emit the annotation when effective is true (positive signal), or when the
|
||||
# caller explicitly set external_monitor=false (opt-out). When the caller
|
||||
|
|
@ -424,3 +444,19 @@ resource "cloudflare_record" "non_proxied_aaaa" {
|
|||
zone_id = var.cloudflare_zone_id
|
||||
allow_overwrite = true
|
||||
}
|
||||
|
||||
# 'internal': a publicly-resolvable A record carrying the INTERNAL Traefik LB
|
||||
# IP. Outsiders resolve it but can't route to it; home-LAN/WG-site/VPN clients
|
||||
# reach Traefik directly (the WG spokes policy-route 10.0.0.0/8 through the
|
||||
# tunnel), so kiosk devices with baked-in URLs need no DNS overrides anywhere.
|
||||
# IPv4-only on purpose: the spokes route no internal IPv6 range.
|
||||
resource "cloudflare_record" "internal_a" {
|
||||
count = var.dns_type == "internal" ? 1 : 0
|
||||
name = local.dns_name
|
||||
content = var.internal_lb_ip
|
||||
proxied = false
|
||||
ttl = 1
|
||||
type = "A"
|
||||
zone_id = var.cloudflare_zone_id
|
||||
allow_overwrite = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,14 +144,21 @@ resource "kubernetes_service" "immich-frame-emo" {
|
|||
|
||||
module "ingress_emo" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# Photo-frame kiosk display on Emo's Portal — headless browser pulling images
|
||||
# via an Immich API key (no user login). Forward-auth would 302 the device to
|
||||
# Authentik with no way to complete login.
|
||||
# auth = "none": photo-frame kiosk; headless browser with API key; no user login.
|
||||
auth = "none"
|
||||
dns_type = "proxied"
|
||||
namespace = "immich"
|
||||
name = "highlights-immich-emo"
|
||||
tls_secret_name = var.tls_secret_name
|
||||
service_name = "immich-frame-emo"
|
||||
# Photo-frame kiosk display on Emo's Portal Mini (Sofia LAN) — WebView
|
||||
# pulling images via an Immich API key; no user login possible on the
|
||||
# device. Same LAN-only gating as frame.tf: home-lans-only ipAllowList +
|
||||
# dns_type "internal" (Emo's Portal already resolves this host internally
|
||||
# via Technitium; the public internal-IP record covers any resolver).
|
||||
# LAN-only design: docs/plans/2026-07-04-immich-frame-lan-only-design.md.
|
||||
# auth = "none": kiosk WebView, no user auth by design; gated by the home-lans-only ipAllowList instead.
|
||||
auth = "none"
|
||||
dns_type = "internal"
|
||||
extra_middlewares = ["traefik-home-lans-only@kubernetescrd"]
|
||||
# Not externally reachable — explicit opt-out so external-monitor-sync
|
||||
# drops the old [External] monitor instead of default-opting it back in.
|
||||
external_monitor = false
|
||||
namespace = "immich"
|
||||
name = "highlights-immich-emo"
|
||||
tls_secret_name = var.tls_secret_name
|
||||
service_name = "immich-frame-emo"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,14 +142,23 @@ resource "kubernetes_service" "immich-frame" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# Photo-frame kiosk display — runs in headless browser mode on a TV/frame
|
||||
# device and pulls images via an Immich API key (no user login). Forward-auth
|
||||
# would 302 the device to Authentik with no way to complete login.
|
||||
# auth = "none": Photo-frame kiosk display — headless browser with API key; no user login; forward-auth breaks device automation.
|
||||
auth = "none"
|
||||
dns_type = "proxied"
|
||||
namespace = "immich"
|
||||
name = "highlights-immich"
|
||||
tls_secret_name = var.tls_secret_name
|
||||
service_name = "immich-frame"
|
||||
# Photo-frame kiosk display (Viktor's London Portal Plus WebView) — pulls
|
||||
# images via an Immich API key; no user login possible on the device, so
|
||||
# forward-auth would 302 it to Authentik with no way to complete login.
|
||||
# The GATE is network-level: the home-lans-only ipAllowList (Sofia/London/
|
||||
# Valchedrym LANs + 10/8) 403s everyone else, and dns_type "internal"
|
||||
# publishes the Traefik LB IP publicly so the Portal's baked-in URL resolves
|
||||
# from any resolver yet routes only via the home LANs / WG tunnel.
|
||||
# LAN-only design: docs/plans/2026-07-04-immich-frame-lan-only-design.md.
|
||||
# auth = "none": kiosk WebView, no user auth by design; gated by the home-lans-only ipAllowList instead.
|
||||
auth = "none"
|
||||
dns_type = "internal"
|
||||
extra_middlewares = ["traefik-home-lans-only@kubernetescrd"]
|
||||
# Not externally reachable — explicit opt-out so external-monitor-sync
|
||||
# drops the old [External] monitor instead of default-opting it back in.
|
||||
external_monitor = false
|
||||
namespace = "immich"
|
||||
name = "highlights-immich"
|
||||
tls_secret_name = var.tls_secret_name
|
||||
service_name = "immich-frame"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ const SITE_IDS = {
|
|||
"stacks.viktorbarzin.me": "b38fda4285df",
|
||||
"f1.viktorbarzin.me": "7e69786f66d5",
|
||||
"frigate.viktorbarzin.me": "0d4044069ff5",
|
||||
"highlights-immich.viktorbarzin.me": "602167601c6b",
|
||||
"immich.viktorbarzin.me": "35eedb7a3d2b",
|
||||
"mail.viktorbarzin.me": "082f164faa7d",
|
||||
"navidrome.viktorbarzin.me": "8a3844ff75ba",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ routes = [
|
|||
{ pattern = "stacks.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
{ pattern = "f1.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
{ pattern = "frigate.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
{ pattern = "highlights-immich.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
{ pattern = "immich.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
{ pattern = "mail.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
{ pattern = "navidrome.viktorbarzin.me/*", zone_name = "viktorbarzin.me" },
|
||||
|
|
|
|||
|
|
@ -119,6 +119,40 @@ resource "kubernetes_manifest" "middleware_local_only" {
|
|||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# IP allowlist for household access across ALL home sites: Sofia LAN + the
|
||||
# WireGuard spoke LANs (London, Valchedrym) + 10/8 (VLANs, K8s pods/services,
|
||||
# WG tunnel IPs). Deliberately a SEPARATE middleware from `local-only` —
|
||||
# widening local-only would grant the remote LANs access to the admin surfaces
|
||||
# that use it (Prometheus, iDRAC, Loki, …). Use for family-facing services
|
||||
# (e.g. the immich-frame kiosks) that every household device may open but the
|
||||
# public internet must not. Pair with ingress_factory `dns_type = "internal"`:
|
||||
# a Cloudflare-proxied record would deliver public traffic from cloudflared
|
||||
# POD IPs (inside 10/8) and silently bypass this allowlist.
|
||||
resource "kubernetes_manifest" "middleware_home_lans_only" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "home-lans-only"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
ipAllowList = {
|
||||
sourceRange = [
|
||||
"192.168.1.0/24", # Sofia LAN (hub site)
|
||||
"10.0.0.0/8", # VLANs, K8s pod/svc CIDRs, WG tunnel subnet
|
||||
"192.168.8.0/24", # London LAN (via WG tunnel)
|
||||
"192.168.0.0/24", # Valchedrym LAN (via WG tunnel)
|
||||
"fc00::/7",
|
||||
"fe80::/10",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# HTTPS redirect middleware
|
||||
resource "kubernetes_manifest" "middleware_redirect_https" {
|
||||
manifest = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue