Hacker News new | ask | show | jobs
by BilalBudhani 1012 days ago
I believe Caddy brought a much needed paradigm shift in web server space, it is an incredible piece of technology.

I have moved all my servers from NGINX to Caddy for the pass few years and I couldn't be happier.

Also, I would like to give a shoutout to the team behind Caddy. They have been nothing but great about constantly shipping updates and being incredibly helpful in their community forum.

2 comments

Caddy is amazing, but on production machines remember to disable the unauthenticated and enabled by default JSON-based admin API bound to localhost:2019, as it can be a serious security risk in certain deployments.

Put the following in your Caddyfile at the lowest scope to disable it:

  {
      admin off
  }
PSA: systemctl reload caddy will call this api. If you disable it, then reloading the server will no longer work.
Too good for sighup? I deplore an API when signals should work perfectly fine
Signals don't work on Windows. We want a unified API for all platforms. Also signals don't carry arguments, which is necessary to push a new config. At runtime, Caddy doesn't know where the config came from because config is just data.
Apologies in advance, I'm not trying to be mean spirited or too critical. I'm limited in my ability to express at the moment, on mobile.

The API can still be there, I'm just asking for better integration where feasible. Signal handling on Linux/similar

It's silly to tell my init process to go out 'to the network' to do something it can do directly against the child.

I would not expect turning off an admin API to effectively limit my way to administer the process.

Services will generally ordain a path for a config, overridable with arguments. The same file used then is what is re-read on reload.

Argument/command line changing during a reload isn't a thing, that's restarting. We give it config files as an argument (or implicit default) so that can be reloaded.

It's uncommon to start a process with one file, decide you want a new file path, but keep the PID.

See https://news.ycombinator.com/item?id=37482096, the plan is to switch to unix socket by default on certain distributions of Caddy.

But it won't be possible to add signals support. We've thought hard about it but it's simply not a fit. There's discussion in GitHub: https://github.com/caddyserver/caddy/issues/3967

Earlier versions of Caddy were just a single binary that accepted signals to reload; the newer versions add a bunch of process management stuff that just got in the way of our existing tooling (...why remove the signals? ugh!) so we just switched back to Nginx.
The only signal we don't support anymore is USR1. (It's not a powerful-enough API for config reloads.) That was why you switched your entire web server stack?
This default behaviour makes sense. If you're going to be using it for hosting in production, then read the documentation, and it's trivial to disable. If I recall, AWS has a similar default for some services. That is, access to the subnet (VPC) gives you full access to the attached service, no password required.
Disagree, to a degree. It's fine to offer this for extended use cases (ie: restarting from a second, trusted, host)

It would be more appropriate to handle signals, particularly SIGHUP. That's how most services have been handling reloads.

It's fine to offer an admin API, especially if I want a peer to be able to affect the local instance, but this shouldn't be the position init is placed in.

Put simply, the init process is what we depend on if everything else fails.

And mongo, and many others packages with insane defaults.

What if rm would by default just delete everything, as it assumes that makes sense? Stupid comparison, I know, also a stupid default.

Do you recall which AWS services are like this? Thinking I better check a few things!
If you have any old S3 buckets, listing the index used to (in relative terms quite a long time ago) be enabled by default.
Thanks!
At least, have it respond only to authenticated requests. Caddy supports client certificate authentication:

https://caddyserver.com/docs/json/admin/remote/access_contro...

Caddy also supports Unix sockets, which should be rather more difficult to smuggle requests to, and can be protected by file permissions:

    admin listen unix//var/run/caddy/admin.sock
This (if they definitely must leave the functionality enabled by default) is what should be the default honestly. I still can't fathom why that isn't the case!
Caddy maintainer here: we're looking to move to unix socket by default for Linux distributions. See https://github.com/caddyserver/caddy/issues/5317, the plan is to set this env var in the default service config but I'm trying to be careful about backwards compatibility so I haven't pushed the change for our deb package yet. Will likely do it soon.
I'll see about getting it made the default for the FreeBSD port at least.
I would imagine so the default behaviour could be identical across platforms.
I imagine it's for Windows users. But yes, it could very sensibly be the default in Unix.
While you are right, remember there are usually additional layers of security (and if not, there should be). On the network level, you would only allow ports 80/443 to reach the machine. And if you use a containerized deployment, you would only expose 80/443 as well.
If your application can be used to make outbound requests to the internet (and so many apps can be), you can easily make a GET against localhost. There are ways to lock that down, but they aren’t automatic.
Just another weird and stupid default waiting to be exploited.
Works on localhost. It is not a big deal.
This is how trivial bugs turn into full-fledged threats. Increasing attack surfaces without any justification is bad cyber security.
If you're hosting your applications on localhost it can be a security risk.

A blind SSRF vulnerability (with payload control) in your application could be used to gain full control over the reverse proxy resulting in the attacker gaining full unfettered access to your network.

If you're not using it (and you shouldn't be using such functionality on a production machine), then you don't need it and should disable it, see: https://owasp.org/Top10/A05_2021-Security_Misconfiguration/

It is absolutely a big deal. Any server software should be secure by default, period.
If your server reaches out to user-provided URLs, it can be a big deal. Especially with DNS rebinding, remote users can bind domains to 127.0.0.1. Which avoids cors like protections.
We mitigate both DNS rebinding and cross-origin in the admin endpoint by verifying Host and Origin headers -- by default.
Alternatively don't serve your site over HTTP at all. Just redirect to HTTPS.

Edit, I just checked the Caddyfile for one of my sites. There is no config for redirecting HTTP to HTTPS is does it automatically. So this is entirely unnecessary.

No what I'm talking about here is the unauthenticated JSON-based configuration API that hosts itself on port 2019 on localhost of the machine that runs Caddy.

This is unrelated to sites hosted using HTTP. I was clumsily using the term "HTTP" to refer to the fact that this configuration mechanism is based on HTTP-communication.

So if I understand this correctly, anyone can bring down a site with a Caddy server by just running : curl -X POST "https://example.com:2019/stop" ? [0]

Seems counter to their objective of having secure defaults.

[0] https://caddyserver.com/docs/api#post-stop

No, by default it listens on localhost. So only processes running on the same machine can connect to that port.
Okay that makes sense. So why would you bother disabling this thing?

I'd imagine if someone already has local access to the server, it's already too late.

No, it is only bound to localhost.
Their filebrowser (originally part of caddy, since split out)[1] is a pretty nice tool for serving web-based browser of your NAS files.

I'm also a huge fan of Caddy's "handle" and "handle_path" directives for their simplicity.

One thing I will say against it though is that it does seem to run a little hotter than Nginx on my Pi4. Just random spikes here and there, whereas Nginx barely used to blip.

1: https://filebrowser.org/installation/

I've been using this for years but never knew it was a spin-off from Caddy. I really like it!
Technically it was shipped as a plugin for Caddy back then, it wasn't actually part of Caddy proper. Now they ship it standalone and recommend to reverse proxy to it. IMO it would be nice to still have the ability to include it as a Caddy plugin, but alas.
Yeah! Henrique Dias did great work with it. He should be very proud of his project.