Overview
The validated baseline is the openSUSE-based grommunio appliance 2026.06.1. The examples consistently use the neutral appliance domain https://mail.example.test; paths such as /web/, /admin/, /auth/, /chat/, /meet/ and /files/ live on the same appliance.This article shows how to validate, configure and test grommunio-antispam with Rspamd on an existing grommunio appliance.
You open Rspamd from grommunio Admin and test GTUBE, history, symbols, Bayes learning, allowlist, denylist, logs and technical acceptance.
Tested environment
grommunio 2026 on the openSUSE-based grommunio appliance.
All appliance commands are run directly on the grommunio appliance.
Public examples consistently use the neutral appliance domain https://mail.example.test.
Prerequisites
An existing or planned grommunio environment, matching DNS names, TLS, administrative access and a clear target for mail, collaboration or operations.
Goal of this guide
This guide builds on the grommunio 2026.06.1 installation and shows step by step how you understand, verify, test, train and operate grommunio-antispam with Rspamd. It is deliberately practical: you get commands, checkpoints, real appliance screenshots and guidance on which values you should not copy blindly into production.
You identify which Rspamd processes run inside grommunio.
You test the mail filter with a safe GTUBE test message.
You read score, action, symbols and history correctly.
You train spam and ham in a controlled way.
You understand which features matter in production: SPF, DKIM, DMARC, RBL/SURBL, fuzzy checks, greylisting, rate limits, neural/Bayes, multimap and monitoring.
The baseline installation is here: install grommunio 2026.06.1.
Validated appliance basis
This guide was validated against an isolated grommunio appliance. Hostname, domain and messages are synthetic, but the steps follow the production administration path. The Rspamd web interface was not exposed through a free controller port; it was validated through the grommunio admin path `https://mail.example.test:8443/antispam/`.
hostname -fcat /etc/os-release | grep -E '^(PRETTY_NAME|VARIANT|ID_LIKE)='rpm -qa | grep -Ei 'grommunio-antispam|rspamd|postfix|redis' | sortrspamd --version
Validation used grommunio 2026.06.1 with grommunio-antispam 4.1.5, Postfix 3.10.2 and Redis 8.2.3. Important: this appliance used XFS for the root filesystem and systemd-networkd for network configuration. That is the validated appliance state, not a general statement about every SUSE or SLES installation.
Architecture: Postfix, Rspamd and Redis
grommunio-antispam is based on Rspamd. Rspamd is a modular mail filter: a message is evaluated by multiple independent checks. Each check produces a symbol and optionally a score. The accumulated score results in an action such as no action, add header, greylist or reject.
Postfix receives mail and passes it to Rspamd via milter.
The proxy worker listens locally on port 11332.
Normal workers scan messages on port 11333.
The controller with web UI and API listens locally on port 11334.
Redis stores state such as Bayes, history, greylisting, rate limits and other learning data.
ss -ltnp | grep -E ':(25|587|11332|11333|11334)\b'postconf -n | grep -Ei 'milter|content_filter'systemctl list-units --type=service --all | grep -Ei 'redis|valkey'
On the validated appliance, `smtpd_milters = inet:localhost:11332` was configured. The controller was reachable only locally or through the grommunio admin path. That is the right production model as well: publish mail services as needed, but keep the antispam controller inside a management network, behind VPN or behind explicit IP rules.
Step 1: Verify services and configuration
Always start with a state check. If services are not running or configuration does not parse, every functional filter analysis is meaningless.
systemctl is-active grommunio-antispam postfix redis@grommuniorspamadm configtestrspamc statjournalctl -u grommunio-antispam --since "30 minutes ago" --no-pager
Expected output is `syntax OK`, an active antispam service and plausible `rspamc stat` output. Evaluate warnings carefully: DNS failures, missing maps or broken local includes are often operational issues, while a freshly built system naturally has little statistical data.
Step 2: Open the web interface from the admin interface
On the validated appliance, open Rspamd directly from the grommunio admin interface. The reachable URL is `https://mail.example.test:8443/antispam/`; a separate public controller port is not needed for this path.
https://mail.example.test:8443/antispam/
Screenshot: Dashboard of the validated grommunio 2026.06.1 appliance with grommunio-antispam 4.1.5.
Step 3: Understand actions, scores and symbols
Rspamd does not make a magical yes/no decision. It collects symbols, adds scores and recommends an action. In the validated configuration, the thresholds were greylist 4, add header 6 and reject 15. In production, change these values only after observing real mail flows.
Screenshot: Actions and maps in the Rspamd configuration; local overrides should be controlled and documented.
rspamadm configdump actionsrspamadm configdump spfrspamadm configdump dkimrspamadm configdump dmarc
Do not edit shipped defaults directly. Add local files in `local.d` and always run `rspamadm configtest` afterwards. In the grommunio appliance, the configuration path is `/etc/grommunio-antispam`; generic Rspamd documentation often uses `/etc/rspamd`.
Step 4: Scan a first message
Create a harmless synthetic message first and scan it with `rspamc symbols`. Do not look only at the action; look at the reasoning: missing Received headers, test domains or DNS issues can cause higher scores for synthetic messages than in a real mail flow.
cat > /tmp/ham.eml <<'EOF'From: Alex Example <alex@example.test>To: Admin Example <admin@example.test>Subject: Testtermin für MailfilterDate: Mon, 7 Sep 2026 10:00:00 +0200Message-ID: <ham-001@example.test>MIME-Version: 1.0Content-Type: text/plain; charset=UTF-8Hallo,das ist eine harmlose interne Testnachricht für die Antispam-Validierung.EOFrspamc symbols < /tmp/ham.eml
In the validated environment, this message was classified as `add header` because of synthetic characteristics. This is a useful example: the technology works, but the data basis is not identical to a real production message.
Step 5: Test spam safely with GTUBE
Use GTUBE for reproducible tests. It is a harmless test signature that spam filters are expected to classify as spam. This avoids storing or forwarding real spam.
cat > /tmp/gtube.eml <<'EOF'From: Sender Example <sender@example.net>To: Alex Example <alex@example.test>Subject: GTUBE FunktionstestDate: Mon, 7 Sep 2026 10:05:00 +0200Message-ID: <spam-gtube-001@example.net>MIME-Version: 1.0Content-Type: text/plain; charset=UTF-8This is a safe spam-filter test message.XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34XEOFrspamc symbols < /tmp/gtube.eml
The GTUBE test returned `Action: reject`, `Score: 15.00 / 15.00` and the `GTUBE` symbol. This validates the filter path from client to Rspamd action.
Screenshot: Scan/Learn with GTUBE: the interface shows reject, score and triggering symbol.
Step 6: Use Bayes learning carefully
Bayes learning is valuable, but only with clean training data. Train clear spam examples as spam and clear false positives as ham. If users report everything without review, you can make filtering worse.
rspamc learn_spam /tmp/gtube.emlrspamc learn_ham /tmp/ham.emlrspamc stat
After learning, the dashboard showed a ham learn entry. In production, add a reporting workflow, sample review, backup of state data and regular false-positive checks.
Step 7: Read history and concrete causes
History is the fastest path from a user complaint to the cause. Open the concrete message and check sender, recipient, subject, action, score, scan time and symbols. Only then decide whether DNS, reputation, content, attachment, URL, Bayes or a local rule caused the classification.
Screenshot: History after the functional test with action, score, symbols and scan time.
journalctl -u postfix --since "2 hours ago" --no-pagerjournalctl -u grommunio-antispam --since "2 hours ago" --no-pagermailq
Step 8: Use symbols as tuning input
The symbols view shows which checks exist and how they are scored. This is a better starting point than blindly raising thresholds. If a symbol repeatedly produces wrong results, first check DNS, local maps, authentication and real examples.
Screenshot: Symbols show which individual checks Rspamd includes in the overall score.
Wrong classification: analyse first, add exceptions later
Allowlisting is not the first step. If you immediately allow a legitimate message without understanding the cause, you hide DNS, authentication, reputation or training problems. Work in this order:
Message classified incorrectly?-> Are SPF, DKIM and DMARC correct?-> Are IP, domain and URL reputation plausible?-> Are Bayes or neural involved?-> Is a local rule, map or override involved?-> only then add a controlled allowlist, denylist or exception
Step 9: Plan allowlists, denylists and multimap cleanly
Exceptions are useful, but dangerous when too broad. Separate rule definition from dynamic map files: the multimap rule lives in `/etc/grommunio-antispam/local.d`, while lists maintained by admin workflows live under `/var/lib/grommunio-antispam`. This keeps package defaults untouched and lets you back up, version or maintain the lists through an internal tool.
install -d -m 0750 -o groas -g grommunio /var/lib/grommunio-antispam/mapscat > /etc/grommunio-antispam/local.d/multimap.conf <<'EOF'WHITELIST_SENDER_DOMAIN {type = "from";filter = "email:domain";map = "/var/lib/grommunio-antispam/maps/whitelist_sender_domain.map";score = -5.0;description = "Whitelisted sender domains reviewed by mail operations";}WHITELIST_SENDER_ADDRESS {type = "from";filter = "email";map = "/var/lib/grommunio-antispam/maps/whitelist_sender_address.map";score = -5.0;description = "Whitelisted sender addresses reviewed by mail operations";}BLACKLIST_SENDER_DOMAIN {type = "from";filter = "email:domain";map = "/var/lib/grommunio-antispam/maps/blacklist_sender_domain.map";score = 8.0;description = "Blacklisted sender domains reviewed by mail operations";}BLACKLIST_SENDER_ADDRESS {type = "from";filter = "email";map = "/var/lib/grommunio-antispam/maps/blacklist_sender_address.map";score = 8.0;description = "Blacklisted sender addresses reviewed by mail operations";}EOFprintf '%s\n' 'partner.example' > /var/lib/grommunio-antispam/maps/whitelist_sender_domain.map: > /var/lib/grommunio-antispam/maps/whitelist_sender_address.map: > /var/lib/grommunio-antispam/maps/blacklist_sender_domain.map: > /var/lib/grommunio-antispam/maps/blacklist_sender_address.mapchown groas:grommunio /var/lib/grommunio-antispam/maps/*.mapchmod 0640 /var/lib/grommunio-antispam/maps/*.maprspamadm configtestsystemctl reload grommunio-antispamrspamc symbols < /tmp/ham.eml | grep -E 'WHITELIST|BLACKLIST|Action|Score' || true
Use specific senders, partner domains or technical relay IP addresses. Do not globally allow large freemail or cloud domains. After every change, run `rspamadm configtest`, reload the service, send or scan a concrete test message and check history, score and symbols.
Production changes need a review process: who may add exceptions, how long do they last, which samples justify the exception and when is it reviewed again?
Step 10: Understand test selectors
Selectors extract fields from messages. They help you verify whether a rule sees the value you expect: SMTP sender, recipient, headers, subject, IP, MIME structure or URL components.
Screenshot: Test selectors with a synthetic message; useful before adding custom rules and maps.
Important feature areas in grommunio-antispam
Group the features by problem class. Reputation answers whether sender, IP, domain or URL look trustworthy. Content and phishing checks inspect body, links, attachments and patterns. Delivery controls shape delivery behaviour and speed. Learning adjusts classification through clean training data. These groups help you avoid solving every problem with the same exception.
SPF, DKIM, DMARC and ARC validate identity and authenticity of mail flows.
RBL and SURBL evaluate IPs, domains and URLs through reputation data.
Fuzzy checks detect known or similar spam content.
Bayes and neural improve classification through training and learning models.
Greylisting and rate limits slow suspicious delivery patterns.
Multimap, force actions and local maps implement controlled exceptions and rules.
Milter headers can make results visible in message headers.
External services and antivirus integration are extension points, but they need deliberate planning and monitoring.
Screenshot: Throughput and actions support operations, especially after policy or DNS changes.
Place SPF, DKIM, DMARC and ARC correctly
These checks are not cosmetic extras; they are the trust chain of your mail domains. SPF validates whether the sending server belongs to the domain. DKIM validates the message signature. DMARC combines SPF and DKIM with a domain policy. ARC helps when messages pass through forwarders or mailing lists.
dig TXT example.com +shortdig TXT _dmarc.example.com +shortdig TXT default._domainkey.example.com +short# DMARC für neue Domains zuerst beobachten:# v=DMARC1; p=none; rua=mailto:dmarc@example.com# Erst nach Auswertung verschärfen:# v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com# v=DMARC1; p=reject; rua=mailto:dmarc@example.com
For production domains, usually start DMARC in observation mode. Once legitimate senders, forwarders, newsletter systems and partner mail servers are understood, you can move deliberately to `quarantine` or `reject`.
Evaluate RBL, SURBL and URL checks
RBLs evaluate sending IPs or networks, while SURBL and URL checks evaluate domains and links inside the message. These hits are often strong signals, but should not be interpreted in isolation. For false positives, check whether a legitimate service is compromised, misconfigured or only temporarily listed.
rspamadm configdump rblrspamadm configdump surblrspamc symbols < /tmp/gtube.eml | grep -E 'RBL|SURBL|URL|PHISH|Action|Score' || true
Validate fuzzy, phishing and content patterns
Fuzzy checks detect known or similar content without requiring every message to be identical. Phishing and URL modules evaluate suspicious targets, redirects and patterns. In production, DNS must work reliably and external lookups must not be slowed down by firewall, proxy or resolver issues.
rspamadm configdump fuzzy_checkrspamadm configdump phishingjournalctl -u grommunio-antispam --since "1 hour ago" --no-pager | grep -Ei 'fuzzy|phishing|surbl|resolve|timeout' || true
Enable greylisting and rate limits deliberately
Greylisting delays suspicious delivery attempts, and rate limits restrict unusual sending patterns. Both features can be effective, but they intentionally introduce friction. Do not enable them blindly; operate them with monitoring, exceptions for legitimate systems and clear communication.
rspamadm configdump greylistrspamadm configdump ratelimitrspamc stat | grep -Ei 'greylist|reject|add header|no action'
Operate Bayes, neural and training data
Bayes and neural are learning mechanisms. They need clean data, time and control. A fresh system already catches a lot through rules, reputation and authentication; learning becomes important when real false positives and false negatives are classified cleanly.
rspamadm configdump classifier-bayes 2>/dev/null || rspamadm configdump statisticsrspamadm configdump neuralrspamc stat
Treat training data as operational data. If Redis, Bayes or maps are lost, the filter does not start from zero technically, but important local experience is missing.
Spam gets through: check false negatives
When spam gets delivered, do not immediately raise global thresholds. First verify whether the message passed through the filter path, which symbols were set and whether a local exception lowered the score.
Check scan and milter path: Postfix must reach Rspamd.
Open history and read action, score, symbols and scan time.
Check reputation: RBL, SURBL, URL checks and DNS resolution.
Check Bayes/neural: was the message incorrectly learned as ham?
Check local maps: allowlist, force action or override involved?
Learn as spam in a controlled way and then retest with a comparable message.
Add a custom rule only when you have repeatable samples and a clear cause.
postconf -n | grep -Ei 'milter|smtpd_milters'journalctl -u postfix --since "2 hours ago" --no-pager | grep -Ei 'milter|rspamd|reject|warning' || truerspamc symbols < /tmp/suspect.emlrspamc learn_spam /tmp/suspect.emlrspamadm configtest
Integrate antivirus and external services consciously
grommunio-antispam provides interfaces for antivirus and external checks. Whether you enable them depends on operating model, privacy, latency, licensing and existing security architecture. The key point: external checks must be monitored so timeouts do not damage mail flow.
rspamadm configdump antivirusrspamadm configdump external_servicesjournalctl -u grommunio-antispam --since "1 hour ago" --no-pager | grep -Ei 'antivirus|external|timeout|error' || true
Monitoring and Day-2 operations
In daily operations, rejects are not the only signal. Monitor scan time, queue length, DNS resolution, Redis state, mail volume, error log, certificates, disk space, updates and unusual action shifts. This is where dashboard, throughput, history and logs become valuable together.
systemctl is-active grommunio-antispam postfix redis@grommuniomailqrspamc statdf -hjournalctl -u grommunio-antispam --since "24 hours ago" --no-pager | tail -200
Plan backup and restore realistically
Rspamd does not store mailbox data. For grommunio-antispam, back up local configuration, local maps and relevant state data. Not every Redis counter is equally critical, but Bayes/learn state, history, greylisting and rate-limit state can matter for operations and analysis.
Back up: `/etc/grommunio-antispam`, local includes, local maps under `/var/lib/grommunio-antispam`, documented secrets and operational notes.
Review: Redis data, Bayes/learn state, history, greylisting and rate limits depending on your desired recovery behaviour.
Do not confuse this: mailbox data lives in grommunio/Gromox, not in Rspamd/Redis.
After restore, test: `rspamadm configtest`, service start, web interface, GTUBE, ham test, history and a real delivery path.
Order in the grommunio series
If you are building grommunio from scratch, start withthe installation guide. This antispam article is the next Day-2 step. For SSO and central authentication, continue withgrommunio-auth.
More product context is available on the grommunio-antispam page.
Automatic spam learning with grommunio-spam-run
The tested grommunio 2026.06.1 appliance ships its own spam-training implementation: grommunio-spam-run.service and grommunio-spam-run.timer. Do not use old community scripts as the default path. The delivered script is /usr/sbin/grommunio-spam-run.sh and learns messages from users’ Junk folders with rspamc learn_spam.
Important: learning is not the same as deleting. The timer calls the script without a delete argument. Deleting trained Junk messages happens only when the script is started deliberately with -d. Do not enable automatic deletion blindly, because false positives could otherwise be trained first and removed afterwards.
systemctl cat grommunio-spam-run.servicesystemctl cat grommunio-spam-run.timersystemctl status grommunio-spam-run.timerrspamc stat
In the validated lab, service and timer existed but were not enabled by preset. The manual run completed successfully; without prepared training messages, the learned-message counter remained at 0 as expected. In production, enable the timer only after the Junk-folder process, false-positive handling and monitoring are clear.
systemctl enable --now grommunio-spam-run.timersystemctl start grommunio-spam-run.servicejournalctl -u grommunio-spam-run.service --since "10 minutes ago"rspamc stat
Automatic ham learning was not present as a dedicated grommunio ham-run timer in the installed appliance. Ham training therefore belongs in a controlled review process with validated samples, not in an invented timer recipe.
Result Validation / Technical Acceptance
| Test area | Check | Expected result | Status |
|---|---|---|---|
| Installation | Check packages and components | The component is fully installed | PASS |
| Services | Check systemd services | The required services are active | PASS |
| Network | Check ports and URLs | The component is reachable through the intended paths | PASS |
| Core function | Run standalone test | The core function works before deeper integration | PASS |
| Authentication | Test SSO/login | Login works through the intended path or is intentionally not required | PASS or N/A |
| grommunio Web | Check integration from Web | The component is reachable or usable from grommunio Web | PASS or N/A |
| End-to-end | Test real user workflow | The full workflow is reproducibly successful | PASS |
| Restart | Restart services | The function remains available after service restart | PASS |
| Logs | Check relevant logs | No blocking errors in the validated flow | PASS |
Installation
- Check
- Check packages and components
- Expected result
- The component is fully installed
- Status
- PASS
Services
- Check
- Check systemd services
- Expected result
- The required services are active
- Status
- PASS
Network
- Check
- Check ports and URLs
- Expected result
- The component is reachable through the intended paths
- Status
- PASS
Core function
- Check
- Run standalone test
- Expected result
- The core function works before deeper integration
- Status
- PASS
Authentication
- Check
- Test SSO/login
- Expected result
- Login works through the intended path or is intentionally not required
- Status
- PASS or N/A
grommunio Web
- Check
- Check integration from Web
- Expected result
- The component is reachable or usable from grommunio Web
- Status
- PASS or N/A
End-to-end
- Check
- Test real user workflow
- Expected result
- The full workflow is reproducibly successful
- Status
- PASS
Restart
- Check
- Restart services
- Expected result
- The function remains available after service restart
- Status
- PASS
Logs
- Check
- Check relevant logs
- Expected result
- No blocking errors in the validated flow
- Status
- PASS









