Using NGINX Reverse Proxy (Authentication and HTTPS)

Hello all
I just followed the instructions of Benjy but I can not get ot work.

When I enter
http://openhabianpy
into my browser it always redirects to
https://start/index

This is the config at /etc/nginx/sites-enabled/openhab

server {
        listen                          80;
        listen                          [::]:80;
        server_name                     openhabianpi.fritz.box;
        return 301                      https://$server_name$request_uri;
}
server {
        listen                          443 ssl;
        listen                          [::]:443 ssl;
        server_name                     openhabianpi.fritz.box;
        ssl_certificate                 /etc/ssl/3bert.crt;
        ssl_certificate_key             /etc/ssl/3bert.key;
        add_header                      Strict-Transport-Security "max-age=31536000"; # Remove if using self-signed and are having trouble.
        location / {
                proxy_pass                              http://localhost:8080/;
                proxy_buffering                         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;
                auth_basic                              "Username and Password Required";
                auth_basic_user_file                    /etc/nginx/.htpasswd;
        }
}

What is wrong?

Thank you very much in advance!

Best regards,
Matze

There is a button for that :slight_smile:

Firstly I’d remove the Strict-Transport-Security line in your config, since you’re using self-signed certificates

Secondly, where did the listen [::]:80; come from? If you had the Strict-Transport-Security line on a previous setup, then it’s likely still cached even when you remove it or use it for another item. See http://classically.me/blogs/how-clear-hsts-settings-major-browsers

Finally, what happens if you change:

                proxy_set_header Host                   $http_host;

to

                proxy_set_header Host                   $proxy_host;

Remember to test sudo nginx -t and sudo service nginx restart too! Hope this helps.

That was a fast solution! :slight_smile:
Thank you very much!

Changing to $proxy_host did it!

Not a problem, out of interest, which of the three solutions solved your problem or did all three?

Hi, I’ve followed this thread carefully but can’t find an answer to my problem.

All I want to do is use NGINX as a reverse proxy without SSL or other authentication, with local LAN clients only. I want NGINX to filter requests by IP address and deny access to certain OH sitemaps, depending on the IP address. (This is to work around the problem where a tablet user can access any sitemap simply by selecting it in the pop-over try that appears when clicking the icon.)

Details, including relevant nginx conf file code snippets are here. (If you all prefer I consolidate & move my entire query over here I will condense it and do so.)

I actually just updated the docs version of this (which has also been moved to a general security thread)

Note the part about “satisfy any”, which I beleive is the line that you’re missing. You also seem to be missing the proxy pass line in your more specific location.

I reviewed your updated docs & noted the new section on controlling access by IP address. I tried adding the “satisfy any;” line above my IP allow/deny blocks (see other post here,) but with no effect.

I emphasize that when I access sitemaps NOT selected by the special location ~ { } regexp, I have no problems with access at all. Nginx & OH, & my OH tablet clients work fine together.

There is only a problem when trying to access a specific sitemap that I wish to block access to for certain IP addresses on the LAN, while allowing other IPs access. As mentioned in my other post, I know my regexp & allow/deny rules are working fine, because I do get proper “access forbidden by rule…” messages in the error log, for the denied IP addresses.

The trouble is when a permitted IP address tries to access the location ~ regexp { } item, it spits back back the “no such file or directory” message.

With appreciation for your time.

A wanted to post a quick update about running nginx in a Docker container and reverse proxying multiple servers, not just openHAB.

Docker

I ended up abandoning running nginx in Docker primarily because I can’t use soft links in the volumes I mount into the container. This becomes a problem with the LetsEncrypt certs because the “current” certs are presented in a directory with softlinks. To make it work I would have to point at the actual cert files and then update it every time the cert expires and gets updated. The advantages of Docker at this point became overcome but this future maintainence.

Reverse Proxying Multiple Services

What I wanted to do was use addresses like

Upon further research, the solutions discussed above with rewrites provide only half of the solution.

Nginx does not actually go into the HTML files being transmitted and update the URLs used therein to point to /gogs (for example). So nginx provides the main page as expected but all the other elements of the page and links on the page omit the leading “/gogs/” in subsequent requests and Nginx fails to find the resource to return.

Some servers (gogs and calibre in particular) have an option you can use when starting the server to rewrite the URLs to include the “/gogs/” in the pages it serves. Thus you get the original page through nginx and each subsequent request has the correct relative URL.

However, as a forewarning, I’ve not yet made this work correctly. It’s low on my list of priorities right now.

And this also means that using “/openhab/” to get at your openHAB will not work unless/until changes are made to OH to support adjusting the URLs in the pages it serves.

Dear friends,

first of all I would like to express my gratitude for this brillant piece of software! I just love it!

Now to my question or problem: In the habpanel I created basically two dashboards and I want to redirect based on $remote_user. The reason behind is that I can’t figure out how to set up users that have only access to distinctive dashboards (as far as I skimmed the tutorials and documentation there is no such concept as of now, right?).

I tried it with a very easy approach through:

proxy_pass http://127.0.0.1/habpanel/index.html#/view/$remote_user;

but I get connection lost trying to reestablish connection.

Has anybody an idea how to sperate dashboards and restrict to specific users? I can’t get my head around this topic somehow.

Any hint is appreciated.

Thanks,
David

I’ve discovered that NGIFX won’t install if Apache2 service is running, even if Apache2 is on a different set of ports.

sudo service apache2 stop 

allows ngifx to install

Forget NGINX! Use Apache2 instead, if you want to change the path to e.g. https://myserver/openhab/basicui/app – after quite a few hours, I got it working with the following config file:

<Location "/openhab">
        Options SymLinksIfOwnerMatch

        AuthType Basic
        AuthName "openHAB"

        ## BEGIN LDAP
        AuthLDAPURL "ldap://localhost:389/ou=person,dc=codewizards,dc=co?cn?sub?(objectClass=person)"
        AuthLDAPBindDN "cn=CENSORED,ou=CENSORED,ou=person,dc=codewizards,dc=co"
        AuthLDAPBindPassword "CENSORED"
        #AuthzLDAPAuthoritative on
        AuthBasicProvider ldap
        Require valid-user
        ## END LDAP

        RewriteEngine On
        RewriteRule "/openhab/openhab/(.*)" "/openhab/$1" [R,L]
        RewriteRule "/openhab/?(.*)" "http://localhost:10080/$1" [P,L]
#               LogLevel alert rewrite:trace8

## We cannot use ProxyPass, because this implicitly adds its own rewrite-rules *before* ours!
## Hence, we cannot redirect the browser from .../openhab/openhab/... to .../openhab/...!
#               ProxyPass http://localhost:10080
        ProxyPassReverse http://localhost:10080

        ProxyHTMLEnable On

## The ProxyHTMLExtended can be used to work on *embedded* JavaScript. It does not work
## on separate .js-files. Thus, I now use SUBSTITUTE instead -- which works on both separate
## and embedded. Thus, this ProxyHTML* is not needed, anymore.
#               ProxyHTMLExtended On
#               ProxyHTMLURLMap / /openhab/ [e]
#               ProxyHTMLURLMap /basicui /openhab/basicui
#               ProxyHTMLURLMap /openhab/basicui /openhab/basicui

## Seems the suppression of gzip is not needed. Found this hint in the web,
## before, but the problem was actually another one. Thus, commented the following line
## again.
## UPDATE: IT IS NEEDED! My smarthome.js was obviously cached, before.
        RequestHeader unset Accept-Encoding

        AddOutputFilterByType SUBSTITUTE text/html
        AddOutputFilterByType SUBSTITUTE text/css
        AddOutputFilterByType SUBSTITUTE application/javascript
        AddOutputFilterByType SUBSTITUTE application/json
        Substitute "s|/basicui/|/openhab/basicui/|n"
        Substitute "s|/rest/|/openhab/rest/|n"
        Substitute "s|'/rest'|'/openhab/rest'|n"
        Substitute "s|/paperui/|/openhab/paperui/|n"
        Substitute "s|/inbox/|/openhab/inbox/|n"
        Substitute "s|/icon/|/openhab/icon/|n"
        Substitute "s|http://|https://|n"
</Location>

This file is included in my default-ssl.conf:

<VirtualHost ... CENSORED ...>

... lots of other stuff ...

    Include /etc/apache2/openhab/openhab-ssl.conf
</VirtualHost>

Both basicui and paperui work fine this way. But no guarantee: Maybe there are still more Substitute rules needed. I didn’t test everything, yet.

I hope this helps everyone who wants to use openHAB behind a reverse-proxy (and with LDAP-authentication)!

Best regards, Marco :slight_smile:

P.S.: It seriously sucks that openHAB doesn’t allow to configure a path-prefix! I have written quite a few programs in my life, already, and always when there were URLs involved, things like a prefix (or even more) were configurable. How can you even get the idea that this is an unnecessary feature?! And most importantly: If you really don’t want to configure it, why don’t you hard-code such a prefix (e.g. “openhab/”) – it would be far easier to remap an existing prefix than to deal with all these individual paths (like “basicui”, “paperui”, “rest” etc.).

1 Like

ARG!!! The Android app did not work, yet :frowning:

The following two lines need to be added:

AddOutputFilterByType SUBSTITUTE application/json

Substitute "s|http://|https://|n"

I’ll try to edit my previous post and add this.

Again an update:

RequestHeader unset Accept-Encoding

is needed! I thus removed the comment-# in my post above. It seems the smarthome.js was still in my browser-cache, after I disabled and tested it.

Well, it’s a pity that we can’t use gzip, but it doesn’t really matter. We’re usually in the LAN, anyway :wink:

Hey @nlmarco,
your contribution here is very much appreciated! Why don’t you move these steps to their own tutorial? The topic sure deserves one and a thread is easier found than reply number 38 here :wink:

Hi Thom, you’re absolutely right!

I was trying to get things running, read this thread, saw that things don’t work the way I need with NGINX, tried it with Apache (which was running already, anyway) and directly wrote it here :wink:

Now it’s really late and I’m going to postpone any further stuff to tomorrow. But certainly, I should write it in a cleaner way somewhere else.

Cheers, Marco :slight_smile:

3 Likes

As promised:

3 Likes

Hi, I run into this thread while banging my head to wall with nginx proxy. To simplify https certs, I have all my stuff behind one domain, separated by suffixes. OH2 basic UI looses all graphics and CSS files if it’s proxied like that. Any configuration option like grafana has: http://docs.grafana.org/installation/behind_proxy/ which I could set?

To clarify: not like openhab.example.com, but example.com/openhab, where nginx location is /openhab/ for the proxy.

I see there is post about “forget nginx” above, but I have it all in nginx, and I just can’t get it out of my mind :slight_smile:

Any new input for this topic?

My location:

  location /openhab/ {
    proxy_pass           http://192.168.1.32:8091/basicui/app;
    proxy_buffering                         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;
    auth_basic           "authme";
    auth_basic_user_file htpasswd;
  }

To short answer is no.

Some have managed to figure out most of the urls that need to be replaced in the nginx config but I’ve not seen a complete working solution.

I think people using Apache have had better luck.

An issue has been filed and has remained open for quite some time but no progress has been made that I know of.

I see the right way to do it would be to have conf options for domain an suffix for UI components. All web server confs are temporary tricks around the problem, and any app change could break the web server confs again.

Is any app developer interested of this change? The conf should ask for domain and suffix used in proxy, and app should use those as variables for any internal links. In short :slight_smile:

EDIT: the issue seems to be reported here: https://github.com/openhab/openhab-core/issues/150