Administration¶
In the following chapter we explain the inner workings of Æther including monitoring and usermanagement.
Managing User accounts¶
- User management is done through a centralized LDAP server which is connected to:
Nextcloud
Postfix (MTA, through dovecot)
Dovecot (MDA)
Mailman (Malinglists)
Grafana (Monitoring)
Users can be added to groups which grant access to different services:
|
Users in this group are granted administrative rights to mailman and can login to the monitoring system. |
|
Users in this group can create other users and groups in lldap. |
|
This group is only meant for services that need to query information from the LDAP server. |
|
Same as above. |
|
Users in this group have an standard email address. |
|
Mail for |
|
Members of this group can open the shared mailbox |
|
Users in this group have access to mailman. |
|
This group grants access to nextcloud. |
|
This group is meant to give access to user management or mailinglist management without being able to change system settings. |
Creating New Accounts¶
New user accounts can be created via the webinterface at https://auth.windsbraut-ev.de. Don’t set a password during creation, instead use the password reset form to generate an email that gets sent to the users address. After creation, groups can be added at the bottom of the user detail page.
Deleting Accounts¶
Accounts can be deleted via the user overview page. Once deleted only the account on the lldap server is gone. Mailboxes and files in Nextcloud still exist on disk and have to be deleted manually if desired.
Spam Filtering¶
Incoming mail passes through rspamd before Postfix accepts it. Rspamd adds up the scores of its rules and acts on the total (ae_rspamd_action_*):
|
4 |
The sending server is told to try again later, most spam bots never do. |
|
6 |
The message is delivered with an |
|
15 |
The message is refused during the SMTP dialogue. |
The rules fall into three groups. Reputation lookups ask DNS blocklists (Spamhaus, dnswl.org, SURBL, URIBL and others) about the sending server and the domains in the message; these need the resolver described under Blocklists and DNS. Static rules look at the message itself; among them FROM_SUSPICIOUS_TLD adds ae_rspamd_suspicious_tld_score for sender domains ending in one of ae_rspamd_suspicious_tlds, the cheap top-level domains that carry most of the spam that otherwise passes SPF, DKIM and DMARC. Finally the Bayes classifier compares the words of a message with what it has been trained on, contributing up to -3 for ham and +5.1 for spam.
Training Bayes¶
Bayes learns from three sources:
Messages a user moves into
Junkare learned as spam, messages moved out ofJunk(except intoTrash) as ham. This works from any mail client.Mail that users send through the server is learned as ham automatically.
Mail that the other rules already tag as spam is learned as spam automatically.
Bayes stays silent until both classes have at least ae_rspamd_bayes_min_learns messages; the counts are shown by:
podman exec ae-rspamd rspamc -h /run/rspamd-sockets/worker-controller stat
To train from mail that is already on disk, point the helper at a maildir folder or at single message files; messages it already knows are skipped:
ae-rspamd-learn spam /ae/userdata/buero/mail/.Junk
ae-rspamd-learn ham /ae/userdata/buero/mail/.Sent
Resetting Bayes¶
Until September 2026 every message with a negative score was learned as ham. Spam that passes SPF, DKIM and DMARC scores slightly below zero, so Bayes was trained on spam and ended up vouching for it. A database with that history is worth less than an empty one. To start over, stop rspamd, flush its Redis instance (it only holds caches: the Bayes tokens, greylisting and rate-limit state and the neural network) and train it from the mail on disk:
systemctl stop ae-rspamd.service
podman exec ae-redis-rspamd redis-cli FLUSHALL
systemctl start ae-rspamd.service
ae-rspamd-learn spam /ae/userdata/*/mail/.Junk
ae-rspamd-learn ham /ae/userdata/*/mail/.Sent
Check the Junk folders for false positives before learning them, and look at the stat output afterwards. Both classes have to reach ae_rspamd_bayes_min_learns before Bayes says anything at all; the spam side is the one that lags, because everything it knows comes from mail that was filed as Junk. Lowering the variable is safe: BAYES_SPAM is worth 5.1 at most and the add_header threshold is 6, so a Bayes verdict on a thin corpus still cannot move a message into Junk without a second signal agreeing.
Blocklists and DNS¶
The blocklists count queries per resolver and refuse the shared ones that most servers forward to, because they cannot tell the individual users behind them apart. Every list has its own way of saying so, and rspamd reads all of them as „not listed“:
List |
Answer |
Meaning |
|---|---|---|
Spamhaus |
|
Query through a public or open resolver |
dnswl.org |
|
Over 100’000 queries a day from that resolver, counted across all of its users |
URIBL |
|
Query blocked, possibly due to high volume |
Two things fix this together. Rspamd resolves through the unbound container, which recurses from the root servers itself instead of forwarding, so the lists see this machine. Since container names would no longer resolve that way, unbound passes the dns.podman zone back to podman’s own DNS. And Spamhaus, which refuses shared resolvers regardless of volume, gets queried under a key, see Spamhaus DQS below.
Losing dnswl.org matters as much as losing a blocklist: it is a whitelist, and without it known-good senders no longer get their negative score, which pushes ordinary mail towards the Junk folder.
To check the resolver, ask it for the test entries from inside the rspamd container. Each has to return an address in 127.0.0.0/8 other than the refusal codes above:
podman exec ae-rspamd getent hosts 2.0.0.127.zen.spamhaus.org
podman exec ae-rspamd getent hosts 2.0.0.127.list.dnswl.org
podman exec ae-rspamd getent hosts test.uribl.com.multi.uribl.com
Do not judge this by /etc/resolv.conf inside the container: it still lists podman’s own DNS addresses, and that is correct. Podman keeps itself as the container’s nameserver so that container names go on resolving, and hands our resolver to it as the upstream for everything else. The per-container upstream is visible as the last field of the container’s line in /run/containers/networks/aardvark-dns/podman. The lookups above are what tells you whether it works.
To check the whole path rather than just DNS, scan a message carrying Spamhaus‘ test domain. This only scans, it sends nothing:
printf 'From: t@example.com\nTo: postmaster@example.com\nSubject: t\n\nhttp://dbltest.com/\n' > /tmp/t.eml
podman cp /tmp/t.eml ae-rspamd:/tmp/t.eml
podman exec ae-rspamd rspamc -h /run/rspamd-sockets/worker-controller symbols /tmp/t.eml
DBL_SPAM has to appear in the symbol list. Note that URIBL’s own test domain does not work this way, because rspamd reduces a URL to its registrable domain before querying, and only the longer test label is listed.
If the resolver is down, rspamd keeps running without any blocklist and Postfix still accepts mail, because milter_default_action is accept.
Spamhaus DQS¶
The Spamhaus lists (ZEN for sending addresses, DBL for domains) are the most valuable of the blocklists and refuse shared resolvers outright. The Data Query Service (DQS) identifies the deployment by a key in the queried name and is free for non-commercial use at this volume. It also adds the Zero Reputation Domains list, which flags domains registered or reactivated within the last day.
Register at https://www.spamhaus.com/dqs/, copy the key from the portal (section „Datafeed Query Service“) into host_vars/<host>.yml and deploy the rspamd role:
ae_rspamd_spamhaus_dqs_key: "abcdefghijklmnopqrstuvwxyz"
ansible-playbook -i hosts.ini setup.yml --tags mail
The rules are the ones Spamhaus publishes for rspamd (local.d/rbl.conf and local.d/rbl_group.conf), without the Hash Blocklist of the paid tier. Confirm the key works, the answer has to list the three test codes and not 127.255.255.254:
podman exec ae-rspamd getent hosts 2.0.0.127.<key>.zen.dq.spamhaus.net
Over time the symbol counters (rspamc ... counters) show hits for SPAMHAUS_ZEN, DBL_* and ZRD_*.
Monitoring¶
In order to make sure all services are operating smoothly, Æther collects non user specific metrics about the system. E.g. CPU and memory usage, list and status of all processes, number of sent emails, number of requests to the webserver. These metrics can be accessed at: https://monitoring.windsbraut-ev.de. Via alerts it is possible to receive emails if certain parameters are outside of specified limits.