diff --git a/default.nix b/default.nix
index 5854226..7958d74 100644
--- a/default.nix
+++ b/default.nix
@@ -167,7 +167,7 @@ in
vmailUserName = mkOption {
type = types.str;
- default = "virtualMail";
+ default = "vmail";
description = ''
The user name and group name of the user that owns the directory where all
the mail is stored.
@@ -176,7 +176,7 @@ in
vmailGroupName = mkOption {
type = types.str;
- default = "virtualMail";
+ default = "vmail";
description = ''
The user name and group name of the user that owns the directory where all
the mail is stored.
@@ -331,8 +331,8 @@ in
./mail-server/networking.nix
./mail-server/systemd.nix
./mail-server/dovecot.nix
- ./mail-server/postfix.nix
- ./mail-server/rmilter.nix
+ ./mail-server/opensmtpd.nix
+ # ./mail-server/rmilter.nix
./mail-server/nginx.nix
];
diff --git a/mail-server/dovecot.nix b/mail-server/dovecot.nix
index 89249b5..0b51600 100644
--- a/mail-server/dovecot.nix
+++ b/mail-server/dovecot.nix
@@ -63,10 +63,10 @@ in
ssl = required
service lmtp {
- unix_listener /var/lib/postfix/queue/private/dovecot-lmtp {
- group = postfix
+ unix_listener /run/dovecot/lmtp {
+ group = ${vmailGroupName}
mode = 0600
- user = postfix # TODO: < make variable
+ user = ${vmailUserName}
}
}
@@ -74,14 +74,6 @@ in
mail_plugins = $mail_plugins sieve
}
- service auth {
- unix_listener /var/lib/postfix/queue/private/auth {
- mode = 0660
- user = postfix # TODO: < make variable
- group = postfix # TODO: < make variable
- }
- }
-
auth_mechanisms = plain login
namespace inbox {
diff --git a/mail-server/opensmtpd.nix b/mail-server/opensmtpd.nix
new file mode 100644
index 0000000..497eb0b
--- /dev/null
+++ b/mail-server/opensmtpd.nix
@@ -0,0 +1,146 @@
+# nixos-mailserver: a simple mail server
+# Copyright (C) 2016-2017 Robin Raymond
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+
+{ config, pkgs, lib, ... }:
+
+with (import ./common.nix { inherit config; });
+
+let
+ inherit (lib.strings) concatStringsSep;
+ cfg = config.mailserver;
+
+ # valiases_postfix :: [ String ]
+ valiases_postfix = lib.flatten (lib.mapAttrsToList
+ (name: value:
+ let to = name;
+ in map (from: "${from} ${to}") value.aliases)
+ cfg.loginAccounts);
+
+ vmailMaps = lib.flatten (lib.mapAttrsToList
+ (name: value: "${name} ${cfg.vmailUserName}") cfg.loginAccounts);
+
+ # catchAllPostfix :: [ String ]
+ catchAllPostfix = lib.flatten (lib.mapAttrsToList
+ (name: value:
+ let to = name;
+ in map (from: "@${from} ${to}") value.catchAll)
+ cfg.loginAccounts);
+
+ # extra_valiases_postfix :: [ String ]
+ # TODO: Remove virtualAliases when deprecated -> removed
+ extra_valiases_postfix = (map
+ (from:
+ let to = cfg.virtualAliases.${from};
+ in "${from} ${to}")
+ (builtins.attrNames cfg.virtualAliases))
+ ++
+ (map
+ (from:
+ let to = cfg.extraVirtualAliases.${from};
+ in "${from} ${to}")
+ (builtins.attrNames cfg.extraVirtualAliases));
+
+ # all_valiases_postfix :: [ String ]
+ all_valiases_postfix = valiases_postfix ++ extra_valiases_postfix ++ catchAllPostfix ++ vmailMaps;
+
+ # accountToIdentity :: User -> String
+ accountToIdentity = account: "${account.name} ${account.name}";
+
+ # vaccounts_identity :: [ String ]
+ vaccounts_identity = map accountToIdentity (lib.attrValues cfg.loginAccounts);
+
+ # valiases_file :: Path
+ valiases_file = builtins.toFile "valias"
+ (lib.concatStringsSep "\n" all_valiases_postfix);
+
+ # vhosts_file :: Path
+ vhosts_file = builtins.toFile "vhosts" (concatStringsSep "\n" cfg.domains);
+
+ passwdList = lib.flatten (lib.mapAttrsToList (name : value:
+ "${name}:${value.hashedPassword}:5000:5000::/var/vmail/:/run/current-system/sw/bin/nologin")
+ cfg.loginAccounts);
+ passwd = lib.concatStringsSep "\n" passwdList;
+
+
+ example =
+ ''
+ user1@example.com:$6$IsXn9Xe2kUTPETVl$Z.gkkqpwi95/ZsL/FXZaAjMjdv03m5jae6v8Pv7aaNnzdzNd01nbgt3HtKnaS10hZTbXgumqdQyTU0m1wkr76.:5000:5000::/var/vmail:/run/current-system/sw/bin/nologin
+ '';
+
+ passwd_file = builtins.toFile "passwd" passwd;
+
+ # vaccounts_file :: Path
+ # see
+ # https://blog.grimneko.de/2011/12/24/a-bunch-of-tips-for-improving-your-postfix-setup/
+ # for details on how this file looks. By using the same file as valiases,
+ # every alias is owned (uniquely) by its user. We have to add the users own
+ # address though
+ vaccounts_file = builtins.toFile "vaccounts" (lib.concatStringsSep "\n"
+ (vaccounts_identity ++ all_valiases_postfix));
+
+ submissionHeaderCleanupRules = pkgs.writeText "submission_header_cleanup_rules" ''
+ # Removes sensitive headers from mails handed in via the submission port.
+ # See https://thomas-leister.de/mailserver-debian-stretch/
+ # Uses "pcre" style regex.
+
+ /^Received:/ IGNORE
+ /^X-Originating-IP:/ IGNORE
+ /^X-Mailer:/ IGNORE
+ /^User-Agent:/ IGNORE
+ /^X-Enigmail:/ IGNORE
+ '';
+in
+{
+ config = with cfg; lib.mkIf enable {
+
+ services.opensmtpd = {
+ enable = true;
+ procPackages = [ pkgs.opensmtpd-extras ];
+ extraServerArgs = [ "-v" ];
+ serverConfiguration =
+ ''
+ # pki setup
+ pki ${fqdn} certificate "${certificatePath}"
+ pki ${fqdn} key "${keyPath}"
+
+ # tables setup
+ # table aliases file:/etc/mail/aliases
+ table domains file:${vhosts_file}
+ table passwd passwd:${passwd_file}
+ table virtuals file:${valiases_file}
+
+ # # listen ports setup
+ listen on 0.0.0.0 port 25 tls pki ${fqdn}
+ listen on 0.0.0.0 port 587 tls-require pki ${fqdn} auth received-auth
+
+ # allow local messages
+ accept from any for domain virtual deliver to lmtp "/run/dovecot/lmtp" rcpt-to
+
+ # DKIM
+ listen on lo hostname ${fqdn}
+ listen on lo port 10028 tag DKIM hostname ${fqdn}
+
+ accept tagged DKIM \
+ for any \
+ relay \
+ hostname ${fqdn}
+ accept from local \
+ for any \
+ relay via smtp://127.0.0.1:10027
+ '';
+ };
+ };
+}
diff --git a/mail-server/systemd.nix b/mail-server/systemd.nix
index 0f98b7d..e13029a 100644
--- a/mail-server/systemd.nix
+++ b/mail-server/systemd.nix
@@ -68,13 +68,21 @@ in
{
config = with cfg; lib.mkIf enable {
# Make sure postfix gets started first, so that the certificates are in place
- systemd.services.dovecot2.after = [ "postfix.service" ];
+ systemd.services.dovecot2 = {
+ after = [ "postfix.service" ];
+ preStart =
+ ''
+ mkdir -p '/run/dovecot/'
+ chown 'dovecot2:dovecot2' '/run/dovecot'
+ '';
+ };
# Create certificates and maildir folder
- systemd.services.postfix = {
+ systemd.services.opensmtpd = {
after = (if (certificateScheme == 3) then [ "nginx.service" ] else []);
preStart =
''
+ mkdir -p /var/empty
# Create mail directory and set permissions. See
# .
mkdir -p "${mailDirectory}"
diff --git a/tests/intern.nix b/tests/intern.nix
index 3d49c15..3bdacb8 100644
--- a/tests/intern.nix
+++ b/tests/intern.nix
@@ -54,6 +54,7 @@ import {
subtest "vmail gid is set correctly", sub {
$machine->succeed("getent group vmail | grep 5000");
+ $machine->succeed("systemctl status opensmtpd.service -l >&2");
};
'';