First, a warning: This code runs as root to get access to the mail server log and firewall. I know there's better ways I could have done that, but I wrote this for myself and already have spent too much time on it. I'm not particularly worried about this, but everyone has to decide for themselves what their tolerance for risk is. The following configuration variables can appear in /etc/pf-sasl-fail-blocker.conf.php (defaults shown) ------------------------------------------------------------------------------------------------------- /dev/null 2>&1'; $unblock='/usr/sbin/iptables -D INPUT -s {IP} -j DROP >/dev/null 2>&1'; The only settings you probably require are $block and $unblock, since you are using ufw. "{IP}" is the placeholder for an IP address. Substitute suitable ufw commands to block and unblock. I am blocking these bots from any access to my server, you may wish to use a command that only blocks the mail server ports. Each log line is checked for both "traditional" timestamps and the newer ISO 8601 timestamps, thus the two regexes. It is intended to continue working in the event a system is switched from traditional to ISO timestamps while it is running. Blocked IPs are stored in a blocklist so the blocking persists across both system reboots and program shutdowns. Upon startup, pf-sasl-fail-blocker reads the blocklist and unblocks and re-blocks every IP that is still eligible to be blocked, this is to avoid both duplicate blocks and blocks remaining past the expiration of the defined TTL. Because of this, startup can take a few minutes when there are thousands of IPs that were blocked. Also upon startup, pf-sasl-fail-blocker reads the entire mail.log file, so that it can block things that happened while it was not running that are still eligible for blocking. The timestamp recorded is the one from the line of the mail logfile when the failed attempt took place. pf-sasl-fail-blocker --help --------------------------- pf-sasl-fail-blocker v. 1.2.0 Blocks or unblocks IP addresses given on command-line, or in --run and --daemonize modes, monitors the mail server logfile to block bots trying to guess SASL passwords. Config file is /etc/pf-sasl-fail-blocker.php.conf Usage: pf-sasl-fail-blocker [options] [IP IP ...] Options: [-h|--help] (show this help, exit) [-v|--version] (show version number, exit) [-r|--run] (runs pf-sasl-fail-blocker in monitor mode in foreground, use with systemd) [-D|--daemonize] (runs pf-sasl-fail-blocker in monitor mode as a daemon) [-R|--restart] (restarts already running pf-sasl-fail-blocker) [-S|--stop] (shuts down already running pf-sasl-fail-blocker) [-s|--show] (shows blocklist with human-readable timestamps, exit) [-u|--unblock IP IP ...] (unblocks specified IPs previously blocked by pf-sasl-fail-blocker, exit) [-U|--unblockall] (unblocks all IPs blocked by pf-sasl-fail-blocker, exit) [-t|--stats] (shows the pf-sasl-fail-blocker TTL and number of IPs blocked, exit) [-e|--expire] (unblock records whose TTL has expired, exit)