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 is localhost.
  • port โ€” is the port the server should listen for queries. Default is 5525.
  • sync_listen โ€” is the address to listen for communication with the peer. It defaults to the host setting.
  • 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 is 5524.
  • status_host โ€” is the address grossd(8) listens for status queries. Default is localhost.
  • status_port โ€” is the port number grossd(8) listens for status queries. Default is 5522.
  • protocol โ€” activates the server protocols grossd(8) will support. Valid settings are sjsms, postfix and milter.
  • milter_listen โ€” is the socket address for the Milter service. The format is proto: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 be 2^filter_bits. Lowering this value will increase the probability of false matches in each individual filter. Default is 24.
  • 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 is 8.
  • rotate_interval โ€” is the number of seconds between Bloom filter rotations. Let N := number_buffers and I := rotate_interval. An entry will stay in the server's memory for N - 0.5 * I seconds on average. Defaults to 3600 seconds (one hour).
  • update โ€” is the way server updates the database. Valid options are grey and always. If set to grey, which is the default, grossd(8) will update the database only if the response is STATUS_GREY. Setting it to always may reduce the impact on DNS servers.
  • grey_tuple โ€” is the greylisting tuple. Valid options are user and server. If set to user, which is the default, grossd(8) will create the tuple from the masked smtp-client-ip, sender email and recipient email. If set to server it will create the tuple from the masked smtp-client-ip, the sender email domain and helo message.
  • grey_mask โ€” is the mask for grossd(8) to use when matching the smtp-client-ip against the database. Default is 24, which makes grossd(8) to treat addresses like a.b.c.d as a.b.c.0. Setting grey_mask to 32 makes grossd(8) to require that consecutive attempts are made from the same smtp-client-ip.
  • grey_mask6 โ€” is the same as grey_mask but for IPv6 addresses. Default is 64.
  • 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 file grossd(8) writes its pid into. You can set parameter check, if you want to keep grossd(8) from starting should pidfile already exist.

๐ŸŒ€ Query constraints ๐ŸŒ€

  • grey_delay โ€” is the time in seconds new triplets are kept on the greylist. Default is 180.
  • 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 than 100 queries per second and/or have slow DNS servers. The rule of thumb is to decide how many queries you want grossd(8) to be able to handle per second, and multiply that with query_timelimit (in seconds, of course). It defaults to 100.

๐Ÿ’… Configuring server responses ๐Ÿ’…

  • block_threshold โ€” is the threshold after which grossd(8) sends a permanent error to the client. Every check that considers smtp-client-ip as suspicious returns a value (check weight). When sum of these values gets equivalent or greater than block_threshold grossd(8) sends a STATUS_BLOCK response. Default is 0 which disables this functionality.
  • block_reason โ€” is the reason given when client is too suspicious, see block_threshold. Default is โ€œBad reputationโ€.
  • grey_threshold โ€” is analogous to block_threshold, except at the threshold grossd(8) sends a STATUS_GREY response. Default is 1. If set to 0 grossd(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, see grey_threshold. Default is โ€œPlease try again later.โ€.

๐ŸŽ€ Logging options ๐ŸŽ€

  • log_method โ€” is used to choose the logging method. Currently the only implemented method is syslog, which is the default.
  • log_level โ€” sets the logging verbosity. Possible values in the order of increasing verbosity are error, warning, notice, info and debug. log_level defaults to info.
  • syslog_facility โ€” is the facility syslog sends log messages with. It defaults to mail.
  • 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 and
    • delay โ€” log processing delay statistics.

Default is none.

Setting both none and full is undefined. Bestie, don't do it. ๐Ÿ˜ญ
  • stat_interval โ€” is the number of seconds between status log entries. Default is 3600.

๐Ÿ”ฅ Configuring checks ๐Ÿ”ฅ

  • check โ€” is a multivalued option, that is, you can configure multiple checks by setting check option multiple times. Currently implemented checks are dnsbl, dnswl, rhsbl and blocker. Refer to sections describing the checks below. If you don't configure any checks grossd(8) will act as a traditional greylisting server.
  • dnsbl โ€” is a DNS domain name of the dnsbl that dnsbl check 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 that grossd(8) makes all queries as fully qualified. You may assign different weights for the dnsbls, default weight is 1. Refer to grey_threshold and block_threshold about the weights. dnsbl is a multivalued option.
  • dnswl โ€” is analogous to dnsbl. Remember that dnswl is a definitive check, that is grossd(8) waits for the check to complete before deciding how to respond. This may cause unwanted latency, although you can adjust the maximum latency by query_timelimit option. dnswl is highly recommended if you use grossd(8) as a traditional greylister. This is a multivalued option.
  • rhsbl โ€” is analogous to dnsbl, 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 if check is set to blocker.
  • blocker_port โ€” is the TCP port of the Sophos blocker service. Default is 4466.
  • blocker_weight โ€” is the weight of the blocker check. See description of grey_threshold and block_threshold regarding 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 template grossd(8) uses for a STATUS_GREY result. Default is $X4.4.3|$N%reason%, where %reason% is the template for the reason string.
  • sjsms_response_match โ€” is the mapping result template grossd(8) uses for a STATUS_MATCH result. Default is $Y.
  • sjsms_response_trust โ€” is the mapping result template grossd(8) uses for a STATUS_TRUST result. Default is $Y.
  • sjsms_response_block โ€” is the mapping result template grossd(8) uses for a STATUS_BLOCK result. Default is $N%reason%, where %reason% is the template for the reason string.

๐Ÿ“ Postfix specific options ๐Ÿ“

  • postfix_response_grey โ€” is the response template grossd(8) uses for a STATUS_GREY result. Default is action=defer_if_permit %reason%, where %reason is the template for the reason string.
  • postfix_response_block โ€” is the response template grossd(8) uses for a STATUS_BLOCK result. Default is action=reject %reason%, where %reason is 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:

  1. full path of the grosscheck.so
  2. function name to call (always grosscheck โ€” that's the name, don't fight it)
  3. first server's IP address
  4. second server's IP address
  5. UDP port for server connections
  6. SMTP client's IP address
  7. envelope sender's email address
  8. envelope recipient's email address
  9. 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 ๐Ÿ‘€


๐Ÿ’– 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