gross - Greylisting of suspicious sources
Gross is a greylisting server. It is designed to be fast and resource efficient. It can be configured to perform a number of checks, and enforce greylisting only for hosts that have not passed them. Hosts that failed to pass multiple checks can be blocked immediately.
Gross can be replicated and run parallel on two servers.
It supports Postfix, Exim, Sendmail and Oracle Communications Messaging Server.
Gross was originally written by Eino Tuominen eino@utu.fi and Antti Siira antti@utu.fi
Since 2023 maintained by Dmitry Mikhirev dmitry@mikhirev.ru
Gross consists of grossd, the greylisting daemon, and a client plugin for OCMS. The server also implements Postfix policy delegation protocol and Milter protocol.
Upon receiving a request from a client, grossd first validates it. The request includes a triplet (smtp-client-ip, sender-address, recipient-address). A hash is then calculated and matched against the Bloom filter. If a match is found, server sends an OK message.
If the triplet has not been seen before, grossd then performs configured checks. Supproted checks are querying DNSBL databases for the smtp-client-ip, checking canonical hostname and matching HELO name to IP address. If something suspicious is found, grossd sends client a GREY response. If DNSBL tests are negative, an OK response is sent. Database is then updated; currently there are two updating styles: either to always update or to only update if the result was GREY.
As mentioned above, the data store is implemented with Bloom filters. A Bloom filter is a very efficient way to store data. It's a probabilistic data structure, which means that there is a possibility of error when querying the database. False positives are possible, but false negatives are not. This means that there is a possibility that grossd will falsely give an OK response when a connection should be greylisted. By sizing the bloom filters, you can control the error possibility to meet your needs. The right bloom filter size depends on the number of entries in the database, that is, the retention time versus the number of handled connections.
DNS queries are done asynchronously using c-ares library
You'll need cmake and a decent compiler, such as gcc or clang. To build manual pages, asciidoctor is needed.
In order to configure dnsbl queries, reverse DNS lookup and HELO check, you need c-ares library for asynhronous dns queries. You can download it here. To enable SPF check, you need libspf2.
Milter protocol support requres libmilter that is a part of sendmail.
You should be able to compile it for testing by just commanding:
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install
Default install location is /usr/local which can be overridden by
specifying a -DCMAKE_INSTALL_PREFIFIX=<path>
argument to cmake.
Run cmake -LH ..
or use either cmake-gui
or ccmake
to see
other options.
An example configuration is included in doc/example/grossd.conf
.
It is installed also as the default configuration in
$PREFIX/etc/grossd.conf. You may tell grossd to use another config
file via -f command line option.
Grossd query server defaults to port 5525/tcp with proto=postfix
,
port 5525/udp with proto=sjsms
and replication service
(if configured) to port 5526/tcp. Grossd listens for status queries
on port 5522/tcp.
Detailed information about each option is included within the example configuration file.
The server keeps the state information in the Bloom filter bit arrays.
By the nature of the filters you can insert elements in the filters, but
not to remove them. So we actually use several filters, and rotate them
on intervals. The actual filter is just a logical OR of those rotating
filters. number_buffers
is the number of the rotating filters, and
rotate_interval
is the interval in seconds.
The default setting in the example grossd.cnf is:
number_buffers = 8
rotate_interval = 3600
So, this will give you approximately 60 * 7.5 minutes worth of state
information. That is, any greylisted triplet will be stored for
7.5 hours on average. If you find that remote servers are taking
longer than 7.5 hours to retry their messages, then you should increase
the the number_buffers
setting accordingly. Alternatively, you could
increase the rotate_interval
, but setting this value too high isn't
recommended.
The filter_bits
setting (default is 24) defines the size of each
Bloom filter. Increasing the filter_bits
setting will reduce the
likelihood of false positives within the filter. See the
Wikipedia article for more information.
If you get this far, you can start the server. I suggest you run the server first in foreground with -d option. If you configured statefile, you have to start grossd with -C option in order to create the state file.
$ sudo -u nobody $PREFIX/sbin/grossd -C
Note: make sure that the run-time user has permissions to create and write to the statefile.
To start the grossd server, just run this.
$ sudo -u nobody $PREFIX/sbin/grossd
After starting, you can test it with $PREFIX/bin/gclient.
Gross works with Postfix's native filtering protocol.
On the other hand, SJSMS needs some mapping entry for queries. This is an example production server config:
ORIG_MAIL_ACCESS
! allow all DSNs and MDNs
TCP|*|*|*|*|*|*|tcp_local||*|* $Y$E
! allow all incoming mail to postmaster and abuse
TCP|*|*|*|*|*|*|tcp_local|*|*|postmaster@* $Y$E
TCP|*|*|*|*|*|*|tcp_local|*|*|abuse@* $Y$E
! use gross to check all triplets (client_ip,sender,recipient)
TCP|*|*|*|*|SMTP/*|*|tcp_local|*|*|* $[/usr/local/gross/lib/grosscheck.so,grosscheck,10.10.13.1,10.10.13.2,5525,$2,$=$8$_,$=$6$_,$=$4$_]
The server will always query the first server if it's available.
First, when you have only one server, you can test it like this:
TCP|*|*|*|*|SMTP/*|*|tcp_local|*|*|* $[/path/to/grosscheck.so,grosscheck,127.0.0.1,,5525,$2,$=$8$_,$=$6$_,$=$4$_]
grossd is able to query the proprietary Sophos Blocker service, which is basically a private DNSBL that is part of the Sophos PureMessage product. You can configure grossd to query your existing PureMessage system, or install it on the same server(s) as gross.
See https://codeberg.org/bizdelnick/gross/issues for bugs and known issues.
grossd logs everything through syslog. Facility is LOG_MAIL
, loglevel
defaults to INFO
. You can control logging with log_level
and
syslog_facility
configuration options.
You can enable full debugging by starting grossd with -D command line option. You may also want -d, as grossd then writes output on standard terminal instead of syslog.
gclient is a tool for manually querying the grossd server. You can install and run gclient on any server.
$ gclient PROTOCOL sender recipient ip_address [runs] [host port]
$ /usr/local/bin/gclient sjsms foo@abc.com bar@def.org 127.0.0.2 2 10.10.10.13 5525
(note that 127.0.0.2 will always be blacklisted)
Gross is published on a BSD-like license.
See https://codeberg.org/bizdelnick/gross for more information.
If you have any suggestions regarding the software or wish to take part on the development, feel free to contact the authors. We'll be happy to hear if you dare to try out the software.