Skip to content

Ringyuki/cf-ip-guard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cf-ip-guard

Keep local ipsets in sync with Cloudflare IP ranges and consume them in firewall rules.

What it does

  • Fetches Cloudflare IPv4/IPv6 ranges from https://api.cloudflare.com/client/v4/ips.
  • Maintains two ipsets (default: cloudflare4, cloudflare6) with atomic swap.
  • Does not create iptables/nftables rules; you must reference the ipsets yourself.

Prerequisites

  • Linux with ipset and iptables installed. For persistence, install iptables-persistent and ipset-persistent (or netfilter-persistent).
  • Root privileges (ipset operations need CAP_NET_ADMIN).
  • Go toolchain if building from source.
  • Create your own firewall rules that use the ipsets (examples below).

Build & run (manual)

go build -o cf-ip-guard .
sudo mv cf-ip-guard /usr/local/bin/
sudo cf-ip-guard daemon --ipset4 cloudflare4 --ipset6 cloudflare6 --interval 30m --log-level info

Deploy with systemd

./deploy/install.sh
# optional: edit flags
sudo sed -n '1,20p' /etc/cf-ip-guard.env
sudo systemctl restart cf-ip-guard
  • Unit file: deploy/cf-ip-guard.service (installs to /etc/systemd/system/cf-ip-guard.service).
  • Extra CLI flags: set CF_IP_GUARD_OPTS in /etc/cf-ip-guard.env (e.g. --interval 10m --log-level debug).
  • Persistence: by default the daemon runs netfilter-persistent save only when ETag changes. Disable via --persistent-save=false or in CF_IP_GUARD_OPTS.

Firewall rule examples (iptables, only 80/443)

The design goal is to allow only Cloudflare IPs to reach HTTP/HTTPS. Ensure the ipsets exist (daemon creates/syncs them), then:

# Allow HTTP/HTTPS from Cloudflare IPv4
sudo iptables -I INPUT -p tcp -m set --match-set cloudflare4 src --dport 80  -j ACCEPT
sudo iptables -I INPUT -p tcp -m set --match-set cloudflare4 src --dport 443 -j ACCEPT

# Allow HTTP/HTTPS from Cloudflare IPv6
sudo ip6tables -I INPUT -p tcp -m set --match-set cloudflare6 src --dport 80  -j ACCEPT
sudo ip6tables -I INPUT -p tcp -m set --match-set cloudflare6 src --dport 443 -j ACCEPT

# Drop all other HTTP/HTTPS traffic
sudo iptables  -A INPUT -p tcp --dport 80  -j DROP
sudo iptables  -A INPUT -p tcp --dport 443 -j DROP
sudo ip6tables -A INPUT -p tcp --dport 80  -j DROP
sudo ip6tables -A INPUT -p tcp --dport 443 -j DROP

Adjust chains (e.g., use a dedicated service chain) and insertion order to fit your policy. For nftables, create equivalent rules referencing the same ipsets.

Runtime notes

  • Defaults: interval 30m, ipset names cloudflare4/cloudflare6, API URL Cloudflare /ips.
  • On startup the daemon performs an immediate fetch/update, then loops on the interval.
  • Logs go to stderr; configure level via --log-level or CF_IP_GUARD_OPTS.
  • Persistence saves require root and the tools installed; failures are logged as warnings without stopping the loop.

About

keep ipsets in sync with Cloudflare IP ranges

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors