For the longest time I’ve accessed my home assistant through an SSH tunnel when I’m away from home. But I recently did some digging into how the login system works now, and it’s much more secure than it once was. Enough that with 2FA enabled, I’m happy exposing it directly to the internet on 443.

I use Nginx as a gateway to my network, everything that comes from the internet and speaks HTTP needs to go through it. Normally the configuration is very simple, but for Home Assistant it’s slightly more complicated due to Home Assistant’s use of webhooks.

Here’s the site configuration that works for me:

server {
        root /var/www/html/stub;

        index index.html index.htm index.nginx-debian.html;

        location / {
                proxy_pass_header Authorization;
                proxy_set_header Host;
                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/websocket {
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";

    listen 443 ssl;
    ssl_certificate /path/to/ssl/cert
    ssl_certificate_key /path/to/privkey

The key is the extra configuration for /api/websocket that passed the Upgrade and Connection headers.

It’s also worth noting that there’s just a blank index.html file at /var/www/html/stub. Due to the proxy_pass on /, you should never see it.