1e8d045815
- 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
63 lines
1.2 KiB
Cheetah
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}}
|