Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website

HSTS causing HTTPS redirect loop


  • Hey guys, hoping someone can point out my mistake but I am trying to get HTTPS redirecting working but I currently have a redirect loop happening somewhere.

    I have mango running on a VS with ip $IP.
    I have a DNS A record of my main domain pointing a subdomain to $IP.

    Originally I had a rule in .htaccess to send all http to https but I've taken it out for now.

    I've enabled SSL and HSTS in env.properties and accessing the https://subdomain.domain.com works perfectly. However, when accessing http:... for the first time it causes a redirect loop.

    Disabling HSTS and applying a catch-all http -> https rule in .htaccess doesn't seem to work as you end up at http and no redirect seems to occur.

    If you restart mango while HSTS is enabled, you'll get to see the loading screen for mango as it boots up and then at 100% is stays on "mango is running". Then a refresh of the page causes a redirect loop.

    However, if you manually go to the https first, then try the http you will be redirected properly. Clear the cache and go to to http and you'll get the redirect loop again.

    Firefox inspection:
    0_1565795137280_redirect.png

    If anyone has any ideas, that'd be great!


  • Mango uses tomcat server not apache 2.4 for the web service so an .htaccess based redirect will not work.
    Are you using the SSL cert within mango? If sure, be sure to follow through with this thread here as someone has worked out how to get SSL working with mango.
    I personally use an apache proxy with mango as I'm running multiple web based domains on the same dedicated server.
    https://forum.infiniteautomation.com/topic/4331/ssl-installation-on-the-mango-cloud/14

    Be sure to also check help.infiniteautomation.com as that provides info on using SSL.


  • Hi cbyrne,

    I was going to refrain from answering until I had looked into these questions in specific, but, @MattFox said,

    Mango uses tomcat server not apache 2.4 for the web service so an .htaccess based redirect will not work.

    Mango is using Jetty (tomcat is the webserver in Mango m2m2, so pre-Mango Automation and pre-Infinite Automation), and if all of the webserver traffic is going through Apache you can certainly set up virtual hosts to handle the traffic redirect for you, although probably not through .htaccess files since that scheme is more directed toward file servers / website servers rather than Apache serving as an application proxy.

    As to using SSL, you can also have something like Apache proxying the SSL traffic or you can have Apache handling the encryption and forwarding the traffic on a non-SSL connection to Mango, eliminating the need for a java keystore.


  • Hi guys,

    From following @phildunlap 's instructions in a previous thread, I made my keystore and got mango to use it just fine. So I do have a working https connection to the mango instance.

    The httaccess is on our base webserver, mango lives on a completely separate VPS.

    So the issue isn't with getting SSL working, it does, but rather when redirected to the loop is made.

    In the mean time I'll look into how apache proxy's work as an alternative!


  • I use an apache proxy and integrated it with lets encrypt. Happy to offer advice if needed

    Fox


  • @mattfox Thanks Matt, I may well do that. I'll try it in the morning and update this post later on in the day.


  • All working now. Here's my solution using an Apache proxy as advised by @MattFox.
    Starting with a mango installation running on port 8080 and not handling ssl.

    1. Make sure you have httpd and mod_ssl installed.
    2. Place SSL cert files (your cert, cert bundle and key) in a directory of your choosing.
    3. Check for ssl.conf. Installing mod_ssl created a ssl.conf in /etc/httpd/conf.d/ which I had to disable (I just named it ssl.conf.old). It overrode my SSL settings below and used the packaged self-signed cert.
    4. Make a new config file eg. /etc/httpd/conf.d/mango.conf
    5. Populate is as follows:
    <VirtualHost *:80>
        Redirect permanent / https://subdomain.maindomain.com
    </VirtualHost>
    
    <VirtualHost *:443>
        ProxyPreserveHost On
        SSLEngine On
        SSLCertificateFile "path/to/your.crt"
        SSLCertificateChainFile "/path/to/your.ca-bundle"                               
        SSLCertificateKeyFile "/path/to/your_key"
        ProxyPass / http://127.0.0.1:8080/
        ProxyPassReverse / http://127.0.0.1:8080/
    </VirtualHost>
    
    1. Restart the httpd service.

    If anyone notices any loopholes or things I could add to harden it up please let me know.


  • I suspect this thread may be of some assistance: https://forum.infiniteautomation.com/topic/3892/latest-version-3-5-5-appears-to-fail-rendering-data/14

    I would expect you may be seeing websocket issues currently.


  • You've forgotten the http rewrite to handle web sockets. Proxy only works for http traffic. Add a redirect to ensure websockets get redirected to port 443 to 8080 if I recall correctly.


  • A colleague of mine pointed out that to use the HTTP2 protocol (which should provide faster initial page loading) Mango must be running on SSL with a keystore, and have ALPN enabled (see Mango/bin/ext-available). I would not expect using HTTP2 to have a significant effect on REST requests.


  • Correct, the push provided by HTTP/2 is for file resources only.
    Although I'm hoping to change that once my dashboard gets moved into a web directory...


  • I wrote this help article not too long ago which may provide some insight into configuring the Apache proxy.

    https://help.infiniteautomation.com/proxy


  • Thanks Terry! I was unaware that existed on the help site.


  • Perfect, thanks for all your help @terrypacker @MattFox @phildunlap.

    edit:
    @terrypacker Quick question regarding the help article

    0_1565944443039_Screenshot_2019-08-16 Proxy — Infinite Automation Support.png

    Specifically "we set the Host and Origin to the public facing server".
    Isn't "mango.example.com" the private facing address?


  • Actually I spoke too soon, proxying web sockets isn't working yet. I followed your example in the other thread @phildunlap but unfortunately I'm still getting errors. Perhaps my rewrite rule is incorrect for a localhost address?

    0_1565950148266_websock.png

    My config:

    <VirtualHost *:80>
        Redirect permanent / https://ems1.glasenergytechnology.ie/
    </VirtualHost>
    
    Listen 443
    <VirtualHost *:443>
        ProxyPreserveHost Off
        ServerName sub.domain.com
        ServerAlias sub.domain.com
        ProxyRequests On
        RewriteEngine On
        RewriteCond %{HTTP:Upgrade} =websocket
        RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
        RewriteCond %{HTTP:Upgrade} !=websocket
        RewriteRule /(.*) http://127.0.0.1:8080/$1 [P,L]
        RequestHeader set Host sub.domain.com
        RequestHeader set Origin "http://sub.domain.com"
        Header edit Location ^http://sub.domain.com https://sub.domain.com
        CustomLog "/var/log/apache-access-public-mango.log" common
        ErrorLog "/var/log/apache-error-public-mango.log"
        SSLEngine On
        SSLProxyEngine On
        SSLCertificateFile "/path/to/crt"
        SSLCertificateChainFile "/path/to/ca-bundle"
        SSLCertificateKeyFile "/path/to/private_key"
        ProxyPass / http://127.0.0.1:8080/
        ProxyPassReverse / http://127.0.0.1:8080/
    </VirtualHost>

  • Man your ssl conf file is messy!

    You've got an uneccessary rewrite rule. You've got a condition asking for a websocket upgrade check and then applying an http rule to it! Unless you're redirecting, just leave the http stuff to the proxy rules.

    Here, follow this:

    #STRAIGHT HTTP, THIS REDIRECTS
    <VirtualHost *:80>
    ServerName subdomain.example.com
    DocumentRoot /opt/mango/overrides/web/modules/mangoUI/web
      ErrorLog ${APACHE_LOG_DIR}/subdomain.example.com_error.log
      # Possible values include: debug, info, notice, warn, error, crit,
      # alert, emerg.
      LogLevel warn
      CustomLog ${APACHE_LOG_DIR}/subdomain.example.com_access.log combined
    
    ProxyRequests Off
    ProxyPreserveHost On
    
    RewriteEngine on
    RewriteCond %{SERVER_PORT} 80
    RewriteRule ^(.*)$ https://subdomain.example.com/$1 [R,L]
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
    
     ProxyPass /.well-known !
            <Location />
                ProxyPass http://127.0.0.1:8080/
                ProxyPassReverse /
            </Location>
    
    </VirtualHost>
    
    #HTTPS PROXY HANDLER
    <IfModule mod_ssl.c>
    <VirtualHost *:443>
    ServerName subdomain.example.com
    DocumentRoot /opt/mango/overrides/web/modules/mangoUI/web
    
    <Directory />
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
    </Directory>
    
      SSLProxyEngine On
      ProxyRequests Off
      ProxyPreserveHost On
    ProxyPass /.well-known !
    
    RewriteEngine on
     RewriteCond %{HTTP:Connection} Upgrade [NC]
     RewriteCond %{HTTP:Upgrade} websocket [NC]
     RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
    
    RequestHeader set Origin "http://subdomain.example.com"
    Header edit Location ^http://subdomain.example.com https://subdomain.example.com
    
    
            <Location />
                ProxyPass http://127.0.0.1:8080/
                ProxyPassReverse /
            </Location>
    
    
    SSLCertificateFile /etc/letsencrypt/live/subdomain.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/subdomain.example.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
    </VirtualHost>
    </IfModule>
    

    Specifically "we set the Host and Origin to the public facing server".

    Isn't "mango.example.com" the private facing address?

    No Because mango.example.com is what is accessible by the public domain. You want that because apache is now the front for mango. The private domain is now the server's own loopback address.

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin

    The HTTP referer (originally a misspelling of referrer) is an optional HTTP header field that identifies the address of the webpage (i.e. the URI or IRI) that linked to the resource being requested. By checking the referrer, the new webpage can see where the request originated.


  • Amazing, thanks @MattFox. Using your as a guide I managed to get it working.

    One or two questions just for my own knowledge/curiosity.

    1. Difference/benefits of your mod_rewrites vs. my Redirect permanent for the HTTP virtual host? I get that the rewrite happens on the server and the redirect tells the client to send a new request to the redirect URL; but is there a notable benefit of one over the other?

    2. What exactly is happening in the <Proxy *> block?


  • I like mod_rewrites because you can stack a load of conditions/regexs. That and mod rewrites generally pass header info if I recall correctly. Although it's possible that your permanent will give a 301 http header.

    Ignore the proxy* I think that was from my experiment to get letsencrypt working. I succeeded with the proxypass .well-known ! line. I could be wrong and it's there for another reason... shoulda left a comment!!!

    But as you know, the * applies to all paths,