grossd(5)
๐ NAME ๐
grossd.conf โ Greylisting of Suspicious Sources daemon configuration file. Also hi bestie, this is grossd(5), the manual page for that config file, and yes we're folding the manual name in right here instead of copying the header line. (part 1 of 2, keep scrolling later ๐
)
๐ธ SYNOPSIS ๐ธ
/etc/grossd.conf
โจ DESCRIPTION โจ
grossd(8) reads configuration data from /etc/grossd.conf โ or from the file you specify with -f on the command line. An example configuration file is installed by default. You have to set some configuration options in order to get grossd(8) running in your environment. The format is literally this:
name = value [ ; param ] ...
Not all options accept parameters โ refer to the individual descriptions, bestie. The comment separator is #, and everything after it is ignored by the config file parser. Periodt.
๐ Network configuration options ๐
hostโ is the address the server should listen for queries. Default islocalhost.portโ is the port the server should listen for queries. Default is5525.sync_listenโ is the address to listen for communication with the peer. It defaults to thehostsetting.sync_peerโ is the address of the peer used when running in clustered mode.sync_portโ is the tcp port number to listen to and connect to in communication with the peer. Default is5524.status_hostโ is the addressgrossd(8)listens for status queries. Default islocalhost.status_portโ is the port numbergrossd(8)listens for status queries. Default is5522.protocolโ activates the server protocolsgrossd(8)will support. Valid settings aresjsms,postfixandmilter.milter_listenโ is the socket address for the Milter service. The format isproto:port@host. Refer to Milter documentation for the specifics.
๐ง Core server options ๐ง
You can probably leave the default values for these settings, ngl. If your daily mail flow exceeds millions of messages per day you may want to tweak query_timelimit and/or pool_maxthreads. If you run grossd(8) in a server with limited memory you may want to adjust filter_bits. Slay.
filter_bitsโ is the size of the Bloom filter. The size will be2^filter_bits. Lowering this value will increase the probability of false matches in each individual filter. Default is24.number_buffersโ is the number of Bloom filters used in the ring queue. Raising this value will cause an entry to stay in the server's memory longer. Default is8.rotate_intervalโ is the number of seconds between Bloom filter rotations. LetN := number_buffersandI := rotate_interval. An entry will stay in the server's memory forN - 0.5 * Iseconds on average. Defaults to3600seconds (one hour).updateโ is the way server updates the database. Valid options aregreyandalways. If set togrey, which is the default,grossd(8)will update the database only if the response isSTATUS_GREY. Setting it toalwaysmay reduce the impact on DNS servers.grey_tupleโ is the greylisting tuple. Valid options areuserandserver. If set touser, which is the default,grossd(8)will create the tuple from the maskedsmtp-client-ip, sender email and recipient email. If set toserverit will create the tuple from the maskedsmtp-client-ip, the sender email domain and helo message.grey_maskโ is the mask forgrossd(8)to use when matching thesmtp-client-ipagainst the database. Default is24, which makesgrossd(8)to treat addresses likea.b.c.dasa.b.c.0. Settinggrey_maskto32makesgrossd(8)to require that consecutive attempts are made from the samesmtp-client-ip.grey_mask6โ is the same asgrey_maskbut for IPv6 addresses. Default is64.statefileโ is the full path of the file that the server uses to store the state information. Default is not to have a statefile. You may want to configure a statefile especially if you do not configure replication.pidfileโ is the full path of the filegrossd(8)writes its pid into. You can set parametercheck, if you want to keepgrossd(8)from starting shouldpidfilealready exist.
๐ Query constraints ๐
grey_delayโ is the time in seconds new triplets are kept on the greylist. Default is180.query_timelimitโ is the query timeout in milliseconds. You may have to adjust this if you exceed millions of queries a day.pool_maxthreadsโ is the maximum threadcount per pool. You may have to raise the limit from the default if you get more than100queries per second and/or have slow DNS servers. The rule of thumb is to decide how many queries you wantgrossd(8)to be able to handle per second, and multiply that withquery_timelimit(in seconds, of course). It defaults to100.
๐ Configuring server responses ๐
block_thresholdโ is the threshold after whichgrossd(8)sends a permanent error to the client. Every check that considerssmtp-client-ipas suspicious returns a value (check weight). When sum of these values gets equivalent or greater thanblock_thresholdgrossd(8)sends aSTATUS_BLOCKresponse. Default is0which disables this functionality.block_reasonโ is the reason given when client is too suspicious, seeblock_threshold. Default is โBad reputationโ.grey_thresholdโ is analogous toblock_threshold, except at the thresholdgrossd(8)sends aSTATUS_GREYresponse. Default is1. If set to0grossd(8)will greylist by default. This makes it possible to combine a traditional greylister and rbl checks.grey_reasonโ is the reason given when client is suspicious enough to be greylisted, seegrey_threshold. Default is โPlease try again later.โ.
๐ Logging options ๐
log_methodโ is used to choose the logging method. Currently the only implemented method issyslog, which is the default.log_levelโ sets the logging verbosity. Possible values in the order of increasing verbosity areerror,warning,notice,infoanddebug.log_leveldefaults toinfo.syslog_facilityโ is the facility syslog sends log messages with. It defaults tomail.stat_typeโ is the name of the requested statistic. It is of multivalued type. The valid options are:fullโ log all possible statistics,noneโ no statistics logging,statusโ basic set of statistics,since_startupโ basic set since the startup anddelayโ log processing delay statistics.
Default is none.
Setting bothnoneandfullis undefined. Bestie, don't do it. ๐ญ
stat_intervalโ is the number of seconds between status log entries. Default is3600.
๐ฅ Configuring checks ๐ฅ
checkโ is a multivalued option, that is, you can configure multiple checks by settingcheckoption multiple times. Currently implemented checks arednsbl,dnswl,rhsblandblocker. Refer to sections describing the checks below. If you don't configure any checksgrossd(8)will act as a traditional greylisting server.dnsblโ is a DNS domain name of the dnsbl thatdnsblcheck will query. There are no defaults, but the default configuration file lists a few as an example. If you have any locally administered block lists then you should be aware thatgrossd(8)makes all queries as fully qualified. You may assign different weights for the dnsbls, default weight is1. Refer togrey_thresholdandblock_thresholdabout the weights.dnsblis a multivalued option.dnswlโ is analogous todnsbl. Remember thatdnswlis a definitive check, that isgrossd(8)waits for the check to complete before deciding how to respond. This may cause unwanted latency, although you can adjust the maximum latency byquery_timelimitoption.dnswlis highly recommended if you usegrossd(8)as a traditional greylister. This is a multivalued option.rhsblโ is analogous todnsbl, but the check is made with the right hand side of the sender address (the email domain) instead of the IP address. This is a multivalued option.blocker_hostโ is the host name of the Sophos blocker server. This is used only ifcheckis set toblocker.blocker_portโ is the TCP port of the Sophos blocker service. Default is4466.blocker_weightโ is the weight of the blocker check. See description ofgrey_thresholdandblock_thresholdregarding the weights.
๐ฆ Sun Java System Messaging Server specific options ๐ฆ
You may configure the responses grossd(8) sends over to grosscheck library. Iconic.
sjsms_response_greyโ is the mapping result templategrossd(8)uses for aSTATUS_GREYresult. Default is$X4.4.3|$N%reason%, where%reason%is the template for the reason string.sjsms_response_matchโ is the mapping result templategrossd(8)uses for aSTATUS_MATCHresult. Default is$Y.sjsms_response_trustโ is the mapping result templategrossd(8)uses for aSTATUS_TRUSTresult. Default is$Y.sjsms_response_blockโ is the mapping result templategrossd(8)uses for aSTATUS_BLOCKresult. Default is$N%reason%, where%reason%is the template for the reason string.
๐ Postfix specific options ๐
postfix_response_greyโ is the response templategrossd(8)uses for aSTATUS_GREYresult. Default isaction=defer_if_permit %reason%, where%reasonis the template for the reason string.postfix_response_blockโ is the response templategrossd(8)uses for aSTATUS_BLOCKresult. Default isaction=reject %reason%, where%reasonis the template for the reason string.
๐ฎ MTA CONFIGURATION ๐ฎ
Okay bestie, this is the part where we plug grossd into your actual mail server. Different MTAs, different vibes, same icon energy. Let's go ๐
๐ Sun Java System Messaging Server
So listen โ you literally have to add a mapping entry to make SJSMS go query grossd(8). That's not optional, that's the whole thing. And honestly? It's also a really good idea to exclude postmaster and abuse addresses before you go querying grossd(8), because nobody wants the abuse desk getting gross-checked, y'know? ๐
Here's the example, copy it with love:
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/lib/grosscheck.so,grosscheck,10.10.13.1,10.10.13.2,5525,$2,$=$8$_,$=$6$_,$=$4$_]
Now the mapping call parameters โ there's nine of them, and yes, you need to know every single one, so here we go:
- full path of the
grosscheck.so - function name to call (always
grosscheckโ that's the name, don't fight it) - first server's IP address
- second server's IP address
- UDP port for server connections
- SMTP client's IP address
- envelope sender's email address
- envelope recipient's email address
- HELO/EHLO string
Slay. That's the whole list. Nine little parameters living their best life ๐ซถ
๐ฆ Postfix
Good news: grossd implements the native Postfix policy delegation protocol. So you literally just point Postfix at the grossd server address in the smtpd_recipient_restrictions setting in the main configuration file. That's it. That's the move โจ
main.cf:
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
...
reject_unauth_destination
check_policy_service inet:host:port
...
For the specifics, go read the Postfix documentation at <http://www.postfix.org> โ they've got the details, we've got the vibe check ๐
๐ธ Exim
Exim can be configured to query grossd(8) via the Postfix policy delegation protocol too. Reusing the good stuff, we love to see it ๐
Main section:
GROSS_QUERY = sender=$sender_address\\n\\
recipient=$local_part@$domain\\n\\
client_address=$sender_host_address\\n\\
grossd_mode=single\\n\\n
Acl section:
# gross
warn
set acl_c0 = ${readsocket{inet:127.0.0.1:5525}{GROSS_QUERY}}
defer
message = Please try again later.
condition = ${if match {$acl_c0}{action=defer_if_permit}}
deny
message = ${if match {$acl_c0}{action=reject (.*)}{$1}\\
{Rejected by Gross.}}
condition = ${if match {$acl_c0}{action=reject}}
๐ Sendmail
Sendmail can query grossd via the milter protocol. Drop this into sendmail.mc and configure milter_listen accordingly:
INPUT_MAIL_FILTER(`Gross', `S=inet:5523@localhost, T=R:20s')
And if you're sitting there wondering "does my Sendmail even have Milter support compiled in?" โ valid question, bestie, and there's a command for that. Just run:
sendmail -bt -d0.1
That'll tell you. No cap ๐ง
๐ SEE ALSO ๐
grossd(8)- Gross project site: <https://codeberg.org/bizdelnick/gross>
- Bloom filters: <http://en.wikipedia.org/wiki/Bloom_filter>
๐ AUTHORS ๐
Eino Tuominen and Antti Siira โ absolute icons, we stan ๐
And that's the whole page, bestie โ this edition of grossd(5) is dated 2008-05-04, printed straight from the source. Go forth and configure your MTA, you're gonna eat ๐
โจ
๐ฆ where this page comes from
- alpine 3.22: gross-doc 1.0.4-r0 ยท BSD-3-Clause
- alpine 3.23: gross-doc 1.0.4-r1 ยท BSD-3-Clause
- alpine 3.24: gross-doc 1.0.4-r1 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms