Cloudflare Magic Firewall: Stateless Packet Filtering at the Network Edge
What Is Magic Firewall?
Magic Firewall is Cloudflare’s network-level firewall delivered as a service. It lets you write packet filtering rules that execute inside Cloudflare’s global network — before traffic reaches your infrastructure through Magic Transit tunnels.
Think of it as a stateless ACL engine that runs at the edge of the internet, not on hardware you own or manage. No appliances, no capacity planning, no per-packet processing hitting your routers. Rules run at Cloudflare scale across every data center in their network simultaneously.
What Problems It Solves
Offload filtering from your perimeter. Your on-premise firewalls have finite throughput. Every packet they inspect is CPU cycles and bandwidth consumed. Magic Firewall drops unwanted traffic before it even enters your tunnels, meaning your edge devices only process traffic that should actually reach them.
Consistent policy across all ingress points. In traditional architectures, each data center has its own firewall hardware with potentially divergent rule sets. Magic Firewall gives you a single policy that applies uniformly to all traffic entering via Magic Transit, regardless of which Cloudflare PoP it enters through.
Protocol and port enforcement at scale. Lock down which protocols and ports are allowed to reach your network without tuning hardware ACLs on every upstream device. Changes take effect globally in seconds.
Block bogons and unwanted source IPs. Drop traffic from RFC1918 addresses, known malicious ASNs, or unexpected geographies before it consumes any of your resources.
How Rules Work
Magic Firewall uses a Wireshark-like filter syntax called Wirefilter to match packets. Rules are evaluated in priority order and result in either allow or block.
# Block all traffic from a specific source IP
ip.src == 198.51.100.0/24
# Block UDP on non-DNS ports from external sources
ip.proto == 17 and udp.dstport != 53
# Allow only TCP and UDP, block everything else
not (ip.proto == 6 or ip.proto == 17)
# Block ICMP floods by dropping all ICMP
ip.proto == 1
# Block traffic from specific countries (using IP lists)
ip.src in $malicious_ips
Rules reference:
ip.src/ip.dst— source/destination IP or CIDRip.proto— protocol number (6=TCP, 17=UDP, 1=ICMP, 47=GRE)tcp.dstport/udp.dstport— destination porttcp.srcport/udp.srcport— source porttcp.flags— TCP flag matching (SYN, ACK, RST, FIN)
Key Capabilities
- Stateless packet filtering — high-throughput L3/L4 rule matching with no connection tracking overhead
- IP Lists — maintain named lists of IPs/CIDRs (up to millions of entries) and reference them in rules
- TCP flag inspection — match on specific TCP flags to block malformed packets or half-open connection floods
- Protocol filtering — allow or deny specific IP protocols across your entire address space
- Rule priority ordering — rules evaluated top-down, first match wins
- API-driven management — create, modify, and delete rules programmatically via Cloudflare API
- Integrated with Magic Transit — rules apply to all traffic entering your network through Magic Transit tunnels
Best Practices
Default Deny Where Possible
Structure your ruleset around a default-deny posture. Explicitly allow the protocols and ports your infrastructure requires, then block everything else. This is more work upfront but far more effective than trying to enumerate what to block.
Priority 1: Allow TCP port 80, 443 from any
Priority 2: Allow UDP port 53 from your DNS resolvers
Priority 3: Allow ICMP from Cloudflare health check ranges
Priority 10: Block everything else
Drop Bogons at the Edge
Packets with RFC1918 source addresses should never arrive from the internet. Drop them immediately — they’re either spoofed or misconfigured and have no legitimate reason to reach your network.
# Block private/bogon source IPs
ip.src in {10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 127.0.0.0/8 0.0.0.0/8}
Use IP Lists for Scalable Block Lists
Rather than writing individual rules for every IP you want to block, maintain IP Lists in the Cloudflare dashboard and reference them in a single rule. Update the list without touching the rule itself. This is essential for maintaining threat intel feeds — update the list via API whenever your feed refreshes.
Don’t Over-Block ICMP
ICMP is used for path MTU discovery, health checks, and diagnostics. Blocking all ICMP causes subtle connectivity problems that are difficult to debug. Instead of block all ICMP, be surgical:
# Allow ICMP echo (ping) but rate limit — done at Magic Transit layer
# Block ICMP redirect messages (type 5) — legitimate reason to drop
ip.proto == 1 and icmp.type == 5
Separate Environments with Rule Priority Ranges
If you manage multiple networks or environments through Magic Transit, use priority ranges to logically separate them:
1-999: Global rules (apply everywhere)
1000-1999: Production network rules
2000-2999: Dev/staging network rules
Test Rules in Log Mode First
Before blocking, set a new rule to log mode. Review what traffic it would have matched for 24-48 hours. Only flip to block once you’re confident you’re not dropping legitimate traffic. A block rule that drops production traffic is worse than no rule at all.
Keep Rules Documented
Magic Firewall rules accumulate over time. Every rule should have a description explaining why it exists, who requested it, and when it was added. Rules without context become untouchable — nobody wants to delete something they don’t understand.
Pair With Magic Transit Tunnel Health Alerts
Magic Firewall rules that are too aggressive can inadvertently block Cloudflare’s own tunnel health check probes. Always verify your tunnel health check IPs are explicitly allowed before deploying broad ICMP or UDP block rules.