Redirect loop when rewriting / to /index.html to apply basicauth to it

(Renaud Guérin) #1

Hi, basically this redirect loop bug described below, which I hope would be fixed in 0.10.4 (it looked like the issue was this one : is still present in 0.10.11

Any ideas how else to implement basicauth for all paths except a health-checking path ?
I’m even happy to list all paths explicitly, the problem is “index.html” then gets into a redirect loop, as described.


(Magikstm) #2

Could you share a caddyfile and possibly a working repo that reproduce the issue?

(Matthew Fay) #3

I don’t think that setup is possible any more due to a change (I don’t recall which commit) to the static file server to enforce proper requests for indexes. Specifically, the static file server issues redirects for index files back to the parent folder (e.g. /index.html -> /).

Since you’re rewriting / -> /index.html internally, a request for / results in a redirect to /.

Try renaming index.html to home.html or similar and rewriting to that instead, and see if that solves the issue. Unfortunately, basicauth doesn’t have any method of excepting paths under a protected base path.

(Renaud Guérin) #4

Here’s a sample Caddyfile showing the problem :

root .

rewrite /Dockerfile /index.html
rewrite /Caddyfile /index.html

# Note: don't break /config.json !
# It's currently used as the health check URL for this container in Kubernetes.
rewrite /config.json /config.json.tmpl
templates /config.json.tmpl

# We explicitly rewrite "/" to index.html so that we can apply basicauth to it.
# Unfortunately "basicauth /" is catch-all, not an exact match.
# WARNING : this rewrite works in Caddy 0.9 but causes a redirect loop in 0.10.3
# Might be fixed when 0.10.4 is out :
rewrite / /index.html
# Same result with:
# rewrite / {
#     regexp ^/$
#     to /index.html
# }

# We want to protect everything except the health check path (config.json)
# which must return 200 even without auth
# Unfortunately basicauth exceptions don't exist in Caddy, so we instead we
# need to explicitly list here everything that must be protected
basicauth {$AUTH_USER} {$AUTH_PASSWORD} {

# Force Content-Type for JS because (at the time of writing) Caddy defaults to
# application/x-javascript which is deprecated, plus a typo in the nginx controller code
# causes gzip compression to be disabled for x-javascript 
mime .js application/javascript

# Supports things like /about
# Defaults to index.html to let the app handle 404s
rewrite {
    to {path} {path}/ {path}.html /app.html

(Renaud Guérin) #5

Just to restate my goal : I need Caddy to return 200 on some health checking path (any path!), bypassing basic auth on this path only. Similar to return in nginx :

Each of the workarounds I could think of to achieve this seems to have a gotcha.
If ANY one of the following was possible, there would be a way forward for my use case :

  • Immediately return a specific HTTP response code when a specific path is requested, bypassing static file serving and basicauth altogether.
  • Allow specifying an exact path in basicauth (like “^/$”) (currently / is a subpath match, there’s no way to express a match for / only)
  • Allow exceptions in basicauth
  • Not have things like index.html hard-coded in the static file server so that my / -> index.html rewrite hack could work.

I may try the home.html workaround you mention, but it could be a problem with whichever webserver our devs are using locally.

(Magikstm) #6

I would suggest trying loginsrv with jwt.

I’ve not tested your setup, but I believe it’s doable.

Additions in you caddyfile should minimally be something like:

jwt {
path /
redirect /login
except /healthcheckpath

login {
success_url /index.html
htpasswd file=passwords
jwt-secret secret