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
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
- 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