Skip to content

Instantly share code, notes, and snippets.

@Manouchehri
Last active April 17, 2024 05:51
Show Gist options
  • Save Manouchehri/cdd4e56db6596e7c3c5a to your computer and use it in GitHub Desktop.
Save Manouchehri/cdd4e56db6596e7c3c5a to your computer and use it in GitHub Desktop.
Allow CloudFlare only
# Source:
# https://www.cloudflare.com/ips
# https://support.cloudflare.com/hc/en-us/articles/200169166-How-do-I-whitelist-CloudFlare-s-IP-addresses-in-iptables-
for i in `curl https://www.cloudflare.com/ips-v4`; do iptables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ip6tables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
# Avoid racking up billing/attacks
# WARNING: If you get attacked and CloudFlare drops you, your site(s) will be unreachable.
iptables -A INPUT -p tcp -m multiport --dports http,https -j DROP
ip6tables -A INPUT -p tcp -m multiport --dports http,https -j DROP
# WARNING: This does NOT block Cloudflare's clients from accessing your website over HTTP or HTTPS with a Cloudflare Worker.
@sinevid
Copy link

sinevid commented Jun 24, 2020

Great job. works like a charm!

@thyagosiqueira
Copy link

Congratulations on the solution, I already used the for to block IPs, now the curl. Thanks for sharing.

@thyagosiqueira
Copy link

@stokito thanks also for the script, I will implement it in my padavan firmware !

@thyagosiqueira
Copy link

In moments of attack I did not know that Cloudflare was releasing traffic to the server. I would like to appreciate reports.

In their latest post on attacks, they comment on maintaining site protection on free accounts, even large-scale ones: https://blog.cloudflare.com/mitigating-a-754-million-pps-ddos-attack-automatically/

@AlexanderMatveev
Copy link

Maybe use ipset?

@iraqiboy90
Copy link

How often should this script refresh?

@stokito
Copy link

stokito commented Mar 5, 2021

Here https://www.cloudflare.com/ips/ is said that the list was updated only once in Oct 1, 2020.
But headers says different:

GET https://www.cloudflare.com/ips-v4
date: Fri, 05 Mar 2021 05:00:33 GMT
last-modified: Thu, 04 Mar 2021 22:45:21 GMT
cache-control: public, max-age=31536000
expires: Sat, 05 Mar 2022 05:00:33 GMT

So the file was updated yesterday and it will expire in a year (31536000 seconds).
I guess it's better to refresh it more often like once in three months and you can use wget -N option to minimize load

@Galomortal47
Copy link

this one helped me massively, thanks a lot

@stokito
Copy link

stokito commented Apr 19, 2021

FYI: recently the list of IPs was changed:
Please make the following changes to your allow list by May 7, 2021. This change is safe to make today.

Remove:
104.16.0.0/12

Add:
104.16.0.0/13
104.24.0.0/14

@surlro
Copy link

surlro commented Jun 10, 2021

Hi, seems the DROP rules not work for me on Centos 6, after i add them, website is not loading anymore.

@campones
Copy link

campones commented Nov 1, 2021

looks good to me

how could I allow a subdomain to be accessed without cloudflare?

example: main domain can only be accessed through cloudflare (typically the www host)
a sub domain wouldn't suffer from that restriction.

@iAmSaugata
Copy link

iAmSaugata commented Mar 24, 2022

Hi,
I am trying to block all the incoming traffic towards my Pi, which is exposed to my static public IP on port 80 and 443, and my public IP configured in CloudFlare proxy. I have docker installed, and multiple container running on it. I am trying to set rules in iptables which will DROP all the traffic on port 80 and 443 if it is not originated from CloudFalre and my local LAN/VPN, I have applied the rules by downloading all the IPv4 from CloudFlare.

Unfortunately it is not dropping the direct external traffic on port 443 and 80, if I am trying to access it from AWS EC2.I have also saved the iptables permanently, but it is same.

I am not very much comfortable with iptables, but I would like to use this. Please help me fixing this.

This is the output of my Pi from sudo iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 131.0.72.0/22 anywhere multiport dports http,https
ACCEPT tcp -- 172.64.0.0/13 anywhere multiport dports http,https
ACCEPT tcp -- 104.24.0.0/14 anywhere multiport dports http,https
ACCEPT tcp -- 104.16.0.0/13 anywhere multiport dports http,https
ACCEPT tcp -- 162.158.0.0/15 anywhere multiport dports http,https
ACCEPT tcp -- 198.41.128.0/17 anywhere multiport dports http,https
ACCEPT tcp -- 197.234.240.0/22 anywhere multiport dports http,https
ACCEPT tcp -- 188.114.96.0/20 anywhere multiport dports http,https
ACCEPT tcp -- 190.93.240.0/20 anywhere multiport dports http,https
ACCEPT tcp -- 108.162.192.0/18 anywhere multiport dports http,https
ACCEPT tcp -- 141.101.64.0/18 anywhere multiport dports http,https
ACCEPT tcp -- 103.31.4.0/22 anywhere multiport dports http,https
ACCEPT tcp -- 103.22.200.0/22 anywhere multiport dports http,https
ACCEPT tcp -- 103.21.244.0/22 anywhere multiport dports http,https
ACCEPT tcp -- 173.245.48.0/20 anywhere multiport dports http,https
ACCEPT tcp -- 10.8.0.0/24 anywhere multiport dports http,https
ACCEPT tcp -- 192.168.0.0/24 anywhere multiport dports http,https
DROP tcp -- anywhere anywhere multiport dports http,https

Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere 10.8.0.0/24 ctstate RELATED,ESTABLISHED /* openvpn-forward-rule /
ACCEPT all -- 10.8.0.0/24 anywhere /
openvpn-forward-rule */
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain DOCKER (11 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.27.0.2 tcp dpt:8200
ACCEPT tcp -- anywhere 172.26.0.2 tcp dpt:5005
ACCEPT tcp -- anywhere 172.28.0.2 tcp dpt:http
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:https
ACCEPT tcp -- anywhere 172.24.0.2 tcp dpt:3001
ACCEPT tcp -- anywhere 172.17.0.3 tcp dpt:9000
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:81
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:http
ACCEPT tcp -- anywhere 172.21.0.4 tcp dpt:3000
ACCEPT tcp -- anywhere 172.31.0.3 tcp dpt:http
ACCEPT tcp -- anywhere 172.17.0.4 tcp dpt:8182
ACCEPT tcp -- anywhere 172.17.0.5 tcp dpt:http
ACCEPT tcp -- anywhere 172.17.0.6 tcp dpt:http
ACCEPT tcp -- anywhere 172.17.0.6 tcp dpt:https
ACCEPT udp -- anywhere 172.17.0.6 udp dpt:bootps
ACCEPT tcp -- anywhere 172.17.0.6 tcp dpt:domain
ACCEPT udp -- anywhere 172.17.0.6 udp dpt:domain

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere

Chain DOCKER-ISOLATION-STAGE-2 (10 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere

Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere

Regards,
Saugata D.

@Septrum101
Copy link

#! /bin/bash

apt install ufw -y
ufw allow ssh
for i in `curl https://www.cloudflare.com/ips-v4`; do ufw allow from $i to any port http; done
for i in `curl https://www.cloudflare.com/ips-v4`; do ufw allow from $i to any port https; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ufw allow from $i to any port http; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ufw allow from $i to any port https; done

easy way to apply rules on startup

@urbanspring
Copy link

great script, does anyone know how you restore the real users i.ps using remoteip? im on centos 7

any help would be greatly appreciated

@dragonsxslayer
Copy link

great script, does anyone know how you restore the real users i.ps using remoteip? im on centos 7

any help would be greatly appreciated

yes use ip restore, in ny panel it's built in function however if you search in Google for cloudfalre ip restore you'll find it

@dragonsxslayer
Copy link

can i use this script safely , it's won't look me out of my server right ?

@isaackogan
Copy link

isaackogan commented Apr 15, 2023

#! /bin/bash

apt install ufw -y
ufw allow ssh
for i in `curl https://www.cloudflare.com/ips-v4`; do ufw allow from $i to any port http; done
for i in `curl https://www.cloudflare.com/ips-v4`; do ufw allow from $i to any port https; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ufw allow from $i to any port http; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ufw allow from $i to any port https; done

easy way to apply rules on startup

Just adding on that if you want to do this with more ports, you can modify slightly:

#! /bin/bash

for i in `curl https://www.cloudflare.com/ips-v4`; do ufw allow from $i to any port http,https,69420,8443 proto tcp; done
for i in `curl https://www.cloudflare.com/ips-v4`; do ufw allow from $i to any port http,https,69420,8443 proto udp; done

...etc

This becomes more efficient if you want to apply the rules to a ton of ports in different ranges, else you might have 6000000 rules

@dgrzjohn
Copy link

dgrzjohn commented May 6, 2023

If you are trying to drop connections to docker containers, these rules must be added to the DOCKER-USER chain, or they will not get dropped correctly.
To access the original destination ports of the docker container, the -m conntrack --ctorigdstport is used. --ctdir ORIGINAL is to drop only connections going to the container, not coming back from the container.
Discussion here: https://serverfault.com/questions/704643/steps-for-limiting-outside-connections-to-docker-container-with-iptables

The DROP must be added first, not appended, because the docker automatically appends a RETURN to the end of the chain.

iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport http --ctdir ORIGINAL -j DROP

for i in `curl https://www.cloudflare.com/ips-v4`; do iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport http --ctdir ORIGINAL -s $i -j ACCEPT;done

Repeat for other ports/ipv6. There's probably a better way but its working for me.

@Lalmi-Issam
Copy link

My life saver thx man i was facing DDos Attack on with 20milion request per hour

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment