Dovecot

From Leo's Notes
Last edited on 14 June 2020, at 23:33.

Dovecot is a mail delivery agent (MDA). It is capable of delivering email messages directly into user's inbox on their home directory.

Configuration

cPanel configures Dovecot with the following configuration file.

protocols = lmtp imap pop3
ssl_cert = </etc/dovecot/ssl/dovecot.crt
ssl_key = </etc/dovecot/ssl/dovecot.key
ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

!include_try /etc/dovecot/sni.conf

namespace inbox {
   type = private
   separator = .
   prefix = INBOX.
   inbox = yes
  mailbox Drafts {
    special_use = \Drafts
    auto = subscribe
  }
  mailbox spam {
    special_use = \Junk
    auto = subscribe
  }
  mailbox Trash {
    special_use = \Trash
    auto = subscribe
  }
  mailbox Sent {
    special_use = \Sent
    auto = subscribe
  }
  mailbox "Sent Messages" {
    special_use = \Sent
    auto = no
  }
  mailbox Archive {
    special_use = \Archive
    auto = create
  }
  mailbox "Archives" {
    special_use = \Archive
    auto = no
  }
}

first_valid_uid = 201
mail_plugins = quota quota_clone zlib
mailbox_list_index = yes
mailbox_idle_check_interval = 30 secs
mail_prefetch_count = 20

protocol !indexer-worker {
}

maildir_copy_with_hardlinks = yes
maildir_very_dirty_syncs = yes
maildir_broken_filename_sizes = yes
mdbox_rotate_size = 10M

protocol imap {
  mail_max_userip_connections = 20
  mail_plugins = acl quota imap_quota
  mail_plugins = $mail_plugins zlib imap_zlib quota_clone virtual
  imap_logout_format = in=%i, out=%o, bytes=%i/%o
  imap_capability = +NAMESPACE
  imap_idle_notify_interval = 24 min
  namespace spam {
      prefix = spam
     separator = .
    location = virtual:/usr/local/cpanel/etc/dovecot/virtual/spam:INDEX=~/mail/virtual/%u/spam
    list = no
    hidden = yes
  }
  namespace sent {
      prefix = sent
     separator = .
    location = virtual:/usr/local/cpanel/etc/dovecot/virtual/sent:INDEX=~/mail/virtual/%u/sent
    list = no
    hidden = yes
  }
}

protocol pop3 {
  pop3_uidl_format = UID%u-%v
  pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s, bytes=%i/%o
  mail_max_userip_connections = 3
  mail_plugins = quota
  mail_plugins = $mail_plugins quota quota_clone virtual zlib
  namespace spam {
      prefix = spam
     separator = .
    location = virtual:/usr/local/cpanel/etc/dovecot/virtual/spam:INDEX=~/mail/virtual/%u/spam
    list = no
    hidden = yes
  }
  namespace sent {
      prefix = sent
     separator = .
    location = virtual:/usr/local/cpanel/etc/dovecot/virtual/sent:INDEX=~/mail/virtual/%u/sent
    list = no
    hidden = yes
  }
}

protocol lmtp {
    quota_full_tempfail = no
    postmaster_address = root
    mail_plugins = quota quota_clone zlib
}

lmtp_save_to_detail_mailbox = yes
lmtp_user_concurrency_limit = 4
recipient_delimiter = +
lmtp_rcpt_check_quota = yes

protocol lda {
  quota_full_tempfail = no
  postmaster_address = root
  mail_plugins = quota quota_clone zlib
}

lda_mailbox_autocreate = yes
disable_plaintext_auth = no
auth_cache_size = 1M
auth_cache_ttl = 3600 sec
auth_cache_negative_ttl = 3600 sec
auth_username_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$-=?^_{}~./@+%"
auth_mechanisms = plain login
auth_policy_server_url = http://127.0.0.1:579/dovecot-auth-policy
auth_policy_server_timeout_msecs = 3000
auth_policy_hash_mech = sha512
auth_policy_request_attributes = auth_database=mail database=mail service=dovecot username=%{orig_user} authtoken_hash=$0$0$%{hashed_password} local_host=%{real_lip} local_port=%{real_lport} remote_host=%{real_rip} remote_port=%{real_rport}
auth_policy_reject_on_fail = no
auth_policy_hash_truncate = 64
auth_policy_hash_nonce = "dummmy"
!include_try /etc/dovecot/auth_policy.conf

passdb {
  driver = dict
  args = /usr/local/cpanel/etc/dovecot/cpauthd-dict.conf
  result_internalfail = continue
  result_failure = return-fail
}

userdb {
   driver = prefetch
}
userdb {
  driver = dict
  args = /usr/local/cpanel/etc/dovecot/cpauthd-dict.conf
}

plugin {
}

service config {
    vsz_limit = 2048 M
}

service quota-status {
  executable = quota-status -p postfix
  unix_listener {
    path = quota-status
    mode = 0666
  }
}

service auth {
  unix_listener auth-client {
    path = auth-client
    mode = 0666
  }
}

service stats {
  client_limit = 2000
  unix_listener stats-writer {
    mode = 0666
  }
}

plugin {
}

mail_access_groups = dovecot

service dict {
  unix_listener dict {
    mode = 0660
      group = dovecot
  }
}

service lmtp {
    vsz_limit = 512 M
    client_limit = 1
    process_limit = 500
    unix_listener lmtp {
       user = mailnull
       group = mail
       mode = 0660
    }
}

service imap-login {
  client_limit = 500
    process_limit = 50
    process_min_avail = 2
    service_count = 0
    vsz_limit = 128 M
    inet_listener imap {
      address = *,::
    }
    inet_listener imaps {
      address = *,::
    }
}

service imap {
    process_limit = 512
    vsz_limit = 512 M
}

service managesieve-login {
  client_limit = 500
    process_limit = 50
    process_min_avail = 2
    service_count = 0
    vsz_limit = 128 M
}

service managesieve {
    process_limit = 512
    vsz_limit = 512 M
}

service pop3-login {
  client_limit = 500
    process_limit = 50
    process_min_avail = 2
    service_count = 0
    vsz_limit = 128 M
    inet_listener pop3 {
      address = *,::
    }
    inet_listener pop3s {
      address = *,::
    }
}

service pop3 {
    process_limit = 512
    vsz_limit = 512 M
}

dict {
}

plugin {
  quota_exceeded_message = "Mailbox is full / Blocks limit exceeded / Inode limit exceeded"
  acl = vfile:cache_secs=86400
}


cPanel also handles the Dovecot authentication by processing dict lookups through a socket at /usr/local/cpanel/var/cpdoveauthd.sock.

The dict protocol is simple. The client (Dovecot) will do lookups using the L keyword followed by the lookup key shared/$user_key/%u, as defined in the Dovecot configuration.

uri = proxy:/usr/local/cpanel/var/cpdoveauthd.sock:cpdoveauthd

user_key = dovecot_userdb/%u
password_key = dovecot_userdb/%u

iterate_disable = yes

cPanel lets the account holder to access any email accounts by allowing a one-time password to be used by the Dovecot authentication by appending the password to the username. When logging in using this method, the username will be user@example.com/cpses_xxxxxxxx and the password will be the same session ID, followed by [::cpses::]RandomString, where the RandomString is a random string that's generated for this session and can be found at /var/cpanel/cpses/keys/user@example.com:cpses_xxxxx.

When a user attempts to log in normally via IMAP, Dovecot will look up the user without the one-time password section. The password that is returned by cpsrvd is the hashed password stored in ~/etc/$domain/passwd and ~/etc/$domain/shadow.

Lshared/dovecot_userdb/test1@test.steamr.com/cpses_teq7gn18v1
O{"quota_status_overquota":"552 5.2.2 Mailbox is full / Blocks limit exceeded / Inode limit exceeded","quota2_grace":"0","userdb_quota_status_overquota":"552 5.2.2 Mailbox is full / Blocks limit exceeded / Inode limit exceeded","userdb_gid":"1003","home":"/home/steam/mail/test.steamr.com/test1","userdb_quota2_grace":"0","quota":"maildir:Mailbox:ns=INBOX.","quota2":"fs:cPanel Account","userdb_mail":"maildir:/home/steam/mail/test.steamr.com/test1:UTF-8","quota_rule2":"INBOX.INBOX:ignore","userdb_quota_vsizes":"yes","password":"{PLAIN}cpses_teq7gn18v1[::cpses::]aBaksfiTgcMN48W4wiky1F8_6Se37Xsi","userdb_quota":"maildir:Mailbox:ns=INBOX.","userdb_quota_rule2":"INBOX.INBOX:ignore","mail":"maildir:/home/steam/mail/test.steamr.com/test1:UTF-8","userdb_quota_clone_dict":"file:/home/steam/mail/test.steamr.com/test1/dovecot-quota","quota_clone_dict":"file:/home/steam/mail/test.steamr.com/test1/dovecot-quota","quota_rule":"*:bytes=1073741824","userdb_password":"{CRYPT}$6$ISt1wyxWoTB3piKY$SFLQnfcbazWNw5E18Mk/X25IShf1M4FI.hg8b5ULCU5L7PKx1jlLOGdZtUfrsn/gSHSEk/dfVmFr7O3xtF7zl/","uid":"1002","userdb_user":"test1@test.steamr.com","gid":"1003","userdb_uid":"1002","quota_vsizes":"yes","user":"test1@test.steamr.com","userdb_home":"/home/steam/mail/test.steamr.com/test1","userdb_quota_rule3":"INBOX.Trash:ignore","userdb_quota_rule":"*:bytes=1073741824","quota_rule3":"INBOX.Trash:ignore","userdb_quota2":"fs:cPanel Account"}

Lshared/dovecot_userdb/test1@test.steamr.com
O{"uid":"1002","userdb_user":"test1@test.steamr.com","userdb_uid":"1002","gid":"1003","mail":"maildir:/home/steam/mail/test.steamr.com/test1:UTF-8","userdb_quota_clone_dict":"file:/home/steam/mail/test.steamr.com/test1/dovecot-quota","quota_clone_dict":"file:/home/steam/mail/test.steamr.com/test1/dovecot-quota","quota_rule":"*:bytes=1073741824","userdb_password":"{CRYPT}$6$ISt1wyxWoTB3piKY$SFLQnfcbazWNw5E18Mk/X25IShf1M4FI.hg8b5ULCU5L7PKx1jlLOGdZtUfrsn/gSHSEk/dfVmFr7O3xtF7zl/","userdb_quota_rule3":"INBOX.Trash:ignore","userdb_quota_rule":"*:bytes=1073741824","quota_rule3":"INBOX.Trash:ignore","userdb_quota2":"fs:cPanel Account","quota_vsizes":"yes","user":"test1@test.steamr.com","userdb_home":"/home/steam/mail/test.steamr.com/test1","userdb_quota_status_overquota":"552 5.2.2 Mailbox is full / Blocks limit exceeded / Inode limit exceeded","userdb_gid":"1003","userdb_quota2_grace":"0","quota":"maildir:Mailbox:ns=INBOX.","home":"/home/steam/mail/test.steamr.com/test1","quota2_grace":"0","quota_status_overquota":"552 5.2.2 Mailbox is full / Blocks limit exceeded / Inode limit exceeded","quota_rule2":"INBOX.INBOX:ignore","userdb_quota_vsizes":"yes","password":"{CRYPT}$6$ISt1wyxWoTB3piKY$SFLQnfcbazWNw5E18Mk/X25IShf1M4FI.hg8b5ULCU5L7PKx1jlLOGdZtUfrsn/gSHSEk/dfVmFr7O3xtF7zl/","userdb_quota":"maildir:Mailbox:ns=INBOX.","userdb_quota_rule2":"INBOX.INBOX:ignore","quota2":"fs:cPanel Account","userdb_mail":"maildir:/home/steam/mail/test.steamr.com/test1:UTF-8"}

## A locked account will have *LOCKED* prepended to the hash.
Lshared/dovecot_userdb/test2@hello.com
O{"userdb_quota_status_overquota":"552 5.2.2 Mailbox is full / Blocks limit exceeded / Inode limit exceeded","userdb_gid":"1002","quota":"count:Mailbox","userdb_quota2_grace":"0","home":"/home/hello/mail/hello.com/test2","quota2_grace":"0","quota_status_overquota":"552 5.2.2 Mailbox is full / Blocks limit exceeded / Inode limit exceeded","userdb_quota_vsizes":"yes","quota_rule2":"INBOX.INBOX:ignore","password":"{CRYPT}*LOCKED*$6$RZYEnFeWHBbkmVum$OQ6vimkTlHvvYPWWSPdYGfcAOZ4Wxq4Wx4zFEA5oIhia9sfHxVP2EEatBbXfyUhbeUkwu/BKeYDxNYMRfCUEV.","userdb_quota_rule2":"INBOX.INBOX:ignore","userdb_quota":"count:Mailbox","quota2":"fs:cPanel Account","userdb_mail":"mdbox:/home/hello/mail/hello.com/test2:UTF-8","uid":"1001","userdb_user":"test2@hello.com","userdb_uid":"1001","gid":"1002","userdb_quota_clone_dict":"file:/home/hello/mail/hello.com/test2/dovecot-quota","mail":"mdbox:/home/hello/mail/hello.com/test2:UTF-8","quota_clone_dict":"file:/home/hello/mail/hello.com/test2/dovecot-quota","quota_rule":"*:bytes=1073741824","userdb_password":"{CRYPT}*LOCKED*$6$RZYEnFeWHBbkmVum$OQ6vimkTlHvvYPWWSPdYGfcAOZ4Wxq4Wx4zFEA5oIhia9sfHxVP2EEatBbXfyUhbeUkwu/BKeYDxNYMRfCUEV.","userdb_quota_rule3":"INBOX.Trash:ignore","quota_rule3":"INBOX.Trash:ignore","userdb_quota_rule":"*:bytes=1073741824","userdb_quota2":"fs:cPanel Account","quota_vsizes":"yes","user":"test2@hello.com","userdb_home":"/home/hello/mail/hello.com/test2"}

Exim can use Dovecot as an authenticator. As a consequence, the same authentication mechanism can be used for SMTP as well provided that Exim is configured to use Dovecot. See Exim#Authenticators for more information.

See Also