{
    admin localhost:2019
}

#### Shared Snippets
(common) {
    tls {{CADDY_TLS_EMAIL:-admin@example.com}} {
        dns cloudflare {env.CLOUDFLARE_DNS_TOKEN}
        # DNS-01 must see the public Cloudflare zone, not the internal Technitium split-DNS zone.
        # Exclude the Caddy DMZ host from DNS DNAT so these queries are not redirected to Technitium.
        resolvers 1.1.1.1 1.0.0.1
    }
    header {
        # Enable HSTS
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-XSS-Protection 0
        # Prevent browsers from incorrectly detecting non-scripts as scripts and MIME type sniffing
        X-Content-Type-Options nosniff
        Referrer-Policy same-origin
        -Server
        X-Frame-Options "SAMEORIGIN"
        Permissions-Policy "geolocation=(self), microphone=(), camera=(), interest-cohort=()"
        import content-security-general
    }
}

#### Content Security Snippets
(content-security-general) { # Default setup
    # Disable unsafe inline/eval and plugins, only load scripts and stylesheets from same origin, fonts from google,
    #   and images from same origin and imgur. Sites should aim for policies like this.
    Content-Security-Policy "frame-ancestors 'self' https://*.{{CADDY_BASE_DOMAIN:-home.example.com}}"
    #"default-src 'self'; style-src 'self'; script-src 'self'; font-src 'self'; img-src 'self'; form-action 'self'; connect-src 'self'; frame-ancestors 'none';"
    #default-src 'none'; font-src https://fonts.gstatic.com; img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'
}
(content-security-basic) { # Most basic setup
    # Disable unsafe inline/eval, only load resources from same origin except also allow images from imgur
    # Also disables the execution of plugins
    Content-Security-Policy default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'
}
(content-security-api) { # API
    # Disable the loading of any resources and disable framing, recommended for APIs to use
    Content-Security-Policy default-src 'none'; frame-ancestors 'none'
}

# Shared block for office admin apps with self-signed upstream TLS.
(office-admin-upstream) {
    transport http {
        tls_insecure_skip_verify
    }
    header_up Host {upstream_hostport}
}

# Like office-admin-upstream but also strips the Origin header.
# UniFi devices (UDM, UNAS) validate Origin on WebSocket upgrades and reject
# connections where Origin doesn't match their own hostname, causing real-time
# dashboard stats to show N/A. Stripping Origin bypasses that check.
(unifi-upstream) {
    transport http {
        tls_insecure_skip_verify
    }
    header_up Host {upstream_hostport}
    header_up -Origin
}

# Shared security headers for office admin apps.
(office-admin-security) {
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "no-referrer"
    }
    encode gzip
}

#### VLAN 1 — LAN (TRUSTED zone, 10.0.1.x)
udm.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_LAN_PREFIX:-10.0.1}}.1:443 {
        import unifi-upstream
    }
    import office-admin-security
}

switchlite8poe.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_LAN_PREFIX:-10.0.1}}.6
}

#### VLAN 10 — Office (TRUSTED zone, 10.0.10.x)
## Physical / static devices
dns01.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{DNS_BIND_IP:-10.0.10.5}}:5380
}

pbs.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.8:8007 {
        import office-admin-upstream
    }
    import office-admin-security
}

proxmox.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.10:8006 {
        import office-admin-upstream
    }
    import office-admin-security
}

nas.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.24:5000
}

unas.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.25:443 {
        import unifi-upstream
    }
    import office-admin-security
}

## LXC Apps (.6–.19; all in use)
bento-pdf.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.6:8080
}

it-tools.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.7:80
}

paperless-ngx.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.11:8000 {
        header_up Host {host}
    }

    encode gzip
}

beszel.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.13:8090
}

ytd.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.14:3087
}

immich.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.15:2283
}

vaultwarden.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.16:8800
}

gramps.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.17:80
}

koffan.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.12:8080
}

# Forgejo (LXC 114, .18) -- publicly exposed at git.brianpooe.com (proxied via
# the VPS over NetBird for outside visitors) as well as reachable directly on
# the LAN via split-horizon DNS. One canonical hostname everywhere, so this
# is NOT under CADDY_BASE_DOMAIN like other internal-only apps.
# Git-over-SSH is not proxyable through Caddy -- forgejo.brianpooe.com
# resolves straight to the LXC (10.0.10.18) instead, bypassing Caddy entirely.
# Root redirects to the .profile landing page instead of the repo explore
# list -- see the Forgejo README's "Public Exposure" section.
git.brianpooe.com {
    import common
    redir / /brianpooe 302
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.18:3000
}

# Hermes Agent web dashboard (LXC 113, not docker — systemd service)
hermes.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    # Upstream bug: with a single password-only auth provider the gate
    # auto-redirects to the OAuth-only /auth/login endpoint, which 500s.
    # Send browsers to the server-rendered /login form instead.
    redir /auth/login* /login
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.19:9119
}

## Arr Stack — LXC 101 (.20)
bazarr.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:6767
}

emby.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:8096
}

flaresolverr.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:8191
}

gluetun.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:8000
}

prowlarr.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:9696
}

qbittorrent.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:8080
}

radarr.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:7878
}

sabnzbd.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:8282
}

seerr.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:5055
}

sonarr.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.20:8989
}

#### VLAN 30 — IoT (IoT zone, 10.0.30.x)
zigbee.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_IOT_PREFIX:-10.0.30}}.5
}

# Requires in HA configuration.yaml:
#   http:
#     use_x_forwarded_for: true
#     trusted_proxies:
#       - <caddy-host-ip>
ha.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_IOT_PREFIX:-10.0.30}}.6:8123
}

z2m.{{CADDY_BASE_DOMAIN:-home.example.com}} {
    import common
    reverse_proxy {{CADDY_IOT_PREFIX:-10.0.30}}.6:8080
}
