Fail2ban fails when trying to add IP to Cloudflare

I am running a WordPress site on a CentOS 7 server. I have fail2ban installed and working, and have verified that it is adding IPs to iptables. I just added Cloudflare to the site, and now I’m trying to get fail2ban working with the Cloudflare v4 API. I’ve already configured Cloudflare and Apache to report the real IP of the visitor and not the Cloudflare proxy IP. I followed this guide to get up the fail2ban jails and configs. Everything seems to be working, but fail2ban is unable to send the banned IP to Cloudflare. But, I can run the same curl command myself and Cloudflare will ban the IP. My Google-fu is failing me, as everything I’ve found is for failures to un-ban IPs.

Here’s what’s going on:

This is the command I’m running. If I run this from the command line, the IP will show up in the Cloudflare site as banned.

curl -s -o /dev/null -X POST -H 'X-Auth-Email: [email protected]' -H 'X-Auth-Key: xxxx' \
        -H 'Content-Type: application/json' -d '{ "mode": "block", "configuration": { "target": "ip", "value": "1.2.3.4" } }' \
        https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules

When fail2ban tries the same command, this is the result:

2020-02-29 22:09:02,968 fail2ban.utils          [29787]: ERROR   7f5ad2ea9810 -- exec: curl -X POST -H 'X-Auth-Email: [email protected]' -H 'X-Auth-Key: XXXX' \
-H 'Content-Type: application/json' -d '{ "mode": "block", "configuration": { "target": "ip", "value": "1.2.3.4" } }' \
https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules
2020-02-29 22:09:02,968 fail2ban.utils          [29787]: ERROR   7f5ad2ea9810 -- stderr: '  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current'
2020-02-29 22:09:02,968 fail2ban.utils          [29787]: ERROR   7f5ad2ea9810 -- stderr: '                                 Dload  Upload   Total   Spent    Left  Speed'
2020-02-29 22:09:02,969 fail2ban.utils          [29787]: ERROR   7f5ad2ea9810 -- stderr: ''
2020-02-29 22:09:02,969 fail2ban.utils          [29787]: ERROR   7f5ad2ea9810 -- stderr: '  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to 2606:4700:300a::6813:c01d: Permission denied'
2020-02-29 22:09:02,969 fail2ban.utils          [29787]: ERROR   7f5ad2ea9810 -- returned 7
2020-02-29 22:09:02,969 fail2ban.actions        [29787]: ERROR   Failed to execute ban jail 'wordpress-hard' action 'cloudflare' info 'ActionInfo({'ip': '1.2.3.4', 'fid': <function <lambda> at 0x7f5ad2e64a28>, 'family': 'inet4', 'raw-ticket': <function <lambda> at 0x7f5ad2e64ed8>})': Error banning 1.2.3.4

It’s the same API call so I’m not sure what fail2ban is doing differently. Any help would be greatly appreciated.

Do you know if your Command Line example is connecting over IPv4? The fail2ban routine is getting a permission denied over IPv6.

Hmm, yea I noticed the denied was over IPv6. How do I check which one the command line is using? Or can I force fail2ban to use IPv4?

Try curl -sv -o blahblah, so the ‘v’ will show Verbose output.

I don’t know how to get fail2ban to do this over IPv4.

Here’s the command line output:

* About to connect() to POST port 80 (#0)
*   Trying 204.74.99.100...
* Connected to POST (204.74.99.100) port 80 (#0)
> POST / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: POST
> Accept: */*
> X-Auth-Email: [email protected]
> X-Auth-Key: XXXX
> Content-Type: application/json
> Content-Length: 83
> 
} [data not shown]
* upload completely sent off: 83 out of 83 bytes
< HTTP/1.1 404 Not Found
< Date: Sun, 01 Mar 2020 01:33:03 GMT
< Server: UltraDNS Client Redirection Server
< Last-Modified: Sun, 01 Mar 2020 01:33:03 GMT
< Accept-Ranges: none
< Connection: close
< Content-Type: text/html
< 
{ [data not shown]
* Closing connection 0
* About to connect() to api.cloudflare.com port 443 (#1)
*   Trying 2606:4700:300a::6813:c11d...
* Connected to api.cloudflare.com (2606:4700:300a::6813:c11d) port 443 (#1)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: CN=api.cloudflare.com,O="CloudFlare, Inc.",L=San Francisco,ST=CA,C=US
* 	start date: Aug 21 00:00:00 2019 GMT
* 	expire date: Aug 20 12:00:00 2020 GMT
* 	common name: api.cloudflare.com
* 	issuer: CN=CloudFlare Inc ECC CA-2,O="CloudFlare, Inc.",L=San Francisco,ST=CA,C=US
> POST /client/v4/user/firewall/access_rules/rules HTTP/1.1
> User-Agent: curl/7.29.0
> Host: api.cloudflare.com
> Accept: */*
> X-Auth-Email: [email protected]
> X-Auth-Key: XXXX
> Content-Type: application/json
> Content-Length: 83

And here’s the results from the fail2ban log:

2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* About to connect() to POST port 80 (#0)'
2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '*   Trying 204.74.99.100...'
2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Failed to connect to 204.74.99.100: Permission denied'
2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: "* couldn't connect to host at POST:80"
2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Closing connection 0'
2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* About to connect() to api.cloudflare.com port 443 (#1)'
2020-03-01 01:36:17,197 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '*   Trying 2606:4700:300a::6813:c11d...'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Failed to connect to 2606:4700:300a::6813:c11d: Permission denied'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '*   Trying 2606:4700:300a::6813:c01d...'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Failed to connect to 2606:4700:300a::6813:c01d: Permission denied'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '*   Trying 104.19.193.29...'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Failed to connect to 104.19.193.29: Permission denied'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '*   Trying 104.19.192.29...'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Failed to connect to 104.19.192.29: Permission denied'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: "* couldn't connect to host at api.cloudflare.com:443"
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- stderr: '* Closing connection 1'
2020-03-01 01:36:17,198 fail2ban.utils          [30287]: ERROR   7f69082b7438 -- returned 7

I’m still figuring this stuff out, but is it my firewall that’s blocking the connection? I wouldn’t think that would be the case since it works one way. I have all the Cloudflare IPs whitelisted in iptables.

So make it a curl -sv6 -o blahblah and troubleshoot your outbound connection. stackoverflow is a good resource for fixing this.

1 Like

you using a 3rd party DNS resolver for the server itself ?

The server is using the Linode DNS resolvers. Do I need to change that to Cloudflare?

cat /etc/resolv.conf
# Generated by NetworkManager
search members.linode.com com
nameserver 172.105.170.5
nameserver 172.105.167.5
nameserver 172.105.171.5

Quick update, I appreciate the help here. I now have narrowed it down to an SELinux issue, which is good. I ran setenforce permissive and fail2ban worked correctly, updating iptables and Cloudflare. So I will be chasing that issue down next, and will update this once I get a solution.

1 Like

I tracked it down and fixed it by adding a new policy package following this guide: Fiddling With SELinux Policies. Now fail2ban is properly updating Cloudflare.

Note for anyone who find this on Google in the future: I had to name the new policy fail2ban-mod in order for it to install. Naming it fail2ban wouldn’t work, although some internet guides said it should.

Thanks for the help on this guys, you pointed me in the right direction.

3 Likes