246 lines
8.1 KiB
Nix
246 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'
|
|
```
|
|
'';
|
|
};
|
|
|
|
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 = {};
|
|
};
|
|
|
|
virtualAliases = lib.mkOption {
|
|
type = let
|
|
isAccount = value: builtins.elem value (builtins.attrNames cfg.accounts);
|
|
isDomain = value: !(lib.hasInfix "@" value) && (builtins.elem value cfg.domains);
|
|
account = lib.mkOptionType {
|
|
name = "Mail Account";
|
|
check = isAccount;
|
|
};
|
|
accountOrDomain = lib.mkOptionType {
|
|
name = "Mail Account or Domain";
|
|
check = value: (isAccount value) || (isDomain value);
|
|
};
|
|
in
|
|
with lib.types; attrsOf (either (nonEmptyListOf account) accountOrDomain);
|
|
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"];
|
|
"aliasdomain.com" = "domain.com";
|
|
};
|
|
description = ''
|
|
Virtual account and domain aliases. A virtual alias means, that all mail directed
|
|
at a given target are forwarded to the specified other destinations, too.
|
|
|
|
For account aliases, this means that, e.g., `"user1@example.com"` receives all mail
|
|
sent to `"info@example.com"`. In addition, `"user1@example.com"` is also able to
|
|
impersonate `"info@example.com"` when sending mails. 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"`.
|
|
|
|
For domain aliases, this means that all mails directed at an aliased domain, e.g.,
|
|
`"aliasdomain.com"` are forwarded to `"domain.com"` This also entails, that any
|
|
account or alias of `"domain.com"` receives mails directed at `"aliasdomain.com"`.
|
|
However, if `"user@domain.com"` shall be able to send mails using
|
|
`"user@aliasdomain.com"`, an explicit alias needs to be configured.
|
|
'';
|
|
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 = {};
|
|
};
|
|
|
|
extraSettingsFile = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.path;
|
|
description = ''
|
|
YAML file to merge into the mailsystem configuration at runtime.
|
|
This can be used to store secrets, and, more importantly, keep your email
|
|
addresses out of the hands of spammers. This `extraSettingsFile` currently
|
|
supports `domains`, `accounts` and `virtualAliases` which can be defined in
|
|
the same manner as they can be via nix.
|
|
'';
|
|
default = null;
|
|
};
|
|
|
|
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
|
|
];
|
|
}
|