Caddyfile headers snippet redundant?

1. Caddy version: v2.6.4

2. How I installed, and run Caddy: docker compose

a. System environment: Debian on j5005 cpu

c. Service/unit/compose file:

(headers) {
        header {
                Permissions-Policy interest-cohort=()
                Strict-Transport-Security max-age=31536000;
                X-Content-Type-Options "nosniff"
                X-Frame-Options "DENY"
                Referrer-Policy "strict-origin-when-cross-origin"
        }
}

This is not really a help issue, just a question.

I’m running the simple headers snippet above in my Caddyfile, and I get “duplicate” entries when testing my server on sites like ssllabs etc.

I’m simply asking whether caddy already has these kind of headers implemented out of the box, and there’s actually no need to run these snippets and import them in our subdomains.

I’ve seen many examples on the forums where users actually define their ssl version or some other snippets with gzip etc, are these recommended, or are they superfluous and it’s better to keep the Caddyfile as minimal as possible? Similar question regarding the Cors snippet as well.

Thank you.

My Caddyfile config:

(restricted-access) {
        forward_auth authelia:9091 {
                uri /api/verify?rd=https://auth.{$DOMAIN}/
                copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
        }
}

(cloudflare-tls) {
        tls {$EMAIL} {
                dns cloudflare {$CLOUDFLARE_API_TOKEN}
        }
}

(localSubnets) {
        @localSubnets remote_ip private_ranges
}

(headers) {
        header {
                Permissions-Policy interest-cohort=()
                Strict-Transport-Security max-age=31536000;
                X-Content-Type-Options "nosniff"
                X-Frame-Options "DENY"
                Referrer-Policy "strict-origin-when-cross-origin"
        }
}

(logs) {
        log {
                output file {$LOG_FILE} {
                        roll_size 10mb
                        roll_keep 10
                        roll_keep_for 2160h
                }
                format formatted "e[35m[{ts}]e[0m e[96me[1m{request>remote_ip}e[0m e[31m{request>headers>X-Forwarded-For}e[0m e[33m{request>method}e[0m e[92m{request>host}e[32m{request>uri}e[0m e[97m{status}e[0m	e[90m{request>headers>User-Agent}e[0m e[34m{request>headers>Referer}e[0m" {
			time_format "02/Jan/2006:15:04:05-0700"
                }
                level INFO
        }
}

# CORS handling
# This is a modified version of: https://kalnytskyi.com/posts/setup-cors-caddy-2/
#
(cors) {
        @cors_preflight method OPTIONS
        @cors header Origin {args.0}

        handle @cors_preflight {
                header {
                        Access-Control-Allow-Origin "{args.0}"
                        Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
                        Access-Control-Allow-Headers *
                        Access-Control-Max-Age "3600"
                        defer
                }
                respond "" 204
        }

        handle @cors {
                header {
                        Access-Control-Allow-Origin "{args.0}"
                        Access-Control-Expose-Headers *
                        defer
                }
        }
}

{$DOMAIN} {
        reverse_proxy homepage:3000
        import headers
        import cloudflare-tls
}

omv.{$DOMAIN} {
        import restricted-access
        reverse_proxy {$SERVER_IP}:5024
        import headers
        import cloudflare-tls
}

portainer.{$DOMAIN} {
        reverse_proxy {$SERVER_IP}:9000
        import headers
        import cloudflare-tls
}

adguard.{$DOMAIN} {
        reverse_proxy adguardhome:80
        import headers
        import cloudflare-tls
}

auth.{$DOMAIN} {
        # This is necessary until Authelia learns prompt handling. It's planned for beta 7 (https://www.authelia.com/roadmap/active/openid-connect/#beta-7).
        # Without this, the ownCloud desktop client cannot authenticate.
        uri /api/oidc/authorization replace &prompt=select_account%20consent ""

        import cors https://cloud.{$DOMAIN}
        reverse_proxy authelia:9091
        import headers
        import cloudflare-tls
        import logs
}

dav.{$DOMAIN} {
        import restricted-access
        reverse_proxy baikal:80
        #php_fastcgi 127.0.0.1:9000
        #file_server
        import headers
        import cloudflare-tls
        import logs
}

Make a request with curl -v. What do you see?

Maybe your upstream app is already sending the same headers.

Now I’m a little confused.

Some apps (outline, owncloud ocis, etc) already send their own headers.

I thought that when you reverse proxy with caddy, it will be responsible of headers etc.
It seems not, some apps already have their own headers sent, and thus overlapping or contradicting even.

Is there a way to edit those/disable said app headers, and only let caddy be in charge of the sent headers?

No, the applications are always responsible for setting headers, because headers are heavily dependent on the data being sent, the protocol, needed caching behaviour, etc.

You can configure Caddy to augment or manipulate them. But in general, the applications should be setting their own headers.

Only set security headers if you understand what they do and what the implications are. If you don’t, then you’re better off not playing with them.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.