Custom Filter for Exim Through Fail2ban

Description

I have noticed a lot of unsolicited smtp traffic on my box and I have started taking anti-spam measures to remove unauthorized usage of mail on my server. I use exim to transport and route mail. Exim is great and there are a lot of custom tweaks that can be done with Exim’s ACLs to prevent spam. However I feel there is even another step that can be taken to prevent the waste of precious cpu resources to fight spam. I love iptables and an extension to iptables – fail2ban.

Procudure

  1. Install and use exim and fail2ban
  2. Edit /etc/fail2ban/jail.conf and add the following section:
    [exim]
    enabled = true
    filter  = exim
    port    = smtp,ssmtp
    action  = iptables-allports[name=exim, protocol=tcp]
    #action   = iptables[name=exim, port="smtp", protocol=tcp]
    logpath = /var/log/exim/reject.log
    maxretry = 1
    
  3. Edit /etc/fail2ban/filter.d/exim.conf
    # Fail2Ban configuration file
    #
    # Author: Derek Carr
    
    [Definition]
    failregex = .*[<HOST>].*[192.168.0.196].*(?:rejected by local_scan|Unrouteable (address|user)|rejected RCPT.*(callout verification failure|response.*Unknown user|relay not permitted|)|Host is listed in*|See RFC821)
    
    ignoreregex = 
    

    NOTE: This filter is based off of python’s regex library and I am filtering this based of how my exim.conf sends denied requests to the log file. A great way to test either my configuration or custom regular expressions you use to match your reject.log is the following:

    fail2ban-regex /var/log/exim/reject.log ".*[<HOST>].*[192.168.0.196].*(?:rejected by local_scan|Unrouteable (address|user)|rejected RCPT.*(callout verification failure|response.*Unknown user|relay not permitted|)|Host is listed in*|See RFC821)"
    

    192.168.0.196 is my local mail relay, you might want to include your LAN ip address of your box. This really depends on how the rejected addresses look like inside your exim/reject.log

  4. Restart fail2ban
    /etc/init.d/fail2ban restart
    

Conclusion

The great thing about this configuration is exim is blocking spam emails based off access control lists, checking against spamhaus and other blacklist providers, and etc, but we can save our computer the cpu cycles needed to check through all of exim’s configuration every time. Instead we take the list of repeat offenders and block them inside iptables using fail2ban. This way the next time they try to connect to the computer they are blocked before they even make it to exim. To view currently blocked IP’s trying to use your mail server just use the following:

# To view the currently blocked IP's
iptables -nL | grep -A100000 'Chain fail2ban-exim'
# To count how many accounts are banned currently
iptables -nL | grep -A100000 'Chain fail2ban-exim' | wc -l

8 Responses

Subscribe to comments with RSS.

  • Daniel Black says:

    Can you please provide some sample logs (via a pull request) to http://github.com/fail2ban/fail2ban. We at fail2ban would really like users to have this sort of protection by default?

    • zaphinath says:

      I would love to give some sample logs, however one thing to note is the output of exim logs is very tailored to how you have your exim.conf setup. The regular expression that I was using is to help filter a bunch of custom mail responses that I set up with exim, which is far from the default configuration. I eventually just started using spamhaus and spamcop to filter the ip address requesting the box rather than building my own list and maintaining it.


      begin acl
      deny
      message = Host is listed in $dnslist_domain.
      dnslists =
      zen.spamhaus.org :
      virbl.dnsbl.bit.nl :
      bl.spamcop.net :
      sbl-xbl.spamhaus.org :
      cbl.abuseat.org :

      • Daniel Black says:

        hey, appreciate that ‘Host listed in’ is a very custom message.

        The currently upstream filter and test logs look like the following respectively

        https://github.com/grooverdan/fail2ban/blob/25c3bbfc2fead08c54891f293f5522d61199a62e/config/filter.d/exim.conf

        https://github.com/grooverdan/fail2ban/blob/25c3bbfc2fead08c54891f293f5522d61199a62e/testcases/files/logs/exim

        Is my ‘rejected found in dnsrbl ‘ regex too custom?

        I’d still like logs for the following if they aren’t too custom:

        Unrouteable user
        callout verification failure
        Unknown user
        relay not permitted
        See RFC821

        I much appreciate all input provided. Thanks.

        • zaphinath says:

          Here is the example I have for relay not permitted.

          #2012-09-27 09:44:40 [12118] H=(67.199.177.70) [77.123.53.122]:1512 I=[192.168.0.196]:25 F=<050296@msa.hinet.net> rejected RCPT : relay not permitted
          failregex = (.*)[].*(?:relay not permitted)

          I don’t really have to many other logs for any of the others because I stopped filtering with fail2ban for everything a while ago because it is easier to check publicly available blacklists and stop them there so the illegal user doesn’t even have to try authenticating and fail before they are locked out from using email.

          As far as testing the regex for your custom exim outputs – I always used the command fail2ban-regex which will allow you to troubleshoot some log file output and see if you are actually pulling the right IP address from the logs.

          • Daniel Black says:

            thanks for the feedback. We have a “relay not permitted” block now.

            With contributions back the fail2ban of next release will look something like this

            We’re still contemplating whether rbl fails show be a block criteria.

  • Justin says:

    I noticed there is no, bantime set in the Jail Options, is there a default bantime?