MSA MYSTREAM AGENCY

How to Block Email from a Specific Sender in EXIM (With Smart Domain Filters, Pattern Matching, and Advanced Content Rules)

Keyword filtering in EXIM is a powerful but underused tool for fighting spam, scams, and policy violations. By inspecting subject lines, headers, or message bodies, administrators can block or quarantine emails that contain dangerous or unwanted terms - all without third-party filtering software.

In this guide, you’ll learn:

  • How to block emails containing specific words (e.g. “Viagra”, “Cialis”, “gambling”)
  • Where to configure keyword filters in EXIM
  • How to match against various headers or body content
  • How to manage dynamic keyword lists efficiently
  • How to implement smarter keyword logic (e.g. per-sender, per-recipient)
  • Bonus: Using keyword matches to score or quarantine suspicious messages

1. Where to Place Keyword Filtering Rules in EXIM

Keyword filtering is best handled in the ACL phase, typically in acl_check_data, which evaluates content after the SMTP DATA command, when EXIM receives message headers and optionally the body.

File to edit:

Single config: /etc/exim4/exim4.conf.template

Split config: /etc/exim4/conf.d/acl/40_exim4-config_check_data

Make sure this ACL runs after any necessary SPF/DKIM checks, to avoid false positives from valid senders.

2. Basic Keyword Blocking Example (Subject Line Match)

Here's the simplest way to block messages based on spammy subject keywords:

deny
    message = This message has been blocked because it contains spam keywords.
    condition = ${if match{$h_subject:}{(?i)Viagra|Cialis|gambling}{yes}{no}}

Why it works:

${h_subject:} reads the subject header.

(?i) makes it case-insensitive (highly recommended).

match{} returns yes if any term is found.

This will block messages with Viagra, Cialis, or gambling in the subject line — a common spam vector.

3. Matching Keywords in Other Headers or Body Content

You can expand beyond subject lines by targeting:

$message_headers — entire set of headers

$message_body — full message body (slower, use with care)

$h_from:, $h_reply-to:, $h_to: — specific fields

Example: block keywords in sender name or reply-to

deny
    message = Blocked for spam keyword match in headers.
    condition = ${if match{$message_headers}{(?i)CryptoInvestment|FreeMoney}{yes}{no}}

Body match (resource intensive — use only when needed):

deny
    message = Blocked due to spam content in message body.
    condition = ${if match{$message_body}{(?i)bitcoins\s+guaranteed|hot stock tip}{yes}{no}}

4. Smarter Keyword Lists (Dynamic File-Based Management)

Rather than hardcoding strings, load keywords from a file.

Create:

/etc/exim4/keyword_blacklist.txt

With entries like:

Viagra
Cialis
Free Money
CryptoInvestment
bitcoins guaranteed

EXIM ACL:

deny
    message = Blocked for matching blacklisted keyword.
    condition = ${if match{$message_body}{${readfile{/etc/exim4/keyword_blacklist.txt}}}{yes}{no}}

This makes the list editable without reloading EXIM.

Automated tools (like spam traps or abuse reports) can add to this file dynamically.

5. Context-Aware Filtering: Combine Keyword Rules with Sender, IP, or Country

Let's say you only want to block gambling-related keywords from senders in .ru or .cn domains:

deny
    message = Rejected: spam content from restricted region.
    condition = ${if and{
        {match{$h_subject:}{(?i)casino|poker|jackpot}}
        {match_domain{$sender_address_domain}{*.ru:*.cn}}
    }{yes}{no}}

You could also use GeoIP for more accurate region detection.

6. Using Regex Flags for Better Filtering

Use regex flags for smarter matching:

(?i) — case-insensitive

\b — word boundaries to avoid false matches

Example:

condition = ${if match{$h_subject:}{(?i)\b(viagra|cialis|lottery|loan)\b}{yes}{no}}

This avoids matching viagra1234@example.com.

7. Logging and Alerting on Keyword Matches

Add a custom header for matched keywords:

add_header = X-Spam-Keyword-Match: matched keyword

Or log events asynchronously:

grep "Blocked for matching" /var/log/exim4/mainlog | while read line; do
    curl -X POST -d "log=$line" https://your-internal-logger/api/keyword-matches
done

Useful for internal abuse dashboards or security alerts.

8. Advanced: Quarantine Instead of Rejecting

Instead of outright blocking, redirect messages to a quarantine inbox:

warn
    condition = ${if match{$h_subject:}{(?i)lottery|crypto|pills}{yes}{no}}
    redirect = spam-trap@yourdomain.com
    message = Message redirected to quarantine due to suspicious keywords.

This helps avoid false positives while still preventing delivery to real users.

9. Bonus: Score-Based Filtering for Multi-Keyword Detection

You can stack checks and assign scores:

warn
    set acl_m_spam_score = 0
warn
    condition = ${if match{$h_subject:}{(?i)viagra}{yes}{no}}
    set acl_m_spam_score = ${eval:$acl_m_spam_score + 5}
warn
    condition = ${if match{$h_subject:}{(?i)lottery}{yes}{no}}
    set acl_m_spam_score = ${eval:$acl_m_spam_score + 3}
deny
    condition = ${if >{$acl_m_spam_score}{5}{yes}{no}}
    message = Blocked: message exceeded spam keyword threshold.

Conclusion

Keyword-based filtering in EXIM is an incredibly flexible tool for spam prevention, policy enforcement, and abuse mitigation. By tailoring rules based on headers, bodies, sender domains, and scoring, you can intelligently intercept unwanted messages before they ever hit user inboxes.

See also: Learn how to integrate EXIM keyword filters with virus scanners and spamassassin for a layered security model.

Email us right here