Caddyfile validation

I have a Caddyfile, that I convert to JSON and then use the JSON API end-point to make updates.

All I am need is for someone much more knowledgeable than me to quickly look over my Caddyfile and see if you can find anything that can be better. I would greatly appreciate it.

Two things I am missing, that I’d like are to be able to redirect HTTP to HTTPS, but without the Permanatly Moved (301) and to give Temporarily Moved (302). The second is setting up the on_demand_tls end-point.


{
	# This is pointing to Let's Encrypt Staging environment (for dev)
	# https://letsencrypt.org/docs/staging-environment/
	# This will allow you to get things right before issuing trusted
	# certificates and reduce the chance of your running up against rate limits.
	#acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
	acme_ca https://acme-v02.api.letsencrypt.org/directory

	# causes all certificates to be issued internally by default,
	# rather than through a (public) ACME CA such as Let's Encrypt.
	# This is useful in development environments.
	# local_certs

	# configure automatic HTTPS. It can either disable it entirely (off)
	# or disable only HTTP-to-HTTPS redirects (disable_redirects).
	# auto_https off
	auto_https disable_redirects

	email gal....64@gmail.com

	debug
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

(SecurityHeaders) {
	header_up Access-Control-Allow-Origin *
	header_up Access-Control-Allow-Credentials true
	header_up Access-Control-Allow-Headers Cache-Control,Content-Type
}

:80, :443 {
	reverse_proxy jeff.xxxxxx.ca {
		header_up Host {http.reverse_proxy.upstream.hostport}
	}

	tls {
		on_demand
	}

	# serve photography folder
	root /files/* /opt/ivt/photography

	# Enable the static file server.
	file_server

	route /weather/* {
		uri replace /weather /socket.io
		reverse_proxy * localhost:3010 {
			import SecurityHeaders
		}
	}
	route /ptz/* {
		uri replace /ptz /socket.io
		reverse_proxy * localhost:3006 {
			import SecurityHeaders
		}
	}
	route /liveview/snapshotjson* {
		uri replace /liveview/ /
		reverse_proxy * localhost:3004 {
			import SecurityHeaders
		}
	}
	route /liveview/* {
		uri replace /liveview /socket.io
		reverse_proxy * localhost:3004 {
			import SecurityHeaders
		}
	}
	route /archive/* {
		uri replace /archive /socket.io
		reverse_proxy * localhost:3003 {
			import SecurityHeaders
		}
	}
	route /alarms/* {
		uri replace /alarms /socket.io
		reverse_proxy * localhost:3002 {
			import SecurityHeaders
		}
	}
	route /console_socket/* {
		uri replace /console_socket /console/socket.io
		reverse_proxy * localhost:3001 {
			import SecurityHeaders
		}
	}
	route /web_app_socket/* {
		uri replace /web_app_socket /web/socket.io
		reverse_proxy * localhost:3001 {
			import SecurityHeaders
		}
	}
	route /* {
		reverse_proxy * localhost:3001 {
			import SecurityHeaders
		}
	}
}

Remove the /* and * here, they’re redundant. See Request matchers (Caddyfile) — Caddy Documentation

	route {
		reverse_proxy localhost:3001 {
			import SecurityHeaders
		}
	}

This proxy doesn’t make sense, it’ll never do anything, because you have route blocks that will get sorted first and always run before it reaches that.

Also if you’ve updated to v2.4.5, you can use the placeholder shortcut {upstream_hostport} instead, to save a few characters.

Remove :80 from your existing site block, then make a new site block like this:

:80 {
	redir https://{hostport}{uri} 302
}

Just add this to your global options:

	on_demand_tls {
		ask      <endpoint>
	}

The endpoint should be something Caddy can reach. Caddy will make GET requests with the query ?domain=<hostname> in it. If you return an HTTP 200 status, Caddy will accept it and issue a certificate for that domain. If it’s any other status (use like 400 or something) then it won’t.

2 Likes

Does the endpoint have to be https or can it be a local microservice running on the same machine?

I think I did that one because it’s the only matcher that has the subdomain needed for the Let’s Encrypt certificate.

But you have no matcher there. Run caddy adapt, and you’ll see it’ll be ordered last, and will never be reached because you already have a route which will match all requests which will run before that one.

It can be HTTP, on the same machine. Whatever works for you.

Thanks for the info on the endpoint.

If you look at the Caddyfile, where can I put a matcher for the subdomain?
I also want to make sure it’s not locked down to the subdomain and that “localhost” can still be used by the microservices accessing it.

Thanks

You make site blocks: