Haaska alternative without exposing RPi to the internet

Exploring ways to integrate HA with Alexa.

I have been trying to setup Emulated Hue and it hasn’t been a good experience: on port 8300 my 2nd Gen Echo could never discover the Hue, and then on port 80, 1 out of 20 tries it would discover it, but then the discovered switch operation is totally unrealiable (can turn on, but can’t turn off, or directly can’t turn on). No network issues at all, nor traffic in the network.

Thus I discarded emulated hue :). The concept is great though.

Next in complexity is Haaska. I believe I can set it up without major trouble (I have AWS intances and used lambdas before) however, I have a lot of concerns with opening an inbound port to the RPi.

Question: is there any alternative, preferably Haaska-style, but that could allow me use the “Cloud” integration in HA towards my own server out in the internet. So no ports are opened at home.

Of course I would really prefer to use HA’s new cloud integration but the recurrent cost they set doesn’t really work for me, it’s a pity. I only need to expose a single smart switch to alexa

Alternatively, a working version of emulated hue would be nice.

1 Like

As far as I’m aware Haaska and emulated_hue are the only options if you don’t want the integrated HA Cloud.

I used both of them until just a week ago. But with all of the discussions about potential hacking flying around I decided that using the HA Cloud service, setting up a VPN on a spare RPi and closing all my open ports was the right thing to do. $60 bucks a year isn’t too steep considering the added security. People gladly pay over twice that for Netflix. :wink: Maybe I’ll rethink that after the new authentication protocol is in place tho.

Why not used node-red? It has an Alexa add-on.

My high level plan:
-leverage a web server out there that is hardened and supports HTTPS, just forward the API over an ssh tunnel

  • add a homeassistant user in my EC2 server out there in a corner of the internets
  • configure passwordless ssh login so RPi’s user can ssh into the server
  • then use ssh tunneling to bring back port 8123 only allowing connections originated in the server itself (nginx)
  • then configure nginx to proxy the API URL /api/etc , input = https, output http over the tunnel (as a reverse proxy)
    With this approach there is no need to enable IP forwarding in the server nor use more sophisticated VPN tunneling - and avoid a full tcp port of the RPi to the world.

Finally, setup HAASKA

I have no idea if this is feasible but I’ll try.
Not idea but at least I don’t expose the RPi, and add the burden of letsencrypt etc to it. RPi is already pretty busy running kodi (music server) and HA

I thought that I would close on this confirming that the idea of using an outbound ssh connection from the HA RPi out to my own EC2 server, and then simple ssh with port forwarding + reverse-proxy in an existing NGINX installation to expose the HA API to the Amazon Skill has worked really really well.

I set it up 3-4 weeks ago and ZERO issues - using Alexa (via Haaska) every day, plus I monitor the tunnel and availability of the public API via… home-assistant :slight_smile:

Here are a few pointers that might be helpful:

SSH Tunnel from RPi to Server with port forwarding

one-off use for tunnel testing

ssh -R localhost:8123:localhost:8123 [email protected]

systemd service to auto-connect from RPi to Server

The tunnel will keep attempting to reconnect every few seconds if it gets disconnected
SSH options below are optimized to minimize resource consumption

[Unit]
Description=Connect to EC2 Instance for Alexa Skill
ConditionPathExists=|/usr/bin
After=network.target

[Service]
User=osmc
ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes  -R localhost:8123:localhost:8123 [email protected]
# N == do not execute commands (useful for just forwarding ports), T == disable pseudo-terminal allocation
# 60 secconds between keepalives, 3 attempts before giving up

# Restart every >2 seconds to avoid StartLimitInterval failure
RestartSec=5
Restart=always
# keeps restarting upon failure, kills etc; with a hold-off timer of 5 secs

[Install]
WantedBy=multi-user.target

Setting up Reverse Proxy in NGINX
This configuration will expose the HA API to Amazon in the public side, and bring will back the API queries over the shh tunnel back to the RPi.
This configuration can coexist with that of a pre-existing website. This server is configured with TLS.
Caveat: this setup does NOT support loading the entire HA’s Web Front End through the proxy - it will only expose the API. I see this as an advantage from a security POV. To access the HA front end, I use openVPN hosted in my router.

Snippet from /etc/nginx/conf.d/web.conf

	  # reverse-proxy for home-assistant API
	  location /api/homeassistant/ {
	    proxy_pass http://localhost:8123/api/;  # note the ending '/' that redirects the api location to the root of localhost
	    proxy_redirect off;
	    proxy_set_header Host $http_host/api/homeassistant;
	    proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	  }

For the HAASKA skill, take a look at: GitHub - mike-grant/haaska: Home Assistant Alexa Skill Adapter that supports v3 of the Alexa Smart Home Skill API

Finally, you can create ad-hoc command-line sensors in HA to monitor both the ssh tunnel to the server and also the availability of your public API

image

- platform: command_line  # Public API status
  name: Public API
  device_class: connectivity
  command: /home/user/test-public-api.sh  
  payload_on: "UP"                        
  payload_off: "DOWN"
  scan_interval: 300

test-public-api.sh

#! /bin/bash
# used by Home Assistant to test Public API availability 

if [[ 
        $(/usr/bin/curl --silent -I -X GET -H "x-ha-access: your_password" -H "Content-Type: application/json" https://yoursite.com/api/homeassistant/services | /bin/grep "HTTP/2 200") > 0 ]] ; 
        
then /bin/echo -n UP; 

else /bin/echo -n DOWN; 

fi

Hey, this sounds awesome. Are you still running alexa this way? Any issues so far?

I had tried to do reverse ssh tunnel before using EC2 and my domain name. This way I was able to access HA running on rpi without public IP. My ISP don’t provide public IP so can’t directly access it. It was working great no issues but the cost was coming up more than 5-6$ per month. I realized I was using T2 micro and I can go below that but the cheapest EC2 + static was even costing 2-3$ per month.

I’m wondering how much does it cost you on AWS with above setup?

Thanks,
Krupal

Yes still running it this way. Very low maintenance, literally no maintenance actually, it just never failed and it just works. I use voice commands 2-3 times daily to control a thermostat and a few other devices managed by HA and I have never had a command fail.

To be honest I expected some challenges since my RPi is connected to a wireless bridge to reach the internet. However, 3 months later, never an issue. The only downtimes were due to HA upgrades or OSMC/OS updates (the same RPi is a music server, running kodi), or EC2 server patching.

In terms of EC cost, depends on your usage and plan, for the last 3 years I have been using the plan were you pay upfront 100 for 3 years (micro instance), and then have a very low hourly rate, it comes to around just 1.50 per month, less than the value of a coffee. Shortly I will have to renew and the new 3yr plan they have now is even lower cost, you no longer pay for compute monthly IIRC, just networking and storage/IOP. The server hosts a blog and a few little apps, it’s more of a learning tool than anything else

Very interesting. This makes me so curious to give it one more shot. I will explore it when get chance. Thanks for sharing this!

@ariel Thanks for inspiring me to use this.

I am using haaska by exposing RPi through ssh tunnel and reverse proxy in an aws EC2 instance. It is super stable. Not a single failure. I use alexa voice commands daily, never failed yet. I use Caddy server for reverse proxy to my domain using https and this way I can use HA frontend too. For now I chose t3 nano and my monthly bill is yet to come but I anticipate around $2-3. Once I’m confident enough I will purchase a reserved instance for a year or may be 3 to save few more bucks.

I saw that HA cloud subscription has an upcoming feature to remotely access the HA frontend, once it is available, I will re-evaluate the situation and pick the better value. But till then, hoping to use in this way.

Super happy with the setup. Thanks a lot again!

Hi, did you perform any additional configuration to allow the tunnel in your system (such as modifying the firewall or sshd.conf)? This is the first time I’ve configured a tunnel, I added the snippet into the default nginx site (the demo one) for testing purposes, but I keep getting 504 errors.

Thank you.

@serch037 no special firewall rules are needed, as long as you are able to ssh out from your RPi, and that your internet server allows ssh access, and you setup passwordless ssh for that (preinstalling the required key in .ssh/authorized_keys in the server) so the RPi can ssh out to your server and not get a prompt. I created an ad-hoc user for this in the Server just for accounting purposes.
Using Amazon AMI Linux in my server, I did NOT need to touch anything in sshd_config. Other distros could vary, assuming you can ssh from the RPi to your server, you can test if port forwarding is working, and if it’s not, take a look at the value of AllowTcpForwarding in the server sshd_config.

To test, from your raspberry you can do:

ssh -R localhost:8123:localhost:8123 [email protected]

Then, assuming it connected, in your internet server try the following:

curl localhost:8123

If port forwarding is working OK, you should see the HTML of HA’s webpage that came from your HA install in the RPi. If the tunnel is not OK, you will get some 4xx or 5xx error.

If the tunnel worked OK, then your problem is in the NGINX configuration

Back when setting this up I used tcpdump to troubleshoot, e.g. in your Rpi you can use

sudo tcpdump -vv -x -X -s 1500 -i lo ‘port 8123’

and

sudo tcpdump -nni lo -A port 8123 and ‘tcp[13] & 8!=0’

to see what is coming (if anything) over the tunnel.

Once you set it up it has proven to be extremely solid - I set this up in July and I am still using the Haaska integration daily without further tweakings. With the systemd service, the tunnel recovers automatically if I reboot my router, or my server, or the RPi, which very rarely happens anyways.

HI @ariel I’ve looked at your solution and I have a few questions:

Your EC2 instance has a public IP address and is running NGINX has a reverse proxy.
You HA establishes an SSH tunnel to the EC2 instance.

By using this solution you won’t be opening or forwarding any port on the HA, but the NGINX will be publicly open. So what is the pros of your solution vs opening HA? Is just exposing a small fraction of the API?

Thanks

Hi @Andre_Santos, this is to avoid having to expose the humble Raspberry pi to the internet, and in general from having to expose any inbound port in my home router, where people can scan, probe for vulnerabilities &c.
My EC2 instance is a real server, much more powerful than the RPi: hardened, patched regularly, and I use it for other things too (blog, web services playground etc). And most importantly: it’s outside of my home network. Worst case scenario, if it gets hacked, that doesn’t give anyone access to my home network (or at least it makes it a lot more difficult). Lot’s of bad people out there in the internets :slight_smile:

RE this tunnel story - 9 months later and still going strong. In the interim I upgraded haaska once, and HA a bunch of times mainly driven by the Lovelace migration etc. Planning to slow down with HA upgrades to one per quarter as it’s getting very stable… and thanks to the approach in this thread I am minimizing exposure of the platform to the outside world