Using NGINX Reverse Proxy (Authentication and HTTPS)

So, I was able to solve my problems and wanted to share the approach with the community.

About my constellation:
I have rented an inexpensive web server, through which I have my own domain and static IPv4 address available. With this I implement the following

  • get a valid official certificate via Let’s Encrypt
  • convert the IPv4 address to IPv6, as my provider only offers Dual-Stack Lite

The server forwards the requests to the global IPv6 address of my OpenHAB server, on which the nginex server receives the requests. For this purpose, only this one communication port is openend in my router.

(Tip: Initially, I had implemented the access via the standard port 443, which resulted in hundreds, maybe even thousands of contact (hack) attempts in my logs every day. Then I changed to a completely different port quite quickly and since then it has been quiet.)

1. How do I get to the frontail output behind nginx?

I did not realise the access via a second opened port

https://<url>:443   (www)    ->   http://<url>:8080 (local)
https://<url>:9002  (www)    ->   http://<url>:9001 (local)

but via an extended path specification (as found here in the forum in some places)

https://<url>:19999      (www)   ->   http://<url>:8080 (local)
https://<url>:19999/log  (www)   ->   http://<url>:9001 (local)

My working configuration now looks like this:

server {
    listen                                    [::]:19999 ssl;

    server_name                               <MYSERVERNAME>;
   
    ssl_certificate                           /etc/letsencrypt/live/[MYDOMAINNAME]/fullchain.pem;
    ssl_certificate_key                       /etc/letsencrypt/live/[MYDOMAINNAME]/privkey.pem;
    add_header                                Strict-Transport-Security "max-age=31536000";  

    ssl_session_cache                         shared:SSL:20m;
    ssl_session_timeout                       4h;

    # Cross-Origin Resource Sharing
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow_Credentials' 'true' always;
    add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range' always;
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH' always;

    add_header Set-Cookie X-OPENHAB-AUTH-HEADER=1;
    proxy_set_header Authorization          "";

    location / {
        proxy_pass                            http://localhost:8080/;
	    sub_filter                            'http://[MYLOCALIP]:8080' 'https://[MYDOMAINNAME]:19999';
	    sub_filter_once			      		  off;

        proxy_set_header Host                 $http_host;
        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_read_timeout                    3600;

        auth_basic                            "Enter pass ?";
        auth_basic_user_file                  /etc/nginx/.htpasswd;
    }
	
    # Important : in the file "/etc/systemd/system/frontail.service" the command line has to be changed from
    #
    #     ExecStart=/usr/lib/node_modules/frontail/bin/frontail --disable-usage-stats ...
    #
    #  to 
    #
    #     ExecStart=/usr/lib/node_modules/frontail/bin/frontail --url-path /log --disable-usage-stats ... 
    #
    
    location /log {
        proxy_pass                            http://localhost:9001;

        proxy_set_header                      Host                 $http_host;
        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_http_version                    1.1;
        proxy_pass_request_headers            on;
        proxy_set_header                      Connection           "upgrade";
        proxy_set_header                      Upgrade              $http_upgrade;
        proxy_store                           off;
    
	 # that is important otherwise too many sockets in your log
        access_log                            off;


        auth_basic                            "Enter pass ?";
        auth_basic_user_file                  /etc/nginx/.htpasswd;
    }
}

It’s also important to change the file “/etc/systemd/system/frontail.service” (see the comment in the config file) and also change the links in “/etc/openhab/services/runtime.cfg” from

http://[MYLOCALIP]:9001

to

http://[MYLOCALIP]:9001/log

That’s it.

2. A second problem was how do I get the timelinepicker to work behind nginx.

In my sitemap the entries looked like that:

Webview label="Zeitplan" icon="line" url="http://[MYLOCALIP]:8080/static/time-line-picker/index.html?ip=[MYLOCALIP]:8080&transferItem=IFO2R_TLP_TransferItem&yAxisLabel=1,2,3,4,5,6,7&lang=de&states=Aus,Nacht,Tag,Heizen&colorset=2&deactivation=true" height=15

I changed it to

Webview label="Zeitplan" icon="line" url="http://[MYLOCALIP]:8080/static/time-line-picker/index.html?ip=http://[MYLOCALIP]:8080&transferItem=IFO2R_TLP_TransferItem&yAxisLabel=1,2,3,4,5,6,7&lang=de&states=Aus,Nacht,Tag,Heizen&colorset=2&deactivation=true" height=15

and also changed the timelinepicker file “…/openHAB-conf/html/time-line-picker/js/switchPointSet.js”. For this search the line

this.ip = 'http://' + openHAB_ip + '/rest/items/';

and change it to

this.ip = openHAB_ip + '/rest/items/';

Then you can tell nginx to replace the outgoing site-data with these lines in the config file:

	    sub_filter                            'http://[MYLOCALIP]:8080' 'https://[MYDOMAINNAME]:19999';
	    sub_filter_once			      		  off;

Now I can access OpenHAB, my sitemap and the log (frontail) via the internet and also my timeline picker GUI works.

Another hint: One stumbling block for me was that my server provider secures the servers with an additional external firewall by default. As long as you are on the standard ports (80/22/443), this is not noticeable. However, as soon as you change to another port and have problems with access, you should check whether your provider has an additional firewall. It took me a few hours to find the cause.