So, I got a little tired of FTP and SSH brute force attempts. I know that if you have strong passwords on your system, you can safely ignore them, and on customer systems behind real firewalls, I do so. However, on my personal systems, I have 0 problem blocking people who annoy me. So I installed pfBlocker on my virtual firewall to see what I could do.

pfBlocker is a package that has blacklist functions that supersede a couple older packages. I initially installed it a replacement for CountryBlock. The first thing I did was go through my logs and see which countries were the most obnoxious. China was the first to go, followed by Southeast Asia, and Venezuela. Sorry, I don’t want you accessing my network.

That allow took care of 70% of my attempted exploits. There are, however, plenty of compromised machines in the United States of America, so I had to think of something else.

pfBlocker can generate pf tables based off of text file lists of IP addresses and networks in CIDR format. There are a few IP lists out there maintained by third parties, but they are hardly comprehensive. So I thought about automating the process.

The problem that most automatic blocking security software wants either a local firewall or direct control of a remote firewall. Neither are things I want to offer. This was a puzzle. Then, a thought occurred to me. Most of these applications can send email when they block something. Having just done some Postfix work, I hit upon a solution. I could create a custom mail transport that piped to a script. I could then use this script to append a text file with an IP address!

The problem with that? I’m really lazy. I didn’t want to create a script to parse a messages, strip off the headers, grab the content, look for an IP, and then append the file. That sounded like a lot of Perl, with other packages to install and new libraries to learn. Yuck. Then I realized that I could call the script with the recipient as a parameter. That means that I could simply send mail to, say, and it would write to the blacklist.txt file, that then would be used to feed pfBlocker.

Here are the postfix settings, and scripts. Note, you may want to restrict this domain to local recipients only ;)


#Accept mail for these domains and “relay” them to the transport

relay_domains =,

#Piping to a script requires one recipient at a time.

blacklist_destination_recipient_limit = 1


blacklist unix – n n – – pipe

flags=DRhu user=www argv=/usr/local/scripts/ ${recipient}

unblacklist unix – n n – – pipe

flags=DRhu user=www argv=/usr/local/scripts/ ${recipient}

Postfix transport (default postmap file) blacklist: unblacklist:

#!/usr/bin/env bash


echo $1 | cut -d”@” -f1 >> /usr/local/www/blacklist/blacklisted.txt

echo $date >> /usr/local/www/blacklist/.listed

echo $1 >> /usr/local/www/blacklist/.listed

exit 0

#!/usr/bin/env bash


unlist=`echo $1 | cut -d”@” -f1`

cat /usr/local/www/blacklist/blacklisted.txt | grep -v $unlist > /usr/local/www/blacklist/


echo $date >> /usr/local/www/blacklist/.unlisted

echo $unlist >> /usr/local/www/blacklist/.unlisted

mv /usr/local/www/blacklist/.tmp /usr/local/www/blacklist/blacklisted.txt

exit 0

Is it the most practical solution? Not really. Do I recommend it for most systems? No. But it was fun to use some of my Postfix knowledge for something other than standard email.