add vitual mail users
This commit is contained in:
commit
436cf0513b
7 changed files with 61 additions and 22 deletions
10
default.nix
10
default.nix
|
@ -78,6 +78,16 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
quota = mkOption {
|
||||||
|
type = with types; nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "2G";
|
||||||
|
description = ''
|
||||||
|
Per user quota rules. Accepted sizes are `xx k/M/G/T` with the
|
||||||
|
obvious meaning. Leave blank for the standard quota `100G`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
sieveScript = mkOption {
|
sieveScript = mkOption {
|
||||||
type = with types; nullOr lines;
|
type = with types; nullOr lines;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
|
@ -14,10 +14,17 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
{ config }:
|
{ config, lib }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.mailserver;
|
cfg = config.mailserver;
|
||||||
|
# passwd :: [ String ]
|
||||||
|
passwd = lib.mapAttrsToList
|
||||||
|
(name: value: "${name}:${value.hashedPassword}:${builtins.toString cfg.vmailUID}:${builtins.toString cfg.vmailUID}::${cfg.mailDirectory}:/run/current-system/sw/bin/nologin:"
|
||||||
|
+ (if lib.isString value.quota
|
||||||
|
then "userdb_quota_rule=*:storage=${value.quota}"
|
||||||
|
else ""))
|
||||||
|
cfg.loginAccounts;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# cert :: PATH
|
# cert :: PATH
|
||||||
|
@ -37,4 +44,7 @@ in
|
||||||
else if cfg.certificateScheme == 3
|
else if cfg.certificateScheme == 3
|
||||||
then "/var/lib/acme/${cfg.fqdn}/key.pem"
|
then "/var/lib/acme/${cfg.fqdn}/key.pem"
|
||||||
else throw "Error: Certificate Scheme must be in { 1, 2, 3 }";
|
else throw "Error: Certificate Scheme must be in { 1, 2, 3 }";
|
||||||
|
|
||||||
|
# passwdFile :: PATH
|
||||||
|
passwdFile = builtins.toFile "passwd" (lib.concatStringsSep "\n" passwd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
with (import ./common.nix { inherit config; });
|
with (import ./common.nix { inherit config lib; });
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.mailserver;
|
cfg = config.mailserver;
|
||||||
|
@ -33,6 +33,8 @@ in
|
||||||
enable = true;
|
enable = true;
|
||||||
enableImap = enableImap;
|
enableImap = enableImap;
|
||||||
enablePop3 = enablePop3;
|
enablePop3 = enablePop3;
|
||||||
|
enablePAM = false;
|
||||||
|
enableQuota = true;
|
||||||
mailGroup = vmailGroupName;
|
mailGroup = vmailGroupName;
|
||||||
mailUser = vmailUserName;
|
mailUser = vmailUserName;
|
||||||
mailLocation = dovecot_maildir;
|
mailLocation = dovecot_maildir;
|
||||||
|
@ -79,6 +81,16 @@ in
|
||||||
mail_plugins = $mail_plugins sieve
|
mail_plugins = $mail_plugins sieve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
passdb {
|
||||||
|
driver = passwd-file
|
||||||
|
args = ${passwdFile}
|
||||||
|
}
|
||||||
|
|
||||||
|
userdb {
|
||||||
|
driver = passwd-file
|
||||||
|
args = ${passwdFile}
|
||||||
|
}
|
||||||
|
|
||||||
service auth {
|
service auth {
|
||||||
unix_listener /var/lib/postfix/queue/private/auth {
|
unix_listener /var/lib/postfix/queue/private/auth {
|
||||||
mode = 0660
|
mode = 0660
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
with (import ./common.nix { inherit config; });
|
with (import ./common.nix { inherit config lib; });
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
|
@ -124,6 +124,9 @@ in
|
||||||
smtpd_sasl_auth_enable = yes
|
smtpd_sasl_auth_enable = yes
|
||||||
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
|
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
|
||||||
|
|
||||||
|
# quota
|
||||||
|
smtpd_recipient_restrictions = check_policy_service inet:mailstore.example.com:12340
|
||||||
|
|
||||||
# TLS settings, inspired by https://github.com/jeaye/nix-files
|
# TLS settings, inspired by https://github.com/jeaye/nix-files
|
||||||
# Submission by mail clients is handled in submissionOptions
|
# Submission by mail clients is handled in submissionOptions
|
||||||
smtpd_tls_security_level = may
|
smtpd_tls_security_level = may
|
||||||
|
|
|
@ -28,16 +28,6 @@ let
|
||||||
group = vmailGroupName;
|
group = vmailGroupName;
|
||||||
};
|
};
|
||||||
|
|
||||||
# accountsToUser :: String -> UserRecord
|
|
||||||
accountsToUser = account: {
|
|
||||||
isNormalUser = false;
|
|
||||||
group = vmailGroupName;
|
|
||||||
inherit (account) hashedPassword name;
|
|
||||||
};
|
|
||||||
|
|
||||||
# mail_users :: { [String]: UserRecord }
|
|
||||||
mail_users = lib.foldl (prev: next: prev // { "${next.name}" = next; }) {}
|
|
||||||
(map accountsToUser (lib.attrValues loginAccounts));
|
|
||||||
|
|
||||||
virtualMailUsersActivationScript = pkgs.writeScript "activate-virtual-mail-users" ''
|
virtualMailUsersActivationScript = pkgs.writeScript "activate-virtual-mail-users" ''
|
||||||
#!${pkgs.stdenv.shell}
|
#!${pkgs.stdenv.shell}
|
||||||
|
@ -82,7 +72,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
# define all users
|
# define all users
|
||||||
users.users = mail_users // {
|
users.users = {
|
||||||
"${vmail_user.name}" = lib.mkForce vmail_user;
|
"${vmail_user.name}" = lib.mkForce vmail_user;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import <nixpkgs/nixos/tests/make-test.nix> {
|
||||||
|
|
||||||
mailserver = {
|
mailserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
debug = true;
|
||||||
fqdn = "mail.example.com";
|
fqdn = "mail.example.com";
|
||||||
domains = [ "example.com" "example2.com" ];
|
domains = [ "example.com" "example2.com" ];
|
||||||
dhParamBitLength = 512;
|
dhParamBitLength = 512;
|
||||||
|
@ -42,6 +43,10 @@ import <nixpkgs/nixos/tests/make-test.nix> {
|
||||||
"user@example2.com" = {
|
"user@example2.com" = {
|
||||||
hashedPassword = "$6$u61JrAtuI0a$nGEEfTP5.eefxoScUGVG/Tl0alqla2aGax4oTd85v3j3xSmhv/02gNfSemv/aaMinlv9j/ZABosVKBrRvN5Qv0";
|
hashedPassword = "$6$u61JrAtuI0a$nGEEfTP5.eefxoScUGVG/Tl0alqla2aGax4oTd85v3j3xSmhv/02gNfSemv/aaMinlv9j/ZABosVKBrRvN5Qv0";
|
||||||
};
|
};
|
||||||
|
"lowquota@example.com" = {
|
||||||
|
hashedPassword = "$6$u61JrAtuI0a$nGEEfTP5.eefxoScUGVG/Tl0alqla2aGax4oTd85v3j3xSmhv/02gNfSemv/aaMinlv9j/ZABosVKBrRvN5Qv0";
|
||||||
|
quota = "1B";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
enableImap = true;
|
enableImap = true;
|
||||||
|
@ -224,5 +229,22 @@ import <nixpkgs/nixos/tests/make-test.nix> {
|
||||||
# if this succeeds, it means that user1 recieved the mail that was intended for chuck.
|
# if this succeeds, it means that user1 recieved the mail that was intended for chuck.
|
||||||
$client->fail("fetchmail -v");
|
$client->fail("fetchmail -v");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
subtest "quota", sub {
|
||||||
|
$client->execute("rm ~/mail/*");
|
||||||
|
|
||||||
|
$client->succeed("echo '${fetchmailRcLowQuota}' > ~/.fetchmailrc");
|
||||||
|
$client->succeed("sed -i s/SERVER/`getent hosts server | awk '{ print \$1 }'`/g ~/.fetchmailrc");
|
||||||
|
|
||||||
|
$client->succeed("chmod 0700 ~/.fetchmailrc");
|
||||||
|
$client->succeed("echo '${email2}' > mail.txt");
|
||||||
|
# send email from chuck to non exsitent account
|
||||||
|
$client->succeed("msmtp -a test3 --tls=on --tls-certcheck=off --auth=on lowquota\@example.com < mail.txt >&2");
|
||||||
|
$client->succeed("sleep 5");
|
||||||
|
# fetchmail returns EXIT_CODE 0 when it retrieves mail
|
||||||
|
$client->fail("fetchmail -v");
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,6 @@ import <nixpkgs/nixos/tests/make-test.nix> {
|
||||||
$machine->start;
|
$machine->start;
|
||||||
$machine->waitForUnit("multi-user.target");
|
$machine->waitForUnit("multi-user.target");
|
||||||
|
|
||||||
subtest "user exists", sub {
|
|
||||||
$machine->succeed("cat /etc/shadow | grep 'user1\@example.com'");
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "password is set", sub {
|
|
||||||
$machine->succeed("cat /etc/shadow | grep 'user1\@example.com:\$6\$/z4n8AQl6K\$kiOkBTWlZfBd7PvF5GsJ8PmPgdZsFGN1jPGZufxxr60PoR0oUsrvzm2oQiflyz5ir9fFJ.d/zKm/NgLXNUsNX/:1::::::'");
|
|
||||||
};
|
|
||||||
|
|
||||||
subtest "vmail gid is set correctly", sub {
|
subtest "vmail gid is set correctly", sub {
|
||||||
$machine->succeed("getent group vmail | grep 5000");
|
$machine->succeed("getent group vmail | grep 5000");
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue