HA behind nginx reverse proxy - App lost connection after few hours

Hi,

I have some issues with my HA environment together with the App and position tracking.

Current Setup:

  • HA is installed on dedicated x86 baremetal device with HAOS
  • SSL let’s encrypt certs installed on HA
  • nginx reverse proxy is running on OpenWRT Router, also installed with let’s encrypt certs, all collected in DNS mode (route53)
  • All connections to HA going through reverse proxy, also connections coming from LAN.
  • Direct access to %HAIP%:8123 is also possible (from LAN)
  • HA WebGUI and App is working fine from inside and outside my local network.
  • I have the HA app installed on different devices (Xiaomi Mi9, Samsung and ipad) and the behavior described below is the same on all devices. All energy optimizations are disabled.
  • On the ipad app I can see that connection and websocket connection is fine.
  • I do not use an internal URL configuration for the app

Problem description

  • After a few hours I do not get any update from the app devices like geo location or battery level anymore. If I open the app it will connect immediately and all is working, also the app sensor data is updated.
  • If I am using the internal HA IP and Port and an established VPN Connection the app connection looks better because I got the sensor data for more than 24h hours.

nginx.conf config

worker_processes auto;
user root;
include module.d/*.module;
events {}

http {
        access_log off;
        log_format openwrt
                '$request_method $scheme://$host$request_uri => $status'
                ' (${body_bytes_sent}B in ${request_time}s) <- $http_referer';

        ##
        # Connection header for WebSocket reverse proxy
        ##
        map $http_upgrade $connection_upgrade {
            default upgrade;
            ''      close;
        }

        include mime.types;
        default_type application/octet-stream;
        sendfile on;

        client_max_body_size 128M;
        large_client_header_buffers 2 1k;
        server_names_hash_bucket_size 64;

        proxy_request_buffering off;
        proxy_buffering off;

        gzip on;
        gzip_vary on;
        gzip_proxied any;

        root /www;

        include conf.d/*.conf;
}

nginx server config

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name ***;

        ssl_certificate ***;
        ssl_certificate_key ***;
        ssl_session_cache shared:SSL:32k;
        ssl_session_timeout 64m;
        ssl_protocols TLSv1.2;
        access_log off; # logd openwrt;
        proxy_buffering off;


        location / {
                proxy_pass https://192.168.1.1:8123;
                proxy_set_header Host $host;
                proxy_redirect http:// https://;
                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 Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
        }
}

If I check the location tracking log in the android app, I just see “send failed” during the time where I do not get sensor data from the app. That means that the App itself will not be closed and is still running.

Any idea what I did wrong? Have anybody experience with the OpenWRT own nginx version? I’m slowly running out of ideas on how I can narrow down the error even further.

i’m not full specialist on ngnix, but i have some cache control headers in place that might help you too:

Cache-Control ‘no-store, must-revalidate, proxy-revalidate, max-age=0’

Thanks for the hint, but unfortunately that doesn’t help either.

On the picture you can see the red areas where the connection seems to be interrupted.

However, when I look at the location tracking logs in the companion app, I always see “Send failed” at this time. This tells me that the app has been running in the background the whole time. But somehow the app no longer connects properly. Maybe this is also a bug in the app. Because even if the reverse proxy disconnects something, the app has to make sure that it reconnects itself.

the app itself also has ‘automatically close connection’ in the user settings. which would disconnect after 5 minutes of being hidden.
However, i suppose it should not affect the sending of sensor data if you ask me, but also worth a try.

You can also try adding

    location /api/websocket {
        proxy_pass http://YOUR HA IP/api/websocket;
        proxy_set_header Host $host;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

    }

That location for websocket is not needed because it is covered by the “/” location. And the websocket is working fine, my ipad shows websocket as connected and the tcpdump looks also fine. But nevertheless, I has had that in my config before and removed it later because nothing changed.