Skip to content

Nuface Blog

隨意隨手記 Casual Notes

Menu
  • Home
  • About
  • Services
  • Blog
  • Contact
  • Privacy Policy
  • Login
Menu

Amavis + ClamAV + DKIM: The Complete Flow of Virus Scanning, Spam Filtering, and Mail Signing

Posted on 2025-11-202025-11-21 by Rico

Mail Server Series — Part 7

In the previous articles, we completed Postfix, Dovecot, SpamAssassin, and Piler installation and integration.
In this part, we focus on a key security component of the entire mail pipeline: Amavis.

Amavis is the central content filter that orchestrates:

  • ClamAV → virus detection
  • SpamAssassin → spam scoring
  • DKIM → verification (inbound) and signing (outbound)
  • Policy banks → different behaviors for inbound/outbound
  • MIME processing → unzip/unpack attachments for scanning

This part explains how Amavis integrates into your Docker-based mail server and how the full message-security pipeline works.


1. The Role of Amavis

Amavis (A Mail Virus Scanner) acts as a Postfix content_filter middleware, responsible for:

FunctionDescription
Anti-VirusScans attachments and message bodies using ClamAV
Anti-SpamCalls SpamAssassin to assign spam scores
DKIM VerificationVerifies DKIM signatures for inbound mail
DKIM SigningSigns outbound emails
Policy BankDifferent rules for inbound vs outbound
MIME HandlerAutomatically extracts zip/rar/gz for scanning

It is the security “bridge” between incoming/outgoing traffic and the MTA (Postfix).


2. Mail Flow Through Amavis

Inbound Flow (Internet → Internal mailbox)

Internet → Postfix (25)
        → smtp-amavis (10024)
        → Amavis: Virus scan / SpamAssassin / DKIM verify
        → Postfix (10025)
        → Dovecot (LMTP delivery)

Outbound Flow (Internal client → Internet)

Client (587) → Postfix submission
             → smtp-amavis (10026)
             → Amavis: SpamAssassin + DKIM signing
             → Postfix (10027)
             → Internet

Inbound and outbound must be separated because:

  • Inbound requires DKIM verification
  • Outbound requires DKIM signing
  • Spam thresholds differ for inbound/outbound
  • Outbound should not block legitimate outgoing messages

3. Amavis Docker Container Structure

Directory layout:

/opt/docker/mail/amavis/
 ├── amavis.conf
 ├── 50-user.conf
 ├── policies/
 ├── dkim/
 │     └── domain.key
 ├── log/
 └── amavis.sh

Run the Docker container:

docker run -dit --name amavis \
  --restart=always \
  --network intranet-net \
  -e TZ=Asia/Taipei \
  -v $PWD:/etc/amavis \
  -v $PWD/log:/var/log/amavis \
  nuface/amavis:1.0

4. Integrating ClamAV

Amavis connects to ClamAV using a local socket:

/var/run/clamav/clamd.ctl

Recommended Docker service:

clamd:
  image: clamav/clamav:latest
  volumes:
    - /opt/docker/mail/clamav:/var/lib/clamav
    - /opt/docker/mail/clamav/run:/run/clamav
  networks:
    - intranet-net

Amavis config:

@av_scanners = (
  ['ClamAV-clamd',
    \&ask_daemon, ["CONTSCAN {}","\Zclamdsock","/run/clamav/clamd.ctl"],
    qr/\bOK$/m, qr/\bFOUND$/m,
    qr/^.*?: (.*) FOUND$/m ],
);

5. Integrating SpamAssassin

Amavis automatically calls SpamAssassin. In 50-user:

$sa_tag_level_deflt  = -999;
$sa_kill_level_deflt = 6.0;
$sa_dsn_cutoff_level = 10;
$spamassassin_tag_headers = 1;

This means:

  • All messages receive spam headers
  • Messages with score ≥ 6 are treated as spam
  • Score ≥ 10 may be rejected

6. DKIM Signing and Verification

Generate DKIM Keys

For domain it.demo.tw:

amavisd-new genrsa /opt/docker/mail/amavis/dkim/it.demo.tw.key 2048

DNS TXT record:

default._domainkey.it.demo.tw IN TXT "v=DKIM1; k=rsa; p=xxxx"

Enable DKIM Signing

$enable_dkim_signing = 1;
dkim_key('it.demo.tw', 'default', '/etc/amavis/dkim/it.demo.tw.key');

Outbound Policy Bank (10026)

$policy_bank{'OUTBOUND'} = {
  originating => 1,
  enable_dkim_signing => 1,
};

7. Postfix ↔ Amavis Port Assignments

Inbound

smtp inet n - n - - smtpd
   -o content_filter=smtp-amavis:[amavis]:10024

Inbound return path:

10025 inet n - n - - smtpd
  -o content_filter=

Outbound

submission inet n - n - - smtpd
  -o content_filter=smtp-amavis:[amavis]:10026

Outbound return path:

10027 inet n - n - - smtpd
  -o content_filter=

8. Policy Banks

Amavis supports policy banks to split logic:

$inet_socket_port = [10024, 10026];

Inbound Policy

$policy_bank{'AMAVIS'} = {
  enable_dkim_verification => 1,
};

Outbound Policy

$policy_bank{'ORIGINATING'} = {
  enable_dkim_signing => 1,
  allow_disclaimers => 1,
};

9. Logs and Debugging

Reload Amavis

docker exec -it amavis amavisd reload

Check DKIM logs

grep DKIM /opt/docker/mail/amavis/log/amavis.log

Run SpamAssassin debug

spamassassin -D < testmail.eml

10. Security Testing

EICAR Test Virus

curl -O https://secure.eicar.org/eicar_com.txt

Amavis should return:

FOUND Eicar-Test-Signature

GTUBE Spam Test

Insert in any email:

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

SpamAssassin score should be very high.

DKIM Test

Send mail to Gmail and check:

Authentication-Results: dkim=pass

Conclusion: Amavis is the Core of Your Mail Security Pipeline

By completing Part 7, your environment now has:

  • Reliable virus detection (ClamAV)
  • Accurate spam scoring (SpamAssassin)
  • DKIM verification (inbound)
  • DKIM signing (outbound)
  • Proper inbound/outbound separation
  • Policy-based mail processing

This is one of the most critical parts of a secure mail server.

Recent Posts

  • Postfix + Let’s Encrypt + BIND9 + DANE Fully Automated TLSA Update Guide
  • Postfix + Let’s Encrypt + BIND9 + DANE TLSA 指紋自動更新完整教學
  • Deploying DANE in Postfix
  • 如何在 Postfix 中部署 DANE
  • DANE: DNSSEC-Based TLS Protection

Recent Comments

  1. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on High Availability Architecture, Failover, GeoDNS, Monitoring, and Email Abuse Automation (SOAR)
  2. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on MariaDB + PostfixAdmin: The Core of Virtual Domain & Mailbox Management
  3. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Daily Operations, Monitoring, and Performance Tuning for an Enterprise Mail System
  4. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Final Chapter: Complete Troubleshooting Guide & Frequently Asked Questions (FAQ)
  5. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Network Architecture, DNS Configuration, TLS Design, and Postfix/Dovecot SNI Explained

Archives

  • December 2025
  • November 2025
  • October 2025

Categories

  • AI
  • Apache
  • Cybersecurity
  • Database
  • DNS
  • Docker
  • Fail2Ban
  • FileSystem
  • Firewall
  • Linux
  • LLM
  • Mail
  • N8N
  • OpenLdap
  • OPNsense
  • PHP
  • QoS
  • Samba
  • Switch
  • Virtualization
  • VPN
  • WordPress
© 2025 Nuface Blog | Powered by Superbs Personal Blog theme