Dovecot: Difference between revisions

Writer (talk | contribs)
Created page with "== Troubleshooting == === sievec fails to compile basic sieve scripts in 24.05 === Since NixOS 24.05 even basic sieve commands such as ''fileinto'' need to be enabled explicitly with: <syntaxhighlight lang="nix">services.dovecot2.sieve.globalExtensions = ["fileinto"];</syntaxhighlight> Otherwise, the ''sievec'' command will fail to compile sieve scripts with <code>fileinto</code> statements and as a result the Dovecot service itself will fail to start if the configu..."
 
m fix closing tag
 
(13 intermediate revisions by 6 users not shown)
Line 1: Line 1:
== Troubleshooting ==
Dovecot is a mail storage server.  It handles the storage of e-mail
messages and their retrieval by a e-mail client (mail user agent) via
authenticated IMAP.


=== sievec fails to compile basic sieve scripts in 24.05 ===
This article describes a basic Dovecot setup with [[Postfix]] and virtual
users, i.e., e-mail users are configured separately in Dovecot passdb,
and are independent from system users.


Since NixOS 24.05 even basic sieve commands such as ''fileinto'' need to be enabled explicitly with:
= SSL Certificate with ACME =
 
This article assumes a working [[ACME]] configuration for certificate
renewal.
 
<syntaxhighlight lang="nix">
{
  config,
  ...
}:
let
  sslCertDir = config.security.acme.certs."example.org".directory;
  domainName = "example.org";
in
{
  # further dovecot configuration goes here
  ...
}
</syntaxhighlight>
 
= Dovecot passwd database =
 
Create a plaintext virtual user password database in the following
format
 
<syntaxhighlight lang="nix">
  # authenticate via Passwd-file
  #
  # bill@example.org:{PLAIN}your_plain_password
  # alice@example.org:{PLAIN-MD5}1a1dc91c907325c69271ddf0c944bc72::::::
  # This file need to have correct permissions.
 
  age.secrets.dovecot = {
    file = "./dovecot-secret.age";
    # -rw-------
    mode = "600";
    owner = "dovecot2";
    group = "dovecot2";
  };
 
</syntaxhighlight>
 
= Open firewall port =
 
Open firewall port for IMAPS clients.
 
<syntaxhighlight lang="nix">
  networking.firewall.allowedTCPPorts = [ 993 ]; # dovecot imaps
</syntaxhighlight>
 
= Setup auth via passwd-file =
 
<syntaxhighlight lang="nix">
  services.dovecot2 = {
    enable = true;
 
    # use my own passwd file for auth, see below
    enablePAM = false;
 
    # https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_dovecot_lmtp/
    # https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_and_dovecot_sasl/
    extraConfig = ''
      # force to use full user name plus domain name
      # for disambiguation
      auth_username_format = %Lu
 
      # Authentication configuration:
      auth_mechanisms = plain
      passdb {
        driver = passwd-file
        args = ${config.age.secrets.dovecot.path}
      }
    ''
  };
</syntaxhighlight>
 
= Setup virtual users =
<syntaxhighlight lang="nix">
  # /var/spool/mail/vmail needs to be created and owned by vmail
  users.users."vmail" = {
    createHome = true;
    home = "/var/spool/mail/vmail";
  };
 
  services.dovecot2 = {
    # configure virtual mail user and group
    createMailUser = true;
    mailUser = "vmail";
    mailGroup = "vmail";
 
    # implement virtual users
    # https://doc.dovecot.org/2.3/configuration_manual/howto/simple_virtual_install/
    # store virtual mail under
    # /var/spool/mail/vmail/<DOMAIN>/<USER>/Maildir/
    mailLocation = "maildir:~/Maildir";
 
    extraConfig = ''
      userdb {
        driver = static
        # the full e-mail address inside passwd-file is the username (%u)
        # user@example.com
        # %d for domain_name %n for user_name
        args = uid=vmail gid=vmail username_format=%u home=/var/spool/mail/vmail/%d/%n
      }
    '';
  };
</syntaxhighlight>
 
= Connect to postfix via lmtp =
See [[Postfix]] for further setup on postfix side.
 
<syntaxhighlight lang="nix">
  services.dovecot2 = {
    # connection to postfix
    enableLmtp = true;
 
    # https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_dovecot_lmtp/
    # https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_and_dovecot_sasl/
    extraConfig = ''
      # connection to postfix via lmtp
      service lmtp {
      unix_listener /var/spool/postfix/dovecot-lmtp {
        mode = 0600
        user = postfix
        group = postfix
        }
      }
      service auth {
        unix_listener /var/spool/postfix/auth {
          mode = 0600
          user = postfix
          group = postfix
        }
      }
    '';
  };
 
  # postfix connection to dovecot
  services.postfix.config = {
    # https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_dovecot_lmtp/
    mailbox_transport = "lmtp:unix:/var/spool/postfix/dovecot-lmtp";
    virtual_transport = "lmtp:unix:/var/spool/postfix/dovecot-lmtp";
 
    # https://doc.dovecot.org/2.3/configuration_manual/howto/postfix_and_dovecot_sasl/
    smtpd_sasl_type = "dovecot";
    smtpd_sasl_path = "/var/spool/postfix/auth";
    smtpd_sasl_auth_enable = "yes";
    smtpd_recipient_restrictions = "permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination";
  };
 
  # create path for dovecot socket
  users.users."postfix" = {
    createHome = true;
    home = "/var/spool/postfix";
  };
 
</syntaxhighlight>
 
= Configure SSL Certificates =
<syntaxhighlight lang="nix">
  services.dovecot2 = {
    sslServerCert = "${sslCertDir}/fullchain.pem";
    sslServerKey = "${sslCertDir}/key.pem";
    sslCACert = "${sslCertDir}/chain.pem";
  };
</syntaxhighlight>
 
You also need to set proper file permissions on the cert directory and key files.
See [[ACME#Integration_with_service_modules]].
 
= Using sieve plugins =
 
The following is required to use Sieve plugins (<code>imap_sieve</code>, ManageSieve, etc):
 
<syntaxhighlight lang="nix">
environment.systemPackages = with pkgs; [
  dovecot_pigeonhole
];
</syntaxhighlight>
 
= mail_crypt plugin (encryption at rest) =
 
The following seems to make mail_crypt work in its per-user/per-folder mode (note that this mode is still described as 'not production quality' in the dovecot docs):
 
<pre>
security.pam.services.dovecot2 = { }; # needed as we disable PAM below
 
services.dovecot2 = {
  enable = true;
  enablePAM = false; # need to disable this as we redefine passdb
  mailPlugins.globally.enable = [ "mail_crypt" ];
  pluginSettings = {
    mail_crypt_curve = "secp521r1";
    mail_crypt_save_version = "2";
    mail_crypt_require_encrypted_user_key = "yes";
  };
  extraConfig = ''
    mail_attribute_dict = file:%h/.attributes
    userdb {
      driver = passwd
    } 
    passdb {
      driver = pam
      override_fields = userdb_mail_crypt_private_password=%{sha256:password} userdb_mail_crypt_save_version=2
      args = failure_show_msg=yes dovecot2
    } 
  '';
};
</pre>
= Troubleshooting =
== sievec fails to compile basic sieve scripts ==
 
Sieve commands such as ''fileinto'' need to be enabled explicitly with:


<syntaxhighlight lang="nix">services.dovecot2.sieve.globalExtensions = ["fileinto"];</syntaxhighlight>
<syntaxhighlight lang="nix">services.dovecot2.sieve.globalExtensions = ["fileinto"];</syntaxhighlight>


Otherwise, the  ''sievec'' command will fail to compile sieve scripts with <code>fileinto</code> statements and as a result the Dovecot service itself will fail to start if the configuration contains <code>services.dovecot2.sieve.scripts</code>.
Otherwise, the  ''sievec'' command will fail to compile sieve scripts with <code>fileinto</code> statements and as a result the Dovecot service itself will fail to start if the configuration contains <code>services.dovecot2.sieve.scripts</code>.
[[Category:Mail Server]]
[[Category:Server]]