OpenSMTPD

Since setting up TLS worked so smoothly, the next order of business was finally setting up SMTP. Most of the configuration guidance was inspired by the excellent guide at technoquarter. But as usual, documentation beats internet tutorial - a couple of things are different in 6.3 (stable at the time of this writing) and for that particular setup, e.g. we will be using the TLS setup from the previous post.

Basic Setup

Enable OpenSMTPD

Make sure to use key and cert created in the previous post.

Sample /etc/mail/smtp.conf

pki mail.example.com certificate "/etc/ssl/example.com.crt"
pki mail.example.com key "/etc/ssl/private/example.com.key"

table aliases  file:/etc/mail/aliases
table vusers   file:/etc/mail/vusers
table vdomains file:/etc/mail/vdomains

listen on lo0
listen on egress tls pki mail.example.com auth-optional
listen on egress port submission tls-require pki mail.example.com auth

accept for local alias <aliases> deliver to mbox
accept from any for domain <vdomains> virtual <vusers> deliver to mbox
accept from local for any relay

Virtual users and domains are handled in /etc/mail/vusers

# sample vusers
# external           local
john.doe@example.com jdoe
@example.com         jdoe

and /etc/mail/vdomains respectively

# sample vdomains
example.com

Now enable forwarding of smtp-related traffic in /etc.pf.conf:

# accept SMTP
pass in on $ext_if proto tcp to any port smtp
pass in on $ext_if proto tcp from any to $ext_if port submission

At this point, you should be able to send and receive local mail, e.g. using mutt. Until we're looking at IMAP, mbox will do just fine.

Spam Filtering

For spamd(8), the above guide is not very verbose, so rely on the man pages instead! Start by adding spamd to /etc/rc.conf.local

spamd_flags="-v -G 2:4:864 -K /etc/ssl/private/example.com.key -C /etc/ssl/example.com.crt"

since the main configuration of spamd is done via flags, this was a bit tougher to tweak to my needs. The defaults are rather harsh, especially the timeouts. The above values are inspired by frozen geek. The pflog interface mentioned in the post is skipped. I'm not 100% convinced about the performance of spamd vs. the annoyance of greylisting. I might go with the recommendation of C-Keen and turn it off and rely on spampd + spamassassin - or I give the nifty bgp-spamd a try.

and enable spamd forwarding in pf.conf, there's an excellent example in /etc/examples.pf.conf.

# accept SMTP
pass in on $ext_if proto tcp from any to $ext_if port submission
# rules for spamd(8)
table <spamd-white> persist
table <nospamd> persist file "/etc/mail/nospamd"
pass in on $ext_if inet proto tcp from any to any port smtp \
    divert-to 127.0.0.1 port spamd
pass in on $ext_if proto tcp from <nospamd> to any port smtp
pass in log on $ext_if proto tcp from <spamd-white> to any port smtp
pass out log on $ext_if proto tcp to any port smtp

After that, you can try sending mails and checking the respective logs. If you speak a little SMTP, go ahead and telnet into your new setup, but be patient.

[hfi@nexus:~] telnet mail.example.com 25
Trying xx.xx.xx.xxx...
Connected to mail.example.com.
Escape character is '^]'.
220 mail.example.com ESMTP spamd IP-based SPAM blocker; Tue Jul  3 20:53:31 2018
EHLO foo.example.org
250 Hello, spam sender. Pleased to be wasting your time.
MAIL FROM <eve@example.org>
250 You are about to try to deliver spam. Your time will be spent, for nothing.
RCPT TO: <eve@example.org>
250 This is hurting you more than it is hurting me.

Not only does the above telnet session stutter significantly, also the mail bounces after the first attempts. Only if the sender is properly configured and returns later, it will be whitelisted - see the spamd(8) for details on the timeouts and how to change the defaults. All senders that have been whitelisted will be forwarded to smtpd directly. There's also a manual whitelist in /etc/mail/nospamd, which might be empty but needs to exist, otherwise pfctl will refuse to load the above configuration - alternatively, remove the.