Want to subscribe to topics you're interested in?
Become a Member

Security fail2ban for Centmin Mod + CSF Firewall / Cloudflare API

Discussion in 'System Administration' started by eva2000, May 12, 2017.

  1. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
  2. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    One last question:

    Code:
    [nginx-req-limit]
    enabled = true
    filter = nginx-req-limit
    action = csfdeny[name=nginx-req-limit]
    #action   = cloudflare
    logpath = /home/nginx/domains/*/log/error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
    
    
    [nginx-conn-limit]
    enabled = true
    filter = nginx-conn-limit
    action = csfdeny[name=nginx-conn-limit]
    #action   = cloudflare
    logpath = /home/nginx/domains/*/log/error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
    Isn't better to add also the other two error paths on the above?

    Code:
    /usr/local/nginx/logs/*access.log
    /var/log/nginx/*.access.log
    or they may cause any issues?
     
  3. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    And this one also:

    Code:
    [phpmyadmin-cmm]
    enabled = false
    filter = phpmyadmin-cmm
    action = csfdeny[name=phpmyadmin-cmm]
    #action = cloudflare
    logpath = /var/log/nginx/localhost_ssl.access.log
    /var/log/nginx/*.access.log
    port = http,https
    bantime = 3600
    maxretry = 5
    findtime = 60
    
    change to:

    Code:
    [phpmyadmin-cmm]
    enabled = false
    filter = phpmyadmin-cmm
    action = csfdeny[name=phpmyadmin-cmm]
    #action = cloudflare
    logpath = /var/log/nginx/*.access.log
    port = http,https
    bantime = 3600
    maxretry = 5
    findtime = 60
    
    and this one:

    Code:
    [shells]
    enabled = true
    filter = shells
    action = csfdeny[name=shells]
    #action   = cloudflare
    logpath = /home/nginx/domains/*/log/access.log
              /usr/local/nginx/logs/access.log
              /var/log/nginx/localhost_ssl.access.log
              /var/log/nginx/*.access.log
    bantime = 604800
    maxretry = 1
    findtime = 86400
    change to:

    Code:
    [shells]
    enabled = true
    filter = shells
    action = csfdeny[name=shells]
    #action   = cloudflare
    logpath = /home/nginx/domains/*/log/access.log
              /usr/local/nginx/logs/access.log
              /var/log/nginx/*.access.log
    bantime = 604800
    maxretry = 1
    findtime = 86400
    Thank you George ! :)
     
    Last edited: Sep 7, 2017
  4. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
  5. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    Great thank you :)
     
  6. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    The only negative after testing it for a few days is the scenario:

    I use connections limit 20 and a user get banned ...

    Then I want to increase that limit to 30 and after doing that and after unban the user it will be banned again as the fail2ban will detect the related previous error log entry :-(

    So every time I will need to clear the related logs....

    Other than that it works great and it can help a lot !
     
  7. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
    that's how you meant to do it if the retesting is closely timed together - it should NOT be a problem if the user is outside of the findtime/maxretry parameters i.e. if jail sets a ban for 5+ hits within 600s or 10 minutes. If you retest 10+ minutes later, you shouldn't be banned. You will be banned if it's within that 10 min window.
     
  8. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    Is it possible to add some magic on your code? :)

    If i use Cloudflare and a user get banned by a detection from a log file like:
    then the Cloudflare ban will not affect him as the logs there are for access to the ip and not domain :-(

    Then if i set it to use csf it may detect it at the domains log file so it will not affect it again.

    An easy way to fix this is to duplicate the rules and for domains logs to use cloudflare and the duplicated rule will check only the log files ouside of the domains logs so it can ban at the csf ....
     
    Last edited: Sep 8, 2017
  9. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    I think it can't be automated....

    But do you think is better to just duplicate the rule in jail.conf and just point the action to Cloudflare and log to check at the domain level and then at the duplicated rule action csf and point to logs outside of domains log?

    Or is it better to duplicate also the filter like nginx-limit.conf and nginx-limit2.conf and create a second rule for that?
     
  10. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
    you mean separate copies of same fail2ban jails one for logs related to domains and one for main vhost domain ?

    not sure what you mean?
     
  11. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
    Trying to understand the issue and it's because you ran to run fail2ban on server where there are some domains using cloudflare but other site domains not using cloudflare ?

    probably easiest thing to do in fail2ban jail.local is add another separate fail2ban jail rules with different log path. But not sure you can have live working fail2ban jail rules using Cloudflare firewall if there is no Cloudflare API token setup i.e. for non-cloudflare centmin mod users.

    i.e.
    Code (Text):
    /home/nginx/domains/*/log/access.cloudflare.log
    /home/nginx/domains/*/log/error.cloudflare.log
    /var/log/nginx/*.access.cloudflare.log
    /var/log/nginx/*.error.cloudflare.log
    

    then just let end users like yourself add a second set of access_log and error_logs into site nginx vhosts where they are behind cloudflare
    Code (Text):
      access_log /home/nginx/domains/domain.com/log/access.log combined;
      error_log /home/nginx/domains/domain.com/log/error.log;
      access_log /home/nginx/domains/domain.com/log/access.cloudflare.log combined;
      error_log /home/nginx/domains/domain.com/log/error.cloudflare.log;
    


    Apparently, you can have multiple actions within a single jail rule Enabling of multiple of same action in single jail fails with "Action already exists" · Issue #1611 · fail2ban/fail2ban · GitHub but still same issue is for centmin mod users who do not use cloudflare at all and do not setup a Cloudflare API token what happens to the fail2ban action calling cloudflare firewall ?

    edit: ideally you would want separate servers for cloudflare using domains and another server for non-cloudflare domains anyway as you don't want non-cloudflare using domains to compromise the security and privacy of the server ip of cloudflare using domains anyway :)
     
    Last edited: Sep 8, 2017
  12. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    Let me explain a practical scenario :)

    Logs for domain:
    Code:
    /home/nginx/domains/mydomain.com/log/error.log
    /usr/local/nginx/logs/error.log
    So the above have user entries using the domain like:
    Logs for the server ip:
    Code:
    /var/log/nginx/localhost.error.log
    So the above have user entries using the server ip:

    Now let's say that we have:
    Code:
    [nginx-req-limit-main]
    enabled = true
    filter = nginx-req-limit
    #action = csfdeny[name=nginx-req-limit-main]
    action   = cloudflare
    logpath = /usr/local/nginx/logs/error.log
              /var/log/nginx/*.error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
    So if i use Cloudflare and that rule find a user that must be ban at:
    Code:
    /usr/local/nginx/logs/error.log
    Then great the user will not be able to browse again the site and that's how it should be :)

    But if a user found that must be ban at:
    Code:
    /var/log/nginx/*.error.log
    (accessing the ip of the server or try to hit there)

    then the ban at Cloudflare will not affect him and he will be able to continue accessing directly the server ip :(
     
  13. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    A simple solution is to duplicate the rule like (if it's allowed):

    Code:
    [nginx-req-limit-main]
    enabled = true
    filter = nginx-req-limit
    #action = csfdeny[name=nginx-req-limit-main]
    action   = cloudflare
    logpath = /home/nginx/domains/*/log/error.log
                   /usr/local/nginx/logs/error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
    and

    Code:
    [nginx-req-limit-main]
    enabled = true
    filter = nginx-req-limit
    action = csfdeny[name=nginx-req-limit-main]
    #action   = cloudflare
    logpath = /var/log/nginx/*.error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
    Don't know if that's ok or best way to do it.....but with the above if a user use the domain to hit it will get banned on the Cloudflare and if he use the ip it will be banned to the csf !

    Or just create two filters and two rules with one to scan the error log file with ip's and use csf as action and the other to scan the error log file with domain entries and use the Cloudflare action method...

    or am i missing something? :)

    What do you think George?
     
    Last edited: Sep 8, 2017
  14. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
    FYI, you can disable this log it isn't needed from /usr/local/nginx/conf/nginx.conf
    Code (Text):
    #access_log  logs/access.log combined buffer=128k flush=5m;
    #error_log   logs/error.log warn;
    

    don't recall why it was there heh.

    unfortunately duplicating jails would only work if end user sets cloudflare api key token, but fail2ban.sh installer wouldn't know if end user intends to use cloduflare api firewall or not. So really it is only a solution for end users to manually set up themselves

    jail [nginx-req-limit-main] is meant only for main hostname while [nginx-req-limit] is meant for vhost domains
    Code (Text):
    [nginx-req-limit-main]
    enabled = true
    filter = nginx-req-limit
    action = csfdeny[name=nginx-req-limit-main]
    #action   = cloudflare
    logpath = /usr/local/nginx/logs/error.log
              /var/log/nginx/*.error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
    
    [nginx-req-limit]
    enabled = true
    filter = nginx-req-limit
    action = csfdeny[name=nginx-req-limit]
    #action   = cloudflare
    logpath = /home/nginx/domains/*/log/error.log
    findtime = 600
    bantime = 7200
    maxretry = 5
     
  15. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    Ok so we have domains logs at:

    and the logs for direct ip connections at:

    ?

    What I try to figure is which log has attacks to domain so I can set action to Cloudflare and which log has attacks to ip so I can set action to csf ....

    Thank you
     
  16. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    I thought that was for logs from:
    or not?

    As that's a place someone can attack....?

    If not then please remove all related entries from jail.local :)

    Thank you
     
    Last edited: Sep 8, 2017
  17. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
  18. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    The perfect scenario for fail2ban will be:

    One place for log files for domains logs and that is ok now !(ban to Cloudflare)

    One place for logs for direct access to ip.(ban to csf)

    One place for logs for hostname access.(ban to Cloudflare)

    Thank you :)
     
  19. pamamolf

    pamamolf Premium Member Premium Member

    3,808
    369
    83
    May 31, 2014
    Ratings:
    +711
    Local Time:
    2:22 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    Does your like means that you can do that adjustment? :)
     
  20. eva2000

    eva2000 Administrator Staff Member

    44,453
    10,154
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +15,712
    Local Time:
    9:22 PM
    Nginx 1.17.x
    MariaDB 5.5/10.x
    for that

    for that you already have it for rate limits already if you set -main jail to csf and non-main jail to cloudflare

    for others you'd have to create separate jails yourself as having live jails using cloudflare when no cloudflare api key is set isn't ideal as you'd grow the fail2ban error logs and cause duplicate scanning of logs for users who do not use cloudflare = performance issues especially with large logs i.e. 4GB log having to be scanned twice once for csf jail + one for cloudflare jail when users aren't even using cloudflare.

    but i guess can add some -main only jails which also default to csf firewall action and let you change them to cloudflare if needed