I have a webserver running running with Apache on Ubuntu behind Cloudflare. I want to block a user using the iptables of the webserver. Here I want to implement to string match feature of iptables and drop the connection. Here is my rule which does not work:
iptables -I INPUT -m string --string "x-forwarded-for: 216.244.66.205" --algo bm --to 65535 -j DROP
After adding this rule the client is still able to hit the server.
I know Cloudflare’s specific header for client IP that is cf-connecting-ip. I am able to block the client with this. Here is the rule which works fine:
iptables -I INPUT -m string --string "cf-connecting-ip: 216.244.66.205" --algo bm --to 65535 -j DROP
The traffic from Cloudflare to the Web server is HTTP (port 80).
I have a load-balancer (haproxy) and some of the domains are running through this instead of Cloudflare. That is why I want to use XFF because cf-connecting-ip is specific to Cloudflare and XFF is supported by both.
I can see Cloudflare is properly attaching both cf-connecting-ip and XFF headers. Here is the output of tcpdump among multiple requests:
tcpdump -A -s 65535 'tcp port 80' | grep 216.244.66.205
x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205 x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205 x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205 x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205
Somehow the iptables are able to detect the string cf-connecting-ip but not x-forwarded-for.
Any help would be appreciated.
2
Answers
Answering own question in the hope it can help someone.
The issue was due to the differences in CASE of the letters. The server was passing the letters in different which was not matching the one provided.
I just needed to add an extra option that is
--icase
which ignores the case (case-insensitive match).Now the command is:
HTTP headers are at the Application Layer, while IPTables works lower down in the TCP/IP stack. The data you are looking to filter based on is not visible to IPTables.
For websites behind Cloudflare you should configure IPTables to only allow Cloudflare IP addresses through, and use the Cloudflare Firewall to block the client IP addresses.