Enhance Docker Compose Security with CrowdSec and Traefik Proxy
This is a guest post by community member, Killian Stein.
In this tutorial, I’m going to show you how to enhance your Docker security using CrowdSec and Traefik Proxy.
Before we get started, let's have a quick look at CrowdSec, a community-based security solution! CrowdSec analyzes attacks in real time, and provides access to a console that gives you detailed information on IPs, such as their activity rate, their danger score, and the types of attacks carried out on users within the CrowdSec network.
Isn't that great? How have you been managing your security without analyzing data? Other solutions exist, but I challenge you to find a simpler and equally powerful one. 😉
Well, now that I got your attention, here's a diagram illustrating how CrowdSec works technically:
To sum up the illustration in a few words: You have data sources (e.g. reverse proxy connection logs), which are analyzed by the Log Processor that compares your logs to logs that include indications of attacks. The Local API retrieves the process analysis and then does several things:
- LAPI makes a decision and informs the Remediation Component (bouncer) to enforce said decision
- Shares information on malicious attacks with the CrowdSec community
- Sends alerts on configured channels
Here's an overview of the information available in the CrowdSec Console — super handy!
Shall we move on to the lab?
To follow along with this tutorial, here are a few links that will come in handy.
- You can find the Docker Compose file I use in this tutorial in my GitHub repo.
- If you’re not well-versed in the ins and outs of the CrowdSec Suite, I recommend you check out the Introduction section of the documentation or take the Academy Course on CrowdSec Fundamentals.
- If you are not familiar with the Middleware concept of Traefik Proxy, you can find the information you need in the Traefik documentation.
For the demo, I'm going to use a small VPS (Ubuntu 23.04) from OVH. Here's the basic quick setup.
Note: Modify lines 15 and 16 if you want to secure your SSH port.
And we're off!
I'm going to start with a basic configuration for Traefik Proxy. Another tutorial for Nginx Proxy Manager is already available, so I won't go into that here, but you can find the full CrowdSec + Nginx Proxy Manager tutorial here.
For this tutorial, I am going to use WordPress, Uptime Kuma, and a little Jenkins, so it'll speak to everyone. Here's the Docker Compose file — make sure to adapt it to your domain name.
Before launching Docker Compose, I created the external network manually.
Okay, we're now ready to integrate CrowdSec.
By default, Crowdsec proposes some local dashboards through a Metabase Docker container, but it also provides a console managed at https://app.crowdsec.net.
For the sake of this tutorial, I'm only going to show you the CrowdSec Console.
Before adding the CrowdSec container, prepare the folder to host the logs and at the same time create a directory for the CrowdSec configuration.
Next, simply add a CrowdSec container.
Okay, now that it's started, go to your CrowdSec Console to retrieve your enroll command.
Then use a docker exec to execute the command:
Back to the Console to accept the enroll. 👀
Everything rolls, doesn't it? 😆
At this stage of the configuration, CrowdSec doesn't see the Traefik Proxy logs and no decision will be made, so you need to add a Remediation Component and the Traefik Proxy logs .
Note: Remediation Components are used to apply security measures, such as blocking malicious IP addresses. They act in response to signals and decisions taken by LAPI, which are based on log analysis performed by parsers.
So, let's generate a key for the Traefik Remediation Component.
Top! Now, let’s raise the volume to CrowdSec level and create the Remediation Component in Docker Compose:
Modify the Crowdsec acquisition file which allows it to specify which logs to parse.
Path to file is /opt/crowdsec/acquis.yaml.
Here is the complete Docker Compose file:
To verify that everything's OK and that public IPs have been transferred, use the Docker logs.
Note: If you don't retrieve the public IP, remember to use echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf.
The CrowdSec Console checks that the bouncer is present, and I'll do a scan with Nikto to see if the bouncer is active.
The results are available after a few seconds.
And here are the alerts inside the CrowdSec Console:
Now, if you try to get to jenkins.ninapepite.ovh you will be denied access.
Not bad, eh?
We have several alerts on the same IP, you might to tell me, but we can still make attacks? No! The network packet flow explains why:
The packet is received, marked as malicious, an alert is generated, then returns a 403 error to the attacker. Wonderful!
Note: To unban your IP use the following:
Setting up alerts
So far so good, but now I'd like to be alerted without having to go to the CrowdSec Console. Phone notifications are great for production, aren't they?
For this tutorial, I’m going to use Slack, but you can connect to any other application of this kind. You can find detailed instructions in the CrowdSec documentation.
Make a small edit to the /opt/crowdsec/notifications/slack.yaml file and you'll see how the CrowdSec team made our job easier!
All you have to do now is indicate the URL.
Next, tell the ban profile to send a notification about our slack_default configuration. Again, you need to edit the /opt/crowdsec/profiles.yaml file.
Note: The profile is the link between the alert and the notification. As soon as an alert matches the profile filter, a notification will be sent to the indicated source.
Now let’s restart CrowdSec.
Important note: Be extra careful with the scans. After testing on various platforms, my mobile operator's IP doesn't score very well on CrowdSec.
After the scan, the notifications came in.
Setting up allowlists
Allowlists can be very useful, especially in production. If something goes wrong with your internal connections, you'll have a way of mitigating it quickly.
Let's create a whitelist_custom.yaml file in /opt/crowdsec/parsers/s02-enrich/whitelists_custom.yaml.
Let’s restart Docker and test it!
After the restart, if I do a scan, I won't be banned.
Last but not least — blocklists
I've got one last thing to show you, the blocklists. Just take a look at this. 👀
A dynamic fail2ban →
As you can see, in just a few clicks, you can ban thousands of malicious IPs in seconds, and for free! It's better than searching for blocklists on GitHub, isn't it? 😆
In this article, I haven't explored the commands available via the CrowdSec CLI. I recommend you take a look at the documentation, which will give you an overview of all the available commands.
Here's a shortcut: The cscli metrics command is very useful for getting an overview of your CrowdSec components and also for checking which logs are being processed, which is quite handy when troubleshooting.
That's all for this article!
I hope this tutorial provided you with a helpful overview of the capabilities of the CrowdSec suite. Personally, I install it on all my configurations and find it very reassuring to have so much information on the security status of my machine.
Let's not forget to thank the CrowdSec team for this complete solution! ❤️
Thanks for reading, and see you soon!
About Killian Stein
As a young IT enthusiast and teaching enthusiast, Killian tries to demystify modern technologies. He is a DevSecOps Engineer at Aidalinfo, where he is learning and consolidating his experience of the cloud and open source tools. If you liked Killian’s article and are curious to follow his next projects, don't hesitate to connect with him on LinkedIn. New projects are coming soon!