Hi everyone,
I'm looking for some advice for my current architecture.
I've got the following architecture:
A virtual machine on Hetzner Cloud. On this VM is running a Debian with Docker. I'm using Traefik Proxy to make individual containers accessible to the internet. The DNS for these services is on Cloudflare. Some of these services make use of Cloudflare's proxy feature. To prevent requests bypassing the Cloudflare proxy, I've set up Mutual TLS between Cloudflare and Traefik.
Now, I want to add CrowdSec to the mix. I've set up a new Docker container for CrowdSec. I've made Traefik's access logs available to CrowdSec using the existing traefik-logs parser.
This generally works. CrowdSec successfully parses the access logs and can could act based on this. I've not configured any remediation components, yet. However, this shouldn't make any difference to my question.
Now, I've noticed an issue with this architecture:
Because some services are proxied through Cloudflare, the source IP, which the parser sees, are the ones of the Cloudflare proxy servers. The parser doesn't identify the original source IP which the request started with. This would lead to that all requests appear to CrowdSec as if they are coming from some Cloudflare IP address. When I would blocking these IP addresses using a remediation component, I would basically block everyone.
I'm wondering what the correct way is to identify the original IP. When a request is proxied by Cloudflare, Cloudflare adds an additional request header called "Cf-Connecting-Ip". This would be the correct IP address to use as "source IP". However, only some of my services are proxied through Cloudflare. A few other services are directly accessing the IP of my server. That header therefore doesn't exist for them.
What is the correct way to handle this situation?
Do I have to write a custom parser which makes use of some kind of map for my services. In this map each service gets marked as "Cloudflare-proxied" or not. Then the parser either checks for Cf-Connecting-Ip or some other request header?
Or, am I missing something? Is there already some built-in features to handle these situations?