Configuring mail server on OpenBSD 6.5
This guide is mostly notes for myself rather than something readable, but it may be useful anyway. It contains an example of working configuration for OpenSMTPD, SpamPD, SpamAssassin, DKIM Proxy and Dovecot with Sieve support on OpenBSD.
Remember that you should always read manpages before copying someone elses configs. OpenBSD has excellent documentation.
Install required packages:
# pkg_add dkimproxy dovecot dovecot-pigeonhole spampd p5-Mail-SpamAssassin
Create vmail user:
# useradd -m -d /var/vmail -s /sbin/nologin vmail
Firewall
/etc/pf.conf:
# reassemble fragments
set reassemble yes
# return ICMP for dropped packets
set block-policy return
# enable logging on em0 interface
set loginterface em0
# allow all on Loopback interface
set skip on lo
# define ICMP message types to let in
icmp_types = "{ 0, 8, 3, 4, 11, 30 }"
# scrub packets of weirdness
match in all scrub (no-df random-id max-mss 1440)
# drop urpf-failed packets, add label uRPF
block in quick log from urpf-failed label uRPF
# ICMP
pass in quick inet proto icmp icmp-type $icmp_types
pass in quick inet6 proto icmp6
# allow SSH, SMTP and IMAP
pass in quick on em0 proto tcp from any to port { ssh, smtp, submission, smtps, imap, imaps }
# drop other incoming traffic
block in quick log on em0 all
# outbound traffic
pass out quick on em0 proto tcp from any to any modulate state
pass out quick on em0 proto udp from any to any keep state
pass out quick on em0 proto icmp from any to any keep state
pass out quick on em0 proto icmp6 from any to any keep state
Reload rules:
# pfctl -f /etc/pf.conf
OpenSMTPD
/etc/mail/smtpd.conf (replace ENCRYPTION_KEY
with 32 character random string, for instance use openssl rand -hex 16
):
queue compression
queue encryption ENCRYPTION_KEY
table aliases db:/etc/mail/aliases.db
table domains file:/etc/mail/domains
table users file:/etc/mail/users
table passwd file:/etc/mail/passwd
pki mail.example.org cert "/etc/ssl/mail.example.org.crt" # path to SSL certificate
pki mail.example.org key "/etc/ssl/private/mail.example.org.key" # path to private key
smtp max-message-size 100M
listen on em0 tls auth-optional <passwd> # MTA
listen on em0 smtps auth <passwd> # MSA (auth required)
listen on em0 port submission tls-require auth <passwd> # MSA (auth required)
listen on lo0
listen on lo0 port 10028 tag DKIM_OUT
listen on lo0 port 10026 tag SPAM_IN
action vusers_lmtp_deliver lmtp "/var/dovecot/lmtp" rcpt-to virtual <users>
action local_lmtp_deliver lmtp "/var/dovecot/lmtp" rcpt-to alias <aliases>
action relay_spampd relay host smtp://127.0.0.1:10025 # send to spampd
action relay_dkimproxy_out relay host smtp://127.0.0.1:10027 # send to dkimproxy_out
action "relay" relay
match \
from local \
for local \
action local_lmtp_deliver
match \
tag SPAM_IN \
for domain <domains> \
action vusers_lmtp_deliver
match \
tag SPAM_IN \
for local \
action local_lmtp_deliver
match \
tag DKIM_OUT \
for any \
action "relay"
match \
from local \
for any \
action relay_dkimproxy_out
match \
auth \
from any \
for any \
action relay_dkimproxy_out
match \
from any \
for domain <domains> \
action relay_spampd
/etc/domains:
example.org
example.com
/etc/mail/passwd (use smtpctl encrypt
to encrypt passwords):
foo@example.org:ENCRYPTED_PASSWORD
bar@example.org:ENCRYPTED_PASSWORD
nonexistent@example.org:ENCRYPTED_PASSWORD
/etc/mail/users:
# example.com mapping to example.org
abuse@example.com abuse@example.org
postmaster@example.com postmaster@example.org
webmaster@example.com webmaster@example.org
foo@example.com foo@example.org
bar@example.com bar@example.org
# example.org
abuse@example.org foo@example.org
postmaster@example.org foo@example.org
webmaster@example.org foo@example.org
@example.com nonexistent@example.org
@example.org nonexistent@example.org
# final mapping
foo@example.org vmail
bar@example.org vmail
nonexistent@example.org vmail
Append to /etc/mail/aliases if you want to receive mail for root:
root: foo@example.org
Generate /etc/mail/aliases.db
:
# makemap -t aliases -o /etc/mail/aliases.db /etc/mail/aliases
Validate config:
# smtpd -n
SpamAssassin and SpamPD
Enable and start SpamAssassin:
# rcctl enable spamassassin
# rcctl start spamassassin
Enable, set flags for and start spampd:
# rcctl enable spampd
# rcctl set spampd flags "--port=10025 --relayhost=127.0.0.1:10026 --tagall --aw --rh --maxsize=256 -pid=/var/spampd/spampd.pid"
# rcctl start spampd
Fix permissions:
# chown _spampd /var/spool/spamassassin
# chown _spampd /var/spool/spamassassin/spampd
DKIM Proxy
/etc/dkimproxy_out.conf:
# specify what address/port DKIMproxy should listen on
listen 127.0.0.1:10027
# specify what address/port DKIMproxy forwards mail to
relay 127.0.0.1:10028
# specify what domains DKIMproxy can sign for (comma-separated, no spaces)
domain example.org
# specify what signatures to add
signature dkim(c=relaxed)
signature domainkeys(c=nofws)
# specify location of the private key
keyfile /etc/mail/dkim/private.key
# specify the selector (i.e. the name of the key record put in DNS)
selector default
# control how many processes DKIMproxy uses
# - more information on these options (and others) can be found by
# running `perldoc Net::Server::PreFork'.
#min_servers 5
#min_spare_servers 2
Generate keys:
# mkdir /etc/mail/dkim
# openssl genrsa -out /etc/mail/dkim/private.key 2048
# openssl rsa -in /etc/mail/dkim/private.key -pubout -out /etc/mail/dkim/public.key
# chmod 640 /etc/mail/dkim/private.key
# chgrp _dkimproxy /etc/mail/dkim/private.key
For DNS record, you will need public key without header and footer and with all lines concatenated:
# echo $(sed '1d;$d' /etc/mail/dkim/public.key | tr -d $'\n')
(Configuration of DKIM, SPF and other DNS records is out of scope of this guide.)
Enable and start dkimproxy_out:
# rcctl enable dkimproxy_out
# rcctl start dkimproxy_out
Dovecot
/etc/dovecot/conf.d/10-mail.conf:
mail_location = maildir:/var/vmail/%d/%n/Maildir:LAYOUT=fs
/etc/dovecot/conf.d/10-ssl.conf:
ssl = required
ssl_cert = </etc/ssl/mail.example.org.crt
ssl_key = </etc/ssl/private/mail.example.org.key
/etc/dovecot/conf.d/15-lda.conf:
postmaster_address = postmaster@example.org
hostname = example.org
lda_mailbox_autocreate = yes
/etc/dovecot/conf.d/20-lmtp.conf:
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
/etc/dovecot/conf.d/10-auth.conf:
#!include auth-system.conf.ext
!include auth-passwdfile.conf.ext
/etc/dovecot/conf.d/auth-passwdfile.conf.ext:
passdb {
args = /etc/mail/passwd
driver = passwd-file
}
userdb {
args = uid=vmail gid=vmail home=/var/vmail/%d/%n
driver = static
}
To debug auth issues, edit /etc/dovecot/conf.d/10-logging.conf:
auth_verbose = yes
Append to /etc/login.conf:
dovecot:\
:openfiles-cur=2048:\
:openfiles-max=4096:\
:tc=daemon:
Rebuild database:
# cap_mkdb /etc/login.conf
Spam handling with Sieve
/etc/dovecot/conf.d/90-sieve.conf:
plugin {
sieve_before = /var/vmail/sieve/
}
Create scripts directory:
# mkdir /var/vmail/sieve
# chown vmail:vmail /var/vmail/sieve
Create script /var/vmail/sieve/junk.sieve:
require "fileinto";
if header :contains "X-Spam-Flag" "YES" {
fileinto "Junk";
stop;
}
Enable and start dovecot:
# rcctl enable dovecot
# rcctl start dovecot
Optional: autoconfiguration support for Thunderbird
Check this and this for more information.
/etc/httpd.conf:
ext_ip = "YOUR_EXTERNAL_IP"
server "default" {
listen on $ext_ip port 80
root "/default-server/htdocs"
}
server "autoconfig.example.org" {
listen on $ext_ip port 80
root "/autoconfig.example.org"
}
types {
include "/usr/share/misc/mime.types"
}
/var/www/autoconfig.example.org/mail/config-v1.1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
<emailProvider id="example.org">
<domain>example.org</domain>
<displayName>Example.org Mail</displayName>
<displayShortName>example</displayShortName>
<incomingServer type="imap">
<hostname>mail.example.org</hostname>
<port>993</port>
<socketType>SSL</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</incomingServer>
<outgoingServer type="smtp">
<hostname>mail.example.org</hostname>
<port>465</port>
<socketType>SSL</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</outgoingServer>
<outgoingServer type="smtp">
<hostname>mail.example.org</hostname>
<port>587</port>
<socketType>STARTTLS</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</outgoingServer>
</emailProvider>
</clientConfig>
Enable and start httpd:
# rcctl enable httpd
# rcctl start httpd