Categories
Home Automation

Install acme-sh and secure Home Assistant

This is a followup article for the series on how to install and configure the snap-release of Home Assistant. We will use Google Domains as our domain registrar and a TXT-record in our DNS to verify the ownership.

In this article we will install a snap-package of Acme.sh. This an ACME-shell script that issues and renews certificates from Let’s Encrypt.

This snap-release of Acme.sh is not a full version because there is limitations to what a snap-package can do in a confined environment. It’s therefor not possible to restart services etc outside the environment from the app. An app need to support acme-sh’s plug to use certificates and restart itself on renewals.

This release is configured to renew certificates two times a day.

Install and setup acme-sh

Install acme-sh with the snap package manager:

sudo snap install acme-sh

You now have four executables available

  • acme-sh: Normal mode of acme.sh.
  • acme-sh.dns-manual: Run acme.sh under dns-manual mode.
  • acme-sh.connect: connect a snap-instance with acme and expose certificates to it.
  • acme-sh.pub-key: as the daemon that renews certificates is running as root and the owner of the certificates are your user, you will need to add the public key to your authorized_keys to allow the root to run on your behalf.

Issue a new certificate

The computer of my Home Assistant installation is behind a routers firewall and ports for a standalone server is blocked, and I’ll therefor use the DNS-manual mode. If you have the opportunity to open up ports in your firewall and let it be open at all time, then you could use a standalone server etc and the acme-sh-command.

Run the following command to issue a new certificate:

acme-sh.dns-manual --issue -d my.domain.tld

You will the first time using acme-sh get a note about automatic renewal of your certificates. We will do this in a moment, when we have a valid certificate.

Press any key to continue and an additional note about acme.sh will appear. Familiarize yourself with the content and press any key to continue.

Acme.sh will query Let’s Encrypt and fetch an acme-challenge token that we have to add to our DNS-entries with our registrar. The output should look like this:

joachim@:~/Development/home-assistant-configurator$ acme-sh.dns-manual --issue -d test.domain.tld
[Tue Sep 15 15:58:52 CEST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Tue Sep 15 15:58:53 CEST 2020] Create account key ok.
[Tue Sep 15 15:58:53 CEST 2020] Registering account: https://acme-v02.api.letsencrypt.org/directory
[Tue Sep 15 15:58:54 CEST 2020] Registered
[Tue Sep 15 15:58:54 CEST 2020] ACCOUNT_THUMBPRINT='TOKEN HERE'
[Tue Sep 15 15:58:54 CEST 2020] Creating domain key
[Tue Sep 15 15:58:55 CEST 2020] The domain key is here: /var/snap/acme-sh/68/user-data/joachim/certs/test.domain.tld/test.domain.tld.key
[Tue Sep 15 15:58:55 CEST 2020] Single domain='test.domain.tld'
[Tue Sep 15 15:58:55 CEST 2020] Getting domain auth token for each domain
[Tue Sep 15 15:58:56 CEST 2020] Getting webroot for domain='test.domain.tld'
[Tue Sep 15 15:58:57 CEST 2020] Add the following TXT record:
[Tue Sep 15 15:58:57 CEST 2020] Domain: '_acme-challenge.test.domain.tld'
[Tue Sep 15 15:58:57 CEST 2020] TXT value: 'THIS IS THE TOKEN'
[Tue Sep 15 15:58:57 CEST 2020] Please be aware that you prepend _acme-challenge. before your domain
[Tue Sep 15 15:58:57 CEST 2020] so the resulting subdomain will be: _acme-challenge.test.domain.tld
[Tue Sep 15 15:58:57 CEST 2020] Please add the TXT records to the domains, and re-run with --renew.
[Tue Sep 15 15:58:57 CEST 2020] Please add '--debug' or '--log' to check more details.
[Tue Sep 15 15:58:57 CEST 2020] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

You can try to flush the DNS-cache, if you’re in a hurry and want to run the renew command instantly, with the command

sudo systemd-resolve --flush-caches

And then issue the command

acme-sh.dns-manual --renew -d test.domain.tld

It’s however advised to wait about 10 minutes as if the --renew option fails it will force you to re-run the --issue command, and you will have to add a new TXT-record and wait again.

When Acme.sh returns successfully, you should get a response like this:

[Tue Sep 15 16:08:59 CEST 2020] Renew: 'test.domain.tld'
[Tue Sep 15 16:09:00 CEST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Tue Sep 15 16:09:00 CEST 2020] Single domain='test.domain.tld'
[Tue Sep 15 16:09:00 CEST 2020] Getting domain auth token for each domain
[Tue Sep 15 16:09:00 CEST 2020] Verifying: test.domain.tld
[Tue Sep 15 16:09:05 CEST 2020] Success
[Tue Sep 15 16:09:05 CEST 2020] Verify finished, start to sign.
[Tue Sep 15 16:09:05 CEST 2020] Lets finalize the order.
[Tue Sep 15 16:09:05 CEST 2020] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/96721776/5199751331'
[Tue Sep 15 16:09:06 CEST 2020] Downloading cert.
[Tue Sep 15 16:09:06 CEST 2020] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03e508e53fd4c801084f45826067dc0da2dc'
[Tue Sep 15 16:09:07 CEST 2020] Cert success.
-----BEGIN CERTIFICATE-----
[ ...removed content ... ]
-----END CERTIFICATE-----
[Tue Sep 15 16:09:07 CEST 2020] Your cert is in /var/snap/acme-sh/68/user-data/joachim/certs/test.domain.tld/test.domain.tld.cer
[Tue Sep 15 16:09:07 CEST 2020] Your cert key is in /var/snap/acme-sh/68/user-data/joachim/certs/test.domain.tld/test.domain.tld.key
[Tue Sep 15 16:09:07 CEST 2020] The intermediate CA cert is in /var/snap/acme-sh/68/user-data/joachim/certs/test.domain.tld/ca.cer
[Tue Sep 15 16:09:07 CEST 2020] And the full chain certs is there: /var/snap/acme-sh/68/user-data/joachim/certs/test.domain.tld/fullchain.cer

You have now issued a certificate successfully and we can now let the daemon try to renew it twice a day (but only when its due) with the command:

acme-sh.pub-key >> ~/.ssh/authorized_keys \
  && chmod 0600 ~/.ssh/authorized_keys

You will find a log for each time the daemon tries to renew your certificates in ~/.cert-renew, in your home-folder.

Connect Home Assistant and Home Assistant Configurator

We’re now going to connect Home Assistant and the Configurator to acme-sh, so they will be able to use the certificates.

First make sure that both home-assistant-snap and home-assistant-configurator is connected with acme-sh.

snap connections | grep "content\[certs\]"

In my case, only home-assistant-snap auto-connected, and I had to home-assistant-configurator manually.

sudo snap connect acme-sh:certs home-assistant-configurator:certs

I could now verify that both apps was connected successfully.

content[certs] acme-sh:certs home-assistant-configurator:certs manual
content[certs] acme-sh:certs home-assistant-snap:certs -

Now, run the command to start connecting the apps

acme-sh.connect

And choose your certificate and the app you want to connect. A successful output should look like this:

Choose certificate:
1: test.domain.tld
Select a cetificate to expose [1 - 1]: 1

= You choose certificate test.domain.tld

Choose connection for test.domain.tld:
1: home-assistant-snap (uuid: 5fc32b48-f66d-11ea-8bed-1b31217176f3)
2: home-assistant-configurator (uuid: ca89a702-f75f-11ea-a3f3-b7362a622e73)
Choose connection [1 - 2]: 1

= You choose connection home-assistant-snap_5fc32b48-f66d-11ea-8bed-1b31217176f3
Released test.domain.tld for connection home-assistant-snap_5fc32b48-f66d-11ea-8bed-1b31217176f3

Since we’re connecting two apps you’ll have to run acme-sh.connect and connect home-assistant-configurator as well. I’m using the same certificate for both instances (running on the same computer) and if you want separate certificates, then you have to issue a new before connecting the configurator.

Configure Home Assistant

Open up the web UI of Home Assistant in your browser, and go into the configurator.

Create a new folder in the root of the configuration folder, that you name configurations. Go into the folder and create a new file called http.yaml, open it and add the following in that file:

ssl_certificate: !secret ssl_cert
ssl_key: !secret ssl_key
ip_ban_enabled: true
login_attempts_threshold: 5

Save the file and go back into the root of the configuration-directory. Open secrets.yaml and create the two secrets ssl_cert and ssl_key like this:

ssl_cert: /var/snap/home-assistant-snap/current/.ssl/fullchain.pem
ssl_key: /var/snap/home-assistant-snap/current/.ssl/privkey.pem

Save the file file and open up configuration.yaml that is in the same directory, and add the following line to the file:

http: !include configurations/http.yaml
logger:
  default: info

Save the file and go back into the terminal.

We will now have to tell Home Assistant which certificate it should use and to decrypt it before use with the command:

sudo snap set home-assistant-snap domain=test.kgv14.dev

Now monitor the log in the terminal session with

sudo journalctl -xef --unit=snap.home-assistant-*

and run

sudo home-assistant-snap.refresh-certs

to manually recognize the certificate, decrypt it and place it in the .ssl-folder within the configuration-folder. This command will, as long as successful, restart Home Assistant.

You should now be able reach your installation at https://your-domain:8123/, taken into account that you have opened up the port 8132 to the outside world, and forwarded request to the local IP of your Home Assistant installation.

Configure the Configurator

Configuring the Configurator is different, but a lot easier, since you can do it directly from the terminal.

Start to set the domain, as you did for home-assistant-snap:

sudo snap set home-assistant-configurator domain=test.domain.tld

And run the command to force a refresh of certificates:

sudo home-assistant-configurator.refresh-certs

Now configure the configurator to use this, as we did in the previous post on how to configure it:

sudo snap set home-assistant-configurator \ 
    server.ssl.certificate=/var/snap/home-assistant-configurator/current/.ssl/fullchain.pem

sudo snap set home-assistant-configurator \ 
    server.ssl.key=/var/snap/home-assistant-configurator/current/.ssl/privkey.pem

Now restart the server sudo snap restart home-assistant-configurator.server and wait for it to boot up.

You will now see that the configurator is no longer available to you from the web UI of Home Assistant. This is because the url of the panel_iframe we made in the article on integrating them, is pointing to http://ip something and not https://domain.

Edit the configuration.yaml and change this property:

sudo vi /var/snap/home-assistant-snap/current/configuration.yaml

Restart Home Assistant with sudo snap restart home-assistant-snap.hass – and BAM! You’re now secure.

Just a few steps left. You need to update the server.hass.api.url with your domain name, and add the ws-url if needed.

Save a snapshot

Now when the hard part of setting up your Home Assistant installation is over, it’s recommended to take a snapshot of your system.

A snapshot is a copy of the user, system and configuration data stored by snapd (the package manager daemon) for one or more snaps on your system. Snapshots are generated manually with the snap save.

snap save home-assistant-snap \
    home-assistant-configurator \
    acme-sh

And tell snapd to store your backup for a month (720 hours)

snap set system snapshots.automatic.retention=720h

If you ever need to restore a snapshot, run snap saved and find the id of the snapshot you want, and run snap restore ID.

Conclusion

We have now issued a new certificate and secured both Home Assistant and Home Assistant Configurator. The public key of the acme-sh daemon was added to our ssh-keys, so the certificates can renew when they are due.

A snapshot is stored in snapd so we can restore if further configurations breaks, or if we just want to test out different approaches and roll back without going over the whole installation process again.

In an upcoming article we will install HACS, but for those who want to test it already can have a dive into the git repository of home-assistant-hacs.

Feel free to leave a comment. And remember, sharing is caring.

Until next time!

Categories
Home Automation

Home Assistant Configurator

This is a continuation of the already written post Home Assistant Snap, and it’s expected that you already have basic knowledge on the Snap Package Manager. Feel free to have a read-through, before continuing with this article.

In this article will we install the formally known hass-configurator, as a companion app to Home Assistant Snap. The configurator is a web-based editor, that will let you edit the configuration files within Home Assistant Snap through the web brower.

If you want a full detail list of the editor, head over to the github-repository of the project.

We will go through a basic configuration and integrate the editor within the UI of Home Assistant Snap.

The configurator must run on the same computer as Home Assistant Snap, as it’s using plugs/slots to read the configuration files, within the confined environment.

Installation

To install home-assistant-configurator execute the command

sudo snap install home-assistant-configurator

When the installation process is finished, you should be able to find the configurator at the address: http://home-assistant-computer-ip:3218/. If you don’t know or remember the IP-address of the computer running Home Assistant Snap, see the installation section of the Home Assistant Snap-article.

Now make sure that the connecting plug/slot between home-assistant-snap and home-assistant-configurator was successfully auto-connected after installation.

snap connections | grep "content\[configurations\]"

And look for an identical line as this

content[configurations] home-assistant-configurator:configurations home-assistant-snap:configurations -

If you don’t see this connection, run the following

sudo snap connect home-assistant-configurator:configurations home-assistant-snap:configurations

If nothing is returned, the connection is successful. And you can verify this by running the above snap connection-command again.

Configuration

With Home Assistant Configurator we’ll introduce you to a different way of configuring a snap. We’re going to use the snap set and get commands, and not edit the settings.conf-file as the official documentation tells us to – as data added directly to the file will only be temporary until next restart.

Familiarize your self with the available settings

sudo snap get home-assistant-configurator -d

and compare the output you get with the following content of the settings.conf-file:

{
    "LISTENIP": "0.0.0.0",
    "PORT": 3218,
    "GIT": false,
    "BASEPATH": null,
    "ENFORCE_BASEPATH": false,
    "SSL_CERTIFICATE": null,
    "SSL_KEY": null,
    "IGNORE_SSL": false,
    "HASS_API": "http://127.0.0.1:8123/api/",
    "HASS_WS_API": null,
    "HASS_API_PASSWORD": null,
    "USERNAME": null,
    "PASSWORD": null,
    "ALLOWED_NETWORKS": [],
    "ALLOWED_DOMAINS": [],
    "BANNED_IPS": [],
    "BANLIMIT": 0,
    "IGNORE_PATTERN": [],
    "DIRSFIRST": false,
    "SESAME": null,
    "SESAME_TOTP_SECRET": null,
    "VERIFY_HOSTNAME": false,
    "ENV_PREFIX": "HC_",
    "NOTIFY_SERVICE": "persistent_notification.create"
}

The first thing we want to do is to set the BASEPATH, if it’s not set already, to /var/snap/home-assistant-configurator/common/configurations. This is where Home Assistant Snap’s configurations now is «plugged» at.

Set the path with:

snap set home-assistant-configurator server.basepath.dir=/var/snap/home-assistant-configurator/common/configurations

Note we’re using the SNAP_COMMON-directory now, and not SNAP_DATA as we did for Home Assistant Snap, and if the common path is different on your system – do as described in that article.

For simplicity, as you don’t need to edit anything outside of this path, set the ENFORCE_BASEPATH to True:

snap set home-assistant-configurator set server.basepath.enforce=True

Securing the installation

Next generate as password to secure (well, secure-ish, until we add an SSL-certificate..) the installation:

echo -n "TestPass" | sha256sum

And set the output as a password for the configurator, along with an username

sudo snap set home-assistant-configurator server.login.password="{sha256}OUTPUT"
sudo snap set home-assistant-configurator server.login.username=test
Refresh the website of Home Assistant Configurator and you will now be prompted to give a username and a password.

Integrate with Home Assistant Snap

Login to Home Assistant web UI and go to your profile, scroll down to «Long-Lived Access Tokens» and press «create token». Give it a descriptive name, such as «Home Assistant Configurator» and press OK.

Copy the given string and make sure you have it until it’s set withing home-assistant-configurator.

And set it it to Home Assistant Configurator:

snap set home-assistant-configurator server.hass.api.password="COPIED STRING"

Further you have to set the server.hass.api.url (make sure that it ends with /api/) and server.hass.api.ws-url, which I’m confident that you’ll understand how to do by now.

Refreshing Home Assistant Configurator should now let you select entities, conditions, services etc from its dropdown lists.

Additional settings you should use

server.ban.limit=5
server.dir.first=True
server.listen.ip=<actual IP>

You can read the description of all the settings at the official github-repository.

Configuring Home Assistant Snap

Yay! We can now do this from the UI of the Configurator. Make sure you have refreshed the page after the last settings was set.

Now browse by pressing the folder icon in the upper left corner, and select the configuration.yaml-file.

Add the following to the file

panel_iframe:
  configurator:
    title: Configurator
    icon: mdi:wrench
    url: http://<actual ip>:3218

Hit the red-glowing floppy disk in the upper right corner, then press the cog icon to the right of it and select «Restart HASS».

Now go into the web UI of Home Assistant Snap and you should see the configurator in the left menu panel.

Conclusion

We have now installed and configured Home Assistant Configurator, and integrated it with Home Assistant Snap.

In upcoming posts we’ll show you how you can – just as easily – update DNS entries on a domain to make Home Assistant available through a web address and how to secure your installation with SSL.

For anyone interested in the source code, want’s more detailed information about the release or needs to file a bug report, head over to the official repository.

If you have any questions, do not hesitate to leave a comment.

Until next time!

Categories
Home Automation

Home Assistant Snap

Note: The package will remove the hass-ending of the running daemon from home-assistant-snap.hass to only home-assistant-snap

Preface: I have for quite some time (~2 years) thought about packing Home Assistant as a Snap package. My motivation of doing it is that I have been managing up to forty holiday properties during the high season – the past years – and I’ve spent to much time traveling between them, just to make sure windows and doors are closed, temperature is adjusted to a normal level etc. Actually that much that I needed corona to stop the tourism and a summer holiday to rest – to get started with it.

The thought of updating and system maintenance and configuration in every apartment sounds very time consuming and cumbersome, which led me to look at and play around with Ubuntu Core. An strictly confined all-snap operating system, optimized for security and reliability, with transactional updates.

However the Snap Package Manager is shipped with many of the popular Linux Distributions and most likely available for the one you’re using, so if you’re here just to install the Snap package in your system and get familiar with how you configure this version – just follow along.

You can find supported operating systems at the official Snapcraft documentation.

Installation

If you’re unfamiliar with how snap works, you’ll be surprised how quick and easy the installation process is. To install everything needed you’ll have to open up a terminal session, and login over SSH if you’re installing this on a remote/headless computer. In my case am I using a Raspberry Pi 3.

Install home-assistant-snap with the command

sudo snap install home-assistant-snap

After a short while is Home Assistant downloaded, installed and running on your system.

If you installed Home Assistant on your local network, you should be able to reach the setup at http://homeassistant.local:8123/, but in my case I’m using a remote computer on a different network, and therefor will have to use the IP of the computer http://192.168.33.19:8123/.

If you can’t use the homeassistant.local-address and need to figure out the IP of the computer, you can use the command ifconfig on most operating systems, or install toolbox on Ubuntu Core and use the command toolbox.ifconfig.

When you have located Home Assistant in your browser, continue the setup by filling in your details to create a user account and a new zone for your installtion.

Configuration

As the installation process doesn’t give you any clue on how to configure the newly installed app, I will give a brief description here that you need to know to configure Home Assistant for your needs.

Since snap-packages is running in a sandbox-mode and doesn’t have access to the host system, several file systems is mounted on the host system. See the security policy walkthrough at Snapcraft.io if you interested to learn more about it.

We will be using the SNAP_DATA-directory, which in most cases is set to /var/snap/home-assistant-snap/<revision>, but it might be different on a non-Ubuntu system – without being sure.

If you can figure out the directory, login to the Home Assistant daemon with

sudo snap run --shell home-assistant-snap.hass

and execute the command echo $SNAP_DATA, note the output and exit the shell.

Another note is that you should always change the revision number in the path to the word «current», as this is a symlink to the actual revision being used at the system. If you edit files in an unused revision it won’t make any changes to the configuration being used.

When you have determined the path, you can use VIM on Ubuntu Core or your favorite editor on any other distribution. To edit the main configurations file, e.g:

sudo vi /var/snap/home-assistant-snap/current/configuration.yaml

See the official documentation on advanced configuration of Home Assistant for guidance. You can configure the snap-release just as any other release of Home Assistant.

When you’re done editing a configuration file Home Assistant requires a restart to be applied. You restart Home Assistant with

sudo snap restart home-assistant-snap.hass

And it should be up running again shortly after a short while, with the changes applied.

Home Assistant will fail to start if the configuration in invalid, so it’s recommended to watch the log

sudo journalctl -xef --unit=snap.home-assistant-snap.hass

Conclusion

We have now installed Home Assistant through the package manager Snap and shown where to edit the configuration files.

In upcoming posts we’ll show you how you can – just as easily – install an configuration-editor that you can integrate with the web interface of Home Assistant, how to update DNS entries on a domain to make it available through a web address and how to secure your installation with SSL.

For anyone interested in the source code, want’s more detailed information about the release or needs to file a bug report, head over to the official repository.

If you have any questions, do not hesitate to leave a comment.

Until next time!