248 lines
8.1 KiB
Nix
248 lines
8.1 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'
|
|
```
|
|
'';
|
|
};
|
|
|
|
aliases = lib.mkOption {
|
|
type = with lib.types; listOf types.str;
|
|
example = ["abuse@example.com" "postmaster@example.com"];
|
|
default = [];
|
|
description = ''
|
|
A list of aliases of this login account.
|
|
Note: Use list entries like "@example.com" to create a catchAll
|
|
that allows sending from all email addresses in these domain.
|
|
'';
|
|
};
|
|
|
|
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 login account 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 = {};
|
|
};
|
|
|
|
extraVirtualAliases = lib.mkOption {
|
|
type = let
|
|
account = lib.mkOptionType {
|
|
name = "Login 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 Aliases. A virtual alias `"info@example.com" = "user1@example.com"` means that
|
|
all mail to `info@example.com` is forwarded to `user1@example.com`. Note
|
|
that it is expected that `postmaster@example.com` and `abuse@example.com` is
|
|
forwarded to some valid email address. (Alternatively you can create login
|
|
accounts for `postmaster` and (or) `abuse`). Furthermore, it also allows
|
|
the user `user1@example.com` to send emails as `info@example.com`.
|
|
It's 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
|
|
];
|
|
}
|