For easy setup of mailserver we can go declarative way with nixos - we will go through setting up fully working mailserver instance together with proper DNS records.
nixos mailserver is nix package containing these services:
For proper deliverability we first of all need to configure reverse dns record (PTR) (this domain is also used as fqdn in this how-to). With this we can proceed to configuration on vps (placed in configuration.nix config file) accordingly:
(below shown configuration is my own slightly modified for showcase purposes of functionality. So please dont forget to change values (highlighted) according to your needs.
{ config, pkgs, ... }: { imports = [ (builtins.fetchTarball { url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/v2.3.0/nixos-mailserver-v2.3.0.tar.gz"; # for up-to-date tar please follow gitlab repository on link above sha256 = "0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919"; }) ]; # sets up path to sieve scripts # services.dovecot2.sieveScripts = { # before = "/etc/nixos/mailserver/sieve/vpsf.sieve"; # }; mailserver = { enable = true; fqdn = "<your-rDNS-ready-domain-here>"; domains = [ "martinmyska.cz" "domain.cz" "domain2.cz"]; # here we specify hosted domains # A list of all login accounts. To create the password hashes, use # mkpasswd -m sha-512 "super secret password" loginAccounts = { "martin@martinmyska.cz" = { hashedPassword = "<your-sha512-password-here>"; aliases = [ "myska@martinmyska.cz" # alias where to look for other emails (not a mailbox address) ]; # Or we can set this to catch all mails going to whole martinmyska.cz domain.com catchAll = [ "martinmyska.cz" ]; }; "info@domain.cz" = { hashedPassword = "<your-sha512-password-here>"; # Or we can catch all mails going to completely another domain catchAll = [ "domain2.cz" ]; }; }; # Extra virtual aliases. These are email addresses that are forwarded to # loginAccounts addresses. extraVirtualAliases = { # address = forward address; #"abuse@example.com" = "user1@example.com"; }; # Use Let's Encrypt certificates. Note that this needs to set up a stripped # down nginx and opens port 80. certificateScheme = 3; # Enable IMAP and POP3 enableImap = true; enablePop3 = true; enableImapSsl = true; enablePop3Ssl = true; # Enable the ManageSieve protocol enableManageSieve = true; # whether to scan inbound emails for viruses (note that this requires at least # 1 Gb RAM for the server. Without virus scanning 256 MB RAM should be plenty) virusScanning = true; }; }
At last we need to properly configure our domain DNS records as follows:
Domain | Type | TTL | Priority | Value |
---|---|---|---|---|
martinmyska.cz | TXT | 1800 | v=spf1 ip4:<IP address of mailserver> -all | |
_dmarc.martinmyska.cz | TXT | 1800 | v=DMARC1; p=none | |
mail._domainkey.martinmyska.cz | TXT | 1800 | v=DKIM1; k=rsa; p=<your key from /var/dkim/<your-domain>.txt | |
mail.martinmyska.cz | A | 1800 | <IP address of your mailserver> | |
mail.martinmyska.cz | MX | 1800 | 10 | mail.martinmyska.cz |