This is a very quick post, just to summarize some of the last days findings. Often the answer to the questions is explicit once you know about it, but it is very hard to find out when you don't know what you are looking for.
- Using Caddy HTTPS for localhost
I have known for a long time that Caddy is good because it offers out-of-box Let's Encrypt (and ZeroSSL) certificates, but I didn't know how to use them, because the last time I tried to use them for development it was a pain. I decided to give it another try.
The first thing to know is that you need to explicitly set localhost for the site in order to Caddy try to use a self signed certificate. It can later try to configure it, but it seems to need to install a library for that...
This is a very quick post, just to summarize some of the last days findings. Often the answer to the questions is explicit once you know about it, but it is very hard to find out when you don't know what you are looking for.
- Using Caddy HTTPS for localhost
I have known for a long time that Caddy is good because it offers out-of-box Let's Encrypt (and ZeroSSL) certificates, but I didn't know how to use them, because the last time I tried to use them for development it was a pain. I decided to give it another try.
The first thing to know is that you need to explicitly set localhost for the site in order to Caddy try to use a self signed certificate. It can later try to configure it, but it seems to need to install a library for that, also, I was using Podman as a why to keep my machine as clean as possible, so I didn't want to install the library, I think it is just for the automatic configuration.
- Where Caddy stores self signed certificates?
I am using containers, and the official Caddy image has some really nice and useful documentation, the problem is I didn't pay attention because I was not aware I was going to use it.
No matter how you installed caddy caddy environ | grep caddy will tell you some information about the data and config directories, look for AppDataDir and AppConfigDir, respectively. For my container I got the following output:
caddy.HomeDir=/root
caddy.AppDataDir=/data/caddy
caddy.AppConfigDir=/config/caddy
caddy.ConfigAutosavePath=/config/caddy/autosave.json
caddy.Version=v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=
If you are using containers, the documentation says it is important to mount persistent volumes for /data and /config directories, and it is, even if you don't care about the cpu and memory usage, if you create everything each time you will have to configure things again.
The second thing is that by using a named volume for that information, it is easy to use the files from the host without "polluting" your system, at least it will be more explicit if you eventually remove those files.
- Configuring curl and your browser.
Which file I need to use?
First, it is important to know which file to use, it is /data/caddy/pki/authorities/local/root.crt where pki means Public Key Infrastructure, and we need the public part of the root certificate, I tried to look for the reference where I found it, but I was out of luck.
Firefox
I think it is similar for any browser but for simplicity I'll cover only firefox. You need to open about:preferences#privacy, you need to scroll down until you see Security and Certificates, then click the View Certificates button to open the Certificates Manager, be sure to be in the Authorities tab, then click Import... and select the file.
A new certificate authority from Caddy Local Authority will appear and now you can use HTTPS locally without warnings and additional validation steps.
Curl
For curl we have two ways of working with HTTPS, the proper way, and the workaround.
The workaround is using the option -k --insecure, quick and useful, but it can grow into a bad habit. The proper way is to use the --cacert and point to the same root certificate:
curl --cacert ./data/caddy/pki/authorities/local/root.crt https://localhost:3000/
The only thing to be careful about is the path of the certificate, it would be nice to be able to configure that, in a per project basis, but I'll leave that for later.
