Welcome to Centmin Mod Community
Register Now

Featured Security CSF Firewall native fail2ban functionality

Discussion in 'System Administration' started by eva2000, Apr 12, 2018.

  1. rdan

    rdan Well-Known Member

    4,549
    1,090
    113
    May 25, 2014
    Ratings:
    +1,591
    Local Time:
    3:10 AM
    Mainline
    10.2
    Results nothing Sir.
     
  2. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    your own ISP ip if same as one used to install Centmin Mod, would have ISP ip whitelisted in CSF Firewall automatically too
     
  3. rdan

    rdan Well-Known Member

    4,549
    1,090
    113
    May 25, 2014
    Ratings:
    +1,591
    Local Time:
    3:10 AM
    Mainline
    10.2
    I remove it also as my ISP is dynamic :D.

    But the server IP I used to test attack was DigitalOcean droplet.
    Not whitelisted on my server also.
     
    style="display:inline-block;min-width:400px;max-width:970px;width:95%;height:90px" data-ad-client="ca-pub-6669518204467592" data-ad-slot="4024536743" data-ad-format="auto">
  4. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    I think i sorted it out for both main hostname and vhost error logs - problem wasn't getting the IP address correctly
    Code (Text):
    # /home/nginx/domains/*/log/error.log
    # https://community.centminmod.com/posts/74546/
    # Nginx connection limit rule trigger (Default: 10 errors bans for 15mins)
    if (($globlogs{CUSTOM2_LOG}{$lgfile}) and ($line =~ /.*limiting connections by zone .*, client: (\S+),(.*)/)) {
        return ("NGINX Security rule triggered from",$1,"nginx_conn_limit","10","80,443","900","0");
    }
    
    # /var/log/nginx/localhost.error.log
    # https://community.centminmod.com/posts/74546/
    # Nginx connection limit rule trigger (Default: 10 errors bans for 15mins)
    if (($globlogs{CUSTOM4_LOG}{$lgfile}) and ($line =~ /.*limiting connections by zone .*, client: (\S+),(.*)/)) {
        return ("NGINX Security rule triggered from",$1,"nginx_conn_limit_localhost","10","80,443","900","0");
    }
    


    test run checking temp banned ip = xxx.xxx.xxx.xxx
    Code (Text):
    csf -g xxx.xxx.xxx.xxx
    
    Table  Chain            num   pkts bytes target     prot opt in     out     source               destination         
    
    filter DENYIN           2        0     0 DROP       all  --  !lo    *       xxx.xxx.xxx.xxx       0.0.0.0/0
    
    filter DENYOUT          2        0     0 LOGDROPOUT  all  --  *      !lo     0.0.0.0/0            xxx.xxx.xxx.xxx
    
    IPSET: No matches found for xxx.xxx.xxx.xxx
    
    
    ip6tables:
    
    Table  Chain            num   pkts bytes target     prot opt in     out     source               destination         
    No matches found for xxx.xxx.xxx.xxx in ip6tables
    
    Temporary Blocks: IP:xxx.xxx.xxx.xxx Port: Dir:inout TTL:900 (lfd - (nginx_conn_limit_localhost) NGINX Security rule triggered from xxx.xxx.xxx.xxx (US/United States/-): 10 in the last 3600 secs)
    
     
    • Winner Winner x 2
  5. rdan

    rdan Well-Known Member

    4,549
    1,090
    113
    May 25, 2014
    Ratings:
    +1,591
    Local Time:
    3:10 AM
    Mainline
    10.2
    Thanks a lot!

    Works great now.
     
    • Like Like x 1
  6. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    Thanks for confirmation, might add it to default rules in 1st post eventually :)
     
    • Agree Agree x 2
  7. rdan

    rdan Well-Known Member

    4,549
    1,090
    113
    May 25, 2014
    Ratings:
    +1,591
    Local Time:
    3:10 AM
    Mainline
    10.2
    My regex config:
    Code (Text):
    # /home/nginx/domains/*/error.log
    # Nginx Connection Limit per IP errors (Default: 100 errors bans for 6 hours)
    if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /.*limiting connections by zone .*, client: (\S+),(.*)/)) {
        return ("Nginx Conn Limit per IP triggered from",$1,"nginx_limit_conn","100","80,443","21600","0");
    }
    


    Then I got this email notice:
    What is this Interval: 3600 seconds?

    Thanks!
     
  8. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    interval is time time it evaluates those hits, so 100 errors or hits over past 3600 seconds will ban for 6 hrs

    off top of my head, believe it's related to
    Code (Text):
    # Set the time interval to track login and other LF_ failures within (seconds),
    # i.e. LF_TRIGGER failures within the last LF_INTERVAL seconds
    LF_INTERVAL = "3600"
    

    you can verify by changing value to 3601 and restarting csf firewall
    Code (Text):
    csf -ra

    and testing
     
    • Informative Informative x 1
  9. rdan

    rdan Well-Known Member

    4,549
    1,090
    113
    May 25, 2014
    Ratings:
    +1,591
    Local Time:
    3:10 AM
    Mainline
    10.2
    1 hour is perfectly fine to me, so I leave it as is for now.
    Thanks!
     
    • Like Like x 1
  10. pamamolf

    pamamolf Premium Member Premium Member

    3,353
    318
    83
    May 31, 2014
    Ratings:
    +593
    Local Time:
    10:10 PM
    Nginx-1.17.x
    MariaDB 10.3.x
    Very good :)
     
  11. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    FYI, just updated the default template in 1st post setup instructions with the connection rate limit native CSF Firewall ban rules - default is if more than 30 entries for connection rate limit detected in nginx error log, ban for 60 mins (3600 seconds).
     
    • Winner Winner x 3
  12. fabianski

    fabianski Member

    94
    9
    8
    Feb 20, 2019
    Brazil
    Ratings:
    +28
    Local Time:
    4:10 PM
    hey, thanks.
    I checked my log files that i'm also being targeted by these scans. Especially after i installed the pma addon
     
  13. fabianski

    fabianski Member

    94
    9
    8
    Feb 20, 2019
    Brazil
    Ratings:
    +28
    Local Time:
    4:10 PM
    To enable logging of user enumeration and spam control it is necessary, in addition to installing the plugin, to add some filters in functions.php thebrandonallen/wp-fail2ban-redux


    Code:
    // Block user enumeration attempts.
    add_filter( 'wp_fail2ban_redux_block_user_enumeration', '__return_true' );
    
    // Log spammed comments.
    add_filter( 'wp_fail2ban_redux_log_spam_comments', '__return_true' );
     
    • Informative Informative x 1
  14. fabianski

    fabianski Member

    94
    9
    8
    Feb 20, 2019
    Brazil
    Ratings:
    +28
    Local Time:
    4:10 PM
    it would be great to add a regex to block bruteforce attacks in wordpress login.

    Code:
    Jul 11 12:31:54 hostname wp(domain.org)[6343]: Authentication failure for admin from 123.123.123.123
     
  15. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    is that from wp-fail2ban-redux logging ?

    would be simple cause of making a copy of the below regex for admin user
    Code (Text):
    # Wordpress fail2ban plugin https://wordpress.org/plugins/wp-fail2ban-redux/
    # (Default: 2 errors bans for 24 hours)
    if (($globlogs{SYSLOG_LOG}{$lgfile}) and ($line =~ /.*Authentication attempt for unknown user .* from (.*)\n/)) {
      return ("Wordpress unknown user from",$1,"fail2ban_unknownuser","2","80,443","86400","0");
    }
    


    i.e.
    Code (Text):
    # Wordpress fail2ban plugin https://wordpress.org/plugins/wp-fail2ban-redux/
    # (Default: 2 errors bans for 24 hours)
    if (($globlogs{SYSLOG_LOG}{$lgfile}) and ($line =~ /.*Authentication failure for admin .* from (.*)\n/)) {
      return ("Wordpress admin user from",$1,"fail2ban_adminuser","2","80,443","86400","0");
    }
    
     
  16. fabianski

    fabianski Member

    94
    9
    8
    Feb 20, 2019
    Brazil
    Ratings:
    +28
    Local Time:
    4:10 PM
    if I understood correctly, does this only work for the user "admin"?

    because here when I replace the real username with admin

    Code:
    Jul 11 12:31:54 hostname wp(domain.org)[6343]: Authentication failure for USERNAME from 123.123.123.123
    
    Jul 11 12:31:54 hostname wp(domain.org)[6343]: Authentication failure for eva from 123.123.123.123
    
     
  17. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    removing reference to admin should work for all users
    Code (Text):
    # Wordpress fail2ban plugin https://wordpress.org/plugins/wp-fail2ban-redux/
    # (Default: 2 errors bans for 24 hours)
    if (($globlogs{SYSLOG_LOG}{$lgfile}) and ($line =~ /.*Authentication failure for .* from (.*)\n/)) {
      return ("Wordpress admin user from",$1,"fail2ban_adminuser","2","80,443","86400","0");
    }
    
     
    • Winner Winner x 1
  18. fabianski

    fabianski Member

    94
    9
    8
    Feb 20, 2019
    Brazil
    Ratings:
    +28
    Local Time:
    4:10 PM
    thank you eva! you are the master!
     
  19. fabianski

    fabianski Member

    94
    9
    8
    Feb 20, 2019
    Brazil
    Ratings:
    +28
    Local Time:
    4:10 PM
    The rule for nginx 444 of the logs in /home/nginx/domains/*/log/access.log is not working correctly.

    If the file name or url has the number 444 the user who accessed it will be banned (after five times, of course)

    Example:
    The autoptimize generates the cache files with a random name with multiple numbers, so when one is generated with 444 the current rule will consider it to be an nginx error.

    Today autoptimize generated a file under these conditions, and I received several banned ips alerts in the e-mail.

    Code:
    https://domain.org/wp-content/cache/autoptimize/css/autoptimize_single_4444afe7b4ee6787f32ca4602da6f308.css
    The alerts were like these:

    Code:
    Time: Sat Jul 13 21:10:16 2019 -0300
    IP: 123.123.123.123
    Failures: 5 (nginx_444)
    Interval: 3600 seconds
    Blocked: Temporary Block for 86400 seconds [LF_CUSTOMTRIGGER]
    
    Log entries:
    
    123.123.123.123 - - [13/Jul/2019:21:05:41 -0300] "GET /wp-content/cache/autoptimize/css/autoptimize_single_4444afe7b4ee6787f32ca4602da6f308.css HTTP/2.0" 200 5860 "https://domain.org/some-thing/?v=19d3326f3137" "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
    123.123.123.123 - - [13/Jul/2019:21:05:42 -0300] "GET /wp-content/uploads/2019/05/books-mockup-lying-on-a-white-surface-a17401bcdef.png HTTP/2.0" 200 25060 "https://domain.org/wp-content/cache/autoptimize/css/autoptimize_single_4444afe7b4ee6787f32ca4602da6f308.css" "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
    123.123.123.123 - - [13/Jul/2019:21:05:42 -0300] "GET /wp-content/uploads/2019/06/fundo-de-madeira-velho-grunge-textured-escuro-a-superficie-da-textura-de-madeira-marrom-velha_7182-333.jpg HTTP/2.0" 200 21206 "https://domain.org/wp-content/cache/autoptimize/css/autoptimize_single_4444afe7b4ee6787f32ca4602da6f308.css" "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
    123.123.123.123 - - [13/Jul/2019:21:05:42 -0300] "GET /wp-content/uploads/2019/06/istockphoto-698791078-612x612.jpg HTTP/2.0" 200 16836 "https://domain.org/wp-content/cache/autoptimize/css/autoptimize_single_4444afe7b4ee6787f32ca4602da6f308.css" "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
    123.123.123.123 - - [13/Jul/2019:21:05:42 -0300] "GET /wp-content/uploads/2019/06/background-white.jpg HTTP/2.0" 200 29068 "https://domain.org/wp-content/cache/autoptimize/css/autoptimize_single_4444afe7b4ee6787f32ca4602da6f308.css" "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" 
    It also happened when there was a 444 before the url (I do not know what this 39444 means)

    Code:
    123.123.123.123 - - [13/Jul/2019:20:27:47 -0300] "GET /wp-content/themes/buddyboss-theme/assets/icons/bb-icons.woff2?47177912 HTTP/2.0" 200 39444 "https://domain.org/wp-content/cache/autoptimize/css/autoptimize_6d18e1013b9f0cf82f5d654018eef799.css" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" 
     
  20. eva2000

    eva2000 Administrator Staff Member

    40,634
    9,023
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +13,891
    Local Time:
    5:10 AM
    Nginx 1.15.x
    MariaDB 5.5/10.x
    thanks for heads up

    try changing the 444 regex from
    Code (Text):
    # /home/nginx/domains/*/log/access.log
    # Nginx 444  (Default: 5 errors bans for 24 hours)
    if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /(\S+) -.*[GET|POST|HEAD].*(444)/)) {
       return ("Nginx 444",$1,"nginx_444","5","80,443","86400","0");
    }
    
    # /var/log/nginx/localhost.access.log
    # Nginx 444  (Default: 5 errors bans for 24 hours)
    if (($globlogs{CUSTOM3_LOG}{$lgfile}) and ($line =~ /(\S+) -.*[GET|POST|HEAD].*(444)/)) {
       return ("Nginx 444",$1,"nginx_444","5","80,443","86400","0");
    }
    

    to
    Code (Text):
    # /home/nginx/domains/*/log/access.log
    # Nginx 444  (Default: 5 errors bans for 24 hours)
    if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /(\S+) -.*[GET|POST|HEAD].*( 444 )/)) {
       return ("Nginx 444",$1,"nginx_444","5","80,443","86400","0");
    }
    
    # /var/log/nginx/localhost.access.log
    # Nginx 444  (Default: 5 errors bans for 24 hours)
    if (($globlogs{CUSTOM3_LOG}{$lgfile}) and ($line =~ /(\S+) -.*[GET|POST|HEAD].*( 444 )/)) {
       return ("Nginx 444",$1,"nginx_444","5","80,443","86400","0");
    }
    

    or
    Code (Text):
    # /home/nginx/domains/*/log/access.log
    # Nginx 444  (Default: 5 errors bans for 24 hours)
    if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /(\S+) -.*[GET|POST|HEAD].*(\s444\s)/)) {
       return ("Nginx 444",$1,"nginx_444","5","80,443","86400","0");
    }
    
    # /var/log/nginx/localhost.access.log
    # Nginx 444  (Default: 5 errors bans for 24 hours)
    if (($globlogs{CUSTOM3_LOG}{$lgfile}) and ($line =~ /(\S+) -.*[GET|POST|HEAD].*(\s444\s)/)) {
       return ("Nginx 444",$1,"nginx_444","5","80,443","86400","0");
    }
    
     
    • Useful Useful x 1