--- date: 2022-07-29 toc: true title: Setup a local CA for your homelab --- ## Why ? I hate seeing red locks on the website I browse. That's it. ![img](images/wazowskidisappointed.jpg) And since I have friends that like to do very smart pranks involving MITM attacks, I want to protect myself (and my passwords, as long as they might be) from them...... Ok I may be the "friend" that play these pranks but I always ask for their consent! Jokes aside, we will use [step-ca](https://smallstep.com/docs/step-ca) as it's lightweight, easy to deploy and it just works. ## Machine I have deployed my instance on a separate LXC on proxmox: - OS: Debian (I used Buster but chose what you want) - CPU: 1 - RAM: 2G (Might be overkill, but I have loads of RAM) - Storage: 15 GB (Bit too much, but I don't care) Its IP address is assigned by DHCP but its lease is static; make sure to assign it an entry in your local DNS server! ## Installation First, download the latest release of `step` [here](https://github.com/smallstep/cli/releases/latest) and install it. This is pretty straightforward, just follow this example (on an amd64 platform): ```sh wget https://dl.step.sm/gh-release/cli/gh-release-header/v0.21.0/step-cli_0.21.0_amd64.deb sudo dpkg -i step-cli_0.21.0_amd64.deb ``` Then, do the same thing with the latest version `step-ca` of (https://github.com/smallstep/certificates/releases/latest). Again, just do: ```sh wget https://dl.step.sm/gh-release/certificates/gh-release-header/v0.21.0/step-ca_0.21.0_amd64.deb sudo dpkg -i step-ca_0.21.0_amd64.deb ``` `step-ca` can be setup as a systemd service, but instead of copy pasting their instructions like a moron, I'll just tell you to follow them [here](https://smallstep.com/docs/step-ca/certificate-authority-server-production#running-step-ca-as-a-daemon). There are a lot of steps so please be sure to read the instructions carefully. ## Configuration As I am sure that you've carefully followed the instructions on how to make your CA a daemon, your latest creation should be correctly initialized, so no need to `step ca init` :wink:. Congratulations: you can now generate and distribute TLS certificates to whomever you want! You might want to continue reading this though as we'll see how to setup the ACME server and that, I can assure you, is really cool. ### ACME server ? Come on, you've probably already heard about that; ever heard of _Let's Encrypt_ ? Maybe their _certbot_ script ? Well, it can requests certs as an ACME client. If you love reading documentations, go ahead and do so [here](https://letsencrypt.org/docs/client-options/). TLDR: deploying an ACME server on you CA will allow you to requests cetrificates for your local services using scripts like certbot or even [Traefik](https://traefik.io/) (and we'll even talk about this later on). ### I'm sold, show me the magic I knew you'd like it! Setting up the server isn't that hard, you'll need to add an ACME provisionner: ```sh step ca provisioner add acme --type ACME ``` then restart your server (the following command only works if you've made your CA a systemd daemon): ```sh sudo systemctl restart step-ca ``` You can try to request a certificate from your ACME server with: ```sh step ca certificate --provisioner acme ``` Please note that this last command might not work if you already have a service listening on port 80 as the `step` command. ## Actual usage Remember that your ACME server must be able to find your servers to give them certificates; you might be good by just requesting certs with IPs but, in case you want to distribute named certificates (don't know if that's how they're called, but you get me), don't forget to add a DNS entry to your local resolver for each server that needs named certs. ### Traefik I have been proxying my services with [Traefik](https://traefik.io/) for almost a year now and I don't regret switching to it one bit; it is easier to expose my conteneurised service, easier to get new certificates, easier to use in general. I might have had a hard time setting up all the TLS params at the begging but it was all worth it in the end. I won't do a tutorial on how to setup a Traefik reverse proxy, but I'll just show you how to use it like you'd normally use the Letsencrypt resolver. To add your ACME server as an SSL certs resolver, add these commands to your Traefik container (you don't have to delete the other resolver to do so, just in case you were thinking about it): ```yaml # Lets call the resolver myca # The HTTP entrypoint is called http # Your caServer's addresse in myca.lan - "--certificatesresolvers.myca.acme.httpchallenge=true" - "--certificatesresolvers.myca.acme.httpchallenge.entrypoint=http" - "--certificatesresolvers.myca.acme.caServer=https://myca.lan/acme/lan.alxczl.fr/directory" - "--certificatesresolvers.myca.acme.email=me@mail.lan" - "--certificatesresolvers.myca.acme.storage=/myca/acme.json" ``` You'll have to: - Mount the host certs folder to the container's certs folder so that the root CA cert can be retrieved by the container - Add a volume to the container and mount it to `/myca/`; it'll contain the certs, etc. Once your Traefik container is setup, requesting certs from the CA is quite easy; just add the following label: ```yaml # The router here is called myservice - "traefik.http.routers.myservice.tls.certresolver=myca" ``` This will make Traefik automatically fetch the certificates from your CA, just like it would with Let's Encrypt. ### Certbot Using your ACME server with certbot is also pretty easy; you just have to add `--server https://myca.lan/acme/acme/directory` to the command (e.g `certbot certonly -n --standalone -d test.lan --server https://myca.lan/acme/acme/directory`).