Dog walker, Geeky sort…

postfix / postscreen and dns blacklist fun

I decided to stop using my hacky perl script for Postfix policyd stuff as it’s ages since I wrote any perl … and instead use postscreen the other day.

Postscreen setup – was fairly easy – there’s a load of config below.

Gotchas – spamhaus doesn’t like you if you might be sending your DNS through a public resolver (E.g. – so you need to do an =127.0.0.[1..11] to it.

It also logs quite a lot.

Current Postfix postscreen config :

postscreen_access_list = permit_mynetworks, cidr:/etc/postfix/postscreen_access.cidr
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_sites =[2..11]*2*1*1*1*1*1*1*1*1

postscreen_greet_action = enforce
postscreen_greet_wait = 5s
postscreen_greet_ttl = 2d

postscreen_blacklist_action = drop
postscreen_dnsbl_ttl = 2h

SMTP Auth whitelisting …

My server allows people to send out authenticated on port 25, but postscreen doesn’t seem to be aware of this when it runs; so such people may be blocked by their IP being in a DNS Blacklist … and therefore need explicitly whitelisting via a dovecot postlogin script (example below) which if used, requires the postscreen_access_list to change to be something like :

postscreen_access_list = permit_mynetworks

and /etc/postfix/mysql/ looks like :

user = mail_log
password = something
hosts =
dbname = mail_log
query = SELECT 'permit' FROM mail_log WHERE ip_address = '%s' UNION SELECT 'dunno' LIMIT 1 ;

The dovecot config change(s) are – in /etc/dovecot/dovecot.conf

service pop3 {
	executable = pop3 postlogin
service imap {
	executable = imap postlogin

service postlogin {
	executable = script-login /etc/dovecot/
	user = $default_internal_user
	unix_listener postlogin {

and /etc/dovecot/ looks a bit like :


if [ "x${IP}" != "x" ]; then
	if [ ! "$IP" = "" ]; then
		echo "INSERT INTO mail_log (username, ip_address) VALUES ('$USER', '$IP')" | mysql --defaults-extra-file=/etc/dovecot/mysql.cnf mail_log

exec "$@"

exit 0

The /etc/dovecot/ will need to be executable.

/etc/dovecot/mysql.cnf just looks like a normal MySQL cnf file –

user = mail_log
password = something
database = mail_log
CREATE TABLE `mail_log` (
  `username` varchar(255) NOT NULL,
  `ip_address` varchar(255) NOT NULL,
  KEY `mlip` (`ip_address`(191)),
  KEY `dt_idx` (`dt`)

and that being the SQL schema.

Ideally I suppose you’d add a cron job to prune entries in mail_log older than a set time, and probably have a unique key on username with some sort of “INSERT INTO x ON DUPLICATE … ” change to the script above.

, , ,

Leave a Reply

Your email address will not be published.