January 27, 20224 yr This thread is designed to help those of you who want to setup fail2ban docker container on UnRaid. I have so far setup fail2ban with jails for Vaultwarden and Jellyfin. My setup: Unraid OS 6.9.2 All containers running on a custom network called 'proxynet' Nginx Proxy Manager from repository jlesage/nginx-proxy-manager Docker image : https://hub.docker.com/r/crazymax/fail2ban Official fail2ban project page : http://www.fail2ban.org/wiki/index.php/Main_Page My Respository with instructions for this setup: https://github.com/FrankM77/docker-fail2ban Donate: https://paypal.me/built2 Edited January 27, 20224 yr by Built2Succeed grammar
January 28, 20224 yr I am not sure what I did wrong. The difference between yours and mine is just cloudflare. I do not have subdomains proxied via cloudflare. I am trying to set it up for nginx. the logs displays ip is banned (I am using vpn to test the fail2ban). But I can still access the services. I asked in the reddit to see if I can get quick response. Here is the link to the detail issue and configuration I am using, fail2ban detecting IP but not blocking : fail2ban (reddit.com) I saw you were using different config for the action. So I gave second try with exact configuration like you and still stuck with the IP not being actually banned. Any idea?
January 28, 20224 yr Author Are you using cloudflare to host your site? I'm certainly no expert and hopefully i don't steer you in the wrong direction. But it seems to me that your filter and jail are setup correctly since the fail2ban log you show seems to be showing a ban. Did you go into the container console and type 'fail2ban-client status Nginx' ? Does it show as banned? Also I would check your action setup in action.d folder. I have two files in my action.d folder : iptables-common.local and cloudflare-apiv4.conf. My iptables-common.local file looks like this: # /mnt/user/appdata/fail2ban/action.d/iptables-common.local [Init] blocktype = DROP [Init?family=inet6] blocktype = DROP My cloudflare-apiv4.conf file looks like this: # # Author: Gilbn from https://technicalramblings.com # Adapted Source: https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf and https://guides.wp-bullet.com/integrate-fail2ban-cloudflare-api-v4-guide/ # # To get your Cloudflare API key: https://dash.cloudflare.com/profile use the Global API Key # [Definition] # Option: actionstart # Notes.: command executed once at the start of Fail2Ban. # Values: CMD # actionstart = # Option: actionstop # Notes.: command executed once at the end of Fail2Ban # Values: CMD # actionstop = # Option: actioncheck # Notes.: command executed once before each actionban command # Values: CMD # actioncheck = # Option: actionban # Notes.: command executed when banning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: IP address # number of failures # unix timestamp of the ban time # Values: CMD actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \ -H "X-Auth-Email: <cfuser>" \ -H "X-Auth-Key: <cftoken>" \ -H "Content-Type: application/json" \ --data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"Fail2ban <name>"}' # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: IP address # number of failures # unix timestamp of the ban time # Values: CMD # actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$( \ curl -s -X GET "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=<ip>&page=1&per_page=1&match=all" \ -H "X-Auth-Email: <cfuser>" \ -H "X-Auth-Key: <cftoken>" \ -H "Content-Type: application/json" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1);}}}' | tr -d '"' | sed -e 's/^[ \t]*//' | head -n 1)" \ -H "X-Auth-Email: <cfuser>" \ -H "X-Auth-Key: <cftoken>" \ -H "Content-Type: application/json" [Init] # Name of the jail in your jail.local file. default = [jail name] name = default # Option: cfuser # Notes.: Replaces <cfuser> in actionban and actionunban with cfuser value below # Values: Your CloudFlare user account cfuser = your_cloudflare_username # Option: cftoken (Global API Key) # Notes.: Replaces <cftoken> in actionban and actionunban with cftoken value below # Values: Your CloudFlare API key cftoken = your_Cloudflare_API_token
January 29, 20224 yr Author It depends. You'll need to consult the documentation for the container. For instance I have Vaultwarden (the unofficial bitwarden) and it logs to STD OUT by default. Which I believe means the screen. So Vaultwarden does not create a logfile by default. I had to add an environmental variable to get it to log to a file, per the documentation. Which container are you running that you are trying to find the logfile?
January 29, 20224 yr On 1/28/2022 at 9:32 AM, Built2Succeed said: Are you using cloudflare to host your site? I'm certainly no expert and hopefully i don't steer you in the wrong direction. But it seems to me that your filter and jail are setup correctly since the fail2ban log you show seems to be showing a ban. Did you go into the container console and type 'fail2ban-client status Nginx' ? Does it show as banned? Also I would check your action setup in action.d folder. I have two files in my action.d folder : iptables-common.local and cloudflare-apiv4.conf. My iptables-common.local file looks like this: # /mnt/user/appdata/fail2ban/action.d/iptables-common.local [Init] blocktype = DROP [Init?family=inet6] blocktype = DROP My cloudflare-apiv4.conf file looks like this: # # Author: Gilbn from https://technicalramblings.com # Adapted Source: https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf and https://guides.wp-bullet.com/integrate-fail2ban-cloudflare-api-v4-guide/ # # To get your Cloudflare API key: https://dash.cloudflare.com/profile use the Global API Key # [Definition] # Option: actionstart # Notes.: command executed once at the start of Fail2Ban. # Values: CMD # actionstart = # Option: actionstop # Notes.: command executed once at the end of Fail2Ban # Values: CMD # actionstop = # Option: actioncheck # Notes.: command executed once before each actionban command # Values: CMD # actioncheck = # Option: actionban # Notes.: command executed when banning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: IP address # number of failures # unix timestamp of the ban time # Values: CMD actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \ -H "X-Auth-Email: <cfuser>" \ -H "X-Auth-Key: <cftoken>" \ -H "Content-Type: application/json" \ --data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"Fail2ban <name>"}' # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: IP address # number of failures # unix timestamp of the ban time # Values: CMD # actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$( \ curl -s -X GET "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=<ip>&page=1&per_page=1&match=all" \ -H "X-Auth-Email: <cfuser>" \ -H "X-Auth-Key: <cftoken>" \ -H "Content-Type: application/json" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1);}}}' | tr -d '"' | sed -e 's/^[ \t]*//' | head -n 1)" \ -H "X-Auth-Email: <cfuser>" \ -H "X-Auth-Key: <cftoken>" \ -H "Content-Type: application/json" [Init] # Name of the jail in your jail.local file. default = [jail name] name = default # Option: cfuser # Notes.: Replaces <cfuser> in actionban and actionunban with cfuser value below # Values: Your CloudFlare user account cfuser = your_cloudflare_username # Option: cftoken (Global API Key) # Notes.: Replaces <cftoken> in actionban and actionunban with cftoken value below # Values: Your CloudFlare API key cftoken = your_Cloudflare_API_token My domain is hosted at cloudflare, and not using proxy at the moment ( had issue with nextcloud, that auto upload was not working properly for larger files). In my iptables, I see all the IPs are banned as well. I have very similar configuration as yours besides the cloudflare part. 😞
January 30, 20224 yr 14 hours ago, 062bel313 said: My domain is hosted at cloudflare, and not using proxy at the moment ( had issue with nextcloud, that auto upload was not working properly for larger files). In my iptables, I see all the IPs are banned as well. I have very similar configuration as yours besides the cloudflare part. 😞 @062bel313 Just making sure you know that when you uploading via Cloudflare you will be limited to 100MB, however if you upload locally you can upload as much as you like. So rather than paying cloudflare I just gotten used to doing any major uploads at home on my local network bypassing the CF protected domain. I hope you get fail2ban to work but that is my 2 cents on uploading via cloudflare. Also if you dont mind me asking why did you set bantime to "-1" does that set it for forever, dont ban at all, or is it some testing puspose? Edited January 30, 20224 yr by Kevin Marchese
January 30, 20224 yr 1 hour ago, Kevin Marchese said: @062bel313 Just making sure you know that when you uploading via Cloudflare you will be limited to 100MB, however if you upload locally you can upload as much as you like. So rather than paying cloudflare I just gotten used to doing any major uploads at home on my local network bypassing the CF protected domain. I hope you get fail2ban to work but that is my 2 cents on uploading via cloudflare. Also if you dont mind me asking why did you set bantime to "-1" does that set it for forever, dont ban at all, or is it some testing puspose? I have remote users my family members and they always had issues because of cloudflare, i will look into it again. yes, bantime -1 will block it forever.
January 31, 20224 yr Author On 1/27/2022 at 8:57 PM, 062bel313 said: With configuration like yours: jail Same issue. I was wondering. Did you resolve this issue? If you do can you post the solution here. Thank you.
February 1, 20224 yr On 1/30/2022 at 7:19 PM, Built2Succeed said: I was wondering. Did you resolve this issue? If you do can you post the solution here. Thank you. Nope couldn’t figure out why it was not blocking though i have all the ip blocked in the iptables. Decided to not use it after lots of tries and frustration.
February 2, 20224 yr Author Sorry to hear. It took me many hours of jiggering. My setup is with cloudflare using argo tunnel, that way I don't have to mess with port forwarding on my router. If you are using unRAID and port forwarding on your router then your solution will be different than mine. I found this article that might be of interest to you. https://docs.docker.com/network/iptables/ Hope that helps you figure it out.
February 18, 20224 yr I would like to thank you for your hard work. This is a fantastic option to help secure self-hosted services. Could you expand your instructions? Example, I run Valtwarden as well. As you mentioned it does not log to file. I cant figure out how to add the required unraid docker environmental variable. How do I clone your valtwarden jail.d and filter.d example for other hosts? NPM keeps all logs as numbers relating to proxy hosts can I use these logs or do I have to add path to individual dockers logs? Can the same regex be used for all all jails? I admit, I don't understand regex at all. I did see a different filter.d example (listed below). Do I need both? Are ports required as everything is HTTPS? Thanks in advance. [INCLUDES] [Definition] failregex = ^<HOST>.+" (4\d\d|3\d\d) (\d\d\d|\d) .+$ ^.+ 4\d\d \d\d\d - .+ \[Client <HOST>\] \[Length .+\] ".+" .+$
March 20, 20224 yr Author NPM does keep log files as you mentiond. I added a path to my vaultwarden log that i created. You need to add a path to your vaultwarden logfile. The regex is specially formatted for the logfile format that vaultwarden uses. So each regex may be slightly different depending on the format of the specific logfile. For more information/documentation on the formatting of the regex file see https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters Keep in mind how fail2ban works. Basically three things are going on. 1. Jail - this declares each jail 2. Filter - the detection, this detects break-in attempts by matching patterns within your logfile 3. Action- this, as the name implies, tells fail2ban what actions to take when the filter criteria are met If you go here https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters and look under 'General Settings' you will find a more expansive explanation.
April 13, 20224 yr I'm having the same issue as mentioned here above. This install of fail2ban does not seem to work. Ok So I have 2 instances of fail2ban. One is this docker here, the other is the swag docker. I have done identical jails and setups in both dockers. Here I have banned myself in the jellyfin docker. Take a look at what happens when I run the command iptables -nvL in both containers It says Reject on both, but it looks slightly different on the left in Swags, have a return line. I must note that swag is also running my reverse proxy, where as this standalone fail2ban container is not. I do however have both containers running on my same custom network "proxynet". Swags fail2ban works but for some reason this standalone fail2ban does not. Edited April 13, 20224 yr by 007craft
April 24, 20224 yr I am sure I must be missing something, but so far I have set up according to your instructions and f2b is reporting that my test ip gets banned. I can however still access the site. Looking a bit further I can see that f2b docker host is banning the IP within the f2b container, and not in the Unraid iptables. Wouldn't this indicate that the ip never would get blocked, as the actual traffic does not hit the f2b container? Or - as a I'm sure - I've missed something crucial. Edited April 24, 20224 yr by Ulf Thomas Johansen
April 24, 20224 yr 2 minutes ago, Ulf Thomas Johansen said: I am sure I must be missing something, but so far I have set up according to your instructions and f2b is reporting that my test ip gets banned. I can however still access the site. Looking a bit further I can see that f2b docker host is banning the IP within the f2b container, and not in the Unraid iptables. Wouldn't this indicate that the ip never would get blocked, as the actual traffic does not hit the f2b container? Or - as a I'm sure - I've missed something crucial. This fact never stop amazing me: Literarily 15 seconds after posting this, a thought hit me and I went into the container template and changed from bridge to host! Eureka! How come the answer seem to arrive just after "you've given up".
April 24, 20224 yr Spoke too soon it seems. Fail2ban are correctly banning IPs, but doing so within the container, and not on Unraid. Advice?
April 24, 20224 yr I can do everything except mod the IP tables to prevent access. The filter identifies the failed access attempt and put in the jail but now action is taken. The action example on docker website doesn't seem to jive with the jail example. I'm very green. I'll revisit in a few weeks. EDIT: Figured it out. I had to load the container as HOST and made sure the banaction line in the jail.d match action.d conf file name. Edited April 24, 20224 yr by VideoVibrations optimism
June 12, 20224 yr Quick question.... Does anybody know how i can get email notifications working on a ban action? Got everything working except for the notification through email... Anyone have some directions to set it up...?
June 13, 20224 yr Author On 4/13/2022 at 2:32 AM, 007craft said: I'm having the same issue as mentioned here above. This install of fail2ban does not seem to work. Ok So I have 2 instances of fail2ban. One is this docker here, the other is the swag docker. I have done identical jails and setups in both dockers. Here I have banned myself in the jellyfin docker. Take a look at what happens when I run the command iptables -nvL in both containers It says Reject on both, but it looks slightly different on the left in Swags, have a return line. I must note that swag is also running my reverse proxy, where as this standalone fail2ban container is not. I do however have both containers running on my same custom network "proxynet". Swags fail2ban works but for some reason this standalone fail2ban does not. Exactly right. This fail2ban does not work with NPM to ban. Instead it sets firewall rules directly on cloudflare
June 13, 20224 yr Author 22 hours ago, Dantheman said: Quick question.... Does anybody know how i can get email notifications working on a ban action? Got everything working except for the notification through email... Anyone have some directions to set it up...? Not sure because I haven't set that up myself. As you may know, some emails use app passwords for security reasons. (gmail for instance). Hope that helps
June 16, 20224 yr Thanks for the answer. I will investigate how email notifications works. If I know more and got it working i'll leave a note here on how i did it.
July 8, 20224 yr Hello, i am trying to understand how to configure SSMTP_HOST with this container. I tried adding "--environment=SSMTP_HOST=blabla.com" as an extra parameter when starting the container but it says unknown parameter. But watching this video, you can see the enviorment parameter, as well as the net_admin, net_raw which are included extra parameters with this container: Since --cap_add=net_admin is a parameter, i asumed that --enviroment would also be but it isn't so how exactly do you configure the ssmtp stuff with this container?
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.