summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2022-11-30 22:30:45 +0100
committerNaïm Favier <n@monade.li>2022-12-22 20:45:01 +0100
commit4fcab839d7fe55cb6544ac57e615dd3c09cfeeb7 (patch)
treec02c904b0f8bb3214b427eb36504ed944160f3dd
parentbc667fb6afc45f6cc2d118ab77658faf2227cffd (diff)
docs: use MarkDown for option docs
-rw-r--r--.readthedocs.yaml4
-rw-r--r--default.nix51
-rw-r--r--docs/add-roundcube.rst2
-rw-r--r--docs/conf.py12
-rw-r--r--docs/howto-develop.rst8
-rw-r--r--docs/options.md1202
-rw-r--r--docs/options.rst1319
-rw-r--r--docs/requirements.txt6
-rw-r--r--flake.lock17
-rw-r--r--flake.nix90
-rw-r--r--scripts/generate-options.py81
-rw-r--r--scripts/generate-rst-options.py87
-rw-r--r--shell.nix11
13 files changed, 1403 insertions, 1487 deletions
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 3918d82..eb6988e 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -5,9 +5,9 @@
version: 2
build:
- os: ubuntu-20.04
+ os: ubuntu-22.04
tools:
- python: "3.9"
+ python: "3"
sphinx:
configuration: docs/conf.py
diff --git a/default.nix b/default.nix
index 275ac83..ef27f43 100644
--- a/default.nix
+++ b/default.nix
@@ -79,7 +79,7 @@ in
```
Warning: this is stored in plaintext in the Nix store!
- Use `hashedPasswordFile` instead.
+ Use {option}`mailserver.loginAccounts.<name>.hashedPasswordFile` instead.
'';
};
@@ -156,7 +156,7 @@ in
description = ''
Specifies if the account should be a send-only account.
Emails sent to send-only accounts will be rejected from
- unauthorized senders with the sendOnlyRejectMessage
+ unauthorized senders with the `sendOnlyRejectMessage`
stating the reason.
'';
};
@@ -200,7 +200,7 @@ in
description = ''
Folder to store search indices. If null, indices are stored
along with email, which could not necessarily be desirable,
- especially when the fullTextSearch option is enable since
+ especially when {option}`mailserver.fullTextSearch.enable` is `true` since
indices it creates are voluminous and do not need to be backed
up.
@@ -242,8 +242,8 @@ in
default = "no";
description = ''
Fail searches when no index is available. If set to
- <literal>body</literal>, then only body searches (as opposed to
- header) are affected. If set to <literal>no</literal>, searches may
+ `body`, then only body searches (as opposed to
+ header) are affected. If set to `no`, searches may
fall back to a very slow brute force search.
'';
};
@@ -281,7 +281,7 @@ in
randomizedDelaySec = mkOption {
type = types.int;
default = 1000;
- description = "Run the maintenance job not exactly at the time specified with <literal>onCalendar</literal>, but plus or minus this many seconds.";
+ description = "Run the maintenance job not exactly at the time specified with `onCalendar`, but plus or minus this many seconds.";
};
};
};
@@ -333,7 +333,7 @@ in
the value {`"user@example.com" = "user@elsewhere.com";}`
means that mails to `user@example.com` are forwarded to
`user@elsewhere.com`. The difference with the
- `extraVirtualAliases` option is that `user@elsewhere.com`
+ {option}`mailserver.extraVirtualAliases` option is that `user@elsewhere.com`
can't send mail as `user@example.com`. Also, this option
allows to forward mails to external addresses.
'';
@@ -367,7 +367,7 @@ in
description = ''
The unix UID of the virtual mail user. Be mindful that if this is
changed, you will need to manually adjust the permissions of
- mailDirectory.
+ `mailDirectory`.
'';
};
@@ -582,7 +582,7 @@ in
type = types.str;
default = "mail";
description = ''
-
+ The DKIM selector.
'';
};
@@ -590,7 +590,7 @@ in
type = types.path;
default = "/var/dkim";
description = ''
-
+ The DKIM directory.
'';
};
@@ -601,7 +601,7 @@ in
How many bits in generated DKIM keys. RFC6376 advises minimum 1024-bit keys.
If you have already deployed a key with a different number of bits than specified
- here, then you should use a different selector (dkimSelector). In order to get
+ here, then you should use a different selector ({option}`mailserver.dkimSelector`). In order to get
this package to generate a key with the new number of bits, you will either have to
change the selector or delete the old key file.
'';
@@ -673,7 +673,7 @@ in
type = types.str;
example = "ACME Corp.";
description = ''
- The name of your organization used in the <literal>org_name</literal> attribute in
+ The name of your organization used in the `org_name` attribute in
DMARC reports.
'';
};
@@ -681,7 +681,7 @@ in
fromName = mkOption {
type = types.str;
default = cfg.dmarcReporting.organizationName;
- defaultText = literalExpression "organizationName";
+ defaultText = literalMD "{option}`mailserver.dmarcReporting.organizationName`";
description = ''
The sender name for DMARC reports. Defaults to the organization name.
'';
@@ -738,7 +738,7 @@ in
if (ip == "0.0.0.0" || ip == "::")
then "127.0.0.1"
else if isIpv6 ip then "[${ip}]" else ip;
- defaultText = lib.literalDocBook "computed from <option>config.services.redis.servers.rspamd.bind</option>";
+ defaultText = lib.literalMD "computed from `config.services.redis.servers.rspamd.bind`";
description = ''
Address that rspamd should use to contact redis.
'';
@@ -776,7 +776,7 @@ in
sendingFqdn = mkOption {
type = types.str;
default = cfg.fqdn;
- defaultText = "config.mailserver.fqdn";
+ defaultText = lib.literalMD "{option}`mailserver.fqdn`";
example = "myserver.example.com";
description = ''
The fully qualified domain name of the mail server used to
@@ -792,7 +792,7 @@ in
This setting allows the server to identify as
myserver.example.com when forwarding mail, independently of
- `fqdn` (which, for SSL reasons, should generally be the name
+ {option}`mailserver.fqdn` (which, for SSL reasons, should generally be the name
to which the user connects).
Set this to the name to which the sending IP's reverse DNS
@@ -864,7 +864,7 @@ in
start program = "${pkgs.systemd}/bin/systemctl start rspamd"
stop program = "${pkgs.systemd}/bin/systemctl stop rspamd"
'';
- defaultText = lib.literalDocBook "see source";
+ defaultText = lib.literalMD "see [source](https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/blob/master/default.nix)";
description = ''
The configuration used for monitoring via monit.
Use a mail address that you actively check and set it via 'set alert ...'.
@@ -881,7 +881,8 @@ in
description = ''
The location where borg saves the backups.
This can be a local path or a remote location such as user@host:/path/to/repo.
- It is exported and thus available as an environment variable to cmdPreexec and cmdPostexec.
+ It is exported and thus available as an environment variable to
+ {option}`mailserver.borgbackup.cmdPreexec` and {option}`mailserver.borgbackup.cmdPostexec`.
'';
};
@@ -941,7 +942,7 @@ in
default = "none";
description = ''
The backup can be encrypted by choosing any other value than 'none'.
- When using encryption the password / passphrase must be provided in passphraseFile.
+ When using encryption the password/passphrase must be provided in `passphraseFile`.
'';
};
@@ -964,6 +965,7 @@ in
locations = mkOption {
type = types.listOf types.path;
default = [cfg.mailDirectory];
+ defaultText = lib.literalExpression "[ config.mailserver.mailDirectory ]";
description = "The locations that are to be backed up by borg.";
};
@@ -984,9 +986,10 @@ in
default = null;
description = ''
The command to be executed before each backup operation.
- This is called prior to borg init in the same script that runs borg init and create and cmdPostexec.
- Example:
- export BORG_RSH="ssh -i /path/to/private/key"
+ This is called prior to borg init in the same script that runs borg init and create and `cmdPostexec`.
+ '';
+ example = ''
+ export BORG_RSH="ssh -i /path/to/private/key"
'';
};
@@ -996,7 +999,7 @@ in
description = ''
The command to be executed after each backup operation.
This is called after borg create completed successfully and in the same script that runs
- cmdPreexec, borg init and create.
+ `cmdPreexec`, borg init and create.
'';
};
@@ -1009,7 +1012,7 @@ in
example = true;
description = ''
Whether to enable automatic reboot after kernel upgrades.
- This is to be used in conjunction with system.autoUpgrade.enable = true"
+ This is to be used in conjunction with `system.autoUpgrade.enable = true;`
'';
};
method = mkOption {
diff --git a/docs/add-roundcube.rst b/docs/add-roundcube.rst
index 6d4795c..4e6be83 100644
--- a/docs/add-roundcube.rst
+++ b/docs/add-roundcube.rst
@@ -1,5 +1,5 @@
Add Roundcube, a webmail
-=======================
+========================
The NixOS module for roundcube nearly works out of the box with SNM. By
default, it sets up a nginx virtual host to serve the webmail, other web
diff --git a/docs/conf.py b/docs/conf.py
index 84eb68b..1845917 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -18,7 +18,7 @@
# -- Project information -----------------------------------------------------
project = 'NixOS Mailserver'
-copyright = '2020, NixOS Mailserver Contributors'
+copyright = '2022, NixOS Mailserver Contributors'
author = 'NixOS Mailserver Contributors'
@@ -28,8 +28,16 @@ author = 'NixOS Mailserver Contributors'
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ 'myst_parser'
]
+myst_enable_extensions = [
+ 'colon_fence',
+ 'linkify',
+]
+
+smartquotes = False
+
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -50,4 +58,4 @@ html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = []
diff --git a/docs/howto-develop.rst b/docs/howto-develop.rst
index ce74683..0ac9009 100644
--- a/docs/howto-develop.rst
+++ b/docs/howto-develop.rst
@@ -30,8 +30,8 @@ run tests manually. For instance:
Contributing to the documentation
---------------------------------
-The documentation is written in RST, build with Sphinx and published
-by `Read the Docs <https://readthedocs.org/>`_.
+The documentation is written in RST (except option documentation which is in MarkDown),
+built with Sphinx and published by `Read the Docs <https://readthedocs.org/>`_.
For the syntax, see `RST/Sphinx Cheatsheet
<https://sphinx-tutorial.readthedocs.io/cheatsheet/>`_.
@@ -47,11 +47,11 @@ documentation:
$ firefox ./_build/html/index.html
Note if you modify some NixOS mailserver options, you would also need
-to regenerate the ``options.rst`` file:
+to regenerate the ``options.md`` file:
::
- $ nix-shell --run generate-rst-options
+ $ nix-shell --run generate-options
Nixops
------
diff --git a/docs/options.md b/docs/options.md
new file mode 100644
index 0000000..0944fa7
--- /dev/null
+++ b/docs/options.md
@@ -0,0 +1,1202 @@
+
+# Mailserver options
+
+## `mailserver`
+
+
+
+`````{option} mailserver.debug
+Whether to enable verbose logging for mailserver related services. This
+intended be used for development purposes only, you probably don't want
+to enable this unless you're hacking on nixos-mailserver.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.domains
+The domains that this mail server serves.
+
+- type: ```list of string```
+- default: ```[]```
+- example: ```['example.com']```
+`````
+
+
+`````{option} mailserver.enable
+Whether to enable nixos-mailserver.
+
+- type: ```boolean```
+- default: ```False```
+- example: ```True```
+`````
+
+
+`````{option} mailserver.enableImap
+Whether to enable IMAP with STARTTLS on port 143.
+
+
+- type: ```boolean```
+- default: ```True```
+
+`````
+
+
+`````{option} mailserver.enableImapSsl
+Whether to enable IMAP with TLS in wrapper-mode on port 993.
+
+
+- type: ```boolean```
+- default: ```True```
+
+`````
+
+
+`````{option} mailserver.enableManageSieve
+Whether to enable ManageSieve, setting this option to true will open
+port 4190 in the firewall.
+
+The ManageSieve protocol allows users to manage their Sieve scripts on
+a remote server with a supported client, including Thunderbird.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.enablePop3
+Whether to enable POP3 with STARTTLS on port on port 110.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.enablePop3Ssl
+Whether to enable POP3 with TLS in wrapper-mode on port 995.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.enableSubmission
+Whether to enable SMTP with STARTTLS on port 587.
+
+
+- type: ```boolean```
+- default: ```True```
+
+`````
+
+
+`````{option} mailserver.enableSubmissionSsl
+Whether to enable SMTP with TLS in wrapper-mode on port 465.
+
+
+- type: ```boolean```
+- default: ```True```
+
+`````
+
+
+`````{option} mailserver.extraVirtualAliases
+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`.
+
+
+- type: ```attribute set of ((Login Account) or non-empty (list of (Login Account)))```
+- default: ```{}```
+- example: ```{'abuse@example.com': 'user1@example.com', 'info@example.com': 'user1@example.com', 'multi@example.com': ['user1@example.com', 'user2@example.com'], 'postmaster@example.com': 'user1@example.com'}```
+`````
+
+
+`````{option} mailserver.forwards
+To forward mails to an external address. For instance,
+the value {`"user@example.com" = "user@elsewhere.com";}`
+means that mails to `user@example.com` are forwarded to
+`user@elsewhere.com`. The difference with the
+{option}`mailserver.extraVirtualAliases` option is that `user@elsewhere.com`
+can't send mail as `user@example.com`. Also, this option
+allows to forward mails to external addresses.
+
+
+- type: ```attribute set of ((list of string) or string)```
+- default: ```{}```
+- example: ```{'user@example.com': 'user@elsewhere.com'}```
+`````
+
+
+`````{option} mailserver.fqdn
+The fully qualified domain name of the mail server.
+
+- type: ```string```
+
+- example: ```mx.example.com```
+`````
+
+
+`````{option} mailserver.hierarchySeparator
+The hierarchy separator for mailboxes used by dovecot for the namespace 'inbox'.
+Dovecot defaults to "." but recommends "/".
+This affects how mailboxes appear to mail clients and sieve scripts.
+For instance when using "." then in a sieve script "example.com" would refer to the mailbox "com" in the parent mailbox "example".
+This does not determine the way your mails are stored on disk.
+See https://wiki.dovecot.org/Namespaces for details.
+
+
+- type: ```string```
+- default: ```.```
+
+`````
+
+
+`````{option} mailserver.indexDir
+Folder to store search indices. If null, indices are stored
+along with email, which could not necessarily be desirable,
+especially when {option}`mailserver.fullTextSearch.enable` is `true` since
+indices it creates are voluminous and do not need to be backed
+up.
+
+Be careful when changing this option value since all indices
+would be recreated at the new location (and clients would need
+to resynchronize).
+
+Note the some variables can be used in the file path. See
+https://doc.dovecot.org/configuration_manual/mail_location/#variables
+for details.
+
+
+- type: ```null or string```
+- default: ```None```
+- example: ```/var/lib/dovecot/indices```
+`````
+
+
+`````{option} mailserver.keyFile
+Scheme 1)
+Location of the key file
+
+
+- type: ```path```
+
+- example: ```/root/mail-server.key```
+`````
+
+
+`````{option} mailserver.lmtpSaveToDetailMailbox
+If an email address is delimited by a "+", should it be filed into a
+mailbox matching the string after the "+"? For example,
+user1+test@example.com would be filed into the mailbox "test".
+
+
+- type: ```one of "yes", "no"```
+- default: ```yes```
+
+`````
+
+
+`````{option} mailserver.localDnsResolver
+Runs a local DNS resolver (kresd) as recommended when running rspamd. This prevents your log file from filling up with rspamd_monitored_dns_mon entries.
+
+
+- type: ```boolean```
+- default: ```True```
+
+`````
+
+
+`````{option} mailserver.mailDirectory
+Where to store the mail.
+
+
+- type: ```path```
+- default: ```/var/vmail```
+
+`````
+
+
+`````{option} mailserver.mailboxes
+The mailboxes for dovecot.
+Depending on the mail client used it might be necessary to change some mailbox's name.
+
+
+- type: ```unspecified value```
+- default: ```{'Drafts': {'auto': 'subscribe', 'specialUse': 'Drafts'}, 'Junk': {'auto': 'subscribe', 'specialUse': 'Junk'}, 'Sent': {'auto': 'subscribe', 'specialUse': 'Sent'}, 'Trash': {'auto': 'no', 'specialUse': 'Trash'}}```
+
+`````
+
+
+`````{option} mailserver.maxConnectionsPerUser
+Maximum number of IMAP/POP3 connections allowed for a user from each IP address.
+E.g. a value of 50 allows for 50 IMAP and 50 POP3 connections at the same
+time for a single user.
+
+
+- type: ```signed integer```
+- default: ```100```
+
+`````
+
+
+`````{option} mailserver.messageSizeLimit
+Message size limit enforced by Postfix.
+
+- type: ```signed integer```
+- default: ```20971520```
+- example: ```52428800```
+`````
+
+
+`````{option} mailserver.openFirewall
+Automatically open ports in the firewall.
+
+- type: ```boolean```
+- default: ```True```
+
+`````
+
+
+`````{option} mailserver.policydSPFExtraConfig
+Extra configuration options for policyd-spf. This can be use to among
+other things skip spf checking for some IP addresses.
+
+
+- type: ```strings concatenated with "\n"```
+- default: `""`
+- example:
+```
+skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1
+```
+`````
+
+
+`````{option} mailserver.rebootAfterKernelUpgrade.enable
+Whether to enable automatic reboot after kernel upgrades.
+This is to be used in conjunction with `system.autoUpgrade.enable = true;`
+
+
+- type: ```boolean```
+- default: ```False```
+- example: ```True```
+`````
+
+
+`````{option} mailserver.rebootAfterKernelUpgrade.method
+Whether to issue a full "reboot" or just a "systemctl kexec"-only reboot.
+It is recommended to use the default value because the quicker kexec reboot has a number of problems.
+Also if your server is running in a virtual machine the regular reboot will already be very quick.
+
+
+- type: ```one of "reboot", "systemctl kexec"```
+- default: ```reboot```
+
+`````
+
+
+`````{option} mailserver.recipientDelimiter
+Configure the recipient delimiter.
+
+
+- type: ```string```
+- default: ```+```
+
+`````
+
+
+`````{option} mailserver.rejectRecipients
+Reject emails addressed to these local addresses from unauthorized senders.
+Use if a spammer has found email addresses in a catchall domain but you do
+not want to disable the catchall.
+
+
+- type: ```list of string```
+- default: ```[]```
+- example: ```['sales@example.com', 'info@example.com']```
+`````
+
+
+`````{option} mailserver.rejectSender
+Reject emails from these addresses from unauthorized senders.
+Use if a spammer is using the same domain or the same sender over and over.
+
+
+- type: ```list of string```
+- default: ```[]```
+- example: ```['@example.com', 'spammer@example.net']```
+`````
+
+
+`````{option} mailserver.rewriteMessageId
+Rewrites the Message-ID's hostname-part of outgoing emails to the FQDN.
+Please be aware that this may cause problems with some mail clients
+relying on the original Message-ID.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.sendingFqdn
+The fully qualified domain name of the mail server used to
+identify with remote servers.
+
+If this server's IP serves purposes other than a mail server,
+it may be desirable for the server to have a name other than
+that to which the user will connect. For example, the user
+might connect to mx.example.com, but the server's IP has
+reverse DNS that resolves to myserver.example.com; in this
+scenario, some mail servers may reject or penalize the
+message.
+
+This setting allows the server to identify as
+myserver.example.com when forwarding mail, independently of
+{option}`mailserver.fqdn` (which, for SSL reasons, should generally be the name
+to which the user connects).
+
+Set this to the name to which the sending IP's reverse DNS
+resolves.
+
+
+- type: ```string```
+- default: {option}`mailserver.fqdn`
+- example: ```myserver.example.com```
+`````
+
+
+`````{option} mailserver.sieveDirectory
+Where to store the sieve scripts.
+
+
+- type: ```path```
+- default: ```/var/sieve```
+
+`````
+
+
+`````{option} mailserver.useFsLayout
+Sets whether dovecot should organize mail in subdirectories:
+
+- /var/vmail/example.com/user/.folder.subfolder/ (default layout)
+- /var/vmail/example.com/user/folder/subfolder/ (FS layout)
+
+See https://wiki2.dovecot.org/MailboxFormat/Maildir for details.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.virusScanning
+Whether to activate virus scanning. Note that virus scanning is _very_
+expensive memory wise.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.vmailGroupName
+The user name and group name of the user that owns the directory where all
+the mail is stored.
+
+
+- type: ```string```
+- default: ```virtualMail```
+
+`````
+
+
+`````{option} mailserver.vmailUID
+The unix UID of the virtual mail user. Be mindful that if this is
+changed, you will need to manually adjust the permissions of
+`mailDirectory`.
+
+
+- type: ```signed integer```
+- default: ```5000```
+
+`````
+
+
+`````{option} mailserver.vmailUserName
+The user name and group name of the user that owns the directory where all
+the mail is stored.
+
+
+- type: ```string```
+- default: ```virtualMail```
+
+`````
+
+## `mailserver.loginAccounts`
+
+
+`````{option} mailserver.loginAccounts
+The login account of the domain. Every account is mapped to a unix user,
+e.g. `user1@example.com`. To generate the passwords use `mkpasswd` as
+follows
+
+```
+nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt'
+```
+
+
+- type: ```attribute set of (submodule)```
+- default: ```{}```
+- example: ```{'user1': {'hashedPassword': '$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/'}, 'user2': {'hashedPassword': '$6$oE0ZNv2n7Vk9gOf$9xcZWCCLGdMflIfuA0vR1Q1Xblw6RZqPrP94mEit2/81/7AKj2bqUai5yPyWE.QYPyv6wLMHZvjw3Rlg7yTCD/'}}```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.aliases
+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.
+
+
+- type: ```list of string```
+- default: ```[]```
+- example: ```['abuse@example.com', 'postmaster@example.com']```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.catchAll
+For which domains should this account act as a catch all?
+Note: Does not allow sending from all addresses of these domains.
+
+
+- type: ```list of value "example.com" (singular enum)```
+- default: ```[]```
+- example: ```['example.com', 'example2.com']```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.hashedPassword
+The user's hashed password. Use `mkpasswd` as follows
+
+```
+nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt'
+```
+
+Warning: this is stored in plaintext in the Nix store!
+Use {option}`mailserver.loginAccounts.<name>.hashedPasswordFile` instead.
+
+
+- type: ```null or string```
+- default: ```None```
+- example: ```$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.hashedPasswordFile
+A file containing the user's hashed password. Use `mkpasswd` as follows
+
+```
+nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt'
+```
+
+
+- type: ```null or path```
+- default: ```None```
+- example: ```/run/keys/user1-passwordhash```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.name
+Username
+
+- type: ```string```
+
+- example: ```user1@example.com```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.quota
+Per user quota rules. Accepted sizes are `xx k/M/G/T` with the
+obvious meaning. Leave blank for the standard quota `100G`.
+
+
+- type: ```null or string```
+- default: ```None```
+- example: ```2G```
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.sendOnly
+Specifies if the account should be a send-only account.
+Emails sent to send-only accounts will be rejected from
+unauthorized senders with the `sendOnlyRejectMessage`
+stating the reason.
+
+
+- type: ```boolean```
+- default: ```False```
+
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.sendOnlyRejectMessage
+The message that will be returned to the sender when an email is
+sent to a send-only account. Only used if the account is marked
+as send-only.
+
+
+- type: ```string```
+- default: ```This account cannot receive emails.```
+
+`````
+
+
+`````{option} mailserver.loginAccounts.<name>.sieveScript
+Per-user sieve script.
+
+
+- type: ```null or strings concatenated with "\n"```
+- default: ```None```
+- example:
+```
+require ["fileinto", "mailbox"];
+
+if address :is "from" "gitlab@mg.gitlab.com" {
+ fileinto :create "GitLab";
+ stop;
+}
+
+# This must be the last rule, it will check if list-id is set, and
+# file the message into the Lists folder for further investigation
+elsif header :matches "list-id" "<?*>" {
+ fileinto :create "Lists";
+ stop;
+}
+```
+`````
+
+## `mailserver.certificate`
+
+
+`````{option} mailserver.certificateDirectory
+Scheme 2)
+This is the folder where the certificate will be created. The name is
+hardcoded to "cert-DOMAIN.pem" and "key-DOMAIN.pem" and the
+certificate is valid for 10 years.
+
+
+- type: ```path```
+- default: ```/var/certs```
+
+`````
+
+
+`````{option} mailserver.certificateDomains
+Secondary domains and subdomains for which it is necessary to generate a certificate.
+
+- type: ```list of string```
+- default: ```[]```
+- example: ```['imap.example.com', 'pop3.example.com']```
+`````
+
+
+`````{option} mailserver.certificateFile
+Scheme 1)
+Location of the certificate
+
+
+- type: ```path```
+
+- example: ```/root/mail-server.crt```
+`````
+
+
+`````{option} mailserver.certificateScheme
+Certificate Files. There are three options for these.
+
+1) You specify locations and manually copy certificates there.
+2) You let the server create new (self signed) certificates on the fly.
+3) You let the server create a certificate via `Let's Encrypt`. Note that
+ this implies that a stripped down webserver has to be started. This also
+ implies that the FQDN must be set as an `A` record to point to the IP of
+ the server. In particular port 80 on the server will be opened. For details
+ on how to set up the domain records, see the guide in the readme.
+
+
+- type: ```one of 1, 2, 3```
+- default: ```2```
+
+`````
+
+## `mailserver.dkim`
+
+
+`````{option} mailserver.dkimBodyCanonicalization
+DKIM canonicalization algorithm for message bodies.
+
+See https://datatracker.ietf.org/doc/html/rfc6376/#section-3.4 for details.
+
+
+- type: ```one of "relaxed", "simple"```
+- default: ```relaxed```
+
+`````
+
+
+`````{option} mailserver.dkimHeaderCanonicalization
+DKIM canonicalization algorithm for message headers.
+
+See https://datatracker.ietf.org/doc/html/rfc6376/#section-3.4 for details.
+
+
+- type: ```one of "relaxed", "simple"```
+- default: ```relaxed```
+
+`````
+
+
+`````{option} mailserver.dkimKeyBits
+How many bits in generated DKIM keys. RFC6376 advises minimum 1024-bit keys.
+
+If you have already deployed a key with a different number of bits than specified
+here, then you should use a different selector ({option}`mailserver.dkimSelector`). In order to get
+this package to generate a key with the new number of bits, you will either have to
+change the selector or delete the old key file.
+
+
+- type: ```signed integer```
+- def