Skip to content

Initsnow/docker-cloudflare-whitelist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Cloudflare IP Whitelist for Docker Containers (using iptables DOCKER-USER)

This script automates the process of restricting access to specified ports on Docker containers, allowing connections only from Cloudflare's IP ranges. It directly modifies the iptables (and ip6tables if enabled) DOCKER-USER chain.

Purpose

When running services behind Cloudflare (e.g., web servers, APIs in Docker containers), you typically want to ensure that direct access to your origin server (your Docker host) is blocked for IPs other than Cloudflare's proxies. This script helps achieve that by dynamically:

  1. Fetching the latest official Cloudflare IPv4 and IPv6 address ranges.
  2. Adding iptables/ip6tables rules to the DOCKER-USER chain to:
    • ACCEPT traffic from Cloudflare IPs destined for your specified container ports.
    • DROP all other traffic destined for those specific ports.

How it Works

  1. Configuration: You define the Docker container ports to protect (PORTS_TO_PROTECT) in the script.
  2. Prerequisites Check: Verifies if the DOCKER-USER chain exists (indicating Docker is likely running and managing iptables). Checks for both IPv4 (iptables) and IPv6 (ip6tables).
  3. Cleanup: Removes any rules previously added by this specific script (identified by a unique comment: CF_SCRIPT_) before applying new ones. This makes the script safe to re-run (idempotent).
  4. IP Fetching: Downloads the current lists of Cloudflare IPv4 and IPv6 ranges from their official URLs.
  5. Rule Application:
    • Iterates through each port specified in PORTS_TO_PROTECT.
    • For each port:
      • Inserts ACCEPT rules into DOCKER-USER for every Cloudflare IP range targeting that specific port.
      • Inserts a DROP rule below the ACCEPT rules for any other IP targeting that specific port.
    • This logic is applied separately for IPv4 (iptables) and IPv6 (ip6tables), if the IPv6 chain exists.

Why DOCKER-USER? Docker uses iptables extensively for network management. The DOCKER-USER chain is specifically provided as a hook for users to add custom rules that are evaluated before Docker's own rules for forwarding traffic to containers. This makes it the ideal place to filter incoming traffic based on source IP before it reaches your containers.

Note on Interface Matching: This script intentionally does not match rules based on the incoming network interface (-i eth0 etc.) within the DOCKER-USER chain. Such matching is often unreliable in this context because the traffic is being FORWARDed, not hitting the INPUT chain directly in the same way. Rules correctly rely only on source IP and destination port.

Prerequisites

  • Linux Host running Docker.
  • bash shell.
  • iptables command-line tool.
  • ip6tables command-line tool (optional, script will skip IPv6 if not found or DOCKER-USER chain is missing).
  • curl for fetching IP lists.
  • gawk (GNU awk), grep, sort (usually standard).
  • sudo access to modify iptables rules.

Configuration

Edit the apply_cf_rules.sh script and modify the following variable:

  • PORTS_TO_PROTECT=(80 443 8443): Replace the example ports with the actual TCP ports your Docker containers expose that you want to protect.

Usage

  1. Save the Script: Save the code as apply_cf_rules.sh.
  2. Make Executable: chmod +x apply_cf_rules.sh
  3. Run the Script: sudo ./apply_cf_rules.sh
    • The script requires sudo because it modifies iptables rules.
    • It will output the steps it's taking (cleanup, fetching, applying rules).
  4. Verify the Rules: Carefully check the resulting rules:
    sudo iptables -L DOCKER-USER -v -n --line-numbers
    # If IPv6 was processed:
    sudo ip6tables -L DOCKER-USER -v -n --line-numbers
    Ensure that for each protected port, there are ACCEPT rules for Cloudflare IPs followed by a final DROP rule for that port.
  5. Persist the Rules (IMPORTANT!): iptables rules are volatile and disappear on reboot by default. To make them permanent, use a persistence tool. On Debian/Ubuntu systems:
    • Install the tool: sudo apt-get update && sudo apt-get install iptables-persistent
    • During installation, it may ask if you want to save current IPv4/IPv6 rules. Choose yes if you've just successfully run the script.
    • After running the script and verifying the rules are correct, save them:
      sudo netfilter-persistent save
    • Rules will now be loaded automatically on boot.

Automation (Recommended)

Cloudflare IP ranges can change over time. You should run this script periodically to ensure your whitelist stays up-to-date. Use cron to schedule it.

  1. Edit crontab: sudo crontab -e
  2. Add a cron job: Add a line like the following to run the script daily at, for example, 3:05 AM and log output:
    5 3 * * * /full/path/to/your/apply_cf_rules.sh > /var/log/apply_cf_rules.log 2>&1
    • Replace /full/path/to/your/apply_cf_rules.sh with the actual absolute path to the script.
    • Ensure the script is executable by root.

Troubleshooting

  • "Error: iptables chain 'DOCKER-USER' does not exist": Docker might not be running, or its iptables integration might be disabled or malfunctioning. Ensure Docker is installed and running correctly.
  • "Warning: ip6tables chain 'DOCKER-USER' does not exist": Your system might not have IPv6 enabled, ip6tables installed, or Docker might not have created the IPv6 chain. The script will safely skip IPv6 rules.
  • "Error: Failed to fetch Cloudflare IPs": Check internet connectivity from the host. Verify the URLs (CF_IPV4_URL, CF_IPV6_URL) in the script are still valid.
  • Containers Unreachable: Double-check the PORTS_TO_PROTECT list in the script matches the ports your containers actually use. Verify the iptables -L DOCKER-USER output carefully.

Disclaimer

Modifying firewall rules can impact network connectivity. Understand the rules being applied before running the script in a production environment. Use with caution.

About

Bash script to restrict Docker container port access to Cloudflare IPs only using iptables/DOCKER-USER.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages