The number of great web-servers on our tool-belt is constantly growing. From the venerable Apache HTTPS over lighttpd to Nginx - and for the reverse proxy space pound, varnish and also Nginx - the number just keeps growing. Caddy is a newcomer in this field, yet its features are already impressive. Lets take a brief look.
Automatic TLS
While Caddy has all of the features one might expect of a modern web-server, the main selling point for me was the promise of automatic TLS certificate handling using the Let’s Encrypt CA.
Let’s Encrypt
You probably know about Let’s Encrypt, but for a brief recap: Lets Encrypt is a community Certificate Authority (CA) issuing TLS certificates to domain holders for free. They also developed the ACME protocol to make it much easier to request and renew TLS certificates.
Caddy is a ACME client
Caddy uses the ACME protocol to request and renew TLS certificates for the configured domains automatically. In fact it can even fetch certificates for domains not configured in an ad-hoc fashion.
Important to note: not only the setup of TLS is simplified by ACME, also the renewal.
And the renewal is probably even more important than the setup as some sites on the interweb can attest to ;-)
Self signed certificates with Caddy
Apart from the support for ACME, Caddy also has great support for self signed TLS certificates - as we shall see in a minute.
Caddy example
Again, we’ll use Fedora Linux, but the steps outlined here can easily be adapted to other Linux distributions.
Download and install
There are package repositories available for Debian and Fedora based distributions. Other pre built binaries are also available.
For Fedora:
sudo dnf install caddy
For RHEL 8 distributions:
sudo yum install 'dnf-command(copr)'
sudo yum copr enable @caddy/caddy
sudo yum install caddy
Minimal configuration file
Caddy supports configuration via an API or via a Caddy-file. We will use the Caddy-file here, since we seldom require the dynamic features provided by the API.
Let’s imagine we have a web-application running on localhost on port 8080 that we want to provide HTTPS encryption support for.
Lets also image that the name we want to expose this service on is www.example.com
- and we have already made sure that the name www.example.com is mapped to our host.
Mind you: the host does not have to have the IP address, it just needs to be reachable on it - so one can even run this behind NAT if the appropriate port forwardings have been setup. </sub>
The minimal Caddy-file required for such a case is in /etc/caddy/Caddyfile
:
www.example.com {
reverse_proxy 127.0.0.1:8080
}
Please notice how there is no configuration for TLS necessary at all.
Start Caddy:
sudo systemctl start caddy
sudo systemctl enable caddy
and you should have TLS enabled website at https://www.example.com/ - also, when requesting http://www.example.com it will redirect to HTTPS automatically.
The above example is just that - if you want to make this work you’ll need to use a domain under your control and have public inbound traffic.
Hopefully more (web)servers will add native support for the ACME protocol in order to provide support for TLS out of the box.
In the meantime…
Local self signed certificates
For development purposes it may be beneficial to create local self signed certificates only. One method of creating self signed certificates involves running the openssl
command.
As mentioned before, Caddy has also support for this built in.
Lets make the example.com example work by changing our hosts
file. Add the following line to /etc/hosts
:
127.0.0.1 example.com www.example.com
Then modify the /etc/caddy/Caddyfile
to look like this:
{
local_certs
}
www.example.com {
reverse_proxy 127.0.0.1:8080
}
Caddy needs one more tool in order to create certs:
sudo yum install nss-tools
Then restart Caddy:
sudo systemctl restart caddy
And now go to https://www.example.com/.
You will get a certificate warning as is usual for self signed certificates. But again configuration and setup was really pain less.
Please try it out!