Allowing Cloudflare IP addresses only in Nginx

Allowing Cloudflare IP addresses only in Nginx

allow traffic from Cloudflare IPs just in Nginx

If your HTTP server is running behind Cloudflare, it is recommended to only allow traffic from Cloudflare IP addresses. We can configure this systematically using iptables, as demonstrated in Allowing Cloudflare IP addresses.

However, if you have some other services not proxied by Cloudflare, it’s also flexible to white list Cloudflare IPs just inside the Nginx service.

To do this, create a /etc/nginx/allow-cloudflare-only.conf configuration file that allows all of Cloudflare IPs:

# https://www.cloudflare.com/ips
# IPv4
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;
# IPv6
allow 2400:cb00::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2405:b500::/32;
allow 2405:8100::/32;
allow 2a06:98c0::/29;
allow 2c0f:f248::/32;

deny all; # deny all remaining ips

# Generated at Sat Mar  2 19:28:18 UTC 2024

This configuration file can be easily generated by this script1:

#!/usr/bin/bash

set -e

cf_ips() {
echo "# https://www.cloudflare.com/ips"

for type in v4 v6; do
echo "# IP$type"
curl -sL "https://www.cloudflare.com/ips-$type/" | sed "s|^|allow |g" | sed "s|\$|;|g"
echo
done

echo "# Generated at $(LC_ALL=C date)"
}

(cf_ips && echo "deny all; # deny all remaining ips") > /etc/nginx/allow-cloudflare-only.conf

# reload Nginx
# sudo systemctl reload nginx

Note that Cloudflare might update its IP addresses at some point. You’d better run this script regularly or use the cron job to update the IPs.

For example, put this script under the weekly cron job directory as /etc/cron.weekly/update-cfips, give it execution permission with sudo chmod u+x /etc/cron.weekly/update-cfips. And comment out the sudo systemctl reload nginx line.

Then, you can include this configuration file in each server block or globally in Nginx.

For instance, in /etc/nginx/conf.d/example.com.conf:

server {
  listen 80;
  listen [::]:80;
  server_name example.com;

  include /etc/nginx/allow-cloudflare-only.conf;

  #...the rest of your configs here...
}

In this fashion, access the origin from IP addresses other than Cloudflare IPs will give a 403 Forbidden response.

More info on the ngx_http_access_module which provides the allow/deny to certain client addresses: http://nginx.org/en/docs/http/ngx_http_access_module.html.

By the way, if you want to log the IP address of the client, you cannot use the method stating in Reveal real IP for Nginx behind a reverse proxy by setting the set_real_ip_from after setting the allow/deny directives.

Instead, you can use map directive to store the client’s IP into a variable (i.e. $real_client_ip), and use that variable in the log:

# this goes before server section
map $http_x_forwarded_for $real_client_ip {
    ~^(\d+\.\d+\.\d+\.\d+) $1;
    default $http_cf_connecting_ip;
}

# replace the default '$remote_addr' with the '$real_client_ip'
log_format custom_log_format '$real_client_ip - $remote_user [$time_local] '
                             '"$request" $status $body_bytes_sent '
                             '"$http_host" "$upstream_response_time"'
                             '"$http_referer" "$http_user_agent"';

server {
  listen 80;
  listen [::]:80;
  server_name example.com;

  include /etc/nginx/allow-cloudflare-only.conf;

  access_log /var/log/nginx/access.log custom_log_format;

  #...the rest of your configs here...
}
THE END
Ads by Google

林宏

Frank Lin

Hey, there! This is Frank Lin (@flinhong), one of the 1.41 billion . This 'inDev. Journal' site holds the exploration of my quirky thoughts and random adventures through life. Hope you enjoy reading and perusing my posts.

YOU MAY ALSO LIKE

Reveal real IP for Nginx behind a reverse proxy

Tools

2020.12.25

Reveal real IP for Nginx behind a reverse proxy

I'm currently using LogDNA for gathering Nginx logs. However, I can only see IPs from Cloudflare by default in the logs as my server was proxied by Cloudflare. Let's see how to reveal the real IP address of the client in the logs behind such reverse proxy server by using ngx_http_realip_module.

Setup an IKEv2 server with strongSwan

Tutorials

2020.01.09

Setup an IKEv2 server with strongSwan

IKEv2, or Internet Key Exchange v2, is a protocol that allows for direct IPSec tunnelling between networks. It is developed by Microsoft and Cisco (primarily) for mobile users, and introduced as an updated version of IKEv1 in 2005. The IKEv2 MOBIKE (Mobility and Multihoming) protocol allows the client to main secure connection despite network switches, such as when leaving a WiFi area for a mobile data area. IKEv2 works on most platforms, and natively supported on some platforms (OS X 10.11+, iOS 9.1+, and Windows 10) with no additional applications necessary.

Ads by Google