В статье рассказывается об установке и настройке почтового сервера для небольшой компании на основе Postfix, Dovecot, c хранением информации о пользователях в БД Mysql и администрированием через Postfixadmin.

Все вышеперечисленное ставится из портов. Прописываете автозапуск в /etc/rc.conf

В группу  mail добавляете пользователя dovecot

pw groupmod mail -m dovecot

Создаёте базу postfix, и пользователя postfix.

Создаёте папку /home/mail и даёте на неё права пользователю mail и группе mail 

Настройка Postfix

Создаём папку и файлы c конфигами для обращения к Mysql:

mkdir /usr/local/etc/postfix/mysql
touch /usr/local/etc/postfix/mysql/relay_domains.cf
touch /usr/local/etc/postfix/mysql/virtual_alias_maps.cf
touch /usr/local/etc/postfix/mysql/virtual_alias_domain_maps.cf
touch /usr/local/etc/postfix/mysql/virtual_mailbox_maps.cf

Содержимое файлов будет:
relay_domains.cf

hosts = 127.0.0.1
user = postfix
password = password
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1'

virtual_alias_maps.cf

hosts = 127.0.0.1
user = postfix
password = password
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active ='1'

virtual_alias_domain_maps.cf

hosts = 127.0.0.1
user = postfix
password = password
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = '1'

virtual_mailbox_maps.cf

hosts = 127.0.0.1
user = postfix
password = password
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND  active = '1'

master.cf

dovecot unix - n n - - pipe
    flags=DRhu user=mail:mail argv=/usr/local/libexec/dovecot/deliver -f ${sender} -d ${recipient}

smtp      inet  n       -       n       -       -       smtpd
#  -o content_filter=spamassassin
  -o smtpd_sasl_auth_enable=yes

submission inet n       -       n       -       -       smtpd
 -o smtpd_sasl_auth_enable=yes

smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_tls_wrappermode=yes

#628       inet  n       -       n       -       -       qmqpd
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
#qmgr     unix  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
relay     unix  -       -       n       -       -       smtp
        -o syslog_name=postfix/$service_name
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache
postlog   unix-dgram n  -       n       -       1       postlogd

main.cf

compatibility_level = 3.9

#soft_bounce = no
mail_owner = postfix

#default_privs = nobody

myhostname = $mydomain
mydomain = fbsd.site
myorigin = $myhostname
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, bsd.site #Запись bsd.site разрешает релей с домена bsd.site на fbs.site. Написано по мотивам настройки почты в одной организации
mynetworks_style = host
mynetworks =

milter_protocol = 2
milter_default_action = accept

home_mailbox = Maildir/

inet_interfaces = all

local_transport = dovecot
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

sendmail_path = /usr/local/sbin/sendmail
mailq_path = /usr/local/bin/mailq
newaliases_path = /usr/local/bin/newaliases
setgid_group = maildrop

inet_protocols = ipv4

smtpd_discard_ehlo_keywords = CONNECT GET POST
smtpd_delay_reject = yes
smtpd_helo_required = yes
broken_sasl_auth_clients = yes
disable_vrfy_command = yes

smtpd_sasl_security_options = noanonymous noactive nodictionary
smtp_sasl_security_options = noanonymous noactive nodictionary

smtp_sasl_type = dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

local_recipient_maps = $virtual_mailbox_maps $virtual_alias_maps

smtpd_reject_unlisted_recipient = yes

#MYSQL
virtual_alias_maps = mysql:/usr/local/etc/postfix/mysql/virtual_alias_maps.cf, mysql:/usr/local/etc/postfix/mysql/virtual_alias_domain_maps.cf
virtual_mailbox_maps = mysql:/usr/local/etc/postfix/mysql/virtual_mailbox_maps.cf

smtpd_helo_restrictions = permit_sasl_authenticated, reject_non_fqdn_helo_hostname, reject_invalid_hostname
smtpd_data_restrictions = permit_sasl_authenticated reject_unauth_pipelining, reject_multi_recipient_bounce
smtpd_sender_restrictions = permit_sasl_authenticated, reject_sender_login_mismatch,reject_unauthenticated_sender_login_mismatch, reject_non_fqdn_sender, reject_unknown_sender_domain
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_multi_recipient_bounce, reject_unknown_client_hostname, reject_unauth_destination

virtual_mailbox_base = /home/mail # Домашний каталог для писем. можно вынести, например, на сетевой диск

# uid пользователя mail (смотреть в /etc/passwd) и gid группы mail (в /etc/group)
virtual_minimum_uid = 1000
virtual_uid_maps = static:1000
virtual_gid_maps = static:6

smtp_tls_security_level=encrypt
smtp_tls_note_starttls_offer=yes
smtp_tls_session_cache_database=btree:$data_directory/smtp_tls_session_cache

# Здесь используются сертификат, ключ и цепочка полученные с помощью LetsEncrypt
smtp_tls_CAfile=/usr/local/etc/letsencrypt/live/fbsd.site/fullchain.pem
smtp_tls_key_file=/usr/local/etc/letsencrypt/live/fbsd.site/privkey.pem
smtp_tls_cert_file=/usr/local/etc/letsencrypt/live/fbsd.site/cert.pem

smtp_tls_session_cache_timeout=3600s
smtp_tls_protocols=!TLSv1.2
smtp_tls_loglevel=0

#smtpd_tls_auth_only=yes
smtpd_tls_loglevel=2
smtpd_tls_received_header=yes
smtpd_tls_session_cache_timeout=3600s
smtpd_tls_session_cache_database=btree:$data_directory/smtpd_tls_session_cache
smtpd_tls_CAfile=/usr/local/etc/letsencrypt/live/fbsd.site/fullchain.pem
smtp_tls_key_file=/usr/local/etc/letsencrypt/live/fbsd.site/privkey.pem
smtp_tls_cert_file=/usr/local/etc/letsencrypt/live/fbsd.site/cert.pem
smtpd_tls_protocols=!TLSv1.2

tls_random_source=dev:/dev/urandom

unknown_local_recipient_reject_code = 550

alias_maps = hash:/etc/mail/aliases
alias_database = dbm:/etc/mail/aliases.db

smtpd_banner = $myhostname ESMTP $mail_name

debug_peer_list = 127.0.0.1 fbsd.site
debug_peer_level = 1
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5

queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
data_directory = /var/db/postfix
html_directory = no
manpage_directory = /usr/local/share/man
sample_directory = /usr/local/etc/postfix
readme_directory = no
meta_directory = /usr/local/libexec/postfix
shlib_directory = /usr/local/lib/postfix

Настройка Dovecot

dovecot.conf

protocols = imap pop3
listen = *

dict {
    quota = mysql:/usr/local/etc/dovecot/dovecot-dict-sql.conf.ext
}

service stats {
    unix_listener stats-reader {
        user = dovecot
        group = mail
        mode = 0660
  }
  unix_listener stats-writer {
        user = dovecot
        group = mail
        mode = 0660
  }
}

!include /usr/local/etc/dovecot/conf.d/*.conf
!include_try local.conf

dovecot-dict-sql.conf.ext

connect = host=localhost dbname=postfix user=postfix password=password

map {
  pattern = priv/quota/storage
  table = quota2
  username_field = username
  value_field = bytes
}

map {
  pattern = priv/quota/messages
  table = quota2
  username_field = username
  value_field = messages
}

dovecot-sql.conf.ext

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=password
default_pass_scheme = CRYPT

user_query = SELECT '/home/mail/%d/%n/' AS  home, 'maildir:/home/mail/%d/%n' AS mail, 1000 AS uid, 6 AS gid, concat('*:bytes=',quota) as quota_rule FROM mailbox WHERE username ='%u' AND active = '1'
password_query = SELECT username as user, password, '/home/mail/%d/%n' as userdb_home, 'maildir:/home/mail/%d/%n' as userdb_mail,  1000 as userdb_uid, 6 as userdb_gid, concat('*:bytes=',quota) AS userdb_quota_rule FROM mailbox WHERE username ='%u' AND active ='1'

auth-sql.conf.ext

passdb {
    driver = sql
    args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
}

userdb {
    driver = sql
    args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
}

dovecot/conf.d/10-auth.conf

disable_plaintext_auth = yes
auth_mechanisms = plain login

auth_realms = fbsd.site
auth_default_realm = fbsd.site

!include /usr/local/etc/dovecot/auth-sql.conf.ext

dovecot/conf.d/10-logging.conf

log_path = syslog
debug_log_path = /var/log/mail/dovecot.log

#syslog_facility = mail
#log_debug = yes
#log_core_filter =

auth_verbose = yes
auth_verbose_passwords = yes
auth_debug = yes
auth_debug_passwords = yes
#mail_debug = no

verbose_ssl = yes

log_timestamp = "%b %d %H:%M:%S "

#login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c
#login_log_format = %$: %s
#mail_log_prefix = "%s(%u)<%{pid}><%{session}>: "

dovecot/conf.d/10-mail.conf

mail_location = maildir:/home/mail/%d/%n

namespace inbox {
  inbox = yes
}

mail_uid = 1000
mail_gid = 6

mail_plugins = quota

dovecot/conf.d/10-master.conf

service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}

service pop3-login {
  inet_listener pop3 {
    port = 110
  }
  inet_listener pop3s {
    port = 995
    ssl = yes
  }
}

service submission-login {
  inet_listener submission {
    port = 587
  }
}
service auth {
  unix_listener auth-userdb {
    mode = 0600
    user = mail
    group = mail
  }
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
}

service dict {
  unix_listener dict {
    mode = 0660
    user =  mail
    group = mail
    }
 }

dovecot/conf.d/10-metrics.conf

metric auth_success {
  filter = event=auth_request_finished AND success=yes
}

metric auth_failures {
  filter = event=auth_request_finished AND NOT success=yes
}

metric imap_command {
  filter = event=imap_command_finished
  group_by = cmd_name tagged_reply_state
}

metric smtp_command {
  filter = event=smtp_server_command_finished
  group_by = cmd_name status_code duration:exponential:1:5:10
}

metric mail_delivery {
  filter = event=mail_delivery_finished
  group_by = duration:exponential:1:5:10
}

10-ssl.conf

ssl = required

ssl_cert = </usr/local/etc/letsencrypt/live/iphras.ru/cert.pem
ssl_key = </usr/local/etc/letsencrypt/live/iphras.ru/privkey.pem
ssl_ca = </usr/local/etc/letsencrypt/live/iphras.ru/fullchain.pem

ssl_min_protocol = TLSv1.2

dovecot/conf.d/15-lda.conf

quota_full_tempfail = no
lda_mailbox_autosubscribe = yes
protocol lda {
  mail_plugins = $mail_plugins quota
}