MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.

    MagicMirror behind a NGinx Reverse Proxy

    Scheduled Pinned Locked Moved Solved Troubleshooting
    17 Posts 3 Posters 38.7k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • F Offline
      fbr1969
      last edited by

      Hi,
      I’m would like to acced to MM (192.168.10.60:8080) behind a Nginx Reverse Proxy (IP:192.168.10.10 for example). I’m not an expert of Nginx and I tried :

      server {
          listen      80;
          server_name domain.com;
          return      301 https://$server_name$request_uri;
      }
      
      server {
      
          # Setup HTTPS certificates
          listen       443 default ssl;
          server_name  domain.com;
          ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
          ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot
          include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
          ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
      
          location /mmirror {
              proxy_bind              $server_addr;
              proxy_pass              http://192.168.10.60:8080;
              proxy_set_header        Host            $http_host;
              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header        X-Scheme        $scheme;
              proxy_set_header        X-Script-Name   /;  
          }
          location / {
              root   /var/www/html;
              index  index.html ;
          }
      }
      

      But if y want to access to : 192.168.10.10/mmirror
      I get this error : 502 Bad Gateway nginx/1.14.2
      MagicMirror is of course fully fonctionnal in direct by 192.168.10.60:8080.

      Thank for your help.
      François

      S 2 Replies Last reply Reply Quote 0
      • S Do not disturb
        sdetweil @fbr1969
        last edited by

        @fbr1969 is domain.com resolved by the client system to the nginx server?

        this
        192.168.10.10/mmirror
        should get a 301 moved to https://domain.com/mmirror
        where-ever domain.com is…

        I might change the moved to https://$server_addr$request_url

        Sam

        How to add modules

        learning how to use browser developers window for css changes

        F 1 Reply Last reply Reply Quote 0
        • S Do not disturb
          sdetweil @fbr1969
          last edited by sdetweil

          @fbr1969 said in MagicMirror behind a NGinx Reverse Proxy:

          192.168.10.10/mmirror

          if u do

          curl http://192.168.10.10/mmirror
          

          (do not use -L)

          u should get a 301 response, right?

          and if u use the url in the moved, does it work? domain.com shouldn’t. proxy.domain.com might if u have a hosts entry or a dns server resolving that to 192.168.10.10

          you could also do

          curl -iL http://192.168.10.10/mmirror
          

          to see the full flow (-i shows the response headers)
          https://stackabuse.com/follow-redirects-in-curl/

          Sam

          How to add modules

          learning how to use browser developers window for css changes

          1 Reply Last reply Reply Quote 0
          • S Do not disturb
            sdetweil
            last edited by

            I would also try

            https://192.168.10.10/mmirror

            and see if that works (no redirect)
            this will test the certs and the passthru config

            Sam

            How to add modules

            learning how to use browser developers window for css changes

            1 Reply Last reply Reply Quote 0
            • E Offline
              ember1205
              last edited by

              Firstly, do you really want to put your mirror behind a piece of software developed by the Russians, released into Open Source, then claimed by another Russian Company as “theirs” after it was purchased out by a commercial entity (F5)? If you need a reverse proxy, you’re likely to have all that you need from a simply Apache setup.

              Second - you will need to ensure that all of your rewrite rules take into account the back-end port along with the front-end port information as well as specific host name rules.

              For example:

              If your MM is 192.168.1.10 and you have a system running reverse proxy with a VIP on 192.168.1.50, you will need to decide if you’re going to continue using port 8080 on the front-end or if you want to fall back to standard port 80 (or even tie it up with a certificate on 443 with HTTPS/SSL).

              In other words, you could be doing client to proxy as 192.168.1.100 -> http://192.168.1.50 or 192.168.1.100 -> http://192.168.1.50:8080 or 192.168.1.100 -> https://192.168.1.50 or something else entirely.

              After you have decided how you’re handling the front end, you then need to ensure that you’re rewriting ALL of that as it passes through the proxy to/from http://192.168.1.10:8080

              You ALSO need to ensure that you have updated the configuration on MM to allow connections from off-box IP’s. Specifically, unless you are forcing the use of the original source IP, connections to the mirror should be coming from the system running your proxy and THAT address needs to have access to the web server on the mirror.

              1 Reply Last reply Reply Quote 0
              • F Offline
                fbr1969 @sdetweil
                last edited by fbr1969

                @sdetweil @ember1205 Thank for your help.
                I made a mistake ! My error is 404 (Cannot GET /mmirror)

                I forgot to say :

                • My nginx server is fully fonctional with some other locations I’ve masqued in my exemple of configuration files… Like that :
                    # Proxy to the Airsonic server
                    location /airsonic {
                        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 https;
                        proxy_set_header X-Forwarded-Host  $http_host;
                        proxy_set_header Host              $http_host;
                        proxy_max_temp_file_size           0;
                        proxy_pass                         http://192.168.10.30:8080/airsonic;
                        proxy_redirect                     http:// https://;
                    }
                
                    location /calilivre {
                        proxy_bind              $server_addr;
                        proxy_pass              http://192.168.10.20:8080;
                        proxy_set_header        Host            $http_host;
                        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header        X-Forwarded-Host $server_name;
                        proxy_set_header        X-Scheme        $scheme;
                        proxy_set_header        X-Script-Name   /calilivre;  # IMPORTANT: path has NO trailing slash
                    }
                
                    location /calibd {
                        proxy_bind              $server_addr;
                        proxy_pass              http://192.168.10.50:8080;
                        proxy_set_header        Host            $http_host;
                        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header        X-Scheme        $scheme;
                        proxy_set_header        X-Script-Name   /calibd;  # IMPORTANT: path has NO trailing slash
                    }
                
                    location /mmirror {
                        proxy_bind              $server_addr;
                        proxy_pass              http://192.168.10.60:8080;
                        proxy_set_header        Host            $http_host;
                        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header        X-Scheme        $scheme;
                        proxy_set_header        X-Script-Name   /;  # IMPORTANT: path has NO trailing slash
                    }
                

                So, airsonic, calibd or calilivre are fully fonctional in http (redirect to https) or https.
                My 'domainename (ex:domain.com) is resolved by dns.
                I can do my test on my private lan or on Internet. I’ve the same result (502 Bad Gateway).
                Look the curl result :

                curl -iL http://192.168.10.10/mmirror
                HTTP/1.1 301 Moved Permanently
                Server: nginx/1.14.2
                Date: Mon, 23 Dec 2019 18:14:36 GMT
                Content-Type: text/html
                Content-Length: 185
                Connection: keep-alive
                Location: https://[MyDomain]/mmirror
                
                HTTP/1.1 404 Not Found
                Server: nginx/1.14.2
                Date: Mon, 23 Dec 2019 18:14:36 GMT
                Content-Type: text/html; charset=utf-8
                Content-Length: 146
                Connection: keep-alive
                X-DNS-Prefetch-Control: off
                X-Frame-Options: SAMEORIGIN
                Strict-Transport-Security: max-age=15552000; includeSubDomains
                X-Download-Options: noopen
                X-Content-Type-Options: nosniff
                X-XSS-Protection: 1; mode=block
                Content-Security-Policy: default-src 'self'
                
                <!DOCTYPE html>
                <html lang="en">
                <head>
                <meta charset="utf-8">
                <title>Error</title>
                </head>
                <body>
                <pre>Cannot GET /mmirror</pre>
                </body>
                </html>
                

                I think I have some problems with some "proxy_set_header " rules.

                Best regards

                F E 2 Replies Last reply Reply Quote 0
                • F Offline
                  fbr1969 @fbr1969
                  last edited by

                  @fbr1969
                  And yes, Magicmirror is fonctional in direct connection with : http://192.168.10.60:8080

                  1 Reply Last reply Reply Quote 0
                  • E Offline
                    ember1205 @fbr1969
                    last edited by

                    @fbr1969 said in MagicMirror behind a NGinx Reverse Proxy:

                    @sdetweil @ember1205 Thank for your help.

                    I forgot to say :

                    • My nginx server is fully fonctional with some other locations I’ve masqued in my exemple of configuration files… Like that :
                    location /mmirror {
                        proxy_bind              $server_addr;
                        proxy_pass              http://192.168.10.60:8080;
                        proxy_set_header        Host            $http_host;
                        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header        X-Scheme        $scheme;
                        proxy_set_header        X-Script-Name   /;  # IMPORTANT: path has NO trailing slash
                    }
                    

                    I think I have some problems with some "proxy_set_header " rules.

                    It appears that your X-Script-Name IS setting a trailing slash and isn’t inserting / removing mmirror. Shouldn’t that last line be

                         proxy_set_header        X-Script-Name   /mmirror;  # IMPORTANT: path has NO trailing slash
                    

                    ??

                    S 1 Reply Last reply Reply Quote 0
                    • S Do not disturb
                      sdetweil @ember1205
                      last edited by

                      @ember1205 its pretty clear tho

                      curl -iL http://192.168.10.10/mmirror
                      HTTP/1.1 301 Moved Permanently
                      Server: nginx/1.14.2
                      Date: Mon, 23 Dec 2019 18:14:36 GMT
                      Content-Type: text/html
                      Content-Length: 185
                      Connection: keep-alive
                      Location: https://[MyDomain]/mmirror
                      
                      HTTP/1.1 404 Not Found
                      Server: nginx/1.14.2
                      Date: Mon, 23 Dec 2019 18:14:36 GMT
                      Content-Type: text/html; charset=utf-8
                      Content-Length: 146
                      Connection: keep-alive
                      X-DNS-Prefetch-Control: off
                      X-Frame-Options: SAMEORIGIN
                      Strict-Transport-Security: max-age=15552000; includeSubDomains
                      X-Download-Options: noopen
                      X-Content-Type-Options: nosniff
                      X-XSS-Protection: 1; mode=block
                      Content-Security-Policy: default-src 'self'
                      
                      Error
                      <pre>Cannot GET /mmirror</pre>
                      
                      Cannot GET /mmirror

                      because that is on the client issuing the curl command, url with no ip address is same as localhost

                      what is this??
                      Location: https://[MyDomain]/mmirror

                      again this should be server.mydomain

                      if u go to client and do an nslookup domain.com
                      u will get an error
                      ping domain.com will fail

                      Sam

                      How to add modules

                      learning how to use browser developers window for css changes

                      E 1 Reply Last reply Reply Quote 0
                      • E Offline
                        ember1205 @sdetweil
                        last edited by

                        @sdetweil said in MagicMirror behind a NGinx Reverse Proxy:

                        @ember1205 its pretty clear tho

                        curl -iL http://192.168.10.10/mmirror
                        HTTP/1.1 301 Moved Permanently
                        Server: nginx/1.14.2
                        Date: Mon, 23 Dec 2019 18:14:36 GMT
                        Content-Type: text/html
                        Content-Length: 185
                        Connection: keep-alive
                        Location: https://[MyDomain]/mmirror
                        
                        HTTP/1.1 404 Not Found
                        Server: nginx/1.14.2
                        Date: Mon, 23 Dec 2019 18:14:36 GMT
                        Content-Type: text/html; charset=utf-8
                        Content-Length: 146
                        Connection: keep-alive
                        X-DNS-Prefetch-Control: off
                        X-Frame-Options: SAMEORIGIN
                        Strict-Transport-Security: max-age=15552000; includeSubDomains
                        X-Download-Options: noopen
                        X-Content-Type-Options: nosniff
                        X-XSS-Protection: 1; mode=block
                        Content-Security-Policy: default-src 'self'
                        
                        Error
                        <pre>Cannot GET /mmirror</pre>
                        
                        Cannot GET /mmirror

                        because that is on the client issuing the curl command, url with no ip address is same as localhost

                        what is this??
                        Location: https://[MyDomain]/mmirror

                        again this should be server.mydomain

                        if u go to client and do an nslookup domain.com
                        u will get an error
                        ping domain.com will fail

                        He stated that he is masking details of what he’s posting, so it’s definitely something to check.

                        However…

                        The error is delivered from nginx

                        Server: nginx/1.14.2
                        

                        Which means that it isn’t attempting to retrieve the URL from localhost.

                        The missing directive that I mentioned prior is where I believe the issue is… The client IS connecting and requesting /mmirror, but that is not defined on the nginx host. As a result, it’s being processed by the default host configured there which will be on a different back-end server and that server does not have a /mmirror path available to serve. So, 404.

                        S 1 Reply Last reply Reply Quote 0
                        • S Do not disturb
                          sdetweil @ember1205
                          last edited by sdetweil

                          @ember1205 said in MagicMirror behind a NGinx Reverse Proxy:

                          but that is not defined on the nginx host.

                          but it is as a server entry in the nginx.conf

                          I have just set one up and see the same…

                          but the proxy doesn’t explicitly ask to pass the uri too

                          Sam

                          How to add modules

                          learning how to use browser developers window for css changes

                          S 1 Reply Last reply Reply Quote 0
                          • S Do not disturb
                            sdetweil @sdetweil
                            last edited by

                            @ember1205 so, if u take off the mmirror part of the 1st server and use the / location to proxy pass it works, so you are correct… it passed the uri portion along too…

                            Sam

                            How to add modules

                            learning how to use browser developers window for css changes

                            1 Reply Last reply Reply Quote 0
                            • E Offline
                              ember1205
                              last edited by

                              When using a proxy server like this, it functions mostly like a content switch. In other words, you can redirect specific paths to different back-end hosts - this is commonly done when you have different servers holding different kinds of content.

                              When you have a VIP acting as a Content Switch, anything not explicitly defined for a particular path will be handled by the default VIP. In this case, he has not actually defined the /mmirror path, so appending that to his domain will result in the DEFAULT server getting the traffic as opposed to the mirror. That’s why the 404.

                              I believe that the directive I mentioned earlier is all that needs to be defined in order to get the nginx proxy handling that path accordingly…

                              1 Reply Last reply Reply Quote 0
                              • F Offline
                                fbr1969
                                last edited by

                                Re: MagicMirror behind a NGinx Reverse Proxy

                                I watched my Nginx error file and found :

                                2019/12/24 10:20:45 [error] 2341#2341: *1 open() "/var/www/html/socket.io/socket.io.js" failed (2: No such file or directory), client: XX.XXX.XX.XXX, server: mydomain.com, request: "GET /socket.io/socket.io.js HTTP/1.1", host: "mydomain.com", referrer: "https://mydomain.com/mmirror/"```
                                

                                So, I tried to modify my nginx config file.
                                Here’s the final configuration, working fine (don’t forget to change ‘mydomain.com’), and your private IP adress.
                                Magic Mirror will be avaiable by : https://mydomain.com/mmirror :

                                server {
                                    listen      80;
                                    server_name mydomain.com;
                                    return      301 https://$server_name$request_uri;
                                }
                                
                                server {
                                
                                    # Setup HTTPS certificates
                                    listen       443 default ssl;
                                    server_name  mydomain.com;
                                    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
                                    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # managed by Certbot
                                    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
                                    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
                                
                                    # Access to Magic Mirror
                                    location /mmirror/ {
                                        proxy_pass              http://192.168.10.60:8080/;
                                        #proxy_redirect          http://192.168.10.60:8080 /mmirror;
                                        #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_pass_request_headers on;
                                        proxy_set_header Host $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_set_header X-Forwarded-Host $http_host;
                                        proxy_set_header Upgrade $http_upgrade;
                                        proxy_set_header Connection $http_connection;
                                        # Disable buffering when the nginx proxy gets very resource heavy upon streaming
                                        proxy_buffering off;
                                    }
                                
                                        location /socket.io {
                                                # Proxy Magi Mirror Websockets traffic
                                                proxy_pass http://192.168.10.60:8080;
                                                proxy_http_version 1.1;
                                                proxy_set_header Upgrade $http_upgrade;
                                                proxy_set_header Connection "upgrade";
                                                proxy_set_header Host $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_set_header X-Forwarded-Protocol $scheme;
                                                proxy_set_header X-Forwarded-Host $http_host;
                                        }
                                
                                    location / {
                                        root   /var/www/html;
                                        index  index.html ;
                                    }
                                }
                                
                                E 1 Reply Last reply Reply Quote 0
                                • E Offline
                                  ember1205 @fbr1969
                                  last edited by

                                  @fbr1969

                                  A couple of questions about your configuration…

                                  • It seems that you configured ONLY for access to the mirror with a /mmirror path as well - is this accurate? I can’t tell where the ‘default’ VIP might be pointing to.

                                  • It appears that you have to handle the /socket.io path independently of the of /mmirror path, and that leads me to wonder if there is javascript code being returned to the browser that ALSO needs to be rewritten inline?

                                  F 1 Reply Last reply Reply Quote 0
                                  • F Offline
                                    fbr1969 @ember1205
                                    last edited by

                                    @ember1205

                                    Hi,
                                    With my shortcut “mmirror”, I can access directly to the default Magic Mirror page (define in my MM config.js file), at home (LAN) or at work (by Internet).
                                    And effectively, I had needed to handle the /socket.io path independently of the of /mmirror path to correct the error I found I my NGinx error log. And that worked like that.
                                    I’ sorry, but I don’t know how it works exactly…

                                    E 1 Reply Last reply Reply Quote 0
                                    • E Offline
                                      ember1205 @fbr1969
                                      last edited by ember1205

                                      @fbr1969 said in MagicMirror behind a NGinx Reverse Proxy:

                                      @ember1205

                                      Hi,
                                      With my shortcut “mmirror”, I can access directly to the default Magic Mirror page (define in my MM config.js file), at home (LAN) or at work (by Internet).
                                      And effectively, I had needed to handle the /socket.io path independently of the of /mmirror path to correct the error I found I my NGinx error log. And that worked like that.
                                      I’ sorry, but I don’t know how it works exactly…

                                      Thanks for the extra detail - your description increases my suspicion/concern that there is likely a lot of JS content being delivered directly to the browser that is not being otherwise rewritten, hence the need for the additional path for socket.io

                                      On my mirror, with a total of five modules (all default except one), there are twenty-six JS scripts that are delivered to the browser for “local” execution. Fortunately, of them, ONLY the socket.io call has a hard path to the root of the server:

                                      < script type="text/javascript" src="/socket.io/socket.io.js"></script>
                                      

                                      Nothing else uses the leading “/” in the path which means they are all relative paths and will properly pass through a reverse proxy for access. Even though the other twenty-five scripts can be downloaded, there’s nothing to say that the content WITHIN them can execute if they make any subsequent calls using hard-coded information that isn’t being rewritten.

                                      Reverse proxy servers are awesome tools, but the configuration has to be ‘perfect’ to ensure everything will work properly now and in the future. And rewriting JS is not always trivial.

                                      1 Reply Last reply Reply Quote 0

                                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                      With your input, this post could be even better 💗

                                      Register Login
                                      • 1 / 1
                                      • First post
                                        Last post
                                      Enjoying MagicMirror? Please consider a donation!
                                      MagicMirror created by Michael Teeuw.
                                      Forum managed by Sam, technical setup by Karsten.
                                      This forum is using NodeBB as its core | Contributors
                                      Contact | Privacy Policy