Files
felhom-controller/controller/internal/infra/templates/traefik.yml.tmpl
T
admin 1e8d045815 R-753: the box tells visitors apart — cloudflared at a fixed address, traefik trusts only it, the controller reads the hop traefik saw
- felhom-tunnel network 172.16.253.0/29 (ip-range .4/30): cloudflared alone at .2, traefik at .3; traefik's websecure
  trusts forwarded headers from 172.16.253.2/32 only, and every request passes felhom-forwarded@file, which removes
  the client-writable host/path/address headers (X-Forwarded-Host/-Uri/-Method/-Prefix, Forwarded, True-Client-Ip, …)
  and fixes X-Forwarded-Port to 443 (measured: Cloudflare passes a client's X-Forwarded-Host/-Port).
- EnsureBaseStack reconciles a RUNNING traefik/cloudflared whose rendered files changed (recreate), refuses a rewrite
  that would drop a certificate resolver, and moves cloudflared only once traefik is on the tunnel network.
- clientIP: believed only when the TCP peer is traefik; the rightmost X-Forwarded-For entry (the hop traefik saw);
  the tunnel hop → CF-Connecting-IP (the edge refuses a client-sent one, measured 403). rateKey: IPv6 per /64.
  Dashboard login, claim, share and escrow counters key on it; the setup gate logs it.
- Dashboard login messages: keys, informal voice, both languages.
Red-proofs: RP-A1 (leftmost hop), RP-A2 (shared tunnel key), RP-A3 (no reconcile) — felhom.eu audits/visitors-2026-10-01/A.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 21:01:42 +02:00

63 lines
1.2 KiB
Cheetah

# Traefik Static Configuration
# Generated by felhom-controller (base-infra bring-up). Do not edit — regenerated on bring-up.
api:
dashboard: true
insecure: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
{{- if .Tunnel}}
# R-753: believe X-Forwarded-* only from cloudflared's fixed address on felhom-tunnel; every other peer's are dropped.
forwardedHeaders:
trustedIPs:
- "{{.TunnelAddr}}/32"
{{- end}}
http:
middlewares:
- {{.ForwardedMiddleware}}@file
{{- if .ACMEEmail}}
tls:
certResolver: letsencrypt
{{- end}}
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-public
file:
directory: /etc/traefik/dynamic
watch: true
log:
level: INFO
accessLog: {}
{{- if .ACMEEmail}}
certificatesResolvers:
letsencrypt:
acme:
email: {{.ACMEEmail}}
storage: /etc/traefik/acme.json
{{- if .CFAPIToken}}
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
{{- else}}
httpChallenge:
entryPoint: web
{{- end}}
{{- end}}