mailnix/mailsystem/default.nix
Thomas Preisner faf6f549b0
Some checks failed
Test / tests (push) Failing after 3m0s
Remove accounts.<name>.aliases and rename extraVirtualAliases to virtualAccountAliases
In order to simplify configuration and reduce configuration variability,
this commit removes the option to directly add aliases to each single
mail account. Instead, aliaes should be centrally configured using the
option 'virtualAccountAliases'.
2025-01-06 23:29:40 +01:00

234 lines
7.4 KiB
Nix

{
config,
lib,
...
}: let
cfg = config.mailsystem;
in {
options.mailsystem = {
enable = lib.mkEnableOption "nixos-mailsystem";
openFirewall = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Automatically open ports in the firewall.";
};
fqdn = lib.mkOption {
type = lib.types.str;
example = "mail.example.com";
description = "Fully qualified domain name of the mail server.";
};
reverseFqdn = lib.mkOption {
type = lib.types.str;
default = cfg.fqdn;
defaultText = lib.literalMD "{option}`mailsystem.fqdn`";
example = "server.example.com";
description = ''
Fully qualified domain name used by the server to identify
with other servers.
This needs to be set to the same value of the server's IP reverse DNS.
'';
};
domains = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = ["example.com"];
default = [];
description = "List of domains to be served by the mail server";
};
messageSizeLimit = lib.mkOption {
type = lib.types.int;
default = 64 * 1024 * 1024;
description = "Maximum accepted mail size";
};
vmailUID = lib.mkOption {
type = lib.types.int;
default = 5000;
description = "The unix UID of the virtual mail user.";
};
vmailUserName = lib.mkOption {
type = lib.types.str;
default = "vmail";
description = "The user name of the user that owns the directory all the mail is stored.";
};
vmailGroupName = lib.mkOption {
type = lib.types.str;
default = "vmail";
description = "The group name of the user that owns the directory all the mail is stored.";
};
mailDirectory = lib.mkOption {
type = lib.types.str;
default = "/var/vmail";
description = "Storage location for all mail.";
};
accounts = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
options = {
name = lib.mkOption {
type = lib.types.str;
example = "user1@example.com";
description = "Username";
};
hashedPasswordFile = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "/run/secrets/user1-passwordhash";
description = ''
A file containing the user's hashed password. Use `mkpasswd` as follows
```
nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt'
```
'';
};
isSystemUser = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
System users are not allowed to change their password and are
cannot receive any mails (-> send-only). Mails sent to such an
account will be rejected.
'';
};
rejectMessage = lib.mkOption {
type = lib.types.str;
default = "This account cannot receive emails.";
description = ''
The message that will be returned to the sender when an email is
sent to a system account.
'';
};
};
config.name = lib.mkDefault name;
}));
example = {
user1 = {
hashedPassword = "$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/";
};
user2 = {
hashedPassword = "$6$oE0ZNv2n7Vk9gOf$9xcZWCCLGdMflIfuA0vR1Q1Xblw6RZqPrP94mEit2/81/7AKj2bqUai5yPyWE.QYPyv6wLMHZvjw3Rlg7yTCD/";
};
};
description = "All available accounts for the mailsystem.";
default = {};
};
virtualDomainAliases = lib.mkOption {
type = with lib.types; attrsOf str;
example = {
"aliasdomain.com" = "domain.com";
};
description = ''
Virtual aliasing of domains. A virtual alias `"aliasdomain.com" = "domain.com"`
means that all mail directed at `@aliasdomain.com` are forwarded to `@domain.com`.
This also entails, that any account or alias of `domain.com` is partially valid
for `aliasdomain.com`. For example, `user@domain.com` can receive mails at
`user@aliasdomain.com`. However, if `user@domain.com` shall be able to dispatch
mails using `user@aliasdomain.com`, an explicit alias needs to be configured.
'';
default = {};
};
virtualAccountAliases = lib.mkOption {
type = let
account = lib.mkOptionType {
name = "Mail Account";
check = account: builtins.elem account (builtins.attrNames cfg.accounts);
};
in
with lib.types; attrsOf (either account (nonEmptyListOf account));
example = {
"info@example.com" = "user1@example.com";
"postmaster@example.com" = "user1@example.com";
"abuse@example.com" = "user1@example.com";
"multi@example.com" = ["user1@example.com" "user2@example.com"];
};
description = ''
Virtual account aliases. A virtual alias `"info@example.com" = "user1@example.com"`
means that all mail to `info@example.com` is forwarded to `user1@example.com`.
Furthermore, it also allows the user `user1@example.com` to send emails as
`info@example.com`. It is also possible to create an alias for multiple accounts.
In this example, all mails for `multi@example.com` will be forwarded to both
`user1@example.com` and `user2@example.com`.
'';
default = {};
};
dkimSettings = lib.mkOption {
type = with lib.types;
attrsOf (listOf (submodule {
options = {
selector = lib.mkOption {
type = lib.types.str;
example = "mail";
description = "DKIM Selector";
};
keyFile = lib.mkOption {
type = lib.types.path;
example = "/run/secrets/dkim/example.com.mail.key";
description = ''
Path to DKIM private-key-file. A public-private-pair can be generated as follows:
```
nix-shell -p rspamd --run 'rspamadm dkim_keygen -s "selector" -t ed25519 -d example.com
nix-shell -p rspamd --run 'rspamadm dkim_keygen -s "selector" -b 2048 -d example.com
```
'';
};
};
}));
example = {
"example.com" = [
{
selector = "mail";
keyFile = "/run/secrets/dkim/example.com.mail.key";
}
];
};
description = ''
Per-domain DKIM configuration.
This option allows to optionally set one or more DKIM private keys
and their respective selectors for each domain individually.
'';
default = {};
};
certificateScheme = lib.mkOption {
type = lib.types.enum ["acme" "selfsigned"];
default = "acme";
description = ''
The scheme to use for managing TLS certificates:
1. `acme`: The server retrieves letsencrypt certificates via NixOS's acme module using nginx.
2. `selfsigned`: The server creates self-signed certificates on the fly (intended for testing).
'';
internal = true;
visible = false;
};
};
imports = [
./dovecot.nix
./kresd.nix
./nginx.nix
./postfix.nix
./redis.nix
./roundcube.nix
./rspamd.nix
./selfsigned.nix
./user.nix
];
}