Trying to understand NGINX Home Assistant SSL proxy

Tags: #<Tag:0x00007f7399de4928>

I’ve seen similar questions asked but I am still trying to wrap my brain around this solution, so I’m starting a new thread to try to get clarity. Apologies for the churn.

The problem: running on a Raspberry Pi with haaska set up, which means having https (and associated certificates) configured. This prevents me from being able to use the Android/IOS apps internally because I don’t have loopback so I can’t use the external HTTPS URL internally, and the apps won’t accept an internal address because the certificate doesn’t match.

The solution as I understand it: install the NGINX Home Assistant SSL Proxy add-on, configure it, and now THAT handles the https request from the outside (including haaska / Alexa / external app requests from outside the network) and passes requests to HASS, while insecure http works just fine inside because you are on the other side of the proxy.

But the problem with THAT: from what I see in tutorials, you’re supposed to forward all traffic from port 443 to the proxy, and we have a houseful of other machines here, so if I did that there would be several people standing at my desk with pitchforks as I ruined Web access to the rest of the house.

Basically, what would be optimal would be for NGINX to ONLY see requests intended for HASS, so maybe set it up to listen on 8124 or something (and my outside domain would then use the format or subdomains would forward to same, and routers would be set to forward 8124 to it), then forwarding that traffic along to insecure http://myinternalip:8123.

Is that something that can be done or am I completely missing the point?

Thanks for any help!

– Chris

Yes, you would only use NGINX to proxy port 8123.
Unsure why the documentation would suggest anything otherwise as it just leads to confusion.

Here’s my NGINX config file which has worked for 3+ years. About as barebones as it gets. And I think it came from the HASS NGINX example 3+ years ago. It passes HASS externally on port 8124 with SSL, connecting to a non-SSL instance on localhost port 8123.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;

server {
    # Update this line to be your domain

    # These shouldn't need to be changed
    listen [::]:80 default_server ipv6only=off;
    return 301 https://$host$request_uri;

server {
    # Update this line to be your domain

    # Ensure these lines point to your SSL certificate and key
    #ssl_certificate /etc/letsencrypt/live/;
    #ssl_certificate_key /etc/letsencrypt/live/;
    # Use these lines instead if you created a self-signed certificate
     ssl_certificate /etc/nginx/ssl/MY_CERT_bundle.crt;
     ssl_certificate_key /etc/nginx/ssl/MY_KEY.key;

    # Ensure this line points to your dhparams file
    ssl_dhparam /etc/nginx/ssl/dhparams.pem;

    # These shouldn't need to be changed
    listen [::]:8124 default_server ipv6only=off; # if your nginx version is >= 1.9.5 you can also add the "http2" flag here
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    ssl on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    proxy_buffering off;

    location / {
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

Thanks! Yeah, I noodled around and discovered it works exactly as I had hoped; instead of HASS handling the secure web requests, NGINX acts as a gatekeeper between the secure request and the insecure backend and can listen on the right port so it doesn’t affect the rest of the network. And now my apps all work and Alexa is happy. Yay!