https://github.com/fabriziosalmi/wafcontrol
Cloudflare WAF Settings Automation using GitHub Actions
https://github.com/fabriziosalmi/wafcontrol
cloudflare cloudflare-api cybersecurity firewall-rules rules security settings waf web-application-firewall workflow zones
Last synced: 29 days ago
JSON representation
Cloudflare WAF Settings Automation using GitHub Actions
- Host: GitHub
- URL: https://github.com/fabriziosalmi/wafcontrol
- Owner: fabriziosalmi
- License: mit
- Created: 2024-10-03T10:32:51.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-02-20T07:16:29.000Z (3 months ago)
- Last Synced: 2026-02-20T11:17:52.066Z (3 months ago)
- Topics: cloudflare, cloudflare-api, cybersecurity, firewall-rules, rules, security, settings, waf, web-application-firewall, workflow, zones
- Language: Python
- Homepage:
- Size: 110 KB
- Stars: 7
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# WAFcontrol
WAFcontrol applies Cloudflare zone security settings and custom WAF rules across multiple domains using a YAML configuration file and the Cloudflare API. It is designed to run as a GitHub Actions workflow.
## What it does
The script `scripts/apply_cloudflare.py` reads `config/cloudflare.yaml`, validates the configuration, and calls Cloudflare's API to set the following per-zone settings:
- **Security Level** — `off`, `essentially_off`, `low`, `medium`, `high`, or `under_attack`
- **Browser Integrity Check** — `on` or `off`
- **Automatic HTTPS Rewrites** — `on` or `off`
- **Custom WAF Rules** — create or update rules in the zone's `http_request_firewall_custom` ruleset (actions: `block`, `challenge`, `allow`, `log`, `bypass`)
A `default` section in the config applies to all zones. Settings in a zone's own block override the defaults.
> **Note:** Custom WAF rules (rulesets) require a Cloudflare paid plan. Zone-level firewall settings (security level, browser integrity check, automatic HTTPS rewrites) are available on all plans.
## Prerequisites
- Python 3.9 or higher
- A Cloudflare API token with **Zone Settings: Edit** permission
- A GitHub repository secret named `CLOUDFLARE_API_TOKEN`
Install dependencies:
```bash
pip install pydantic requests PyYAML tenacity
```
## Configuration
Edit `config/cloudflare.yaml`. Settings defined under `default` apply to every zone unless overridden.
```yaml
cloudflare:
waf:
default:
firewall_settings:
security_level: "high"
browser_integrity_check: "on"
automatic_https_rewrites: "on"
rules:
- description: "Block bad user agents"
expression: '(http.user_agent contains "bad-bot")'
action: "block"
zones:
- id: "your-zone-id"
domain: "your-domain.com"
waf:
firewall_settings:
security_level: "under_attack"
browser_integrity_check: "off" # overrides default
automatic_https_rewrites: "on"
rules:
- description: "Challenge suspicious requests"
expression: '(ip.geoip.country eq "RU")'
action: "challenge"
```
## Running manually
```bash
export CLOUDFLARE_API_TOKEN=your-token-here
python scripts/apply_cloudflare.py --config config/cloudflare.yaml
```
## GitHub Actions
The workflow at `.github/workflows/cloudflare_deploy.yml` runs on:
- Push to `main` (when `config/`, `scripts/`, or `.github/workflows/` files change)
- Pull requests to `main` (same path filter)
- A daily schedule at midnight UTC
- Manual dispatch via the GitHub Actions UI
The workflow verifies the API token before applying settings and requires a `CLOUDFLARE_API_TOKEN` repository secret and a `production` environment configured in the repository settings.
## Example output
```
2024-01-01 00:00:00 - INFO - Processing zone example.com (zone-id)...
2024-01-01 00:00:00 - INFO - Applying WAF settings for zone zone-id...
2024-01-01 00:00:00 - INFO - Successfully updated security level to under_attack
2024-01-01 00:00:00 - INFO - Successfully updated browser integrity check to off
2024-01-01 00:00:00 - INFO - Successfully updated automatic https rewrites to on
```
When run inside GitHub Actions, log lines use the `::INFO ::` prefix format instead.
## Security
- Store your API token in GitHub Secrets, never in the repository.
- Use a GitHub environment protection rule to restrict production deployments.
- Verify zone IDs before applying settings.
## Troubleshooting
**API token errors**
- Confirm the token has `Zone Settings: Edit` permission.
- Check the token has not expired.
- Confirm the secret name in the repository matches `CLOUDFLARE_API_TOKEN`.
**Configuration errors**
- Verify zone IDs are correct (found in the Cloudflare dashboard overview page for each domain).
- Confirm YAML syntax is valid.
- Check that `security_level` is one of the accepted values listed above.
## Contributing
Open an issue to discuss significant changes before submitting a pull request.
## License
MIT — see the [LICENSE](LICENSE) file.