How to block something in another handler

1. Caddy version (caddy version):

v2.4.3 h1:Y1FaV2N4WO3rBqxSYA8UZsZTQdN+PwcoOcAiZTM8C0I=

2. How I run Caddy:

Docker image caddy:2.4.3

System environment:

Docker

Service/unit/compose file:

version: '3'
services:
 web:
   build: .
   # ...
 caddy:
   image: caddy:2.4.3
   volumes:
     - ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
     - ./files/media:/data/media
     - ./files/static:/data/static
     - ./files/caddy:/data/caddy
   ports:
     - "80:80"
   depends_on:
     - web

d. My complete Caddyfile or JSON config:

http://example.com {
    @denied path_regexp .+\.scss

    handle @denied {
        error 403
    }

    handle_path /media/* {
        root * /data/media
        file_server
    }

    handle_path /static/* {
        root * /data/static
        file_server
    }

    handle {
        reverse_proxy web:8080
    }
}

3. The problem I’m having:

My webserver is behind Caddyserver, and some static files serve in the /static/ and /media/ directory.

Meanwhile some sensitive files are also putted in the /static/ directory, like /static/css/app.scss, I have to block them, so I write something like that:

@denied path_regexp .+\.scss
handle @denied {
    error 403
}

If I request http://example.com/other/path/app.scss, a “403 Forbidden” is returned, it is my expected result.

But if I request http://example.com/static/css/app.scss, the file app.scss is returned as usual.

I think the order of handle directive is confused.

I tried another solution, putting the error directive into the static handler:

http://example.com {
    @denied path_regexp .+\.scss

    handle_path /media/* {
        root * /data/media
        file_server
    }

    handle_path /static/* {
        error @denied 403
        root * /data/static
        file_server
    }

    handle {
        reverse_proxy web:8077
    }
}

It didn’t work either.

So how can I solve this problem? Thank you!

It would be better to use /srv/media and /srv/static for this.

You should persist all of /data, not just /data/caddy. See the docs on Docker Hub


As for your actual issue, since you tried two different things, there’s a bit to talk about.

The Caddyfile adapter will sort directives, first according to this directive order (also note that handle and handle_path are special cased to have the same sorting order), then for directives of the same type, by the length of the path matchers (to make the most specific matcher get tried first) but other kinds of matchers get sorted in an arbitrary order, after those with path matchers.

If you run caddy adapt --pretty on your Caddyfile, you’ll see the JSON that the Caddyfile adapts to. From that, you’ll notice that your .scss handle gets sorted after the other two with path matchers.

It’s possible to override this sorting by wrapping all of your handle blocks in a route block, to force them to be handled in a particular order.


As for what you tried next, moving the error @denied 403 into your handle blocks, the issue is that the error and abort directives, added in v2.4.0, had their directive order set to be the last in the list.

We fixed this in v2.4.4 (just released last week) to put them before other handler directives (like file_server). That version hasn’t been built for Docker yet, because we found a critical bug that we’ll tag a v2.4.5 to fix, to be released probably today or tomorrow (Docker might take a bit longer after that, there’s manual steps involved, including handoff between a few humans).

So that’s to say, your other solution with error @denied 403 should work in v2.4.5.

3 Likes

Excellent answer!

You solved my question and spot my other bugs, thank you a million!

1 Like

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