Fail2Ban with sendEmail Python MTA and SMTP

The servers I administer are on Amazon cloud, and there are often problems with outgoing emails and sendmail, so for a quick fix to add outgoing email support to scripts, I’m okay with using sendEmail, a small Python SMTP email client for use with Bash and Python scripts.

Here’s a very simple tutorial on setting this up with Ubuntu which does the job for me.

To get this working with Fail2Ban, we need to make a couple of changes to /etc/fail2ban/jail.local, and add a new action. I did it this way:


# Comment out sendmail as the MTA, and add sendEmail
# mta = sendmail
mta = sendEmail 

# I use the 'multi-line with whois' action, so I change the action for the jail in question
action = %(action_mwl)s

A new file at /etc/fail2ban/action.d/sendEmail-whois-lines.conf


actionstart =  /usr/bin/sendEmail -f <sender> -t <dest> -s <smtp> -xu <sender> -xp <password> -u "[Fail2Ban] <servername> <name>: started" -m "The jail <name> has been started successfully.\n\nFail2Ban"

actionstop =  /usr/bin/sendEmail -f <sender> -t <dest> -s <smtp> -xu <sender> -xp <password> -u "[Fail2Ban] <servername> <name>: stopped" -m "The jail <name> has been stopped.\n\nFail2Ban"

actioncheck =

actionban =  /usr/bin/sendEmail -f <sender> -t <dest> -s <smtp> -xu <sender> -xp <password> -u "[Fail2Ban] <servername> <name>: banned <ip>" -m "The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n\nHere is more information about <ip>:\n `/usr/bin/whois <ip>`\n\n Lines containing IP:<ip> in <logpath>\n`/bin/grep '\<<ip>\>' <logpath>`\n\n\n\nFail2Ban"

actionunban =


# Amended to be the same as the SMTP user
sender =

# Added

# SMTP password for user
password = XXXXXXX

# SMTP server - use port 587 for Google rather than 25 (times out too often) or 465 (crashes sendEmail)
smtp =

# Name for this server - handy when there are lots of servers sending emails to the destemail
servername = MyServer

So, the main drawback here is the plain text password. But this is nothing that doesn’t happen with other scripts with open config files, like s3cmd. Filters with passwords in them can be “chmod 600” to improve security slightly.

Leave a comment ?


  1. Thank you for the post. This has been very useful. Working with sendmail has been a headache. Using sendEmail was so much easier.

  2. i do not have jail.local can i use only jail.conf ?
    and [apache-wp-noscript] also i do not have
    my sendEmail is working but unfortunately not through fail2ban 🙁

  3. oh I see wp is for wordpress nevermind for that

  4. The fail2ban website states that the jail.conf chould be copied as jail.local so that any changes you make are overrides to the original settings.

    If you provide more details about how sendEmail is not working, I’ll try to help.

  5. everything ok
    super 😆
    i did not put action = %(action_mwl)s in jail.local

    well thank you
    great job


  6. If fail2ban starts coming in in putty:

    Traceback (most recent call last):
    File “/usr/bin/fail2ban-client”, line 401, in
    if client.start(sys.argv):
    File “/usr/bin/fail2ban-client”, line 370, in start
    return self.__processCommand(args)
    File “/usr/bin/fail2ban-client”, line 180, in __processCommand
    ret = self.__readConfig()
    File “/usr/bin/fail2ban-client”, line 375, in __readConfig
    ret = self.__configurator.getOptions()
    File “/usr/share/fail2ban/client/”, line 65, in getOptions
    return self.__jails.getOptions(jail)
    File “/usr/share/fail2ban/client/”, line 64, in getOptions
    ret = jail.getOptions()
    File “/usr/share/fail2ban/client/”, line 70, in getOptions
    self.__opts = ConfigReader.getOptions(self, self.__name, opts)
    File “/usr/share/fail2ban/client/”, line 84, in getOptions
    v = self.get(sec, option[1])
    File “/usr/lib/python2.6/”, line 546, in get
    return self._interpolate(section, option, value, d)
    File “/usr/lib/python2.6/”, line 614, in _interpolate
    self._interpolate_some(option, L, rawval, section, vars, 1)
    File “/usr/lib/python2.6/”, line 649, in _interpolate_some
    section, map, depth + 1)
    File “/usr/lib/python2.6/”, line 646, in _interpolate_some
    option, section, rest, var)
    ConfigParser.InterpolationMissingOptionError: Bad value substitution:
    section: [apache-wp-noscript]
    option : action
    key : port
    rawval : “, protocol=”%(protocol)s]
    %(mta)s-whois-lines[name=%(__name__)s, dest=”%(destemail)s”, logpath=%(logpath)s]

    Please Help, thanks

    • It’s a bit tricky to see what might be causing this from the comment, so I’ve dropped you an email to see if I can help.

  7. Hey, I used your tutorial but for Ubuntu 11.04 x64 Server I had to use /etc/fail2ban/action.d/sendEmail-whois-lines.conf instead of /etc/jail2ban/actions.d/sendEmail-whois-lines.conf

  8. actions.d should be action.d on ubuntu server 12.04
    And, where is coming from? I looked in /etc/fail2ban/jail.local and variable there is destemail.

    • Typo on actions.d fixed.

      I’m not sure what you mean by your other question, though I have fixed a copy=paste error.

      The value for ‘destemail’ is the recipient of the reports emailed by F2B, but I don’t refer to that in my post.

  9. Thank you for the instructions! It worked well on Ubuntu 14.04. 🙂

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>