Every time I attempt to connect to Home Assistant from iOS (browser or app) through my reverse proxy, I get a “Unable to Connect to Home Assistant” message right after logging in. I have no problem connecting through the reverse proxy from a Windows PC and Android phone, only iOS gives me this error. Direct connections internal to the network work fine, even in iOS, so I presume I’m doing something wrong in NGINX, but after hours of troubleshooting I can’t seem to figure out what. I am using a subdomain for HA, but I’m not sure if that’s part of the issue.
NGINX error logs have nothing in them except some socket leaks, but those are not consistently generated when I attempt to connect to HA from iOS. (socket leak error looks like “*7 open socket #21 left in connection 6”) There are zero errors in the conf-specific NGINX error log. On the HA side, the log shows no warnings or errors. I have the reverse proxy configured as trusted in my HA config. I’ve also configured NGINX for websocket proxy. Proxy buffering is disabled as well.
I know there is some communication between HA and the iOS devices, because they show up in Integrations and I can even get battery life and other metadata from those devices in HA. I just can’t get past the “Unable to connect to Home Assistant” to get to the UI.
Any help is appreciated.
I have the following in my NGINX conf, which I see in other posts like this:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
My full NGINX Site Conf file:
upstream ha.mydomain.com_backend {
server 192.168.66.74:8123;
}
server {
listen 80;
listen [::]:80;
server_name ha.mydomain.com;
location / {
return 301 https://$server_name$request_uri;
}
location /.well-known/acme-challenge {
alias /var/www/ha.mydomain.com/.well-known/acme-challenge;
}
access_log /var/log/nginx/ha.mydomain.com_access.log;
error_log /var/log/nginx/ha.mydomain.com_error.log error;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ha.mydomain.com;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
access_log /var/log/nginx/ha.mydomain.com_access.log;
error_log /var/log/nginx/ha.mydomain.com_error.log error;
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/ha.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ha.mydomain.com/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
proxy_buffering off;
location /.well-known/acme-challenge {
alias /var/www/ha.mydomain.com/.well-known/acme-challenge;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://ha.mydomain.com_backend;
}
location /api/websocket {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://192.168.66.74:8123/api/websocket;
}
}