Setup Email Server From Scratch On FreeBSD - 04 Dovecot IMAP
03 Postfix SMTPD <- Intro -> 05 PostfixAdmin
This tutorial is partially complete 2025-05-14
Postfix, Dovecot, & PostfixAdmin work with MySQL and virtual accounts
can be created with PostfixAdmin and used with an email client. Incoming SPF
milter and outgoing OpenDKIM milter signing tested and working.
###############################
# INSTALL DOVECOT IMAP SERVER #
###############################
If you plan to use ARGON2I scheme please compile as follows. I had a lot of difficulty
setting up postfix admin due to several issues but this was one of them
please check ARGON2I after installing dovecot.
# Missing ARGONI
/usr/local/bin/doveadm pw -l
SHA1 SSHA512 SCRAM-SHA-256 BLF-CRYPT PLAIN HMAC-MD5 OTP SHA512 SHA DES-CRYPT
CRYPT SSHA MD5-CRYPT PLAIN-MD4 PLAIN-MD5 SCRAM-SHA-1 SHA512-CRYPT CLEAR
CLEARTEXT SSHA256 MD5 PBKDF2 SHA256 CRAM-MD5 PLAIN-TRUNC SHA256-CRYPT SMD5
DIGEST-MD5 LDAP-MD5
Initially I installed dovecot but didn't include the LIBSODIUM or any FTS
options. The mail client worked but wanted to use ARGON2I, so went and moved
/usr/local/etc/dovecot to /usr/local/etc/dovecot_bak and recompiled with
dovecot-fts-flatcurve.
cd /usr/local/etc
mv dovecot dovecot_bak
cd /usr/ports/mail/dovecot
make deinstall
make clean
make rmconfig
cd /usr/ports/mail/dovecot-fts-flatcurve
make deinstall
make clean
make rmconfig
make
X DOCS
X EXAMPLES
X LIBSODIUM - you will need this for ARGON2I (postfixadmin)
X LIBWRAP
X LUA
X LZ4
X CDB
X LDAP
X MYSQL
ICU - NO IT FAILED EVERY TIME
X SOLR
X TEXTCAT
X GSSAPI-NONE
make install
# Make install output
Installing dovecot-2.3.21.1_1...
===> Creating groups
Creating group 'dovecot' with gid '143'
Creating group 'dovenull' with gid '144'
===> Creating users
Creating user 'dovecot' with uid '143'
Creating user 'dovenull' with uid '144'
You must create the configuration files yourself. Copy them over
to /usr/local/etc/dovecot and edit them as desired:
cp -R /usr/local/etc/dovecot/example-config/* \
/usr/local/etc/dovecot
The default configuration includes IMAP and POP3 services, will
authenticate users agains the system's passwd file, and will use
the default /var/mail/$USER mbox files.
Next, enable dovecot in /etc/rc.conf:
dovecot_enable="YES"
To avoid a risk of mailbox corruption, do not set the
security.bsd.see_other_uids or .see_other_gids sysctls to 0
if Dovecot is storing mail for multiple concurrent users (PR 218392).
Similarly, setting sysctls security.bsd.hardlink_check_uid or
security.bsd.hardlink_check_gid to 1 might result in non-working
mailboxes, depending on what mailbox locking mechanism is used
(PR 242223).
If you want to be able to search within attachments using the
decode2text plugin, you'll need to install textproc/catdoc, and
one of graphics/xpdf or graphics/poppler-utils.
...
https://www.dovecot.org/
#
# Follow the above instructions
#
# Make symlink for convenience
cd /etc
ln -s /usr/local/etc/dovecot
libtool --finish /usr/local/lib/dovecot
sysrc dovecot_enable="YES"
# Copy the example config files.
cp -R /usr/local/etc/dovecot/example-config/* /usr/local/etc/dovecot
# Generate the dh.pem
openssl dhparam -out /usr/local/etc/dovecot/dh.pem 4096
# Dovecot won't start without the certs and vmail configured
cd /usr/local/etc/dovecot/conf.d
nano /usr/local/etc/dovecot/conf.d/10-ssl.conf
# ---
ssl = required
#ssl_cert = </etc/ssl/certs/dovecot.pem
#ssl_key = </etc/ssl/private/dovecot.pem
ssl_cert = </usr/local/etc/letsencrypt/live/mx.okbsd.com/fullchain.pem
ssl_key = </usr/local/etc/letsencrypt/live/mx.okbsd.com/privkey.pem
ssl_dh = </usr/local/etc/dovecot/dh.pem
ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = yes
# <save>
# Add the vmail user and group
pw group add vmail -g 2000
grep vmail /etc/group
vmail:*:2000:
adduser
user: vmail
uid: 2000
homedir: /nonexistent
shell: nologin
lockout after creation: yes
chsh vmail
- remove the full name if you wish
grep vmail /etc/passwd
vmail:*:2000:2000::/nonexistent:/usr/sbin/nologin
service dovecot start
service dovecot status
dovecot is running as pid 12903
dovecot --version
2.3.21.1 (d492236fa0)
# MISC - you might be able to skip this until MISC END
# I got Thunderbird mail client working without installing any of this.
# I installed dovecot without any FTS options but there is a decode2text script.
# Intructions: https://doc.dovecot.org/2.3/settings/plugin/fts-plugin/#plugin-fts
# https://doc.dovecot.org/2.3/configuration_manual/fts/
# Script: /usr/local/libexec/dovecot/decode2text.sh
# Install these dependencies just in case we need them. These take a long time
# to compile, I gave up on xpdf and just used pkg instead.
pkg install catdoc
pkg install xpdf
pkg install poppler-utils
# MISC END
# Check for LIBSODIUM/ARGON2I support if you plan to use it.
/usr/local/bin/doveadm pw -l
SHA1 SSHA512 SCRAM-SHA-256 BLF-CRYPT PLAIN HMAC-MD5 OTP SHA512 SHA DES-CRYPT
CRYPT SSHA MD5-CRYPT PLAIN-MD4 PLAIN-MD5 SCRAM-SHA-1 SHA512-CRYPT CLEAR
CLEARTEXT ARGON2I ARGON2ID SSHA256 MD5 PBKDF2 SHA256 CRAM-MD5 PLAIN-TRUNC
SHA256-CRYPT SMD5 DIGEST-MD5 LDAP-MD5
# Test ARGON2I
pw -s ARGON2I -r 5 -p hello
{ARGON2I}$argon2i$v=19$m=32768,t=5,p=1$RyC0o8I14UBuFpYHC61HEg$i7BQp0F4 ... etc.
# Comment out the following in openssl, not compatible with dovecot lmtp
openssl version
OpenSSL 3.0.15 3 Sep 2024 (Library: OpenSSL 3.0.15 3 Sep 2024)
nano /etc/ssl/openssl.cnf
# ---
# providers = provider_sect
# Add dovecot user to mail group so it can read the maildir
pw group mod mail -m dovecot
grep dovecot /etc/group
mail:*:6:postfix,dovecot
dovecot:*:143:
# Enable Submission in Postfix
# I modified for FreeBSD but shamelessly copied parts from linuxbabe.com. He
# deserves a coffee or 100 coffee's! His tutorial is for Debian and a little
# out of date but still a fantastic guide!
# Backup Postfix configs
cd /etc
cp -R postfix postfix_backup
# Backup Dovecot configs
cd /usr/local/etc
cp -R dovecot dovecot_backup
# Paste the following
nano /etc/postfix/master.cf
# ---
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_wrappermode=no
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
# If you want to compare what is configured between 2 machines useful commands
postconf | grep <value>
# Modify or add the following values
nano /etc/postfix/main.cf
# ---
myhostname = mx.okbsd.com
mydomain = okbsd.com
myorigin = $mydomain
inet_interfaces = all
# mydestination = $myhostname, localhost.$mydomain, localhost
mydestination = $mydomain, $myhostname, localhost.$mydomain, localhost
local_recipient_maps = unix:passwd.byname $alias_maps
mynetworks_style = ${{$compatibility_level} <level {2} ? {subnet} : {host}}
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
relay_domains = ${{$compatibility_level} <level {2} ? {$mydestination} : {}}
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
home_mailbox = Maildir/
mail_spool_directory = /var/mail
smtpd_banner = $myhostname ESMTP $mail_name
inet_protocols = all
setgid_group = maildrop
# Debian setgid_group = postdrop
smtp_tls_CApath = /etc/ssl/certs
shlib_directory = /usr/lib/postfix
meta_directory = /usr/libexec/postfix
message_size_limit = 536870912
mailbox_size_limit = 0
#Enable TLS Encryption when Postfix receives incoming emails
smtpd_tls_cert_file=/usr/local/etc/letsencrypt/live/mx.okbsd.com/fullchain.pem
smtpd_tls_key_file=/usr/local/etc/letsencrypt/live/mx.okbsd.com/privkey.pem
smtpd_tls_security_level=may
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#Enable TLS Encryption when Postfix sends outgoing emails
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
#Enforce TLSv1.3 or TLSv1.2
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# Restart Postfix
service postfix restart
postfix/postfix-script: stopping the Postfix mail system
postfix/postfix-script: starting the Postfix mail system
# Check if postfix is running
service postfix status
postfix is running as pid 13570.
# Finish Configuring Dovecot
# A useful command
doveadm config
# Edit dovecot.conf to enable lmtp
cd /usr/local/etc/dovecot
nano /usr/local/etc/dovecot/dovecot.conf
# ---
protocols = imap lmtp
# To find the mail_spool_dir
postconf mail_spool_directory
mail_spool_directory = /var/mail
# Edit 10-mail.conf
cd /usr/local/etc/dovecot/conf.d
nano /usr/local/etc/dovecot/conf.d/10-mail.conf
# ---
mail_location = maildir:~/Maildir
# later mail_home = /var/vmail/%d/%n
mail_privileged_group = mail
# later mail_plugins = quota
# Edit 10-master.conf
cd /usr/local/etc/dovecot/conf.d
nano /usr/local/etc/dovecot/conf.d/10-master.conf
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
# Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
}
service auth {
unix_listener auth-userdb {
#mode = 0666
#user =
#group =
}
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
# Auth process is run as this user.
#user = $default_internal_user
}
# Edit 20-lmtp.conf
nano /usr/local/etc/dovecot/conf.d/20-lmtp.conf
# ---
protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins
}
# Modify /etc/postfix/main.cf
cd /etc/postfix
nano /etc/postfix/main.cf
# --- add at end of file
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no
# Edit 10-auth.conf
cd /usr/local/etc/dovecot/conf.d
nano /usr/local/etc/dovecot/conf.d/10-auth.conf
# ---
disable_plaintext_auth = yes
auth_default_realm = okbsd.com
auth_username_format = %n
auth_mechanisms = plain login
!include auth-system.conf.ext
# !include auth-sql.conf.ext
auth_debug = yes
auth_debug_passwords = yes
# Double check 10-ssl.conf
nano /usr/local/etc/dovecot/conf.d/10-ssl.conf
# ---
ssl = required
#ssl_cert = </etc/ssl/certs/dovecot.pem
#ssl_key = </etc/ssl/private/dovecot.pem
ssl_cert = </usr/local/etc/letsencrypt/live/mx.okbsd.com/fullchain.pem
ssl_key = </usr/local/etc/letsencrypt/live/mx.okbsd.com/privkey.pem
ssl_min_protocol = TLSv1.2
#ssl_prefer_server_ciphers = no
ssl_prefer_server_ciphers = yes
# Edit 15-mailboxes.conf
nano /usr/local/etc/dovecot/conf.d/15-mailboxes.conf
# ---
mailbox Drafts {
auto = create
special_use = \Drafts
}
mailbox Junk {
auto = create
special_use = \Junk
}
mailbox Trash {
auto = create
special_use = \Trash
}
# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
auto = create
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
# restart
service dovecot restart
service dovecot status
dovecot is running as pid 13915
service postfix restart
service postfix status
dovecot is running as pid 13916
# Configure thunderbird mail client and test send and recieve. If there are any
# problems check /var/log/maillog
cat /var/log/maillog
# If you can't find the error try clearing the log and tail it from one terminal
# while sending and recieving mail with the mail client.
# clear the log
echo '' > /var/log/maillog
# tail it so you can watch the output
tail -f -300 /var/log/maillog
# And test send and recieve again ...