NS8 Mail module with SMTP, IMAP, Spam/Virus filter
Instantiate the module with:
add-module ghcr.io/nethserver/mail:latest
The output of the command will return the instance name. Output example:
{"module_id": "mail1", "image_name": "mail", "image_url": "ghcr.io/nethserver/mail:latest"}
As an example, the following command configures a mail server "mail.example.com" with default settings.
api-cli run module/mail1/configure-module --data '{"hostname":"mail.example.com","user_domain":"ad.example.com","mail_domain":"example.com"}'
-
Users from the domain "ad.example.com" can authenticate with SMTP submission, IMAP and POP services. They are offered an unlimited mailbox quota by default.
-
The domain "example.com" is accepted as final destination with the default configuration for the SMTP MX server, listening on port 25.
Dovecot custom configuration is saved in the dovecot-custom
volume.
To edit it, run the following commands while dovecot.service
is running:
# print the config values that differ from Dovecot defaults
# WARNING! changing one of them may be dangerous!
podman exec -ti dovecot doveconf -n
# start the editor
podman exec -ti dovecot vi /etc/dovecot/local.conf.d/myoverride.conf
systemctl --user reload dovecot
If the service is stopped, start a dedicated container to mount the volume properly:
podman run --rm -ti -v dovecot-custom:/srv:z alpine vi /srv/myoverride.conf
systemctl --user reload dovecot
For Postfix the commands are similar. Custom configuration is saved in
the postfix-custom
volume. Edit it with:
# print the config values that differ from Postfix defaults
# WARNING! changing one of them may be dangerous!
podman exec -ti postfix postconf -n
# start the editor
podman exec -ti postfix vi /etc/postfix/main.cf.d/myoverride.cf
systemctl --user reload postfix
If Postfix is stopped run this one instead:
podman run --rm -ti -v postfix-custom:/srv:z alpine vi /srv/myoverride.cf
systemctl --user reload postfix
After applying a custom configuration, check the services are running properly:
systemctl --user status postfix dovecot
To customize the Rspamd configuration and to access advanced Rspamd settings use the Rspamd web admin UI. It is accessible from the local host on TCP port 11334. If a SSH port forward is not allowed, configure an HTTPS route to expose the web interface publicly, as the web UI is protected by a random password. Retrieve the UI password with
podman exec rspamd ash -c 'echo $RSPAMD_adminpw'
Some settings cannot be controlled by the web UI. In that case, override
the Rspamd configuration by adding configuration files under
/etc/rspamd/override.d
, which is mounted as a persistent volume. For instance run
podman exec -ti rspamd vi /etc/rspamd/override.d/example.conf
Refer to Rspamd documentation, for the allowed file names and expected contents.
The module self-generates a 2048-bit RSA key for DKIM at installation time. The key is used for DKIM signing when any message is submitted by an authenticated user, or from a local IP address.
It is possible to use a different DKIM key for a particular domain by
applying the following procedure. Given the DNS TXT record is be selected
by myselector
,
-
open an interactive shell in the Rspamd running container:
podman exec -ti rspamd ash
-
generate a new key, with the wanted selector:
rspamadm dkim_keygen -s myselector -b 2048 -k /var/lib/rspamd/dkim/myselector.key > /var/lib/rspamd/dkim/myselector.txt chgrp rspamd /var/lib/rspamd/dkim/myselector.key
-
access the Rspamd admin UI, and edit
/var/lib/rspamd/dkim_selectors.map
. Add a line likemydomain.example.com myselector
-
add a DNS TXT record to
mydomain.example.com
, as described in/var/lib/rspamd/dkim/myselector.txt
Changes to clamav-unofficial-sigs
configuration are volatile. When the
clamav
container is stopped, local configuration changes are lost.
To manage a persistent and custom clamav-unofficial-sigs
configuration:
-
Edit the
state/environment
file and set the following variableCLAMAV_CUSCFG_VOLUME_FLAGS=Z
-
Restart the clamav container. The configuration is now mounted on a persistent volume,
clamav-cus-cfg
:systemctl --user restart clamav
-
Edit
/etc/clamav-unofficial-sigs/user.conf
as wanted:podman exec -ti clamav vi /etc/clamav-unofficial-sigs/user.conf
To switch back to the volatile configuration
-
Edit the variable line in
state/environment
(or remove it completely):CLAMAV_CUSCFG_VOLUME_FLAGS=O
-
Stop the clamav service
-
Remove the custom changes:
podman volume rm clamav-cus-cfg
-
Start the clamav service
Either in persistent or volatile mode, changes to the configuration are
picked up on the next clamav-unofficial-sigs.timer
run.
To forcibly download new signatures, run:
podman exec clamav download-sigs cus -F
The username vmail
is reserved and granted the impersonate privilege.
If the user database backend has a homonym vmail
user, it is ignored.
Another module can obtain vmail
credentials by invoking the action
reveal-master-credentials
, provided it has been granted the mailadm
role.
Subfolders of Vmail's INBOX are visible to all users under the Public
namespace. Vmail's INBOX is initialized with a special lookup
permission granted to all authenticated users. To reset it run this
command:
podman exec dovecot doveadm acl set -u vmail INBOX authenticated lookup
- Dovecot --
dovecot.service
. See also dovecot/README.md - Postfix --
postfix.service
. See also postfix/README.md - Rspamd --
rspamd.service
. See also rspamd/README.md - Diffie-Hellman group generator
dhgen.service
. Starts at module boot, then every 15 days. See alsodhgen.timer
. - Freshclam signatures download --
freshclam.service
(with timer) - ClamAV unofficial signatures download --
clamav-unofficial-sigs.service
(with timer)
To access the admin web UI of Rspamd point the browser to
https://<mail host>/rspamd/
Another module can discover IMAP and SUBMISSION endpoints by looking up the following Redis key pattern:
KEYS module/mail[1-9]*/srv/tcp/imap
KEYS module/mail[1-9]*/srv/tcp/submission
Returned key type is HASH, with the the following items:
key | value example | description |
---|---|---|
host |
10.5.4.1 | |
port |
143 | for IMAP |
node |
1 | the node identifier where the service is located |
user_domain |
nethserver.test | name of user domain (LDAP protocol only) |
uuid |
35457a5f-b0c1-421f-86f3-81df090df818 | module instance universal identifier |
When settings change, the mail-settings-changed
event is published. Payload format is
{
"reason": "configure-module",
"module_id": "mail1",
"module_uuid": "35457a5f-b0c1-421f-86f3-81df090df818",
"node_id": 1
}
The event reason reflects the action name that raises the event.
install-certificate
installs the TLS certificate and DH group in the given service container.
To uninstall the instance:
remove-module --no-preserve mail1
Test the module using the test-module.sh
script:
./test-module.sh <NODE_ADDR> ghcr.io/nethserver/mail:latest
Additional arguments are forwarded to the robot
command (see Robot
Framework).
For instance, to speed up testing on a local machine:
-
skip the account provider removal
SSH_KEYFILE=~/.ssh/id_ecdsa bash test-module.sh 10.5.4.1 ghcr.io/nethserver/mail:mail-rspamd --exclude udomANDremove
-
since then, skip also installation
SSH_KEYFILE=~/.ssh/id_ecdsa bash test-module.sh 10.5.4.1 ghcr.io/nethserver/mail:mail-rspamd --exclude udom
The NS7 migration tool (nethserver-ns8-migration
RPM) transfers the
Email app configuration and mailboxes data. It invokes the import-module
action, which implements the conversion procedure from NS7 to NS8 format.
Migration notes:
-
SMTP/IMAP user name. Any
@domain
suffix is ignored, only the user name is considered. -
Mail storage. The user
@domain
suffix was removed in NS8. Mailbox paths are renamed from the olduser@domain
form to newuser
. ACLs and shared-mailboxes.db files are fixed accordingly. -
"Full control" ACLs now includes the "delete" permission. Granted ACLs are upgraded as necessary.
-
root
user. Even if in NS8 a root user does not exist, its mailbox contents are transferred. For additional security theroot
mailbox is marked "disabled" inDOVECOT_DISABLED_USERS
. It is possible to access its contents by either configuring it as shared, or by creating a "root" user in the LDAP database with a new, secure password. -
Quota temporarly unavailable. The new "quota count" Dovecot backend is used. Large mailboxes need a while to reindex the quota size. During reindexing, quota information is not available and the following message is logged:
quota-count: Ongoing quota calculation blocked
-
Filter settings are migrated. Filter bypass rules and Postfix
mynetworks
setting are converted and imported from the following e-smith DB props:postfix/AccessBypassList
,rspamd/SenderWhiteList
,rspamd/RecipientWhiteList
. -
New Full Text Search (FTS) engine Flatcurve. Old FTS indexes are excluded from the migration. To massively rebuild the search indexes run the following command during system idle time:
podman exec dovecot nice doveadm index -A -q '*'
Translated with Weblate.
To setup the translation process:
- add GitHub Weblate app to your repository
- add your repository to hosted.weblate.org or ask a NethServer developer to add it to ns8 Weblate project