Checking before sending bug report

1. Output of caddy version:

v2.5.2 h1:eCJdLyEyAGzuQTa5Mh3gETnYWDClo1LjtQm2q9RNZrs=

2. How I run Caddy:

caddy run --config ./Caddyfile

a. System environment:

ubuntu 20.04, cli

b. Command:

caddy run --config ./Caddyfile

c. Service/unit/compose file:

not applicable

d. My complete Caddy config:

{
	admin 127.0.0.1:20199
	debug
	log stdout
}

(blocked) {
	@blocked not remote_ip 1.1.1.1
	respond @blocked "access denied" 403
}

:7885 {
	import blocked

	handle_path /assets/* {
		root * ./assets
		file_server
	}

	reverse_proxy 127.0.0.1:7886
}

:7886 {
	respond "OK" 200
}

3. The problem I’m having:

I am serving some reverse proxies to private list of whitelist ips, it seems if the handle* directives are used, they somehow bypass the @blocked check.

requesting any then other then the handle path seems to be in correct behavior.

$ http localhost:7885/correct_behavior

HTTP/1.1 403 Forbidden
Content-Length: 13
Date: Fri, 29 Jul 2022 12:09:07 GMT
Server: Caddy

access denied

However, requesting handle path seems to not trigger the block check.

$ http localhost:7885/assets/baz/file.txt

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 12
Content-Type: text/plain; charset=utf-8
Date: Fri, 29 Jul 2022 12:10:53 GMT
Etag: "rfrv8zc"
Last-Modified: Fri, 29 Jul 2022 07:53:23 GMT
Server: Caddy

i am file zz

4. Error messages and/or full log output:


2022/07/29 12:12:51.766 DEBUG   http.handlers.rewrite   rewrote request {"request": {"remote_ip": "127.0.0.1", "remote_port": "54000", "proto": "HTTP/1.1", "method": "GET", "host": "localhost:7885", "uri": "/assets/baz/file.txt", "headers": {"User-Agent": ["HTTPie/1.0.3"], "Accept-Encoding": ["gzip, deflate"], "Accept": ["*/*"], "Connection": ["keep-alive"]}}, "method": "GET", "uri": "/baz/file.txt"}
2022/07/29 12:12:51.766 DEBUG   http.handlers.file_server       sanitized path join     {"site_root": "./assets", "request_path": "/baz/file.txt", "result": "assets/baz/file.txt"}
2022/07/29 12:12:51.766 DEBUG   http.handlers.file_server       opening file    {"filename": "assets/baz/file.txt"}

This is the logs for the 2nd request, the first one didn’t do any logging as expected.

5. What I already tried:

removing file_server from handle part solve the problem. However there are still side effects like, if you add some headers in the handle* part those still leaks However this should not be necessary as global block should in theory be first to be evaluated no? This example works

{
	admin 127.0.0.1:20199
	debug
	log stdout
}

(blocked) {
	@blocked not remote_ip 1.1.1.1
	respond @blocked "access denied" 403
}

:7885 {
	import blocked

	handle_path /assets/* {
		root * ./assets
		header X-Apikey Foo
	}

	file_server
	reverse_proxy 127.0.0.1:7886
}

:7886 {
	respond "OK" 200
}

I mostly use file_server on handle*. So, assumed some thing does not carry over to the handlers, so i tried to import blocked in the handle* However that triggers an error:

run: adapting config using caddyfile: parsing caddyfile tokens for 'handle_path': matcher is defined more than once: @blocked

6. Links to relevant resources:

That’s due to directive ordering. Caddyfile directives are sorted according to this order:

So respond is before reverse_proxy, but after handle_path.

So if you want to override the order, you need to wrap the whole thing in a route to guarantee that they run in the order you specify.

Run caddy adapt --pretty --config Caddyfile to see the underlying JSON config, which will show you the order in which it will run, after the Caddyfile parsing and sorting.

Yeah, you can’t use import twice if it defines a matcher, because then you’ll be defining the same matcher twice, and that’s not allowed (as the error tells you). There’s a bunch of ways to work around that, such as passing an argument to the import and using that argument in the name of the matcher, or just defining the matcher in another snippet that you import only once, etc.

1 Like

Thank you.