How to do request header validation in Caddy v2?

1. Caddy version (caddy version):

v2.4.3 h1:Y1FaV2N4WO3rBqxSYA8UZsZTQdN+PwcoOcAiZTM8C0I=

2. How I run Caddy:

I run it as sudo caddy run --config=/etc/caddy/Caddyfile with the following config file:

example.com 
        @apirequests {
                header X-Auth-token test123
        }

        reverse_proxy @apirequests localhost:5000

        respond "No soup for you!"
}

a. System environment:

Linux Mint 20, the server starts as a regular process (not via systemd or anything like it).

3. The problem I’m having:

My objective is to to achieve what was accomplished in this earlier discussion, but for the newer version of Caddy.

After failing to find any references to the if syntax used in the related thread, I assumed this is because of a difference between versions, so I decided to find an alternative way of expressing that logic.

In the enclosed config I’m trying to say “go to localhost:5000 if the request header X is present and is set to the value Y”, otherwise return a generic response to signalize an issue.

I test it with curl --verbose --header "X-Auth-token: test123" https://example.com and the server always responds with “No soup for you!” - which means that my matching rule for @apirequests was not triggered.

I would appreciate any hints on figuring out the correct way to accomplish this.

It’s because respond comes before reverse_proxy in the default directive order:

You can do one of these things:

  • Wrap your directives in a route { } block:
route {
	reverse_proxy @apirequests localhost:5000
	respond "No soup for you!"
}
  • Wrap each directive in a handle { } block:

handle @apirequests {
	reverse_proxy localhost:5000
}
handle {
	respond "No soup for you!"
}

(Actually you could just wrap the reverse_proxy in handle, since handle comes before respond already.)

  • Or use this global option:
{
    order reverse_proxy before respond
}

so that the reverse_proxy is evaluated first.

(In hindsight, I probably could have put respond more toward the end of the default ordering, but it is useful sometimes as in some cases you want the reverse_proxy to be the “else”, and anyway, it’s too late to change it now.)

See also:

1 Like

Thank you for the quick reply. For the benefit of archaeologists digging through this, here is the full config that works:

example.com {

        @apirequests {
                header X-Auth-token test123
        }

        route {
                reverse_proxy @apirequests localhost:5000
                respond "No soup for you!"
        }
}
2 Likes

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