I searched the entire internet to find a solution to use the Real IP in the rules of a firewall and unfortunately I did not find anything concrete, all the resources were referring to something else but not my case.
I mean, most of them just wanted to find out the Real IP behind a CDN like Cloudflare and set it for backend servers use only!
In the end, I found myself a perfectly functional solution, that proved very useful for multiple configurations that I did later on many other servers.
Below you have the basic configuration for the front end and an example of debugging in the backend, in case you want to check the correct functioning of the settings/algorithm.
... #~~~ Get real IP if CloudFlare is present acl cf_src src -f /etc/haproxy/cf-ip.lst acl cf_real_ip req.hdr(CF-Connecting-IP) -m found http-request set-var(txn.realip) req.hdr(CF-Connecting-IP) if cf_src cf_real_ip http-request set-var(txn.realip) src if !cf_src http-request set-header X-Real-IP %[var(txn.realip)] http-request set-header X-Forwarded-For %[var(txn.realip)] if !cf_src #~~~ save src temporary, restore later http-request set-var(txn.realsrc) src http-request set-src var(txn.realip) ... ... #~~~ restore src original IP http-request set-src var(txn.realsrc) default_backend http_back
Explanation of the code:
acl cf_src src -f /etc/haproxy/cf-ip.lst=> check if the IP belongs to CloudFlare. The list of IPs with which cloudflare connects to our proxy server, you must download it from here: https://www.cloudflare.com/ips-v4
Save the file used above:
wget https://www.cloudflare.com/ips-v4 > /etc/haproxy/cf-ip.lst
acl cf_real_ip req.hdr(CF-Connecting-IP) -m found=> check if the CF-Connecting-IP field is in the header
http-request set-var(txn.realip) req.hdr(CF-Connecting-IP) if cf_src cf_real_ip=> save the real IP in variable txn.realip, if the above conditions are met, ie the source is CloudFlare and in the header I had CF-Connecting-IP
http-request set-var(txn.realip) src if !cf_src=> If the source does not come from CloudFlare, then in variable X we save the current IP src.
http-request set-header X-Real-IP %[var(txn.realip)]=> Now we set in the header the Real IP so that it can be used universally by any script in the backend server, reading the X-Real-IP header and no matter the source, he will always be the real one.
http-request set-header X-Forwarded-For %[var(txn.realip)] if !cf_src=> If the source is not CloudFlare, then we set the real IP in the X-Forwarded-For header
http-request set-var(txn.realsrc) src=> The IP from the src is temporarily saved in the txn.realsrc variable
http-request set-src var(txn.realip)=> We set src with the IP previously saved in the variable txn.realip, and if the source is from CloudFlare, the value from src will be the IP of the client, the one who visits the website. This is the most important line, because from here we can use src as usual, as it contains the IP we need.
http-request set-src var(txn.realsrc)=> At the end of the configuration in the frontend, we restore the real value src, if we do not need it elsewhere.
The following line is useless to use if we use CloudFlare and do not have the above configuration, because we got blocked all the traffic from CloudFlare:
http-request track-sc1 url32+src table per_ip_and_url_rates unless static
... #~~~ for debug only http-response set-header X-Client-IP %[var(txn.realip)] ...
Explanation of the code:
We configure the X-Client-IP header where we can view the IP with which we visit the website (txn.realip), when analyzing the server response in a web page!
That’s all it was, Happy Coding!