graymilter is an excellent (and very simple) tool to implement Greylisting. But what if you want to have whitelists not based on IP lists, but on DNS instead? Say to allow all .amazon.com machines to connect to your mail server without having to know the IP addresses range of Amazon’s outgoing mail servers?
A first attempt using tcp_wrappers:
Here comes my patch on graymilter.c (version 1.23):
Tue Jun 14 16:54 [146] > diff graymilter.c graymilter.c-
76d75
< #include <tcpd.h>
543d541
< struct request_info req;
582,593d579
<
< /*
< * Check if the hostname is allowed in /etc/hosts.allow.
< * Note 1: We are searching only for ALLOW entries. DENY entries
< * are ignored
< * Note 2: The servicename in /etc/hosts.allow is graymilter
< */
< request_init(&req, RQ_DAEMON, "graymilter", RQ_CLIENT_NAME, connhost, 0);
< fromhost(&req);
< if (hosts_access(&req)) {
< syslog( LOG_INFO, "%s is whitelisted by /etc/hosts.allow - accepting",
< connhost );
< return SMFIS_ACCEPT;
< }
Please remember to add -lwrap at LDFLAGS in your Makefile.
Use this hack with great care. An enty like:
graymilter: .gr : ALLOW
in /etc/hosts.allow would mean that any host in the .gr domain name space is whitelisted. This includes DSL and dialup customers of all the Greek ISPs! This is definately not what you wanted whitelisted.
Drawback of this patch: On a mail server with hundred of messages per hour (the patched) graymilter crashes because it opens far too many times /etc/hosts.allow for reading. Part 2 of this post will deal with a solution to this problem.
(part 2)