falcon-vpn-only was defined inline in falcon.yaml even though it's a generic ipAllowList restriction with nothing falcon-specific about it - security.yaml is where the other reusable middlewares (security- headers, no-index, rate-limit) already live. Renamed to vpn-only to match their bare naming style now that it's not tied to one file, and updated falcon.yaml's two router references to vpn-only@file (same cross-file pattern already used there for security-headers@file). Also applies it to the pulsenode stack: it's a dashboard surfacing container names/health for every service here, and there's no auth in front of it yet, so gating it to the tailnet is a real mitigation for that gap rather than leaving it open on the public hostname.
56 lines
1.7 KiB
YAML
56 lines
1.7 KiB
YAML
tls:
|
|
options:
|
|
default:
|
|
minVersion: VersionTLS12
|
|
cipherSuites:
|
|
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
|
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
|
|
- TLS_AES_128_GCM_SHA256
|
|
- TLS_AES_256_GCM_SHA384
|
|
- TLS_CHACHA20_POLY1305_SHA256
|
|
curvePreferences:
|
|
- CurveP521
|
|
- CurveP384
|
|
sniStrict: true
|
|
|
|
http:
|
|
middlewares:
|
|
security-headers:
|
|
headers:
|
|
stsSeconds: 31536000
|
|
stsIncludeSubdomains: true
|
|
stsPreload: true
|
|
forceSTSHeader: true
|
|
customFrameOptionsValue: "SAMEORIGIN"
|
|
browserXssFilter: true
|
|
contentTypeNosniff: true
|
|
referrerPolicy: "strict-origin-when-cross-origin"
|
|
customResponseHeaders:
|
|
Permissions-Policy: "camera=(), microphone=(), geolocation=(), payment=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=()"
|
|
X-Content-Type-Options: "nosniff"
|
|
X-Frame-Options: "SAMEORIGIN"
|
|
no-index:
|
|
headers:
|
|
customResponseHeaders:
|
|
X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex"
|
|
rate-limit:
|
|
rateLimit:
|
|
average: 100
|
|
burst: 50
|
|
period: 1s
|
|
api-rate-limit:
|
|
rateLimit:
|
|
average: 30
|
|
burst: 15
|
|
period: 1s
|
|
# Only let traffic through whose source IP is inside the Tailscale/Headscale
|
|
# mesh (100.64.0.0/10, fd7a:115c:a1e0::/48). Public DNS can still resolve
|
|
# these hostnames, but anyone reaching them over the open internet gets a
|
|
# 403 — this range is only reachable by actually being a peer on the tailnet.
|
|
vpn-only:
|
|
ipAllowList:
|
|
sourceRange:
|
|
- "100.64.0.0/10"
|
|
- "fd7a:115c:a1e0::/48"
|