300 lines
11 KiB
ReStructuredText
300 lines
11 KiB
ReStructuredText
Migrations
|
||
==========
|
||
|
||
With mail server configuration best practices changing over time we might need
|
||
to make changes that require you to complete manual migration steps before you
|
||
can deploy a new version of NixOS mailserver.
|
||
|
||
The initial :option:`mailserver.stateVersion` value should be copied from the
|
||
setup guide that you used to initially set up your mail server. If in doubt you
|
||
can always initialize it at ``1`` and walk through all assertions, that might
|
||
apply to your setup.
|
||
|
||
NixOS 26.05
|
||
-----------
|
||
|
||
.. _migration-5:
|
||
|
||
#5 Sieve script directory migration
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
Sieve scripts managed by users via ManageSieve were previously stored in
|
||
``/var/sieve`` (or via the now-removed option
|
||
``mailserver.sieveDirectory``). This setup partially mirrored the mail
|
||
directory structure in ``/var/vmail`` (``mailserver.storage.path``),
|
||
which proved to be fragile and error-prone.
|
||
|
||
Thanks to a `prior migration`_, we can now migrate these directories into each
|
||
user’s home directory, aligning with upstream recommendations — almost
|
||
nine years later.
|
||
|
||
.. _prior migration: #dovecot-mail-directory-migration
|
||
|
||
This migration is only required if you have :option:`mailserver.enableManageSieve` enabled.
|
||
|
||
1. If you are coming from ``25.11`` and are using LDAP, temporarily disable
|
||
:option:`mailserver.enableManageSieve` by setting it to ``false``, deploy,
|
||
and only then continue with this migration.
|
||
|
||
If you are not coming from ``25.11`` or are not using LDAP, continue with
|
||
this migration as is.
|
||
|
||
2. Copy the migration script to your mailserver and make it executable:
|
||
|
||
.. code-block:: console
|
||
|
||
cd /tmp
|
||
wcurl https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/raw/main/migrations/nixos-mailserver-migration-05.py
|
||
chmod +x nixos-mailserver-migration-05.py
|
||
|
||
3. Stop the ``postfix.service``.
|
||
|
||
.. code-block:: bash
|
||
|
||
systemctl stop postfix.service
|
||
|
||
4. Create a backup or snapshot of your ``mailserver.sieveDirectory``, so
|
||
you can restore should anything go wrong.
|
||
|
||
5. Run the migration script and pass your ``mailserver.sieveDirectory`` as argument:
|
||
|
||
The script should be run under the user who owns the ``mailserver.sieveDirectory``.
|
||
If run as root it will automatically switch into the appropriate user by itself.
|
||
|
||
The script will not modify your data unless called with ``--execute``.
|
||
|
||
The migration script finds all Sieve script directories in
|
||
``/var/sieve/`` (or any other ``mailserver.sieveDirectory``), for
|
||
example that of ``bob`` at ``/var/vmail/bob@example.com``.
|
||
|
||
It then takes ``bob@example.com`` and looks up the home directory
|
||
for ``bob``. Finally, it starts suggesting the necessary move
|
||
operations to migrate the Sieve directory to
|
||
``/var/vmail/example.com/bob/sieve`` and symlinks the active script
|
||
to ``/var/vmail/example.com/bob/.dovecot.sieve``.
|
||
|
||
Example:
|
||
|
||
.. code-block:: bash
|
||
|
||
./nixos-mailserver-migration-05.py \
|
||
/var/sieve
|
||
|
||
6. Review the script output.
|
||
|
||
The script can highlight various inconsistencies and problems, that should
|
||
be reviewed and acted upon.
|
||
|
||
If in doubt, join our community chat for help before applying any changes.
|
||
|
||
7. Rerun the command with ``--execute`` or run the proposed commands manually.
|
||
|
||
8. Update the ``mailserver.stateVersion`` to ``5``.
|
||
|
||
9. The previous Sieve directory (``mailserver.sieveDirectory``) should now be safe to delete.
|
||
|
||
10. If you temporarily disabled :option:`mailserver.enableManageSieve` in step 1,
|
||
re-enable it now by setting it back to ``true``.
|
||
|
||
.. _migration-4:
|
||
|
||
#4 Dovecot LDAP UUID-based home directories
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
LDAP Support in NixOS mailserver was introduced during the 23.11 release cycle
|
||
and came with a number of flaws that we are correcting now, three years later.
|
||
|
||
This particular migration is needed because up until now we were
|
||
relying on email addresses to construct the Dovecot home directory path
|
||
(``var/vmail/ldap/user@example.com``) which is fragile: addresses can
|
||
change, requiring manual homedir relocation. Switching to UUID-based homedirs
|
||
(``/var/vmail/ldap/<uuid>``) ensures stable, unique paths and applies well-known
|
||
best practices to mailserver management.
|
||
|
||
1. Copy the migration script to your mailserver and make it executable:
|
||
|
||
.. code-block:: console
|
||
|
||
cd /tmp
|
||
wcurl https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/raw/main/migrations/nixos-mailserver-migration-04.py
|
||
chmod +x nixos-mailserver-migration-04.py
|
||
|
||
2. Stop the ``dovecot.service``.
|
||
|
||
.. code-block:: bash
|
||
|
||
systemctl stop dovecot.service
|
||
|
||
3. Create a backup or snapshot of your :option:`mailserver.storage.path`, so
|
||
you can restore should anything go wrong.
|
||
|
||
4. Run the migration script and pass the required arguments to enable LDAP lookups:
|
||
|
||
The script should be run under the user who owns the :option:`mailserver.storage.path`.
|
||
If run as root it will automatically switch into the appropriate user by itself.
|
||
|
||
The script will not modify your data unless called with ``--execute``.
|
||
|
||
The migration script finds all Dovecot home directories in
|
||
``/var/vmail/ldap/`` (or any other :option:`mailserver.storage.path`),
|
||
for example that of bob at ``/var/vmail/ldap/bob@example.com``.
|
||
It then takes ``bob@example.com`` and queries the LDAP server for
|
||
``mail=bob@example.com`` to retrieve the UUID attribute. Finally
|
||
it starts suggesting the necessary move operations to arrive at
|
||
``/var/vmail/ldap/f3b4e8ea-087f-42cc-95f0-cbfd99386092`` for bob.
|
||
|
||
Example:
|
||
|
||
.. code-block:: bash
|
||
|
||
./nixos-mailserver-migration-04.py \
|
||
--ldap-uri ldaps://ldap1.example.com
|
||
--ldap-bind-dn cn=mail,ou=accounts,dc=example,dc=com \
|
||
--ldap-bind-pw-file /run/keys/ldap-bind-pw \
|
||
--ldap-base ou=people,ou=accounts,dc=example,dc=com \
|
||
--ldap-scope sub \
|
||
--ldap-filter "(mail=%s)" \
|
||
--ldap-attr-uuid entryUUID \
|
||
/var/vmail
|
||
|
||
For the ``--ldap-attr-uuid`` parameter we expect a long-term stable
|
||
identifier, ideally a UUID field. The exact attribute name depends on your
|
||
LDAP implementation, for example:
|
||
|
||
- Authentik: ``uid`` `[1]`_
|
||
- Kanidm: ``uuid`` `[2]`_
|
||
- Keycloak ``entryUUID``
|
||
- OpenLDAP: ``entryUUID`` (`RFC4530`_)
|
||
|
||
If your LDAP provider isn't listed you can determine the correct
|
||
attribute by querying a user entry with ``ldapsearch``. Finally, configure
|
||
:option:`mailserver.ldap.attributes.uuid` accordingly.
|
||
|
||
Add ``--ldap-starttls`` if you use the the `ldap://` URI scheme and require
|
||
explicit TLS.
|
||
|
||
.. _[1]: https://docs.goauthentik.io/add-secure-apps/providers/ldap#users
|
||
.. _[2]: https://kanidm.github.io/kanidm/stable/integrations/ldap.html#data-mapping
|
||
.. _RFC4530: https://www.rfc-editor.org/rfc/rfc4530.html
|
||
|
||
5. Review the script output.
|
||
|
||
It's primary job is to determine the UUID for an LDAP account, so that it
|
||
can rename the Dovecot home directory from mail address to UUID within the
|
||
same directory.
|
||
|
||
The script can highlight various inconsistencies and problems, that should
|
||
be reviewed and acted upon.
|
||
|
||
If in doubt, join our community chat for help before applying any changes.
|
||
|
||
6. Rerun the command with ``--execute`` or run the proposed commands manually.
|
||
|
||
7. Update the ``mailserver.stateVersion`` to ``4``.
|
||
|
||
NixOS 25.11
|
||
-----------
|
||
|
||
#3 Dovecot mail directory migration
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
The way the Dovecot home directory for login accounts were previously set up
|
||
resulted in shared home directories for all those users. This is not a
|
||
supported Dovecot configuration.
|
||
|
||
To resolve this we migrated the home directory into the individual
|
||
`domain/localpart` subdirectory below the `mailserver.mailDirectory`.
|
||
|
||
But since this now overlaps with the location of the Maildir, it must be
|
||
migrated into the `mail/` directory below the home directory.
|
||
And while the LDAP home directory is not affected we use this migration to
|
||
keep the Maildir configurations of LDAP users in sync with those of local
|
||
accounts.
|
||
|
||
This is a big step forward, since we can now more cleanly colocate other
|
||
data directories, like sieve in the home directory, which in turn simplifies
|
||
backups.
|
||
|
||
This migration is required for every configuration.
|
||
|
||
For remediating this issue the following steps are required:
|
||
|
||
1. Copy the `migration script <https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/blob/main/migrations/nixos-mailserver-migration-03.py>`_ script to your mailserver
|
||
and make it executable:
|
||
|
||
.. code-block:: bash
|
||
|
||
wcurl https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/raw/main/migrations/nixos-mailserver-migration-03.py
|
||
chmod +x nixos-mailserver-migration-03.py
|
||
|
||
2. Stop the ``dovecot.service``.
|
||
|
||
.. code-block:: bash
|
||
|
||
systemctl stop dovecot.service
|
||
|
||
3. Create a backup or snapshot of your ``mailserver.mailDirectory``, so you can restore
|
||
should anything go wrong.
|
||
|
||
4. Run the migration script under your virtual mail user with the following arguments:
|
||
|
||
- ``--layout default`` unless ``useFSLayout`` is enabled, then ``--layout folder``
|
||
- The value of ``mailserver.mailDirectory``, which defaults to ``/var/vmail``
|
||
|
||
The script should be run under the user who owns the ``mailDirectory``.
|
||
If run as root it will try to switch into the appropriate user by itself.
|
||
|
||
The script will not modify your data unless called with ``--execute``.
|
||
|
||
Example:
|
||
|
||
.. code-block:: bash
|
||
|
||
./nixos-mailserver-migration-03.py --layout default /var/vmail
|
||
|
||
5. Review the commands. They should be
|
||
|
||
- create a ``mail`` directory for each account,
|
||
- move maildir contents from the parent directory into it,
|
||
- suggest removal of files that do not belong to the maildir
|
||
|
||
- their removal is not mandatory and the script **will not** remove them when called with ``--execute``
|
||
- review these items carefully if you want to remove them yourself
|
||
|
||
- remove obsolete files from the old home directory location
|
||
|
||
6. Rerun the command with ``--execute`` or run the commands manually.
|
||
|
||
7. Update the ``mailserver.stateVersion`` to ``3``.
|
||
|
||
#2 Dovecot LDAP home directory migration
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
The Dovecot configuration for LDAP home directories previously did not respect
|
||
the ``mailserver.mailDirectory`` setting.
|
||
|
||
This means that home directories were unconditionally located at
|
||
``/var/vmail/ldap/%{user}``.
|
||
|
||
This migration is required if you both:
|
||
|
||
* enabled the LDAP integration (``mailserver.ldap.enable``)
|
||
* and customized the default mail directory (``mailserver.mailDirectory != "/var/vmail"``)
|
||
|
||
For remediating this issue the following steps are required:
|
||
|
||
1. Stop ``dovecot.service``.
|
||
2. Move ``/var/vmail/ldap`` below your ``mailserver.mailDirectory``.
|
||
3. Update the ``mailserver.stateVersion`` to ``2``.
|
||
|
||
#1 Initialization
|
||
^^^^^^^^^^^^^^^^^
|
||
|
||
This option was introduced in the NixOS 25.11 release cycle, in which case you
|
||
can safely initialize its value at `1`.
|
||
|
||
.. code-block:: nix
|
||
|
||
mailserver.stateVersion = 1;
|
||
|