Postfix IPv6 + sqlgrey

I’m not sure if it’s necessary for greylisting in ipv6 smtp right now, seems spammer haven’t move their target on ipv6 smtp server yet.After wandering around for couple of hour with google, i’ve finally found application that’s suitable for my postfix greylisting.i’m using milter-greylist previously, but seems like postfix didn’t have {if_addr} in its milter macros and i have to apply workaround.

so i decided using sqlgrey for easiness sake 🙂

Current state

SQLgrey gained the following features since the beginning:

* SQLgrey can withstand a database crash (grey-listing is automatically switched off)
* 3 grey-listing algorithms to choose from
* Support for file-based IP and FQDN whitelists
* Support for fetching up-to-date whitelists from a repository
* Can mail the admin when the database is unavailable
* Auto-whitelists now understand SRS (SPF-aware mail forwarding)
* IPv6 support
* OPTIN / OPTOUT support
* Fine log controls
* Activity reports

The first thing is to find the package for your distribution.
i personally build sqlgrey from source tarball, you can obtain the tarball here:

http://sourceforge.net/project/showfiles.php?group_id=113566

For the installation you need some perl dependency:

perl-Net-Server
perl-Date-Calc

For sqlgrey database connector you need this perl dependency :

perl-DBD-pg or perl-DBD-MySQL
perl-IO-Multiplex

Now time to build rpm package (i’m using centos)

# rpmbuild -ta sqlgrey-1.7.6.tar.bz2
# rpm -ivh /usr/src/redhat/RPMS/sqlgrey-1.7.6-1.noarch.rpm

edit sqlgrey.conf on the db part

# vi /etc/sqlgrey/sqlgrey.conf
db_type = mysql
db_name = sqlgrey
db_host = localhost
db_port = default
db_user = sqlgrey
db_pass = yourpass (cannot contain spaces)

remember don’t start the service yet.

For db parts, we have to create db named sqlgrey, sqlgrey user and some tables.

Launch the ‘mysql’ command-line utility with admin rights.

Create a sqlgrey database:
– For MySQL < 5.0

> CREATE DATABASE sqlgrey;

– For MYSQL >= 5.0

> CREATE DATABASE sqlgrey CHARACTER SET latin1;

Then set up access rights:

> GRANT ALL ON sqlgrey.* TO sqlgrey@localhost;

Create tables on sqlgrey db.

CREATE TABLE IF NOT EXISTS `config` (
  `parameter` varchar(255) NOT NULL,
  `value` varchar(255) default NULL,
  PRIMARY KEY  (`parameter`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `config` (`parameter`, `value`) VALUES
('version', '3');

CREATE TABLE IF NOT EXISTS `connect` (
  `sender_name` varchar(64) NOT NULL,
  `sender_domain` varchar(255) NOT NULL,
  `src` varchar(39) NOT NULL,
  `rcpt` varchar(255) NOT NULL,
  `first_seen` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  KEY `connect_idx` (`src`,`sender_domain`,`sender_name`),
  KEY `connect_fseen` (`first_seen`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `domain_awl` (
  `sender_domain` varchar(255) NOT NULL,
  `src` varchar(39) NOT NULL,
  `first_seen` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `last_seen` timestamp NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`src`,`sender_domain`),
  KEY `domain_awl_lseen` (`last_seen`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `from_awl` (
  `sender_name` varchar(64) NOT NULL,
  `sender_domain` varchar(255) NOT NULL,
  `src` varchar(39) NOT NULL,
  `first_seen` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `last_seen` timestamp NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`src`,`sender_domain`,`sender_name`),
  KEY `from_awl_lseen` (`last_seen`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `optin_domain` (
  `domain` varchar(255) NOT NULL,
  PRIMARY KEY  (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `optin_email` (
  `email` varchar(255) NOT NULL,
  PRIMARY KEY  (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `optout_domain` (
  `domain` varchar(255) NOT NULL,
  PRIMARY KEY  (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `optout_email` (
  `email` varchar(255) NOT NULL,
  PRIMARY KEY  (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

if you’re done with db, you can start the service now

# chkconfig --add sqlgrey
# service sqlgrey start

or

#/etc/init.d/sqlgrey start

Done with the sqlgrey part, now we’re moving to postfix part which is trivial to be done 😀

just add oneliner like this under your smtpd restriction

smtpd_recipient_restrictions =
              ...
              reject_unauth_destination
              check_policy_service inet:127.0.0.1:2501

done

reload postfix

#postfix reload

this example obtain from maillog

Aug  7 08:19:21 fire postfix/smtpd[12252]: connect from liszt.debian.org[2001:41b8:202:deb:213:21ff:fe20:1426]
Aug  7 08:19:22 fire postfix/smtpd[12252]: setting up TLS connection from liszt.debian.org[2001:41b8:202:deb:213:21ff:fe20:1426]
Aug  7 08:19:24 fire postfix/smtpd[12252]: Anonymous TLS connection established from liszt.debian.org[2001:41b8:202:deb:213:21ff:fe20:1426]: TLSv1 with cipher ADH-AES256-SHA (256/256 bits)
Aug  7 08:19:25 fire sqlgrey: grey: new: 41b8(2001:41b8:202:deb:213:21ff:fe20:1426), bounce-debian-user=hari.h=ipv6.kutukupret.com@lists.debian.org -> hari.h@ipv6.kutukupret.com
Aug  7 08:19:25 fire postfix/smtpd[12252]: NOQUEUE: reject: RCPT from liszt.debian.org[2001:41b8:202:deb:213:21ff:fe20:1426]: 450 4.7.1 <hari.h@ipv6.kutukupret.com>: Recipient address rejected: Greylisted for 5 minutes; from=<bounce-debian-user=hari.h=ipv6.kutukupret.com@lists.debian.org>  to=<hari.h@ipv6.kutukupret.com> proto=ESMTP helo=<liszt.debian.org>

from what i’ve seen in my observation, when remote host retrying connect in properly manner, sqlgrey will automatically add remote host in its whitelist.

Aug  7 10:36:20 fire postfix/smtpd[13006]: connect from mx2.freebsd.org[2001:4f8:fff6::35]
Aug  7 10:36:22 fire sqlgrey: perf: spent 0s cleaning: from_awl (0) domain_awl (0) connect (0)
Aug  7 10:36:22 fire sqlgrey: grey: domain awl match: updating 4f8(2001:4f8:fff6::35), freebsd.org

that’s it folks 🙂

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *