
Caddy 0.10 Released - anc84
https://caddyserver.com/blog/caddy-0_10-released#HNSaysPreviouslySubmittedButCouldNotFind
======
overcast
So far I'm loving Caddy. Super simple to configure, and the auto management of
SSL certificates is magical. However, for all of the simplicity, they are
still pretty resistant to properly packaging it up in the repositories. By far
the longest part of getting it running, is the stupid manual configuration of
launch daemons, working directories, and permissions. For software that prides
itself on dead simple management, the basics of getting it into a package
manager should not even be a discussion.

With that said, I 100% moved all of my sites from Nginx to Caddy after the
config file setup is around three lines per site.

~~~
bauerd
>the basics of getting it into a package manager should not even be a
discussion.

Last time I looked into it, their problem was that Caddy plugins must be
configured at compile-time, because runtime plugins seem to be hard to do with
Golang (besides RPC). Because there's a handful of Caddy plugins, they'd
either have to provide a slim package with no plugins, or ship with all or
only some blessed plugins. Obviously all approaches have drawbacks … they
discussed the option of shipping their own package manager for Caddy plugins,
too (shudder).

See: [https://forum.caddyserver.com/t/packaging-
caddy/61](https://forum.caddyserver.com/t/packaging-caddy/61)

~~~
singlow
Nginx had the same issue. Ubuntu ships 3 or 4 versions - nginx-light, nginx,
nginx-full, nginx-extras - for different numbers of modules included.

~~~
finid
With dynamic modules support now in Nginx, that practice should end.

~~~
JdeBP
As Michael Lustfield said in Debian bug #790623 in October 2015.

------
sergiotapia
Caddy is a web server written entirely in Go.

Features:

\- Easy configuration with Caddyfile

\- Automatic HTTPS via Let's Encrypt; Caddy obtains and manages all
cryptographic assets for you

\- HTTP/2 enabled by default (powered by Go standard library)

\- Virtual hosting for hundreds of sites per server instance, including TLS
SNI

\- Experimental QUIC support for those that like speed TLS session ticket key
rotation for more secure connections

\- Brilliant extensibility so Caddy can be customized for your needs

\- Runs anywhere with no external dependencies (not even libc)

~~~
pbreit
So is it ready for "prime time"? Should I be considering it over Nginx for
side projects or real projects?

~~~
drdaeman
Yes, it's pretty nice and sometimes is even nicer than nginx in some regards.
E.g. it notices DNS changes without SIGHUP, so if your app is containerized,
Caddy just works when you start and stop containers, when nginx requires
special tricks.

However, it lacks in some areas, for example if you need some complex regex-
based routing it could be somewhat unpleasant (while probably doable, the
configs would look really messy).

~~~
majewsky
Wait... why would a web server need to know about changing DNS?

~~~
drdaeman
It doesn't need to know about the changes, but it surely needs to notice them
as they happen.

For example, FLOSS nginx does DNS lookups just once on startup. On config
(re)loads, to be exact.

E.g. when you have "proxy_pass [http://spam;"](http://spam;") or "uwsgi_pass
spam:9000;", you'll end up with permanent 502 (until a SIGHUP) after you've
started a new "spam" Docker container and then removed the old one.

There are well-known workarounds like "set $backend
"[http://spam";](http://spam";) proxy_pass $backend;", but it's nicer when you
don't even have to think about this and know that TTLs are properly honored.
Caddy does that.

------
lol768
The MitM detection is interesting. How long until these appliances start
altering the HTTP request's User-Agent header to avoid detection (or adding
logic such that the handshaking process mimics that of the browser), though?

To me, HPKP with preloading seems like a more reliable approach (and browsers
shouldn't allow this to be overridden [1]).

[1] If this breaks corporate MitM attacks, great. This practice always struck
me as incredibly invasive and I'd personally be concerned if an employer was
doing this. I think some traffic data should be able to be logged and
timestamped in case of abuse (e.g. SNI info, TCP connections, DNS lookups) but
I don't see a need to intercept application data - and honestly, it seems like
the vast majority of these appliances hinder security.

~~~
vosper
I'd also be concerned if an employer was doing it, unless there was a good
reason - and I can think of a few of those. For example, companies that deal
with sensitive health, financial or legal information. They may need
assurances (or at least a paper trail) that's a lot stronger than "we don't
MITM and we trust our employees to do the right thing".

~~~
martingxx
Even with those reasons, I believe the risk outweighs the potential benefits.
It's not just about trusting the intentions and assurances of the company, but
also their competency and knowing they're not being compromised etc. Hackers
don't care about paper trails. These are things you typically can't measure.

If you have untrustworthy employees, you have bigger problems than you can
solve with by MITM attacking everyone.

------
bpierre
How does it compare with [https://traefik.io/](https://traefik.io/) (reverse
proxy, written in Go, automatic HTTPS / letsencrypt) ?

~~~
doublerebel
Yep, I use the similar eBay/fabio which pulls my LE certs from
hashicorp/vault, much better than leaving them in a filesystem. Can't imagine
using a proxy/ingress/LB without automatic reactive routing these days. All I
have to tell Fabio is what interface to listen to.

~~~
zenlikethat
Why do you say it's better to pull them from Vault? Unless MTLS is set up
talking to Vault, you are pulling secrets unencrypted (and maybe
unauthenticated) over the network... a local file system is not bad for small
scale deployments if setup with the proper permissions.

------
papey
Awesome product, I'm using it at work and it's incredibly fast. Configuration
is easy, documentation is clear. The systemd unit provided in the repo is
insane, all the latest security and isolation stuff are in it, a great
inpiration for writing good systemd units.

~~~
mixmastamyk
Took me a while to find:

[https://github.com/mholt/caddy/tree/master/dist/init/linux-s...](https://github.com/mholt/caddy/tree/master/dist/init/linux-
systemd)

------
jbergstroem
I would just like to bring up how much I admire the way they want to profit
off Caddy[1][2]. Sponsorships and focused development; followed by "remember,
caddy is open source". My only feedback would be that they introduce a
"$50/mo; my bank is not big enough" for people that wants to endorse their
model/software.

Look at nginx, where new functionality is hidden behind a paywall. I don't
want to deny them [nginx devs and sales people] their well-deserved money, but
it pushes me away.

[1]: [https://caddyserver.com/blog/options-for-
businesses](https://caddyserver.com/blog/options-for-businesses)

[2]: [https://caddyserver.com/pricing](https://caddyserver.com/pricing)

~~~
mholt
Thanks for the feedback! We are mindful of people who want to contribute funds
but aren't able to because of the price. We get a lot of requests for stickers
and T-shirts and even jackets/sweaters; so we might go that route for
individuals being able to contribute.

~~~
tnorthcutt
Why not introduce a $50/month (hell, even a "pay what you want") option, with
no sponsorship benefits (mentions, link, etc.)? Depending on volume, you could
still offer Slack access as a benefit, perhaps if paid up front for a year.

~~~
mholt
That's possible! We wanted to gauge initial interest first but let me talk to
Cory about this.

------
thearrow
PSA for those who use caddy's proxy "without" configuration item - it is
broken in 0.10:
[https://github.com/mholt/caddy/issues/1604](https://github.com/mholt/caddy/issues/1604)

This bit our app during testing.

------
mike-cardwell
Surprised there isn't more talk about the MITM detection here. Anyone got a
TLDR of how this is supposed to work? I'm going to read the full doc when I
get home, but I'd be interested in hearing peoples opinions on how accurate it
is likely to be.

~~~
kondbg
The authors of the original paper [1] identified that the set of client cipher
suites advertised by each browser can be used to fingerprint and identify a
browser.

Caddy records the cipher suite advertised by the client during the TLS
handshake and then later examines the client's user agent. Using the
fingerprinting techniques mentioned in the paper, Caddy then determines
whether or not the advertised user-agent is compatible with the user-agent
that it inferred through the client cipher suites.

TLS interception proxies establish their own TLS connection to the server.
Depending on what underlying TLS library the proxy uses, it also has its own
unique fingerprint. When the TLS proxy forwards the user's request, Caddy
detects the mismatch and flags it as a MITM.

[1] [https://jhalderm.com/pub/papers/interception-
ndss17.pdf](https://jhalderm.com/pub/papers/interception-ndss17.pdf)

------
nzjrs
Anyone with experience using this as a dynamic reverse proxy - I need to proxy
certain requests to private container (ports) where the port isn't known until
the container is booted, and containers come up and down as users require
them.

~~~
tyingq
Depending on what that private container is serving up, an API gateway might
work better. Tyk is one that's written in golang. It has a rest API and hot
reload, so it should be able to handle your use case of dynamically allocated
ports.

[http://tyk.io](http://tyk.io)

------
dyeje
Pricing page is pretty bad. Draws your eyes with primary colors and bold fonts
to $5000/yr and $9900/yr. I had to swallow the sticker shock and look around
the page to see the weird, faded side-bubble telling me it's free.

------
snowpanda
I always really liked this video by Matt:

[https://www.youtube.com/watch?v=ZyVA9tuif4s](https://www.youtube.com/watch?v=ZyVA9tuif4s)

The way he explains things makes me wish he did tutorials for programming
languages.

------
haarts
They mention that 'Default Timeouts' have been disabled. Urging users to 'Act
according to your threat model!'.

I'm not sure I understand. How is not having these timeouts a security thread?
Someone could potentially open up enough HTTP connections to starve others
from having the opportunity to do so?

~~~
mholt
This is true; but slowloris attacks don't require opening as many connections.
We've seen one or two instances where buggy (or malicious?) clients were
slowlorising Caddy instances; but we were too eager to enable timeouts by
default I think.

~~~
zzzcpan
No, not having timeouts is rather bad practice. There are a lot of clients out
there that never close connections for various reasons. And since TCP doesn't
use healthchecks and most systems by default have limits on the number of
descriptors per process, your web server in default configuration will simply
leak descriptors and memory over time until the whole thing stops working. The
only sane choice here is to have timeouts enabled everywhere and explicitly
allow them to be disabled, not the other way around.

~~~
mholt
Believe me, we wanted to do this, but it broke a lot of WebSocket connections
and other legitimate, long-lived connections. It confused many users. It's
hard to know what is legitimate and what is not. I wish we could configure
timeouts on a per-request basis but not without some serious hacking around
the net/http lib for now.

I do encourage setting timeouts when you are able to. It's easy, for example:

    
    
        timeouts 30s
    

I have heard of occasions where people have done this and it made their
servers breathe again. At this point it's just up to your discretion/judgment.

~~~
zzzcpan
If I remember correctly, websockets have ping/pong support on both ends for
that. So to handle them properly you have to detect connection upgrades and
then start issuing ping requests to clients periodically, closing their
connections if they fail to respond in time, but still using timeouts
everywhere.

------
cdnsteve
Does Caddy have a pluggable extension set where you can write your own
middleware, in Go?

~~~
zalmoxes
It does and it's documented on the wiki. I've written a few plugins privately,
like implementing SCEP into caddy and adding a few other features.

Due to the nature of the plug system, you'll have to build caddy yourself if
you add customizations like that.

------
tlrobinson
Random question: is there a way to start Caddy as root so it can bind to port
80 (for example) then change the user so a non-root user can send a `USR1`
signal to Caddy to get it to reload the configuration?

~~~
zufallsheld
At least with systemd caddy starts as a non-root user, if you use the provided
unit-file:
[https://github.com/mholt/caddy/tree/master/dist/init/linux-s...](https://github.com/mholt/caddy/tree/master/dist/init/linux-
systemd)

~~~
tlrobinson
Is there something like `setcap` for macOS?

    
    
        Give the caddy binary the ability to bind to privileged ports (e.g. 80, 443) as a non-root user:
    
            sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy

~~~
tyingq
There isn't. There's a port of authbind, but I don't think anyone was able to
get it working with caddy. The only solution I've heard of working is using
the pf firewall to port forward, for example, 8080 to 80. Like this:
[https://salferrarello.com/mac-pfctl-port-
forwarding/](https://salferrarello.com/mac-pfctl-port-forwarding/)

------
snowpalmer
Any benefit in using this inside a docker container instead of nginx? No need
for SSL or many of the other features I'm seeing listed here since it's all
behind an Amazon ELB.

~~~
xrstf
We are using Caddy as a simple reverse proxy in Docker environments. The
configuration is a bit simpler than nginx and we love the tiny Docker images
we can create (not sure how large an nginx-full installation is).

That being said, we did run into a few issues that forced us to go back to
older Caddy versions, like broken websocket support or the timeout issue in
0.9.5. Also, sometimes the documentation is a bit lacking and unclear. DNS
resolution seems to be flaky sometimes (we're using alpine-based containers
and sometimes Caddy just won't resolve names of other containers, even though
a curl inside the container can resolve the names just fine).

So if you've got a working nginx setup, I'd say stick with it. For new
projects it is worth to check out Caddy. The issues we ran into occured early
in our development process, they didn't just suddenly happen in production, so
once you've tested everything, Caddy just works.

------
blowski
When would I use Caddy, rather than using nginx and configuring Let's Encrypt
for myself? Honest question.

~~~
knrz
I feel like the niche Caddy's trying to fill is for people who don't want to
bother with that, or don't want to learn. If you already know how to set up
nginx and LE (like you and I do), its only appeal is relatively minor:
potentially saving a quarter or half hour.

~~~
xiphias
I think over time there will be a similar server written in Rust, where at
least we can be sure that there are no buffer overflows..until then nginx is
probably better in every situation.

~~~
Sphax
Do we really need someone to mention Rust in every thread ?

~~~
xiphias
No, it just makes sense to have a fast and safe HTTP server at the same time.

Go is ona average 3x slower than C according to bechmarks, and it's hard to
get rid of this issue because of how the language is architected. I just don't
see Caddy as a possible long term replacement for nginx.

------
jhack
This is the first I've heard of Caddy and I'm really impressed by the feature
set. Looks like a breath of fresh air, can't wait to try it.

------
brotherjerky
Is there an official Docker image yet?

~~~
mholt
No, but this is the one I usually recommend for now:
[https://hub.docker.com/r/abiosoft/caddy/](https://hub.docker.com/r/abiosoft/caddy/)

------
daari0
Is ECDHE_ECDSA possible on Caddy?

