Securely connect to Home Assistant from the outside world using NGINX
So you have Home Assistant running al good in your local network, but no way of accessing it remote. You of course have a few different options, but the combination of hurdles you have to overcome is rather large: Dynamic IP, ISP router/modem that doesn’t do exactly what you want and a general sense of security to not directly expose your devices to the outside network.
In comes NGINX to the rescue! Of course you will need some extra hardware to make this work. A cheap VPS/Dedicated server and a domain name pointed to it should be sufficient!
OpenVPN
Setup an OpenVPN network on your VPN. In the future I may write up how to do this, but it should be very self explanatory. Make sure you are able to ping your Home Assistant (VPN)IP from the NGINX server and vice versa.
Note that OpenVPN is not needed if you have an externally accessible server in the same network as your Home Assistant device.
NGINX
So now the real deal! NGINX will allow you to form a reverse proxy towards any other website. As Home Assistant is working with websockets, you would need a fairly up-to-date version of NGINX. We will also securing the communication with SSL/Certbot
1 |
> sudo apt-get install nginx python-certbot-nginx |
Create a config file for your Home Assistant website in the /etc/nginx/sites-enabled directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
> nano your.domain.conf server { server_name domain.name; # The internal IP of the VM that hosts your Apache config set $upstream 10.8.0.105:8123; location / { proxy_pass_header Authorization; proxy_pass http://$upstream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; #proxy_set_header Connection “”; proxy_buffering off; client_max_body_size 0; proxy_read_timeout 36000s; proxy_redirect off; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } > systemctl restart nginx |
After nginx has restarted, typing in the URL of your nginx server should allow you to login to Home Assistant.
Now comes the “security” stuff!
1 |
sudo certbot --nginx -d your.domain |
Follow the instructions and make sure to force the redirection to HTTPS! Checking your config file again, it should have added some lines to enable SSL. Going to your nginx webserver will also force HTTPS now (after a restart of nginx).
Your Home Assistant is now securely accessible via your nginx server!
Even more security!
Personally, I don’t allow the “wildcard” access to my Home Assistant. If access is needed I just put my phone on the VPN and access it that way. Much more secure!
However, some services like google assistant, Owntracks, … do need direct access to your Home Assistant. For that reason my nginx server block looks like the below!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
location /api/webhook { proxy_pass_header Authorization; proxy_pass http://$upstream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr/api/webhook; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Connection “”; proxy_buffering off; client_max_body_size 0; proxy_read_timeout 36000s; proxy_redirect off; } location /api/google_assistant { proxy_pass_header Authorization; proxy_pass http://$upstream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr/api/google_assistant; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Connection “”; proxy_buffering off; client_max_body_size 0; proxy_read_timeout 36000s; proxy_redirect off; } # location /auth { # proxy_pass_header Authorization; # proxy_pass http://$upstream; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr/auth; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_http_version 1.1; # proxy_set_header Connection “”; # proxy_buffering off; # client_max_body_size 0; # proxy_read_timeout 36000s; # proxy_redirect off; # } # location / { # proxy_pass_header Authorization; # proxy_pass http://$upstream; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_http_version 1.1; # proxy_buffering off; # client_max_body_size 0; # proxy_read_timeout 36000s; # proxy_redirect off; # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection "upgrade"; # } |
Happy remote Home Assistant access!