--- date: 2016-06-11 title: NixOS mail server draft: true --- This is my working, but in progress [NixOS]({{< ref "nixos-intro.md" >}}) mail server configuration. These are the relevant configuration parts, they are *not* tested and **not guaranteed to be secure, deploy at your own risk**. The configuration is based on [this](https://thomas-leister.de/allgemein/sicherer-mailserver-dovecot-postfix-virtuellen-benutzern-mysql-ubuntu-server-xenial/) blog post (German). For an easier overview, I created a seperate `mail.nix` that is included in the main `configuration.nix`. The firewall needs to be open for ports 993 (imps), 25 (smtp) and 587 (smtps). ```nix imports = [ ./mail.nix ]; networking.firewall.allowedTCPPorts = [ 993 25 587 ]; ``` The server is built with postfix. Postfix transports the mail via smtp(s). Dovecot is the interface between user and provides pop3(s) and/or imap(s). Opendkim signs outgoing mail so that it is less likely to be marked as spam by other providers. DNS records must be and a PTR record can be set up. This is not covered here. It is advisable to use SSL certificates. NixOS has a module that gets Let's Encrypt certificates: ```nix security.acme.certs = { "yourdomain.tld" = { webroot = "/var/www/challenges"; extraDomains = { "mail.yourdomain.tld" = null; }; email = "mail@provider.net"; postRun = "systemctl reload nginx.service postfix.service dovecot2.service"; }; }; ``` A web server is needed for the certification process. ```nix services.nginx = { enable = true; httpConfig = '' include ${pkgs.nginx}/conf/mime.types; server { listen 80; listen [::]:80; server_name mail.yourdomain.tld; location /.well-known/acme-challenge { root /var/www/challenges/; } } ''; }; ``` After retrieving certificates once: `systemctl start acme-yourdomain.tld`, they will be regenerated regularly and placed in `/var/lib/acme/yourdomain.tld/` by default. Now comes the main configuration. The user `vmail` is the owner of the mailing system. ```nix users.users.vmail = { home = "/var/vmail"; createHome = true; group = "vmail"; }; users.groups = { vmail = {}; }; ``` Dovecot requires an external configuration file. I put it in `/etc/nixos/mail/dovecot.conf`. ```nix services.dovecot2 = { enable = true; configFile = "/etc/nixos/mail/dovecot.conf"; sslCACert = "/var/lib/acme/yourdomain.tld/fullchain.pem"; sslServerCert = "/var/lib/acme/yourdomain.tld/fullchain.pem"; sslServerKey = "/var/lib/acme/yourdomain.tld/key.pem"; }; ``` This is the dovecot config. It exposes imap, lmtp and auth ports. imap is for the user. lmtp and auth are for exchanging data between dovecot and postfix. Postfix will authenticate via dovecot. `passdb` and `userdb` set to `pam` and `passwd` will allow every local unix user to authenticate with their username and password. Each user has a `~/Maildir` with their mail, each mailbox contains the folders "Spam", "Trash", "Drafts" and "Sent". ```perl default_internal_user = dovecot2 protocols = imap lmtp ssl = required ssl_cert =