-
Notifications
You must be signed in to change notification settings - Fork 0
Creating root CA and enabling HTTPS in HomeAssistant
By default, Home Assistant is accessible through HTTP. In most cases, that is acceptable if you trust your local network and don't plan to access HA from outside. As I have many devices connected to the same Wi-Fi network, I wanted to guard HA. To set up HTTPS, trusted certificates should be created.
Unfortunately, it is not possible to create such certificates using local IPs or local DNS names (like homeassistant
) using services like Let's Encrypt. There was a workaround that used a public DNS and a record in /etc/hosts
to resolve that DNS to the local IP, but that seemed too complicated.
So, I decided to create my own root CA. There is a good tool called minica, but unfortunately, it doesn't allow restricting the root CA to only specific DNS names. This means that if the root CA gets compromised, an attacker can create a server certificate for www.google.com, which your browser will happily accept.
Therefore, the obvious choice was to use openssl
and create certificates from scratch. There is a good instruction on how to do it, but it also lacks the PermittedDNSDomains
option and uses RSA keys, which are slower than Elliptic Curve.
So, I decided to educate myself and write yet another guide.
If you are on Mac, make sure to install OpenSSL with Homebrew and run it using /opt/homebrew/bin/openssl
, instead of openssl
, or create a link to it. Out of the box, Mac has LibreSSL, which won't work.
To make sure you use the correct OpenSSL CLI, run:
openssl version
It should output something like this:
OpenSSL 3.4.0 22 Oct 2024 (Library: OpenSSL 3.4.0 22 Oct 2024)
First, generate a private key that will be used to sign the root CA. Use the elliptic curve algorithm as it is faster than RSA:
openssl ecparam -name secp384r1 -genkey | openssl ec -out home-network-root-ca.key -aes256
Now, generate the root CA certificate and self-sign it. This root CA certificate will only allow end-entity certificates for specific domains specified in nameConstraints
. Make sure to update homeassistant
DNS to whatever name you use and add/remove additional DNS names.
openssl req -x509 -new -key home-network-root-ca.key -sha384 -days 3650 -out home-network-root-ca.crt -subj "/CN=home network root ca" -addext "keyUsage=critical,digitalSignature,keyCertSign" -addext "extendedKeyUsage=critical,serverAuth" -addext "basicConstraints=critical,CA:TRUE" -addext "nameConstraints=critical,permitted;DNS:homeassistant,permitted;DNS:homeassistant-2"
Time to generate the end-entity certificate. First, generate the private key:
openssl ecparam -name prime256v1 -genkey -out homeassistant.key
If you want the key to be encrypted, run instead (keep in mind that HA requires unencrypted key):
openssl ecparam -name prime256v1 -genkey | openssl ec -out homeassistant.key -aes256
Now, let's create the CSR. Before running the command, make sure that -subj "/CN=homeassistant"
and subjectAltName=DNS:homeassistant
have the correct DNS. This DNS should match the DNS specified in the root CA.
openssl req -new -sha256 -key homeassistant.key -out homeassistant.csr -subj "/CN=homeassistant" -addext "keyUsage=critical,digitalSignature,keyEncipherment" -addext "extendedKeyUsage=critical,serverAuth" -addext "basicConstraints=critical,CA:FALSE" -addext "subjectAltName=DNS:homeassistant"
And finally, create the certificate and sign it with the root CA:
openssl x509 -req -in homeassistant.csr -CA home-network-root-ca.crt -CAkey home-network-root-ca.key -CAcreateserial -out homeassistant.crt -days 365 -sha256 -copy_extensions copyall
You can verify certificates by running:
openssl x509 -text -noout -in home-network-root-ca.crt
The root CA should look like:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
Signature Algorithm: ecdsa-with-SHA384
Issuer: CN=home network root ca
Validity
Not Before: Jan 1 00:00:00 2024 GMT
Not After : Jan 1 00:00:00 2034 GMT
Subject: CN=home network root ca
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Subject Key Identifier:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
X509v3 Authority Key Identifier:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
X509v3 Key Usage: critical
Digital Signature, Certificate Sign
X509v3 Extended Key Usage: critical
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Name Constraints: critical
Permitted:
DNS:homeassistant
Signature Algorithm: ecdsa-with-SHA384
Signature Value:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
And end-entity certificates like this:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN=home network root ca
Validity
Not Before: Jan 1 00:00:00 2024 GMT
Not After : Jan 1 00:00:00 2025 GMT
Subject: CN=homeassistant
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage: critical
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
DNS:homeassistant
X509v3 Subject Key Identifier:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
X509v3 Authority Key Identifier:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
??:??:??:??:??:??:??:??:??:??:??:??:??:??:??
To print the content of the CSR for debugging:
openssl req -text -noout -in homeassistant.csr
To add the root CA to Mac, refer to this guide
To add the root CA to Android:
- Copy the
home-network-root-ca.crt
certificate to Google Drive. - On your Android device, go to
Settings
->Security & privacy
->More security & privacy
->Encryption & credentials
->Install a certificate
->CA certificate
->Install anyway
- Select the certificate file from Google Drive. If this doesn't work, download the file and install it from the
Downloads
folder.
To install the certificates in Home Assistant, follow the instructions in this guide
After HA is restarted, a warning will appear in Settings stating that the HA URL is not configured. Follow the instructions in the warning and use the DNS name from your certificate.
Now HA should only accept HTTPS requests and the browser should show secure connection.