Config Nginx to receive real IP when using Cloudflare for noobs


(Khoa Nguyen) #1

Since CloudFlare acts as a reverse proxy, all connections now come from one of CloudFlare’s IP addresses. and as @codinghorror

:wink:

To fix this issue:

Add cloudflare.template.yml to the bottom of the templates: section in your app.yml file.

Historical version of instructions





So here is the instruction :
(see CloudFlare official document )

cd /var/docker
./launcher ssh enter
cd /etc/nginx/
vi nginx.conf

Type A

Add these code between http block

   set_real_ip_from   199.27.128.0/21;
   set_real_ip_from   173.245.48.0/20;
   set_real_ip_from   103.21.244.0/22;
   set_real_ip_from   103.22.200.0/22;
   set_real_ip_from   103.31.4.0/22;
   set_real_ip_from   141.101.64.0/18;
   set_real_ip_from   108.162.192.0/18;
   set_real_ip_from   190.93.240.0/20;
   set_real_ip_from   188.114.96.0/20;   
   set_real_ip_from   197.234.240.0/22;
   set_real_ip_from   198.41.128.0/17;
   set_real_ip_from   162.158.0.0/15;
   set_real_ip_from   104.16.0.0/12;
   set_real_ip_from   2400:cb00::/32;
   set_real_ip_from   2606:4700::/32;
   set_real_ip_from   2803:f800::/32;
   set_real_ip_from   2405:b500::/32;
   set_real_ip_from   2405:8100::/32;
   real_ip_header     CF-Connecting-IP;

Your nginx.conf file should look like this:

http
{
   set_real_ip_from   199.27.128.0/21;
   set_real_ip_from   173.245.48.0/20;
   set_real_ip_from   103.21.244.0/22;
   set_real_ip_from   103.22.200.0/22;
 ......
real_ip_header     CF-Connecting-IP;
........
}

Type ESC >> :wq >> Enter

Test nginx config

nginx -t

If you see this line nginx: configuration file /etc/nginx/nginx.conf test is successful, your nginx configuration file is OK.
Restart nginx to take effect:

service nginx restart
exit

@sam @codinghorror can you help me to add this as a template?


(Jeff Atwood) #2

@supermathie any comments on this?


(Sam Saffron) #3

All you need is cloud flare to tack on X-Forward-For and you should be good, I don’t see why you would need all this gymnastics.


(Kane York) #4

You should be using a replace: rule in app.yml instead of manually editing the nginx config, your edits will be blown away on rebuild.

Read this topic:


(Michael Brown) #5

except there’s no way to tell nginx that an incoming header like that is good, is there? By default it only trusts headers set when the request is coming from an RFC1816 IP.

Similar to All of my internal users show as coming from 127.0.0.1!?

I do like the notion of being able to enable the Cloudflare real-IP in a nice clean way though. Bonus points for downloading the files from IP Ranges | Cloudflare at base or container build time?


#6

I have the following in templates/web.cloudflare.yml (Which is then included in my web container):

run:
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /^add_header Strict-Transport-Security 'max-age=31536000';$/
     to: |
       add_header Strict-Transport-Security 'max-age=31536000';

       # Cloudflare
       set_real_ip_from   199.27.128.0/21;
       set_real_ip_from   173.245.48.0/20;
       set_real_ip_from   103.21.244.0/22;
       set_real_ip_from   103.22.200.0/22;
       set_real_ip_from   103.31.4.0/22;
       set_real_ip_from   141.101.64.0/18;
       set_real_ip_from   108.162.192.0/18;
       set_real_ip_from   190.93.240.0/20;
       set_real_ip_from   188.114.96.0/20;
       set_real_ip_from   197.234.240.0/22;
       set_real_ip_from   198.41.128.0/17;
       set_real_ip_from   162.158.0.0/15;
       set_real_ip_from   104.16.0.0/12;
       set_real_ip_from   2400:cb00::/32;
       set_real_ip_from   2606:4700::/32;
       set_real_ip_from   2803:f800::/32;
       set_real_ip_from   2405:b500::/32;
       set_real_ip_from   2405:8100::/32;
       real_ip_header     CF-Connecting-IP;

I’ll work on the auto-updating the IP list via the link above soon.


Getting Cloudflare IP's instead of client's IP
How do I recover true user IPs?
How redirect non www to www in docker installation
All users have the same IP (the Servers IP)?
All users have the same IP (the Servers IP)?
(Dylan) #7

Is there a simpler way of going about this or is all that in the OP the best way? I use CF for DDoS protection mainly, so the reverse proxy aspect is needed. This is my first time using Discourse, used MyBB/IPB/VB and some custom ones, most of which had a simple way in the admin panel to solve this.


(Kane York) #8

You should be following the steps in this post instead:


(Dylan) #9

@riking It should be just added in, not replace anything correct?

Like this: nvm, messed up

Then do a rebuild? Or any other steps need to be taken before it will take affect?


(Dylan) #10

Create new template called "web.cloudflare.yml"
Enter the information from @mooash’s post
Add “templates/web.cloudflare.yml” to app.yml in /var/discourse/containers
Rebuild, start app again.

That’s what I did, however, it appears it’s not working as logging out/back in and making a new post still shows CF as my IP. Or is there something else I need to do to be able to test it better?


#11

SSH into your app ./launcher ssh <app name> and have a look at /etc/nginx/conf.d/discourse.conf

Are you seeing the CloudFlare block above? By the sounds of it you didn’t do a bootstrap/rebuild correctly.

Please first ./launcher bootstrap <app name> then ./launcher destroy <app name> and finally ./launcher start <app name>

A restart of the app after a bootstrap is not enough to get its new configuration.


(Dylan) #12

I do see the cloudflare block there, saw it when bootstrapping as well.

Followed the steps exactly, it’s finished now, relogged into my site, posted a thread, went to the admin panel, checked my IP and it says:

“Last IP Address 108.162.2XX.X”

Which is a CF IP: Screenshot by Lightshot

Going to make another account real quick to see if the registration IP is still CF just to make sure in case it didn’t update my last IP.


(Dylan) #13

Just checked by creating a completely new user, still had the Cloudflare IP as the registered IP address.


(Khoa Nguyen) #14

@Overmind
Here is my app.yml cloudflare part

  filename: /etc/nginx/conf.d/discourse.conf
  from: /add_header X-UA-Compatible.+$/
  to: |
      add_header X-UA-Compatible "IE=edge";

      # Cloudflare
      set_real_ip_from   199.27.128.0/21;
      set_real_ip_from   173.245.48.0/20;
      set_real_ip_from   103.21.244.0/22;
      set_real_ip_from   103.22.200.0/22;
      set_real_ip_from   103.31.4.0/22;
      set_real_ip_from   141.101.64.0/18;
      set_real_ip_from   108.162.192.0/18;
      set_real_ip_from   190.93.240.0/20;
      set_real_ip_from   188.114.96.0/20;
      set_real_ip_from   197.234.240.0/22;
      set_real_ip_from   198.41.128.0/17;
      set_real_ip_from   162.158.0.0/15;
      set_real_ip_from   104.16.0.0/12;
      set_real_ip_from   2400:cb00::/32;
      set_real_ip_from   2606:4700::/32;
      set_real_ip_from   2803:f800::/32;
      set_real_ip_from   2405:b500::/32;
      set_real_ip_from   2405:8100::/32;
      real_ip_header     CF-Connecting-IP;

Before you save and rebuild your docker, you should validate your app.yml at
http://www.yamllint.com/


(Dylan) #15

Thanks for the help so far guys, used the site, it says my YAML is valid, mine is currently:

run:
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /^add_header Strict-Transport-Security 'max-age=31536000';$/
     to: |
       add_header Strict-Transport-Security 'max-age=31536000';

       # Cloudflare
       set_real_ip_from   199.27.128.0/21;
       set_real_ip_from   173.245.48.0/20;
       set_real_ip_from   103.21.244.0/22;
       set_real_ip_from   103.22.200.0/22;
       set_real_ip_from   103.31.4.0/22;
       set_real_ip_from   141.101.64.0/18;
       set_real_ip_from   108.162.192.0/18;
       set_real_ip_from   190.93.240.0/20;
       set_real_ip_from   188.114.96.0/20;
       set_real_ip_from   197.234.240.0/22;
       set_real_ip_from   198.41.128.0/17;
       set_real_ip_from   162.158.0.0/15;
       set_real_ip_from   104.16.0.0/12;
       set_real_ip_from   2400:cb00::/32;
       set_real_ip_from   2606:4700::/32;
       set_real_ip_from   2803:f800::/32;
       set_real_ip_from   2405:b500::/32;
       set_real_ip_from   2405:8100::/32;
       real_ip_header     CF-Connecting-IP;

it’s in /templates under “web.cloudflare.yml”

then my app.yml shows this for templates:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/sshd.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.cloudflare.yml"

I’ve had several users register since the last rebuild and no luck, still several different CF IP’s.

@thangngoc89 I noticed yours is slightly different as the one posted, does your one show the real IP and if so where did you place that info and what else did you change from the stock install to allow for that?

Any other steps I should take to get this to work?


When all users come from 127.0.0.1, new registrations are blocked
Troubleshooting a 429 (rate limit)
(Khoa Nguyen) #16

The main concept of this is find and replace string
@Mooash find this string add_header Strict-Transport-Security 'max-age=31536000'; and add Cloudflare config after it. But my /etc/nginx/conf.d/discourse.conf doesn’t contain that line so instead, I will find add_header X-UA-Compatible


#17

Use @thangngoc89’s. Mine only works if you’re using the SSL template because of how the replace works.


(Geert Johan Riemer) #18

@codinghorror Would it make sense to include web.cloudflare.template.yml in the Discourse distribution?


(Jeff Atwood) #19

Hard coding the IPs is not the right way, so no.


(Kane York) #20

A proper script would download https://www.cloudflare.com/ips-v4 and https://www.cloudflare.com/ips-v6 and construct the set_real_ip_from rules from that.