Cloudflare
📚 Documentation 💠 Hub 💬 Discourse
A Remediation Component that syncs the decisions made by CrowdSec with CloudFlare's firewall. Manages multi user, multi account, multi zone setup. Supports IP, Country and AS scoped decisions.
Currently use of this component is discouraged if you are on free plan with Cloudflare due to rate limitations. We are working to resolve this with Cloudflare support.
If you are on a premium plan with Cloudflare contact thier support to ask about increasing your rate limit.
Installation
Repository
Packages for crowdsec-cloudflare-bouncer are available on our repositories. You need to pick the package accord to your firewall system :
- Debian/Ubuntu
- RHEL/Centos/Fedora
sudo apt install crowdsec-cloudflare-bouncer
sudo yum install crowdsec-cloudflare-bouncer
Then run the following commands to setup your bouncer:
sudo crowdsec-cloudflare-bouncer -g <CLOUDFLARE_TOKEN1>,<CLOUDFLARE_TOKEN2> -o /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml # auto-generate cloudflare config for provided space separated tokens
sudo crowdsec-cloudflare-bouncer -s # this sets up IP lists and firewall rules at cloudflare for the provided config.
sudo systemctl start crowdsec-cloudflare-bouncer # the bouncer now syncs the crowdsec decisions with cloudflare components.
Please configure your server to emit real IPs rather than cloudflare IPs in logs, so crowdsec can function properly. See how to here
If your component is not installed on the same machine than LAPI, don't forget to set the crowdsec_lapi_url
and crowdsec_lapi_key
in the configuration file /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
You need to run sudo crowdsec-cloudflare-bouncer -d
to cleanup exisiting cloudflare components created by component before editing the config files.
You can run sudo crowdsec-cloudflare-bouncer -g <CLOUDFLARE_TOKEN1>,<CLOUDFLARE_TOKEN2> -o /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
to generate the configuration by discovering all the accounts and the zones associated with the provided tokens.
Manual
Assisted
Download the latest release.
tar xzvf crowdsec-cloudflare-bouncer.tgz
cd crowdsec-cloudflare-bouncer/
sudo ./install.sh
sudo crowdsec-cloudflare-bouncer -g <CLOUDFLARE_TOKEN1>,<CLOUDFLARE_TOKEN2> -o /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml # auto-generate cloudflare config for provided tokens
sudo crowdsec-cloudflare-bouncer -s # this sets up IP lists and firewall rules at cloudflare for the provided config.
sudo systemctl start crowdsec-cloudflare-bouncer # the bouncer now syncs the crowdsec decisions with cloudflare components.
From source
make release
cd crowdsec-cloudflare-bouncer-vX.X.X
sudo ./install.sh
Rest of the steps are same as of the above method.
Container
Make sure you have docker or podman installed. In this guide we will use docker, but podman would work as a drop in replacement too.
Setup
docker run crowdsecurity/cloudflare-bouncer \
-g <CLOUDFLARE_TOKEN1>,<CLOUDFLARE_TOKEN2> > cfg.yaml # auto-generate cloudflare config for provided space separated tokens
You can then review the contents of the file cfg.yaml
and make any necessary changes.
vim cfg.yaml # review config and set `crowdsec_lapi_key`
The crowdsec_lapi_key
can be obtained by running the following:
sudo cscli -oraw bouncers add cloudflarebouncer # -oraw flag can discarded for human friendly output.
The crowdsec_lapi_url
must be accessible from the container.
Runtime
docker run \
-v $PWD/cfg.yaml:/etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml \
-p 2112:2112 \
crowdsecurity/cloudflare-bouncer
Configuration
Configuration file can be found at /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
# CrowdSec Config
crowdsec_lapi_url: http://localhost:8080/
crowdsec_lapi_key: ${API_KEY}
crowdsec_update_frequency: 10s
include_scenarios_containing: [] # ignore IPs banned for triggering scenarios not containing either of provided word, eg ["ssh", "http"]
exclude_scenarios_containing: [] # ignore IPs banned for triggering scenarios containing either of provided word
only_include_decisions_from: [] # only include IPs banned due to decisions orginating from provided sources. eg value ["cscli", "crowdsec"]
#Cloudflare Config.
cloudflare_config:
accounts:
- id:
token:
ip_list_prefix: crowdsec
default_action: managed_challenge
total_ip_list_capacity: # only this many latest ip scoped decisions would be kept
zones:
- actions:
- managed_challenge # valid choices are either of managed_challenge, js_challenge, block
zone_id:
update_frequency: 30s # the frequency to update the cloudflare IP list
# Component Config
daemon: true
log_mode: file
log_dir: /var/log/
log_level: info # valid choices are either debug, info, error
log_max_size: 40
log_max_age: 30
log_max_backups: 3
compress_logs: true
prometheus:
enabled: true
listen_addr: 127.0.0.1
listen_port: 2112
Making changes to configuration
The component creates Cloudflare infra (IP lists, rules etc) according to your config file.
Before changing the config, always run the following command to clear old infra:
sudo crowdsec-cloudflare-bouncer -d
Upgrading from v0.0.X to v0.1.Y
During v0.0.X there was no managed_challenge
action, instead challenge
action was used by bouncer. This is deprecated since v0.1.0 .
This section assumes you used the default config (generated via crowdsec-cloudflare-bouncer -g <TOKEN_1>,<TOKEN_2>
)
After upgrading the component from v0.0.X to v0.1.Y , run the following commands to migrate to managed_challenge
.
sudo crowdsec-cloudflare-bouncer -d
sudo crowdsec-cloudflare-bouncer -g <TOKEN_1>,<TOKEN_2> -o <path_to_config_file>
sudo systemctl restart crowdsec-cloudflare-bouncer
Cloudflare Configuration
Background: In Cloudflare, each user can have access to multiple accounts. Each account can own/access multiple zones. In this context a zone can be considered as a domain. Each domain registered with cloudflare gets a distinct zone_id
.
For obtaining the token
:
- Sign in as a user who has access to the desired account.
- Go to Tokens and create the token. The component requires the following permissions to function.
To automatically generate config for cloudflare check the helper section below.
If the zone is subscribed to a paid Cloudflare plan then it can be configured to support multiple types of actions. For free plan zones only one action is supported. The first action is applied as default action.
Helpers
The component binary has built in helper scripts to do various operations.
Auto config generator
Generates component config by discovering all the accounts and the zones associated with provided list of tokens.
Example Usage:
sudo crowdsec-cloudflare-bouncer -g <TOKEN_1>,<TOKEN_2>... -o /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
This script only generates cloudflare related config. By default it refers to the config at /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
for crowdsec configuration.
Using custom config:
sudo crowdsec-cloudflare-bouncer -c /path/to/config/file -g <TOKEN_1>,<TOKEN_2>...
Cloudflare Setup
This only creates the required IP lists and firewall rules at cloudflare and exits.
Example Usage:
sudo crowdsec-cloudflare-bouncer -s
Cloudflare Cleanup
This deletes all IP lists and firewall rules at cloudflare which were created by the component.
Example Usage:
sudo crowdsec-cloudflare-bouncer -d
How it works
The service polls the CrowdSec Local API for new / deleted decisions. It then makes API calls to Cloudflare to update IP lists and firewall rules depending upon the decision.
Configuration Reference
crowdsec_lapi_url
string
The URL of CrowdSec LAPI. It should be accessible from the component.
crowdsec_lapi_key
string
API key to authenticate with the LAPI.
cert_path
string
Path to the certificate file used to authenticate with the LAPI.
key_path
string
Path to the key file used to authenticate with the LAPI.
ca_path_file
string
Path to the CA file used to trust the LAPI certificate.
crowdsec_update_frequency
string (That is parseable by time.ParseDuration)
The component will poll the CrowdSec every update_frequency
interval.
include_scenarios_containing
[ ]string
Ignore IPs banned for triggering scenarios not containing either of provided word.
include_scenarios_containing: ["ssh", "http"]
exclude_scenarios_containing
[ ]string
Ignore IPs banned for triggering scenarios containing either of provided word.
exclude_scenarios_containing: ["ssh", "http"]
only_include_decisions_from
[ ]string
Only include IPs banned due to decisions orginating from provided sources.
only_include_decisions_from: ["cscli", "crowdsec"]
cloudflare_config
This block contains cloudflare specific config.
update_frequency
string (That is parseable by time.ParseDuration)
The frequency at which to update the cloudflare resources.
update_frequency: "10s"
accounts
List of account of configs
id
string
id of cloudflare account
token
string
cloudflare token to use to access the account.
ip_list_prefix
string
The prefix to use for naming the IP lists created by the bouncer. The name of IP list will be of the form ip_list_prefix
+action
.
total_ip_list_capacity
int
Limit the number of items in IP lists. This is required for avoiding limit of 10k items for lists.
default_action
managed_challenge
|block
|js_challenge
|challenge
|none
The action to be applied for a decision, if the decision's action is not supported by a zone.
default_action
must be supported by all zones.
Example:
Consider your zone config supports the actions managed_challenge
and js_challenge
. Your default_action
is managed_action
. If you create the following decision:
sudo cscli decisions add --ip 1.2.3.4 --type ban
Since the zone doesn't support ban
decision type, it'll be inserted into the IP list given by default_action
. In this case it'll be the list for managed_challenge
.
You can completely ignore such decisions by setting default_action
to none
. It won't be inserted into any list then.
Note:
Following table is mapping of decision type to it's destination IP list.
Decision Type | Default Action |
---|---|
captcha | managed_challenge |
ban | block |
js_challenge | js_challenge |
challenge
action is deprecated in favour of managed_challenge
.
zones
[ ]ZoneConfig
This block contains config for each zone to be managed by the component. The zone must be accessible from the parent account.
zone_id
string
The id of the zone.
actions
[ ]string
List of actions to be supported by this zone. If the zone is not subscribed to premium plan, then only a single action can be given.
The supported action must include the default_action
of the parent account.
Valid choice includes either of
block
js_challenge
challenge
managed_challenge
.
The component creates an IP list for each action. IP list is at account level, so multiple zones with same parent account will share lists for particular action.
challenge
action is deprecated in favour of managed_challenge
Note:
Following table is mapping of decision type to it's destination IP list, which are created according to zone actions
Decision Type | Zone Action |
---|---|
captcha | managed_challenge |
ban | block |
js_challenge | js_challenge |
daemon
boolean
This field has now been deprecated and is ignored within the component
Run the component as a daemon.
log_mode
stdout
|file
Where the log contents are written (With file
it will be written to log_dir
with the name crowdsec-cloudflare-bouncer.log
)
log_dir
string
Relevant if log_mode
is file
. This determines where to create log file.
log_level
trace
|debug
|info
|error
Log level for the component.
compress_logs
true
|false
Compress log files on rotation
log_max_size
int (in MB)
Max size of log files before rotation
log_max_backups
int
How many backup log files to keep before deletion (can happen before log_max_age
is reached)
log_max_age
int (in days)
Max age of backup files before deletion (can happen before log_max_backups
is reached)
Troubleshooting
- Metrics can be seen at http://localhost:2112/metrics
- Logs are in
/var/log/crowdsec-cloudflare-bouncer.log
(Default unless changed in config) - You can view/interact directly in the ban list either with
cscli
- Service can be started/stopped with
systemctl start/stop crowdsec-cloudflare-bouncer