2

I have nginx server behind reverse proxy (Cloudflare) and want to block ips based on the xforwarded ip sent in the header.

I have tried the following iptables string matching rule :

iptables -A INPUT -m string --string "1.1.1.1" --algo bm --to 1024 -j DROP

However this doesn't seem to do anything.

Why isn't the string matching working ? I'm sure the real ip is sent in the packet , either as X-Forwarded-For or CF-Connecting-IP.

Kernel is 3.4.x and iptables 1.4.7, so no issues there .

Rdang
  • 131
  • 2
  • 3
  • 14

1 Answers1

0

As you mention CF-Connecting-IP is the best way to get the real IP behind CloudFlare. This is better than X-Forwarded-For as that can be changed if your server is then placed behind a load balancer or another reverse proxy (X-Forwarded-For even supports a comma separated list in it's RFC).

CloudFlare should only pass secure traffic and only web traffic to CloudFlare supported web server ports, therefore you can whitelist CloudFlare IPs and enable IPTables on other IPs. You can then block IPs in the Firewall tab of the CloudFlare site in question, then looking under IP Firewall. Non-CloudFlare traffic can then have IPTables applied to it.

We use the official Mod_CloudFlare on our Apache servers in order to correctly get the IP Address to our web server and ultimately into the web application itself. On NGinX you can try the ngx_http_realip_module.

mjsa
  • 4,221
  • 1
  • 25
  • 35
  • Essentially, it is best to block IPs at a CloudFlare level. If you want to do this programatically (e.g. with Fail2Ban), it is best to use the official API. – mjsa Sep 30 '15 at 19:10
  • I already am blocking ips at cloudflare level but their API is limited and there's a maximum quota for number of ips. I want to block ips at kernel level and my question is specifically about iptables string matching, but thanks for your suggestion anyway. – Rdang Sep 30 '15 at 21:28
  • Could you try: iptables -A INPUT -m string --algo bm --string "1.1.1.1" -j DROP – mjsa Sep 30 '15 at 21:40