DEV Community

Cover image for Introducing tunnel based remote access for Home Assistant
Karolis for Webhook Relay

Posted on • Updated on

Introducing tunnel based remote access for Home Assistant

First things first, what is Home Assistant? Home Assistant is an automation hub that allows you to easily deploy and interconnect a large number of different apps/services/hardware gadgets together. It can accept webhooks, launch tasks or run more powerful workflow engines such as Node-RED inside it (as an add-on). It's a fantastic thing to have installed on your spare Raspberry Pi (I know you have one 😏).

Home Assistant GitHub repo (https://github.com/home-assistant/home-assistant) has 20K stars which probably is a good testament for its popularity :)

In this short article I will present you my add-on, which uses Webhook Relay cloud service to provide an easy and secure remote access to a Home Assistant running on RPI:

Remote access home assistant addon

It might look like a lot of different tools, but most of it is automated and doesn't require any complex configuration.

If you just want to try it out, skip to the 'Trying it out' section


So, why remote access add-on?

Since Home Assistant is usually deployed in your local network, connecting to it from outside can be problematic, unless you configure your router to do the port forwarding. However, there are cases when it's just not possible:

  • ISP is blocking inbound connections - simple, no port forwarding will help here.
  • Double NAT due to 4G networks - same as above.
  • Can't access/configure the router
  • No static IP
  • Server that is hosting Home Assistant is changing location/IP address
  • Router doesn't support port forwarding

The add-on works by creating a tunnel back to the cloud service and allowing any outside traffic (from your phone on 4G or your office network) ride back to the Home Assistant on top of that previously established tunnel. This way no incoming connections to the server require port forwarding or static IP.

The add-on

The add-on is a lightweight daemon, it's based on the webhookrelayd Docker image and its size is just 5MB. The application is written in Golang, this makes it fast and efficient. It barely uses any RAM or CPU. This application is tailored to consume Home Assistant add-on configuration JSON files and treats it as a first-class citizen, no dirty shell script hacks (like many other add-ons) involved to consume that config.

Security & Privacy

One of the first thing that I had to develop for Webhook Relay for this add-on to succeed was TLS pass-through tunnels. Several main developers of Home Assistant said that TLS termination on the user device is crucial to make it secure. Not even Home Assistant Cloud does this for the webhooks, they terminate TLS on their cloud services and then pass it on to the users. So, I had to look at 3rd party services that would provide free subdomains + support Let's Encrypt. Gladly, DuckDNS saved the day :)

As for TLS pass-through & termination, Golang has a great standard library to deal with this, it's just reversed (normally you would be terminating incoming connections to your server as opposed to terminating outgoing connections from the server).

Putting it all together

Once the add-on starts, it reads the configuration and ensures tunnels in Webhook Relay. These tunnels are just a routing configuration, that tells cloud service to direct requests from example.duckdns.org to client-xxx. It then configures DuckDNS A record example.duckdns.org to an IP address that belongs to Webhook Relay and also retrieves HTTPS certificate from Let's Encrypt using DNS challenge (since we don't have HTTP traffic to the client yet). Having that certificate, we can set up TLS termination on the client side. Home Assistant is still called on HTTP port through http://localhost:8123 while all the external traffic is fully encrypted.

Trying it out

Before we begin, this tutorial will expect you to have:

  • Basic plan subscription ($4.5/m) which enables DuckDNS domains and TLS pass-through tunnels. If you don't want to commit, drop us an email at info@webhookrelay.com and we will set up a 2 weeks trial for you.
  • DuckDNS account to get your own free domain and retrieve TLS certificate through Let's Encrypt.

Configure DuckDNS:

DuckDNS config

Installation of this add-on is pretty straightforward and not different in comparison to installing any other Hass.io add-on:

  1. Add our Hass.io add-ons repository URL to your Hass.io instance: https://github.com/webhookrelay/home-assistant
  2. Install the “Webhook Relay” add-on
  3. Generate a token key & secret pair and add it to the add-on configuration
  4. Get DuckDNS token and create your domain. Add those details to the "tunnels" config section and "duck_dns" section. Set "accept_terms" to true if you accept Let's Encrypt ToS
  5. Start the “Webhook Relay” add-on
  6. Check the logs of the “Webhook Relay” add-on to see if everything went well. It should print out your public URL

Configuration example:

{
    "key": "[YOUR WEBHOOKRELAY KEY]",
    "secret": "[YOUR WEBHOOKRELAY SECRET]",
    "forwarding": [],
    "tunnels": [
        {
            "name": "ha",
            "destination": "http://127.0.0.1:8123",
            "protocol": "tls",          
            "domain": "[YOUR SUBDOMAIN].duckdns.org"            
        }   
    ],
    "duck_dns": {
        "token": "[YOUR DUCKDNS TOKEN]",
        "accept_terms": true
    },
    "tunnels_enabled": true,
    "forwarding_enabled": false
}
Enter fullscreen mode Exit fullscreen mode

That's it, you should be able to access your Home Assistant through your domain that you have configured, in my case it's https://auto-ha.duckdns.org. We have got full, end-to-end encryption without configuring your router or getting a static IP:

HA

Also, instead of using DuckDNS & Let's Encrypt, you can use any certificate you want or just don't supply any certs to the add-on and terminate TLS on Home Assistant server. For that you will just have to specify HTTPS in the destination: "destination": "https://127.0.0.1:8123". Add-on TLS termination is purely just to make your life easier, why do it manually when you can automate it?

Troubleshooting

DNS issues

As with any systems that let you tinker a lot, there can be issues. I have noticed that running pi-hole on my Raspberry Pi often breaks DNS and containers can no longer access the internet. Restarting helps but you might want to look for a more permanent solution by modifying (https://github.com/home-assistant/hassio/issues/497).

If you are using hassio provided image, then the procedure of fixing DNS in Docker is a bit more involved, check their debug documentation

Multiple tunnels & IP addresses

In the example above, you can modify tunnel configuration to have multiple tunnels

"tunnels": [
        {
            "name": "ha",
            "destination": "http://127.0.0.1:8123",
            "protocol": "tls",          
            "domain": "[YOUR SUBDOMAIN].duckdns.org"            
        },
                {
            "name": "node-red",
            "destination": "http://127.0.0.1:1880",
            "protocol": "tls",          
            "domain": "[YOUR NODE RED SUBDOMAIN].duckdns.org"           
        }   
    ],
Enter fullscreen mode Exit fullscreen mode

You can set the IP address to some other local network address such as http://192.168.1.120:1880 if that's where your Node-RED or some other service is running.

Custom domains or no domains

You can always use *.webrelay.io subdomains as they are provided with tunnels by default. Just set the protocol to 'https'.
Another option is to use your own domains and certificates, check [configuration examples(https://www.home-assistant.io/docs/ecosystem/certificates/tls_self_signed_certificate/). Once you have HTTPS on your Home Assistant, specify your domain and change destination to https: "destination": "https://127.0.0.1:8123",. Don't forget to create a CNAME record to your Webhook Relay tunnel (should show up in the tunnels page

Thanks for reading!

Discussion (9)

Collapse
pitp2 profile image
PITP2

Hi,

thank you for this great article :-)

I would like to do the same but with Hassbian (no hassio) and the ovh provider.
Do you know if it's possible ?

Collapse
krusenas profile image
Karolis Author

Hi,
Yes, it's possible, do you have access to Docker? You could start Webhook Relay agent just as a Docker container. Here's an article with such example: webhookrelay.com/blog/2018/09/03/h....
In my case I have both Intel NUC and RPI. On NUC I am running Node-RED, drone.io and webhookrelayd for remote access without HA :)

Collapse
pitp2 profile image
PITP2

Thank you for your reply :-)

But I always have to use the webhookrelay.com/ server ?

If it's possible I would like to use my own server to be independent

Thread Thread
krusenas profile image
Karolis Author

well, it is a SaaS :) If you are using OVH, you can have a static IP and you wouldn't even need such service. Just get an nginx reverse proxy with Let's Encrypt support and create an A record inside your DNS provider.

There are options for self-hosted tunneling server but that's more for business as the cost is higher than the public paid plans.

Thread Thread
pitp2 profile image
PITP2

yes but I have 3 houses with 3 hass :-)

And I have 3 differents internet providers and with one I can't have a static IP and open ports etc

So I would like to use the same thing has described because all my hass could be connected without opening ports

Thread Thread
krusenas profile image
Karolis Author

got it :) You want to use OVH instance as a gateway for your HA instances that are inside private networks.

Have a look at frp: github.com/fatedier/frp

It can do pretty much the same thing as Webhook Relay. You will need to deploy frp server on your OVH servers and the frp clients next to your HA instances. It's really good quality software with many users.

Thread Thread
pitp2 profile image
PITP2

Yes it's that !!!!

I will try to use it

Thank you for the link and your help :-)

Thread Thread
pitp2 profile image
PITP2

So I tried to install the package on my vps but I think that is too hard for me :-)

Thread Thread
pitp2 profile image
PITP2

I achieved the installation of FRPS and FRPC :=)

It works. I tried an ssh redirection and works fine.

Now I would like to connect multiple hass in differents house. Do you know how to configure frpc.ini ?