There are some features in Caddy that are simply outstanding - HTTP/2 and Let's Encrypt integration, to name a few - both pretty much work out-of-the-box with zero-configuration.
On the other hand, there are still some gaping holes - for example, to block (or allow) a 192.168.0.0/17 IPv4 subnet in Caddy, one needs to do all of below:
- Install an addon [1];
- Which used to require recompilation, with 0.9 release you can just click an option during download, yay!;
- Add 128 ranges to cover this single subnet: 192.168.0.0-255, 192.168.1.0-255, ...192.168.127.0-255. Configuration doesn't support subnets, only ranges. And only ranges in last octet, i.e. 192.168.1.0-255 (meaning 192.168.1.0/24), or implied ranges by trailing octet(s) omission, i.e. 192.168 (meaning 192.168.0.0/16) [2].
[2] Which is mildly confusing notation too, since traditional UNIX inet_aton() call would interpret this as 192.0.0.168. Try typing "ping 192.168" on Linux.
Except for iptables doesn't work on per-host or per-URL level (well, technically one could try with a string-matching, but that would be just a crude hack).
I love the super-simple configuration, but it comes with some tradeoffs. For example, last I checked, I couldn't forward some requests to a hostname to another machine, while serving certain URLs (e.g. /static) from the local machine.
On a related note, I haven't used Caddy but have used lego (which Caddy uses under the hood) and lego makes amazingly easy to get certs via commandline and DNS challenge.
Literally, one line (without needing root). Happy user.
Sure, if you want to serve TCP reset / ICMP port-unreachable to blocked users, then yes - iptables or external firewall is a more natural way to do it.
But what if you want to serve different content to "blocked" users? i.e. login page, "we're sorry" page, redirect to read-only version of the site, reminder to connect to office VPN, anything like that...
Another example - more than one site on the same (server) IP, and only part of them are (client) IP-restricted.
Considering that firewalls are the best tools to "filter" by IP ranges, I'd suggest this "hack": Reroute the "blocked" packets (my favourite method is DNAT with iptables) to a different webserver which only serves the special pages.
On the other hand, there are still some gaping holes - for example, to block (or allow) a 192.168.0.0/17 IPv4 subnet in Caddy, one needs to do all of below:
- Install an addon [1];
- Which used to require recompilation, with 0.9 release you can just click an option during download, yay!;
- Add 128 ranges to cover this single subnet: 192.168.0.0-255, 192.168.1.0-255, ...192.168.127.0-255. Configuration doesn't support subnets, only ranges. And only ranges in last octet, i.e. 192.168.1.0-255 (meaning 192.168.1.0/24), or implied ranges by trailing octet(s) omission, i.e. 192.168 (meaning 192.168.0.0/16) [2].
Oh, and ipv6 filtering doesn't exist at all.
[1] https://caddyserver.com/docs/ipfilter
[2] Which is mildly confusing notation too, since traditional UNIX inet_aton() call would interpret this as 192.0.0.168. Try typing "ping 192.168" on Linux.