On cPanel and CloudLinux servers running Imunify Email (IE), official documentation frequently mentions deprecated commands or abstracts away what the binaries actually do under the hood. A common issue arises when attempting to adjust spam score thresholds: messages with high spam scores (above 0.80) continue reaching recipient inboxes with a No Action verdict instead of being isolated in quarantine.
When following standard guides to modify these parameters, administrators frequently encounter non-existent commands and configuration layouts that differ entirely from published manuals.
In this article, we break down Imunify Email's microservice design, trace runtime signals from the Go binary using system calls, explain the conditions that cause spam bypasses, and set up an automated monitoring script to prevent storage limits from disabling protection.
1. Why traditional commands fail in ie-cli#
Many outdated guides recommend using ie-cli config show --global to inspect or alter scoring thresholds. On modern production systems, running this command results in an immediate syntax error:
[root@server ~]# ie-cli config show
Error: unknown command "config" for "ie-cli"
Go runtime clues in system calls#
Running strace against the binary to identify which configuration files were being opened revealed an important behavioral detail:
[root@server ~]# strace -e openat ie-cli filter-settings 2>&1 | grep -v "ENOENT"
openat(AT_FDCWD, "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY) = 3
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=1907699, si_uid=0} ---
{
"allow_windows_executable_attachments": true
}
+++ exited with 0 +++
The interception of the SIGURG signal delivered via SI_TKILL confirms that ie-cli and its companion daemons are compiled in Go (Golang). Since Go 1.14, the runtime uses asynchronous SIGURG signals for non-cooperative goroutine preemption. In addition, accessing /sys/kernel/mm/transparent_hugepage reflects the internal memory allocator sizing pages dynamically.
Microservice process structure#
Rather than operating as a single daemon, Imunify Email runs three decoupled components located in /etc/imunifyemail/ (note the unhyphenated directory name):
ps aux | grep -E "ie-|rspamd"
The output reveals the active daemons:
_imunify+ 2962 0.0 0.0 /usr/bin/ie-dec-node run --config /etc/imunifyemail/dec-node.yaml --env-file /etc/imunifyemail/dec-node.env
_imunify+ 2965 0.0 0.0 /usr/bin/ie-quarantine run --config /etc/imunifyemail/quarantine.yaml --env-file /etc/imunifyemail/quarantine.env
_rspamd 4116 0.0 0.0 rspamd: controller process (/var/lib/rspamd/rspamd-ctl.sock mode=0660 group=_imunify)
Each process handles a dedicated stage in the mail flow:
ie-dec-node: decision node. Acts as asynchronous middleware, receiving analytical scores and determining the fate of the message.ie-quarantine: quarantine storage manager. Manages retention Maildirs and updates index databases.rspamd: heuristic scoring engine. Runs alongside the Imunify daemons and communicates over dedicated UNIX sockets with_imunifygroup permissions.
2. Dec-node.yaml structure and decision flow#
The configuration file /etc/imunifyemail/dec-node.yaml defines listener addresses and disk safety thresholds:
server:
address: :11339
insecure: false
readTimeout: 10s
writeTimeout: 10s
socketAddress: /var/run/imunifyemail/dec-node.sock
logger:
level: info
outputPaths:
- stdout
cleaner:
rootDir: /var/imunifyemail/dec-node/storage/data
hardQuotaGb: 1
softQuotaGb: 0.9
interval: 500s
saver:
rootDir: /var/imunifyemail/dec-node/storage/data
indexFileName: /var/imunifyemail/dec-node/storage/index.db
Data flow during message processing#
When Exim receives an email, the message travels through the following sequence:
[Exim MTA]
│ (Passes message payload via filter transport)
▼
[Rspamd] ──(Scores message using statistical and heuristic rules)
│
▼ Emits score symbols over socket /var/run/imunifyemail/dec-node.sock
[ie-dec-node] ──(Checks local index.db and environment settings)
│
├─ If Score >= Threshold ──> Writes message to quarantine storage and updates index.db
│ ▲
│ │ (Handled by ie-quarantine)
└─ If Score < Threshold ───> Returns "No Action" so Exim completes delivery to inbox
Because ie-cli filter-settings only exposes boolean flags (such as blocking Windows executables), score thresholds do not exist in plain-text configuration files. Instead, they are evaluated through the environment file loaded at startup (/etc/imunifyemail/dec-node.env) and the embedded SQLite database (/var/imunifyemail/dec-node/storage/index.db).
3. Why high-scoring messages receive a "no action" verdict#
When suspected spam messages bypass quarantine, three primary conditions should be investigated from the command line.
1. Score scale mismatch between Rspamd and Imunify#
Rspamd operates natively with an open-ended weight scale (typically between 5.0 and 15.0 for spam). Imunify Email applies a statistical normalization formula to convert that raw score into a decimal probability between 0.00 and 1.00.
To verify whether raw Rspamd action rules are interfering:
rspamadm configdump actions
Conflicting thresholds in Rspamd can alter the metric values delivered to /var/run/imunifyemail/dec-node.sock.
2. Cleaner quota saturation (fail-open safety mode)#
In dec-node.yaml, the cleaner module defines strict volume limits: hardQuotaGb: 1 and softQuotaGb: 0.9. If global quarantine storage or an individual mailbox reaches these limits, Imunify Email enters a passive Fail Open state.
To avoid SQLite database corruption or outbound disk stalls, the daemon begins returning No Action on subsequent incoming messages, allowing them through without quarantine.
To check storage usage across mailboxes:
ie-cli accounts list
If the UsedBytes column matches or approaches LimitBytes, automated quarantine retention has been temporarily suspended to protect disk health.
3. Structural bypasses and whitelists#
Messages lacking mandatory RFC header fields (such as system bounces without a valid Message-ID or timestamp) or senders matching local bypass rules will skip quarantine entirely.
To query active bypass settings in the SQLite database:
sqlite3 /var/imunifyemail/dec-node/storage/index.db "SELECT * FROM settings WHERE key LIKE '%whitelist%' OR key LIKE '%bypass%';"
4. Operational commands and automated monitoring#
Once the system layout is clear, storage capacities can be adjusted and monitored proactively to prevent unwanted bypasses.
Adjusting global quarantine limits#
To inspect current default storage limits across managed mailboxes:
ie-cli quarantine-defaults list
To increase storage capacity per mailbox (for example, raising it to 200 MB) and avoid the Fail Open trigger:
ie-cli quarantine-defaults set --storage-capacity 200
Automated quarantine storage monitoring script#
To avoid relying on manual checks, a lightweight Bash script can inspect ie-cli accounts list, calculate mailbox usage percentages, and send warning events to Syslog whenever a mailbox exceeds 80% capacity.
Save the script to /usr/local/bin/ie_quarantine_monitor.sh:
#!/bin/bash
# Imunify Email quarantine storage monitor
ALERT_PERCENT=80
LOG_DIR="/var/log/imunifyemail"
LOG_FILE="${LOG_DIR}/quarantine_monitor.log"
BINARY="/usr/bin/ie-cli"
if [ ! -d "$LOG_DIR" ]; then
mkdir -p "$LOG_DIR"
chmod 750 "$LOG_DIR"
fi
if [ ! -x "$BINARY" ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] ie-cli binary not found or not executable." >> "$LOG_FILE"
exit 1
fi
$BINARY accounts list | grep -E '^[a-zA-Z0-9]' | while read -r NAME USED LIMIT RELEASE FILT; do
if [[ "$USED" =~ ^[0-9]+$ ]] && [[ "$LIMIT" =~ ^[0-9]+$ ]] && [ "$LIMIT" -gt 0 ]; then
PERCENT=$(( USED * 100 / LIMIT ))
if [ "$PERCENT" -ge "$ALERT_PERCENT" ]; then
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
ALERT_MSG="[QUOTA_ALERT] Account: ${NAME} reached ${PERCENT}% usage (${USED} of ${LIMIT} bytes) in quarantine."
echo "[${TIMESTAMP}] ${ALERT_MSG}" >> "$LOG_FILE"
logger -p mail.warn -t IMUNIFY_EMAIL_MONITOR "${ALERT_MSG}"
fi
fi
done
exit 0
Make the script executable and schedule it through cron every 10 minutes:
chmod +x /usr/local/bin/ie_quarantine_monitor.sh
echo "*/10 * * * * root /bin/bash /usr/local/bin/ie_quarantine_monitor.sh >/dev/null 2>&1" > /etc/cron.d/imunify-quarantine-monitor
systemctl restart crond
Live log inspection for Imunify daemons#
To watch decision events as new mail arrives:
# Monitor verdicts generated by the decision node
journalctl -u ie-dec-node -f --since "1 hour ago" | grep -iE "score|action|quarantine"
# Monitor quarantine storage operations
journalctl -u ie-quarantine -f --since "1 hour ago"
Preventive maintenance and ongoing quarantine monitoring#
Understanding the separation between the decision node (ie-dec-node), quarantine storage (ie-quarantine), and the scoring engine (rspamd) eliminates confusion when configuring newer Imunify Email releases.
For long-term reliability:
- Watch mailbox storage ceilings: remember that protection defaults to Fail Open when individual account limits or the global cleaner threshold in
dec-node.yamlare exceeded. - Use journalctl for troubleshooting: runtime diagnostic events are logged directly to Systemd units rather than standard flat files.
- Automate quota alerts: routing storage warnings to Syslog helps catch full quarantine mailboxes before legitimate spam filters are bypassed.
Was this article helpful?
Leave a quick reaction to help prioritize future technical guides:
This post is licensed under CC BY-NC.



Comments
Join the discussion below.
0 comments