This post assumes you have installed Home Assistant following the diyAutomate installation posts (on Raspbian). Docker and other installation methods can be found on the Home Assistant or Let’s Encrypt web sites.
This post also assumes you have a Dynamic DNS service configured. Many routers have DDNS built in, or you can see the diyAutomate article Using Dynamic DNS in your home Automation Architecture using Duck DNS.
Ensure Port 80 is forwarding to Home Assistant:
For this installation to work you will need to enable port forwarding of external port 80 to your servers internal port 80
Because every router is different I am not going to walk you through opening the port. There is an excellent resource on the net (portforward.com) that has instructions for many routers. Please see https://portforward.com/router.htm
Once port forwarding is complete your Home Assistant server is published to the internet. However it is NOT SECURED. You will need to do the following things to secure it:
As part of the installation I am going to assume that Home Assistant will be served from port 443 (externally) permanently after this process. We will leave port 80 forwarding to port 80 for certbot to use when your certificates need to be renewed. Certbot will only open this port on your server during the renewal process, port 80 will not be available at any other time.
- Ensure you have a complex password
- Setup Port Forwarding
- Install SSL certificates
- Configure Home Assistant to use SSL
- Set IP Banning of anyone who tries to log in multiple times with a bad password
- Create a CRON job (scheduled task) to renew certificates
The most common password attack is called a dictionary attack. this is where an attack has a very large file of possible passwords (10’s of thousands of password guesses), and uses a script to try each password, one after the other until a successful logon is obtained. A complex password is one of the easiest ways to make this difficult I recommend at least 10 characters, including upper case, lower case, and numeric values, special characters such as # add to the security as well.
Install SSL certificates
What is SSL:
Without going into the technical way in which it works (public and private certificates), SSL can be thought of as a way to encrypt communications between two points. In this case a web browser and Home Assistant.
Why use SSL:
You should use SSL because without it all your communication is sent in plain text. Meaning that if someone wanted to, they could listen in on your communications between your browser, (on your computer, cell phone, or any other way you connect) and Home Assistant. Most importantly this includes your user name and password
Why Get certs from Let’s Enctypt:
Let’s encrypt is a free SSL certificate issuing authority maintained by the Electronic Frontier Foundation. It is free, secure, and can be setup to auto-renew (a cert lasts 90 days by default).
There are many agents that can help us get and install certs from Let’s Encrypt. We will use the one Let’s Encrypt recommends (certbot). It is fast, easy, and free.
there are a few ways to install certbot. The EFF website would have you install the backports repository. I think this way is much easier.
How do I install and use a Certificate?
from your home drive (
cd ~) make a directory called certbot:
Change to that directory:
Download the certbot installation files:
change the permissions on the installation file (to allow execution):
chmod a+x certbot-auto
Execute certbot to get your certificates (do not run this as sudu)
./certbot-auto certonly --standalone --preferred-challenges http-01 --email YuurEmail@address.com -d YourDomain.duckdns.org
The instalation will take serveral minutes. You will be asked several questions. You can safely say yes to all of them (there is one asking to give your email address to EFF. That is up to you).
Change to the letsenctypt directory
Change permissions of the live and archive directories, this will make it so users other than root can access the certificates (such as the home assistant users)
sudo chmod 755 /etc/letsencrypt/live/
sudo chmod 755 /etc/letsencrypt/archive
You are now done with the SSL certificate installation and configuration.
Configure Home Assistant to use the new certificates:
Open configuration.yaml and configure the http: component as follows:
http: api_password: !secret http_password ssl_certificate: /etc/letsencrypt/live/YourDomainName/fullchain.pem ssl_key: /etc/letsencrypt/live/YourDomainName/privkey.pem
Set IP Banning
It is also a good idea to limit the amount of failed logon attempts. There are advanced ways to do this, but Home Assistant has an antiquate one built in. Add the following line to the http component (change 5 to any number you are comfy with:
Final http: component:
http: api_password: !secret http_password ssl_certificate: /etc/letsencrypt/live/[Yours].duckdns.org/fullchain.pem ssl_key: /etc/letsencrypt/live/[Yours].duckdns.org/privkey.pem ip_ban_enabled: True login_attempts_threshold: 5
Set Up A CRON job to Automatically Renew Certificates.
We have configured to port forwarding rules on our routers. Port 443 forwards to our Home Assistant instance (port 8123 by default) and Port 80 forwards to the same IP for use by Certbot.
There is a level of build in security because Certbot only opens port 80 when it is needed. When Certbot is not obtaining or renewing certificates it is not listening on any ports.
You can check the ports your server has open by issuing the following command:
For an explanation of netstat and it’s switches see: http://www.computerhope.com/unix/unetstat.htm
Because we are using two different ports, we will not have to take Home Assistant offline to renew the certificates. We will use crontab to schedule the renewals.
To edit your CRON table type the following command (do not use sudo):
pick the editor you would like to use (I recommend nano)
at the end of the file add the following line
0 13 * * * /home/haadmin/certbot/certbot-auto renew --quiet
Save and exit the file
This will schedule a renewal attemp at 13:00 hours every day (you can change this to any time or interval you would like). For more info See: https://debian-administration.org/article/56/Command_scheduling_with_cron
if you would like to ensure your cron job is running (and I recommend you do) follow these stesp:
Make sure you are logged off when the cron job is supposed to run (it will work with you logged in, but being logged off ensure all permissions are set correctly (all permissions are set correctly as part of the default installation)
Change to the log directly root:
grant access to the letsencrypt directory:
chmod 775 /var/log/letsenctypr
The most recent logfile is letsencrypt.log. to see the contents of this log: