Greylisting
2004-03-14
2 minutes read

Some friends of mine were running about and saying nice things about greylisting, so I decided to try it and see how it works out. I actually have a full in-exim-implementation now. It would have been cool if exim had some sort of db4 write support or something, but I’ve gone with postgresql instead. The implementation in exim is as follows:

In the main part, I have

 GRAYLIST_TEST = SELECT CASE \
                  WHEN now() - block_expires > 0 THEN 2 \
                  ELSE 1 \
                 END \
                 FROM relaytofrom \
                 WHERE relay_ip='${quote_pgsql:$sender_host_address}' \
                 AND from_domain='${quote_pgsql:$sender_address_domain}'

 GRAYLIST_ADD  = INSERT INTO relaytofrom (relay_ip, from_domain) \
                 VALUES ( '${quote_mysql:$sender_host_address}', \
                 '${quote_mysql:$sender_address_domain}')

 hide pgsql_servers = localhost/greylisting/exim/password

Then, in the DATA acl, I have

  warn    set acl_m7 = ${lookup pgsql{GRAYLIST_TEST}{$value}{0}}

  defer   message = Greylisted - please try again a little later
          condition      = ${if eq{$acl_m7}{0}{1}}
          condition      = ${lookup pgsql{GRAYLIST_ADD}{yes}{no}}
  defer   condition      = ${if eq{$acl_m7}{1}{1}}

Why the data part, you may ask. The reason is quite simple, I don’t want to break callouts at all. Also, this server is on 100MBit so I don’t care about any wasted bandwidth.

The table definition is fairly simple:

create table relaytofrom
(
        id              serial,
        relay_ip        inet,
        from_domain     varchar(255),
        block_expires   timestamp default now()+(interval ‘60 seconds’)
                        NOT NULL,
        record_expires  timestamp default now()+(interval ‘1 week’)
                        NOT NULL,
        origin_type     varchar(16) DEFAULT ‘AUTO’
                        CHECK (origin_type in (‘MANUAL’,‘AUTO’)) NOT NULL,
        create_time     timestamp        default now() NOT NULL
);

Hope this helps somebody to get a little less spam.

Back to posts