I’m trying to add an extra layer of security on top of the security handled by the app that is being reverse proxied. I want to make it so that requests get a basic auth challenge unless they are
A) a Chromecast which has no way to basic auth through, or
B) the Android app which also has no way to basic auth through.
So in order to do that I’ve created the two named matches @notJellyfinApp and @notChromecast
I can get both of them to work just like I want, but only one at at time
basicauth @notJellyfinApp {
works just fine by itself, and so does the @notChromecast by itself.
I can’t combine both of my requirements into a single named match because those are treated as AND and in my case I want to be an OR condition. From what I’ve read OR can be done by putting two matches into the statement, but that doesn’t seem to work on the basicauth { option as far as I can tell.
4. Error messages and/or full log output:
caddy validate 2020/05/08 15:52:16.766 INFO using adjacent Caddyfile validate: adapting config using caddyfile: parsing caddyfile tokens for 'basicauth': Caddyfile:17 - Error during parsing: unrecognized hash algorithm: @notChromecast
5. What I already tried:
I’ve tried a few different ways to combine them like basicauth [@notJellyfinApp @notChromecast] { basicauth @notJellyfinApp, @notChromecast {
So far I can’t find any other examples of Caddy2 taking two matchers for basicauth, so I’m not sure if it’s just not supported or if I’m missing something obvious. I can’t find anything mentioning multiples for this use case where it’s an OR and not an AND. Request matchers (Caddyfile) — Caddy Documentation
Thanks in advance for your assistance!
I tried your fix, but that doesn’t work unfortunately. Now neither situation A) Chromecast or B) Android app work. That exclude is saying “Don’t do basicauth if it’s an Android app AND and Chromecast” which is impossible, the two can’t be happening at the same time, its an OR situation but this fix would work if it was an AND situation.
Gives an expected 302 to the main URL, and a 200 to exact URLs
curl -I https://caddy.local/jellyfin/
Anything other than either of those two headers, forces basicauth to happen, which gives a 401 and prompts for auth in browsers that support that. curl just dies unless you feed it with curl -I https://caddy.local/jellyfin/ --user username:password and in that case I get a 302 to the main and 200 to exact URLs which is perfect.
Turns out that the following doesn’t adapt to the correct JSON:
I’m working on a bug fix. Essentially only the last header matcher is kept within the not block. It’s a Caddyfile parsing bug.
If you have a sec, could you try this and see if it behaves correctly as well (just for my sanity)? I think it should be equivalent to the expression matcher I gave you, based on my conversation with @matt.
@excluded {
not {
header X-Requested-With org.jellyfin.mobile
}
not {
header X-Referer https://apps.jellyfin.org/chromecast/
}
}
That second config with two not statements also appears to be working correctly on my side. Is there a benefit one way or the other like one being more efficient processing the rules? This system is in a homelab, so load shouldn’t be a concern, it’s more of a curiosity.
Hmm, that’s a good question, regarding performance. CEL matchers are still experimental, we haven’t done a whole lot of performance testing. I would expect that it would be slightly slower than standard matchers though, because there’s more steps involved in passing the data through to the CEL environment.
Since the CEL expression matcher is still considered experimental, I’d probably have to suggest using the regular matchers instead for now, because there’s a chance we change the API.
I also realized you could reduce the syntax a bit further to this:
@excluded {
not header X-Requested-With org.jellyfin.mobile
not header X-Referer https://apps.jellyfin.org/chromecast/
}
The not matcher is special in that if you only need to negate one other matcher, it can be done inline. In Caddy v2.1, you’ll also be able to have single-line named matchers as well (like @x not header a b)