fail2ban skip missing logs

Discussion in 'Installation/Configuration' started by olimortimer, Nov 26, 2014.

  1. olimortimer

    olimortimer Member

    I've created a rule so fail2ban catches incorrect WordPress login attempts, and subsequently bans the IP;

    /etc/fail2ban/filter.d/wp-auth.conf

    Code:
    # WordPress brute force auth filter: /etc/fail2ban/filter.d/wp-auth.conf:
    #
    # Block IPs trying to auth wp wordpress
    #
    # Matches e.g.
    # 94.75.208.136 - - [25/Nov/2014:17:41:07 +0000] "POST /wp-login.php HTTP/1.0" 302 381 "-" "-"
    #
    [Definition]
    failregex = ^<HOST> .* "POST /wp-login.php
    ignoreregex =

    /etc/fail2ban/jail.conf

    Code:
    [wp-auth]
    enabled = true
    filter = wp-auth
    action = iptables-multiport[name=NoAuthFailures, port="http,https"]
    logpath = /var/www/*/log/access.log
    bantime = 1800
    maxretry = 8
    As you can see, I've added a wildcard into the logpath, so it looks at all site access.log files. However, certain sites are missing an access.log (ie, phpMyAdmin), so fail2ban stops searching logs with;

    Code:
    2014-11-26 11:21:06,094 fail2ban.filter : INFO   Added logfile = /var/www/domain1/log/access.log
    2014-11-26 11:21:06,095 fail2ban.filter : INFO   Added logfile = /var/www/domain2/log/access.log
    2014-11-26 11:21:06,101 fail2ban.filter : INFO   Added logfile = /var/www/domain3/log/access.log
    2014-11-26 11:21:06,102 fail2ban.comm : WARNING Invalid command: ['set', 'wp-auth', 'addlogpath', '/var/www/phpmyadminbdomain/log/access.log']
    Is there any way of setting it so fail2ban skips missing logs, rather than halting the scan?
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    The path should be:

    /var/log/ispconfig/httpd/*/access.log
     
  3. olimortimer

    olimortimer Member

    Thanks till, but still the same issue.

    It seems to be sites that aren't accessed very often, don't have an access.log;

    Code:
    drwxr-xr-x  2 web38 client9   4096 2013-12-20 00:30 .
    drwxr-xr-x 34 root  root      4096 2014-11-18 23:01 ..
    lrwxrwxrwx  1 root  root        19 2013-11-20 06:15 access.log -> 20131120-access.log
    -rw-r--r--  1 root  root    223862 2013-11-17 23:12 error.log
    -rw-r--r--  1 root  root     25719 2013-11-21 00:30 webalizer.conf
     
  4. bzuro

    bzuro New Member

    Hey man,
    did you solved this issue? I have the same problem and no elegant solutions comes to mind.
     
  5. till

    till Super Moderator Staff Member ISPConfig Developer

    Write a script that iterates trough all sites and downloads a page once a day right after midnight.
     
  6. olimortimer

    olimortimer Member

    I didn't really solve it. I kept meaning to create a cron that would 'touch' the access.log files for each site, which would then create the actual symlinked file.

    Basically it just needs a script to loop through all the sites in '/var/log/ispconfig/httpd/'...

    Code:
    touch /var/log/ispconfig/httpd/site1.com/access.log
    touch /var/log/ispconfig/httpd/site2.com/access.log
    touch /var/log/ispconfig/httpd/site3.com/access.log
    
     
  7. bzuro

    bzuro New Member

    thanks guys for the direction.
     
  8. olimortimer

    olimortimer Member

    Will be interested to see what solution you come up with.

    @till is it possible to change the logrotate to create / touch the file on rotation?
     
  9. till

    till Super Moderator Staff Member ISPConfig Developer

    There is no logrotate job running. The file gets createdy by the script that wites the log files, so if there is no access to the website, no new file gets created.
     
  10. olimortimer

    olimortimer Member

    Ok, I haven't looked into it too much.

    What rotates the logs then? Is it Apache itself? Or an ISPConfig script?
     
  11. bzuro

    bzuro New Member

  12. olimortimer

    olimortimer Member

    Something like this should do the job, and make sure the access.log symlink files are created;

    Code:
    for site in /var/log/ispconfig/httpd/*;
    do
            [ -d $f ] && touch "$site"/access.log && echo Touched $site/access.log
    done;
    The logs rotate at 00:30, so running the above at a minute or so after that should be good.
     
  13. bzuro

    bzuro New Member

    @olimortimer your touching solution is probably the easiest. till's wgetting all the sites would not work for me, because some webistes/clients have expired/misconfigured domains.
     
  14. bzuro

    bzuro New Member

    also what bothers me a little is that we are feeding all logs to fail2ban, but what we need is only the WP logs.

    solution would be creating parallel log structure symlinking only WP sites. itterate through websites and if it has wp-admin or something in the webroot, create a symlink to logs from somewhere.
     
  15. bzuro

    bzuro New Member

    @olimortimer I may have mislead you with logrotate. I think ISPconfig rotates the logs. see /usr/local/ispconfig/server/cron_daily.php
     
  16. olimortimer

    olimortimer Member

    You can get a fail2ban plugin for WP, so it only logs what fail2ban needs to see. However, most of the WP installs on my server are client sites, so I don't want to require them to have a plugin installed etc. Grabbing all the logs allows me to keep a tight control on access attempts.

    Note if you're using Cloudflare, you will need to use mod_cloudflare to log the real visitor IP to access.log, then send the IP to the Cloudflare API to block / unblock the IP on your Cloudflare account.

    /etc/fail2ban/jail.local
    Code:
    [wp-auth]
    enabled = true
    filter = wp-auth
    action = iptables-multiport[name=wp-auth, port="http,https"]
             cloudflare-api
    logpath = /var/log/ispconfig/httpd/*/access.log
    maxretry = 3
    /etc/fail2ban/filter.d/wp-auth.conf
    Code:
    [Definition]
    failregex = ^<HOST> .* "POST /wp-login.php
    ignoreregex =
    /etc/fail2ban/action.d/cloudflare-api.local
    Code:
    [Definition]
    actionban = curl https://www.cloudflare.com/api_json.html -d 'a=ban' -d 'tkn=YOURTOKEN' -d 'email=YOUREMAIL' -d 'key=<ip>'
    actionunban = curl https://www.cloudflare.com/api_json.html -d 'a=nul' -d 'tkn=YOURTOKEN' -d 'email=YOUREMAIL' -d 'key=<ip>'
     
  17. bzuro

    bzuro New Member

    @olimortimer thanks for that info. for now I will just use your solution with touching the access.log
     
    Last edited: Feb 17, 2015

Share This Page