X-Forwarded-For proxy tag not recognized by Discourse?

Our Set Up

  1. Discourse is installed on Google Compute VM machine with no SSL certificates on this server.
    Force_https discourse setting is set to true (checked to force https).

  2. We have the front end running with ‘Google Load Balancer’ with HTTPS certificate attached at Load balancer level.

  3. Google Oauth credentials settings has both http and https callback URL’s set up.

  4. User Request HTTPS.www.truvisa.com -> Google Load balancer -> HTTP Discourse on Google Compute engine.

  • The https://www.truvisa.com URL works fine.
  • User tries to log-in with Google OAuth. Works fine and user is logged in.

Problem:

User Request HTTP -> Google Load balancer -> HTTP Discourse on Google Compute engine.
The http://www.truvisa.com url works fine. We actually expected this to be redirected to HTTPs (as we have force https enabled), but it did not work.

What we think is happening:
I searched through the discourse forum for a solution and understand that Google load balancer (a proxy in our case) need to send the X-Forwarded-Proto header for discourse to redirect the http request to https version.

Google load balancer does send this X-Forwarded-Proto to discourse installation server.

My question:
Is there anything that needs to be changed in Discourse set up anywhere to make this work?
Are we missing any kind of redirection from http to https setting in default discourse install?

Please help.

Probably the list of trusted IP addresses in nginx needs to be updated so it’ll trust the XFF and XFP headers that the GAE load balancer is sending.

6 Likes

Can you please elaborate on where I can add those IP addresses with respect to Discourse installation?

Take a look at the templates/cloudflare.template.yml file. Basically, you need to insert set_real_ip_from directives for the full list of load balancer IPs.

6 Likes

Thanks Kane for your help, but the primary problem is something else.

After further analysis, I think what we need is this redirection rule on Discourse Nginx config:

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;
      }
}

This is because if the User is on HTTPS url and tries to log in with Google OAuth, it works fine. So, our primary problem is only related to redirection of http to https domain always.

I tried adding the above rule to app.yml file inside after_web_config and rebuild. It, then shows the nginx welcome screen

Our app.yml file’s content

  after_web_config:
- replace:
    filename: /etc/nginx/nginx.conf
    from: /sendfile.+on;/
    to: |
      server_names_hash_bucket_size 64;
      sendfile on;
- replace:
    filename: /etc/nginx/conf.d/discourse.conf
    from: /server.+{/
    to: |
      server {
        listen 80;
        server_name www.truvisa.com;
        if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;              
        }
      }
      server {
- file:
    path: /etc/nginx/conf.d/discourse_redirect_1.conf
    contents: |
      server {
        listen 80;
        server_name truvisa.com;
        return 301 https://www.truvisa.com$request_uri;
      }

Can you help with right way of adding this http_x_forwarded_proto rule to discourse?

NOTE: Our discourse installation is still on HTTP server. The SSL certificate is only installed on load balancer server.

2 Likes

No ideas? Nobody has tried this set up?

These days, it is pretty common to have a LOAD balance server (using HTTPS) and then have Discourse or any other software sitting behind on HTTP.

Can anybody guide (if they have successfully tried) as to where the redirection rule can be added in Discourse configuration?

I need this rule to be configured:

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;
      }
}

Why would you do the redirect there? Do it at the outer layer, where you’re terminating HTTPS.

That’s the problem.
Its a google load balance server and it does not allow doing it at the load balane server.

They advise to manage the http to https redirection using http_x_forwarded_proto at the end server.

I have tried the same thing with Apache server running wordpress and this same rule works in similar set-up.

As a matter of fact, even Amazon’s ELB suggests the same solution.

Use a dedicated redirection container on cloud load balancers.

6 Likes

Thanks for quick response. I will try it.