Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 35 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save tiagofreire-pt/4920be8d03a3dfa8201c6afedd00305e to your computer and use it in GitHub Desktop.
Save tiagofreire-pt/4920be8d03a3dfa8201c6afedd00305e to your computer and use it in GitHub Desktop.
Self Signed Certificate with Custom Root CA for Home Assistant

Create Root Certificate Authority and self-signed certificate for your Home Assistant. Compatible with Chrome browser > version 58, including the macOS Catalina 10.15 / iOS 13 (and above) new requirements.

Create Root Key

Attention: this is the key used to sign the certificate requests, anyone holding this can sign certificates on your behalf. So keep it in a safe place!

openssl genrsa -des3 -out rootCA.key 4096

If you want a non password protected key just remove the -des3 option

Create and self sign the Root Certificate

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.pem

Use this one instead, only if you are planning to use/allow Apple devices with macOS vs 10.15 / iOS 13 (or above):

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 825 -out rootCA.pem

Here we used our root key to create the root certificate that needs to be distributed in all the computers that have to trust us.

Create a certificate (Done for each HA instance)

This procedure needs to be followed for each server/appliance that needs a trusted certificate from our CA

Create rootCA.csr.cnf file

# rootCA.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=my_2_letters_ISO_country
ST=my_state
L=my_town
O=my_organization_name
OU=my_departement_name
emailAddress=my_emailaddress
CN = my_local_ha_domain_name_check_your_local_dhcp_or_dns_server_eg_hassio.homelan

Create v3.ext file

# v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
extendedKeyUsage=serverAuth

[alt_names]
DNS.1 = my_local_ha_domain_name_check_your_local_dhcp_or_dns_server_eg_hassio.homelan
IP.1 = my_local_ha_ip_address_check_your_local_dhcp_or_dns_server_eg_192.168.1.22

Create the certificate key

openssl req -new -sha256 -nodes -out hassio.csr -newkey rsa:2048 -keyout hassio.key -config <( cat rootCA.csr.cnf )

Exclusively on Windows OS: Pay attention to the rootCA.csr.cnf file path after the -config. Follow this example, changing it accordingly:

openssl req -new -sha256 -nodes -out hassio.csr -newkey rsa:2048 -keyout hassio.key -config "C:\Program Files\Git\usr\bin\rootCA.csr.cnf"

Create the certificate itself

openssl x509 -req -in hassio.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out hassio.crt -days 3650 -sha256 -extfile v3.ext

Use this one instead, only if you are planning to use/allow Apple devices with macOS vs 10.15 / iOS 13 (or above):

openssl x509 -req -in hassio.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out hassio.crt -days 825 -sha256 -extfile v3.ext

Rename hassio.crt and hassio.key

Copy both hassio.crt and hassio.key, through SSH add-on or Console, to your HA /ssl/ folder and rename both accordingly:

rename hassio.crt fullchain.pem
rename hassio.key privkey.pem

Also, setup correctly both file permissions (only read and write by the file owner):

chmod 600 fullchain.pem privkey.pem

Setup your configuration.yaml file with the following:

http:
  base_url: https://YOUR_HA_IP_ADDRESS:8123
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem

Setup all your HA add-ons with its SSL configuration and reboot afterwards the host of your HA instance.

Meanwhile, add the rootCA.pem file to your web browser or system wide Authority Certicates repository.

References:

https://serverfault.com/a/867838

https://gist.github.com/fntlnz/cf14feb5a46b2eda428e000157447309

https://superuser.com/questions/1492207/neterr-cert-revoked-in-chrome-chromium-introduced-with-macos-catalina

@tiagofreire-pt
Copy link
Author

@indyjason79, please check the path after the option -config, on the command executed.

@Woodpeckercz
Copy link

I'm unable to create the certs:
I'm getting:

writing new private key to 'hassio.key'

unable to find 'distinguished_name' in config
problems making Certificate Request
3069407248:error:0E06D06A:configuration file routines:NCONF_get_string:no conf or environment variable:../crypto/conf/conf_lib.c:270:

Any ideas?

@indyjason79
Copy link

indyjason79 commented Mar 11, 2020

@indyjason79, please check the path after the option -config, on the command executed.

For those who ran into the same issue as me, just replace "<( cat rootA.csr.cnf )" with the actual path of the cnf file. I've never seen the syntax "<( cat ... )" before because I'm a Windows user and don't know Linux.

Example:
openssl req -new -sha256 -nodes -out hassio.csr -newkey rsa:2048 -keyout hassio.key -config "C:\Program Files\Git\usr\bin\rootCA.csr.cnf"

@tiagofreire-pt
Copy link
Author

tiagofreire-pt commented Mar 11, 2020

@indyjason79 that syntax is outputing and piping the entire content of that file into the inline command, as parameters for execution. It's a native unix way of including some non linear contents within an inline command.

My apologies, as this tutorial is made for using it on linux distros, being implicit on that in some commands such as the permissions or piping instructions.

I also appreciate that you did share a solution for the problem you faced, as many others may face it, especially on windows OS. Based on that, tutorial is update accordingly.

Thanks.

@tiagofreire-pt
Copy link
Author

@Woodpeckercz could you share your rootCA.csr.cnf file, please?

If there is any sensitive or personal data, anonymise it.

@Woodpeckercz
Copy link

@tiagofreire-pt I was trying to get it going on raspbian buster with no luck, i then tried it on ubuntu 19.04 (with the same parameters) and it worked first time.

@janser01
Copy link

janser01 commented Mar 20, 2020

I'm getting this error:

$ sudo openssl req -new -sha256 -nodes -out hassio.csr -newkey rsa:2048 -keyout hassio.key -config <( cat rootCA.csr.cnf )
Can't open /dev/fd/63 for reading, No such file or directory
140176059512000:error:02001002:system library:fopen:No such file or directory:../crypto/bio/bss_file.c:72:fopen('/dev/fd/63','r')
140176059512000:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:79:
Generating a RSA private key
.........................+++++
.........+++++
writing new private key to 'hassio.key'
-----
unable to find 'distinguished_name' in config
problems making Certificate Request
140176059512000:error:0E06D06A:configuration file routines:NCONF_get_string:no conf or environment variable:../crypto/conf/conf_lib.c:269:

I did a lot of googling but there seems to be something wrong with the command on my installation Ubuntu 19.04 as well... :(

My rootCA.csr.cnf ;

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name= req_distinguished_name
[distinguished_name]
C=XX
ST=XX
L=XX
O=XX
OU=XX
emailAddress=x@gmail.com
CN = x.duckdns.org

@tiagofreire-pt
Copy link
Author

tiagofreire-pt commented Apr 10, 2020

I'm getting this error:

$ sudo openssl req -new -sha256 -nodes -out hassio.csr -newkey rsa:2048 -keyout hassio.key -config <( cat rootCA.csr.cnf )
Can't open /dev/fd/63 for reading, No such file or directory
140176059512000:error:02001002:system library:fopen:No such file or directory:../crypto/bio/bss_file.c:72:fopen('/dev/fd/63','r')
140176059512000:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:79:
Generating a RSA private key
.........................+++++
.........+++++
writing new private key to 'hassio.key'
-----
unable to find 'distinguished_name' in config
problems making Certificate Request
140176059512000:error:0E06D06A:configuration file routines:NCONF_get_string:no conf or environment variable:../crypto/conf/conf_lib.c:269:

I did a lot of googling but there seems to be something wrong with the command on my installation Ubuntu 19.04 as well... :(

My rootCA.csr.cnf ;

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name= req_distinguished_name
[distinguished_name]
C=XX
ST=XX
L=XX
O=XX
OU=XX
emailAddress=x@gmail.com
CN = x.duckdns.org

I assume there is an error on the rootCA.csr.cnf file, around the distinguished_name parameter. Follow this example: https://gist.github.com/tiagofreire-pt/4920be8d03a3dfa8201c6afedd00305e#create-rootcacsrcnf-file

@mirceadamian
Copy link

@BlueBlueBlob, yes, is an issue. Thanks for referring it, it's important. πŸ‘

πŸ”΄ This method can be trusted as long you don't allow any other (third-party) custom root CA installed in your android device. πŸ”΄

Also, done properly, you could use it for a huge number of devices and hosts inside your LAN, even WWW ones (.com, .org, etc), defining them here.

Furthermore, I don't see this kind of method to be used by new HA users. Most of them may be using Let's Encrypt Home Assistant add-on, if exposing their HA instance to the WAN interface.

I made this gist mostly for HTTPS inside LANs, as the currently available add-ons for Home Assistant don't fully support this kind of setup or generate short period certificates. 😍

Does anyone here figured out how to convince a Google Home accept own custom CA?
I'm so pleased to find other people using own custom CA.
I managed to get it trusted by most of my devices but not on my Google Home.

Because of that the casting from HA does not work for me.

@buentead
Copy link

Thank you very much for the excellent 'cook book'. I successfully followed the steps with one exception:

  • The validity of the rootCA.pem can be unlimited even for iOS 13 (or above)

I entered 7300 days (~20 years) and was able to import the root certificate in iOS 13.7 (it doesn't make sense to restrict the validity period of the root certificate). Having this 'none expiring' root CA allows me to renew the Home Assistant server certificate once the 825 days are over with the same root CA. With the benefit of less work and administration.

@mirceadamian
Copy link

@BlueBlueBlob, yes, is an issue. Thanks for referring it, it's important. πŸ‘
πŸ”΄ This method can be trusted as long you don't allow any other (third-party) custom root CA installed in your android device. πŸ”΄
Also, done properly, you could use it for a huge number of devices and hosts inside your LAN, even WWW ones (.com, .org, etc), defining them here.
Furthermore, I don't see this kind of method to be used by new HA users. Most of them may be using Let's Encrypt Home Assistant add-on, if exposing their HA instance to the WAN interface.
I made this gist mostly for HTTPS inside LANs, as the currently available add-ons for Home Assistant don't fully support this kind of setup or generate short period certificates. 😍

Does anyone here figured out how to convince a Google Home accept own custom CA?
I'm so pleased to find other people using own custom CA.
I managed to get it trusted by most of my devices but not on my Google Home.

Because of that the casting from HA does not work for me.

Trying my luck again by bumping this question(^^).
I'm sure there must be someone using Google Home and having a custom root CA in his home. :-)

@buentead
Copy link

@mirceadamian: Sorry, I don't use Google Home and, hence, I cannot give you any advice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment