Configuring an SSL certificate for Home Assistant with a vanity domain

One of the challenges with Home Assistant running locally in our network is enabling remote control via the internet while we’re not home. While there’s a $5/mo service that makes this easy, I decided to go my own way and punch a hole in our firewall to allow direct remote access to our Home Assistant instance. While there are a couple add ons such as Duck DNS and Lets Encrypt that promise to make this easy, I wanted to re-use the vanity domain I already own that is already pointed to our network for alternate purposes rather than a subdomain of Duck DNS. This left the challenge of acquiring and getting an SSL cert in-place, which ended up being more of a challenge than I expected, especially for this sleep deprived father of a newborn. Here are a few notes on how I pulled this off, both for myself when I need to renew this cert and anyone else who may find this useful.

Opening a hole in the firewall

This of course varies across different brands of networking equipment. We have Ubiquiti Unifi gear in our home and I found this blog post a useful reference as I got this configured. I kept it simple and opened port 8123 (the default webserver port for Home Assistant), redirecting this traffic to 8123 on my Raspberry Pi running Home Assistant. This simple config took no more than a few mins to get in-place and functional.

This is out of scope for this post, but our Home Assistant Raspberry Pi runs on a VLAN dedicated to our IoT equipment that doesn’t have access to the other VLAN we put our phones and PCs on, while our phones and PCs can initiate connections to equipment on our IoT VLAN. This isolation makes me feel slightly better about the risks of opening this port up.

Getting the SSL cert in place

This is the part that took some time. Likely in equal parts due my sleep deprivation as a father to a newborn, the limited documentation I could find on pulling this off, and the poor error codes that showed up in the Home Assistant logs when things weren’t right.

Before diving in, the documentation here worked flawlessly to get a self-signed certificate generated and in-place which was a useful first step. This post was also a great reference, but I couldn’t replicate these steps exactly myself in a way that worked. To be fair, I may have been making other mistakes that caused issues.

Here’s what ultimately worked for me, using the SSH & Web Terminal add-on for shell access and the Samba Share add-on to copy files to and from my Home Assistant Raspberry Pi. Keep in mind the following the caveats: I’ve only done this on my Raspberry Pi instance of Home Assistant, it may not work with other install methods. I’m also no SSL expert so I can only say that this worked, not that it’s the best way to do this.

Start by generating a private key and CSR with the following command:

openssl req -sha256 -new -newkey rsa:4096 -keyout privkey.pem -out request.csr

In the prompts that come up, make sure to provide a Country Code and FQDN while *not* entering a challenge password. There’s probably a way to suppress the challenge password prompt from coming up, I just hit enter without typing anything.

I used https://my.gogetssl.com/ to buy my cert, pasting in the contents of request.csr into their website. I host my domains with Google and used DNS verification, temporarily adding the CNAME record GoGetSSL provided. They offer other verification routes that may be easier for you.

Once verification is complete, rather than downloading the full bundle of certs from GoGetSSL, copy and paste the certificate payload they email into a text file named “fullchain.pem”

Copy the fullchain.pem and privkey.pem files into the /config folder on the Raspberry Pi. Use VIM with the “set list” option to ensure there are no funky characters in the fullchain.pem file. Mine had several that needed to be removed, likely a byproduct of creating the file in Notepad on Windows before copying it the Raspberry Pi. I probably should have used VSCode or another editor instead.

At this point I used the steps outlined here to double check the private and public keys matched. This step is likely unnecessary, but I derived some comfort from it given the significant number of time I had to power cycle the Pi while trying to get this right.

Finally, add the following into your config.yaml and power cycle the Raspberry Pi:

http:
  ssl_certificate: /config/fullchain.pem
  ssl_key: /config/privkey.pem

While the above should work, in the case that it doesn’t:

  • Open the home-assistant.log via Samba Share to get some idea what went wrong. As noted earlier I didn’t find these error codes particularly helpful, but they are better than nothing.
  • To get things running again, comment out the entries in the config.yaml and power cycle the Raspberry Pi.

Here’s the end result I see from my web browser. Note that as in interim step, on Windows the fullchain.pem file can be renamed to fullchain.crt, to open a similar dialog before uploading the cert to the Pi. This doesn’t guarantee Home Assistant will accept it, but is a good sign.

Published by terryjdolan

Software engineering by day, I do projects around the house for fun. I'm also a new dad!

Leave a comment