How to use NGINX as a proxy to redirect http to https to access Home Assistant securely?

Hello,

I have HomeAssistant running on a Raspberry Pi in Virtual Environment. It is all running ok from LAN and from Internet so
192.168.1.2:8123
and
mysite.duckdns.org:8123
work ok.

As I intend to run it behind an nginx webserver and because of ISP limitations, ports 80, 443 cannot be used so I have adopted this approach


and server config splitting as in

Certificates were generated successfully with

So I have configured it as http in port 8888 and https in port 8889. Of course, router port forwarding is configured as external 8888 to internal 8888 and external 8889 to internal 8889 in 192.168.1.2

/etc/nginx/sites-available/default

server {
  listen 8888; # HTTP
  server_name mysite.duckdns.org;
  #rewrite ^ https://mysite.duckdns.org:8889$request_uri? redirect;
  rewrite ^ https://mysite.duckdns.org:8889 redirect; # Alternate rewrite
}

server {
    listen       8889 ssl;
    server_name  mysite.duckdns.org;

    ssl on;
    ssl_certificate /home/pi/.acme.sh/mysite.duckdns.org/fullchain.cer;
    ssl_certificate_key /home/pi/.acme.sh/mysite.duckdns.org/mysite.duckdns.org.key;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:8123;
        proxy_set_header Host $host;

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

    location /api/websocket {
        proxy_pass http://localhost:8123/api/websocket;
        proxy_set_header Host $host;

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

    }
}

The outcome is…

https://mysite.duckdns.org:8889
is perfect and gives secure access to HA securely

However,

http://mysite.duckdns.org:8888
results in
ERR_CONNECTION_TIMED_OUT
website cannot be accessed

So it is not redirecting to 8889? Please, provide your advice so as to get a proper redirection/rewrite or any other approach.

Appreciated in advance.

Try this instead:

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

server {
    # Update this line to be your domain
    server_name mysite.duckdns.org;

    # These shouldn't need to be changed
    listen 8888;
    return 301 https://$host$request_uri;
}

server {
    # Update this line to be your domain
    server_name mysite.duckdns.org;
    ssl on;
    ssl_certificate /home/pi/.acme.sh/mysite.duckdns.org/fullchain.cer;
    ssl_certificate_key /home/pi/.acme.sh/mysite.duckdns.org/mysite.duckdns.org.key;
    ssl_prefer_server_ciphers on;

    # These shouldn't need to be changed
    listen 8889 http2; # 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_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    access_log /var/log/nginx/hass.access.log;
    error_log /var/log/nginx/hass.error.log;

    proxy_buffering off;

    location / {
        proxy_pass http://localhost:8123;
        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;
    }
}

If you would rather stick with your config and just deal with the redirect, try

return 301 https://$host$request_uri;

Hello,

Thank you for your input. I have tried both options.

Firstly, with
return 301 https://$host$request_uri;
has resulted in already known ERROR_CONNECTION_TIMED_OUT message. May it be that $host is not storing any value? Or not storing? mysite.duckdns.org?

Secondly, with the long script: I have pasted it into a brand new default file (removed duplicate ssl on; and ssl_prefer_server_ciphers on; that resulted in error after testing default with sudo nginx -t
I have restarted nginx and http://mysite.duckdns.org:8888/ will produce the same ERROR_CONNECTION_TIMED_OUT message whereas https://mysite.duckdns.org:8889/ works ok and shows secure Home Assistant website.

Sorry I have not been successful. Thank you in advance for any input.

edit: I have even generated dhparams as described in Home Assistant NGINX webpage and added to server just below

ssl_certificate /home/pi/.acme.sh/mysite.duckdns.org/fullchain.cer;
ssl_certificate_key /home/pi/.acme.sh/mysite.duckdns.org/mysite.duckdns.org.key;
ssl_dhparam /etc/nginx/ssl/dhparams.pem;

restarted nginx… but no positive result.

Honestly, why not just NOT forward port 8888 and not worry about redirecting?

change

 listen 8889 http2; # if your nginx version is >= 1.9.5 you can also add the "http2" flag here

to

listen [::]:8889 ipv6only=off default_server;