Auto-detects Cloudflare outages and toggles DNS proxy to keep domains accessible. When CF throws 500/502/503 errors, script disables proxy (grey cloud) to route direct to origin. Re-enables when healthy.
Built during the Nov 18, 2025 CF outage incident.
git clone [email protected]:richardevcom/cloudflare-dns-toggle.git
cd cloudflare-dns-toggle
cp .env.example .env
# Edit .env with your CF_API_TOKEN (CF_ZONE_ID is optional)
chmod +x cloudflare-dns-toggle.shGet credentials:
- API Token: https://dash.cloudflare.com/profile/api-tokens (needs
Zone.DNS Edit) - Zone ID: Optional - auto-detected from domain (or set manually in CF Dashboard → Overview)
# Health check
./cloudflare-dns-toggle.sh check example.com
# Toggle proxy
./cloudflare-dns-toggle.sh disable example.com # grey cloud
./cloudflare-dns-toggle.sh enable example.com # orange cloud
# Check status
./cloudflare-dns-toggle.sh status example.com
# Monitor mode (auto-toggle every 60s)
./cloudflare-dns-toggle.sh monitor example.com
# Quiet mode (minimal output, logs only errors/changes)
./cloudflare-dns-toggle.sh monitor --quiet example.com
./cloudflare-dns-toggle.sh monitor -q example.com
# Background with nohup
nohup ./cloudflare-dns-toggle.sh monitor -q example.com &
# Interactive mode (pick domains from DNS records)
./cloudflare-dns-toggle.sh monitor
# Install as systemd service (runs in quiet mode)
./cloudflare-dns-toggle.sh install-service
# Rollback to original state
./cloudflare-dns-toggle.sh restore example.com- Curls domain over HTTPS
- If 500/502/503 → disables proxy via CF API
- If 2xx → re-enables proxy
- Saves original state to
.state.jsonfor rollback
Monitor mode checks every 60s (configurable in .env), respects CF rate limits.
curljq
Install: sudo apt install curl jq (Ubuntu/Debian) or brew install curl jq (macOS)
401/403 errors: Check API token permissions (needs Zone.DNS Edit)
Rate limiting: Increase CHECK_INTERVAL in .env or monitor fewer domains
DNS not updating: Changes take 1-5 min to propagate
Edit .env:
CF_API_TOKEN=your_token
# CF_ZONE_ID=your_zone_id # Optional - auto-detected from domain
CHECK_INTERVAL=60 # seconds
AUTO_TOGGLE=true
LOG_FILE=./cloudflare-dns-toggle.log # local dir (or /var/log/ for system-wide)Verify your token:
curl "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer your_api_token_here"Option 1: nohup (simple)
nohup ./cloudflare-dns-toggle.sh monitor -q domain1.com domain2.com &
tail -f cloudflare-dns-toggle.log
# Stop: pkill -f cloudflare-dns-toggleOption 2: systemd service (production)
./cloudflare-dns-toggle.sh install-service domain1.com domain2.com
sudo systemctl status cloudflare-dns-toggle
sudo journalctl -u cloudflare-dns-toggle -fOption 3: screen/tmux
screen -S cf-monitor
./cloudflare-dns-toggle.sh monitor -q domain1.com domain2.com
# Detach: Ctrl+A then D
# Reattach: screen -r cf-monitor# Secure permissions
chmod 600 .env # Only owner can read/write
chmod 700 cloudflare-dns-toggle.sh # Only owner can executeMIT - richardevcom