Install ClamAV on FreeBSD 15.0 and link it with Amavis against Postfix.
ClamAV is anti-virus software.
We will proceed on the assumption that you have already implemented Postfix.
Before proceeding, update the Ports Collection.
1. ClamAV
1.1 Install
|
1 |
# pkg install -y clamav |
clamav version check
|
1 2 |
# pkg version -v | grep clamav clamav-1.4.3_1,1 < needs updating (index has 1.5.1_1,1) |
1.2 Configuration File Editing
①Edit clamd.conf
Run ClamAV as root user
|
1 2 3 4 5 6 7 8 9 10 |
# chmod 640 /usr/local/etc/clamd.conf # vi /usr/local/etc/clamd.conf Line 35 : Uncomment #LogTime yes LogTime yes Line 233 : Comment out User clamav #User clamav |
➁Edit freshclam.conf
Settings about virus pattern files
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# chmod 640 /usr/local/etc/freshclam.conf # vi /usr/local/etc/freshclam.conf Line 62 : change DatabaseOwner clamav ↓ DatabaseOwner root Line 78 : Mirror site change #DatabaseMirror database.clamav.net DatabaseMirror db.jp.clamav.net Line 121 : Uncomment #Checks 24 Checks 24 |
1.3 Virus database update
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# freshclam ClamAV update process started at Sat Dec 6 10:26:10 2025 daily database available for download (remote version: 27841) Time: 1.2s, ETA: 0.0s [========================>] 61.77MiB/61.77MiB Testing database: '/var/db/clamav/tmp.6ad6d99603/clamav-b45655c87bb47e43c29c94a7ddb7c837.tmp-daily.cvd' ... Database test passed. daily.cvd updated (version: 27841, sigs: 2077269, f-level: 90, builder: svc.clamav-publisher) main database available for download (remote version: 62) Time: 5.5s, ETA: 0.0s [========================>] 162.58MiB/162.58MiB Testing database: '/var/db/clamav/tmp.6ad6d99603/clamav-b2657eaf58446bf30a743c7a5ff2d1a9.tmp-main.cvd' ... Database test passed. main.cvd updated (version: 62, sigs: 6647427, f-level: 90, builder: sigmgr) bytecode database available for download (remote version: 339) Time: 0.1s, ETA: 0.0s [========================>] 275.10KiB/275.10KiB Testing database: '/var/db/clamav/tmp.6ad6d99603/clamav-56650b4405d66192787fb0f1e6f4296e.tmp-bytecode.cvd' ... Database test passed. bytecode.cvd updated (version: 339, sigs: 80, f-level: 90, builder: nrandolp) WARNING: Clamd was NOT notified: Can't connect to clamd through /var/run/clamav/clamd.sock: No such file or directory |
1.4 ClamAV start
ClamAV auto-start configuration
|
1 2 3 4 |
# vi /etc/rc.conf Add the following clamav_clamd_enable="YES" clamav_freshclam_enable="YES" |
start
|
1 2 3 4 5 |
# /usr/local/etc/rc.d/clamav_clamd start Starting clamav_clamd. # /usr/local/etc/rc.d/clamav_freshclam start Starting clamav_freshclam. |
1.5 manual virus check
To manually check for viruses, do the following(Scanning range is /home/)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# clamscan --infected --remove --recursive -r /home ----------- SCAN SUMMARY ----------- Known viruses: 8708962 Engine version: 1.4.3 Scanned directories: 20 Scanned files: 29 Infected files: 0 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 19.869 sec (0 m 19 s) Start Date: 2025:12:06 10:28:32 End Date: 2025:12:06 10:28:52 |
1.6 automatic virus scanning
• Scanning range is /home/.
• Output scan results to /var/log/clamav.log
• Automatic deletion of detected viruses
• Executed daily
Create an execution script with the above conditions
①Creation of virus storage directory
|
1 |
# mkdir -p /var/lib/clamav/virus |
➁Shell Script Creation
|
1 2 3 4 5 6 7 8 |
# vi /etc/clamscan.sh Please describe the following content. #!/bin/sh # clamscan script CLAMSCAN='/usr/local/bin/clamscan' echo "clamscan start "`date '+%Y%m%d'` $CLAMSCAN --log=/var/log/clamav/clamav.log -i --move=/var/lib/clamav/virus/ -r /home |
Grant execution permissions to scripts
|
1 |
# chmod 755 /etc/clamscan.sh |
Register in cron to be executed at 0:00 AM
|
1 2 3 |
# crontab -e The following content description 0 0 * * * /etc/clamscan.sh > /dev/null 2>&1 |
Run the following as a test
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# /etc/clamscan.sh clamscan start 20251206 ----------- SCAN SUMMARY ----------- Known viruses: 8708962 Engine version: 1.4.3 Scanned directories: 20 Scanned files: 29 Infected files: 0 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 17.447 sec (0 m 17 s) Start Date: 2025:12:06 10:30:57 End Date: 2025:12:06 10:31:14 |
If you look at /var/log/clamav/clamav.log, you will see the same log as above
|
1 |
# cat /var/log/clamav/clamav.log |
2. Amavis
Install Amavis, which links ClamAV and Postfix
2.1 Install
|
1 |
# pkg install amavisd-new |
2.2 Configuration File Editing
Edit amavisd.conf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# vi /usr/local/etc/amavisd.conf Line 13: Uncomment # @bypass_spam_checks_maps = (1); @bypass_spam_checks_maps = (1); Line 23: Change to your own domain name $mydomain = '<domain name>'; Line 169: Append your hostname # $myhostname = 'host.example.com'; $myhostname = 'mail.<domain name>'; # Change to local hostname Lines 170-171: Uncomment # $notify_method = 'smtp:[127.0.0.1]:10025'; # $forward_method = 'smtp:[127.0.0.1]:10025'; ↓ $notify_method = 'smtp:[127.0.0.1]:10025'; $forward_method = 'smtp:[127.0.0.1]:10025'; Lines 824-827: Uncomment # ['ClamAV-clamd', # \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"], # qr/\bOK$/m, qr/\bFOUND$/m, # qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ], ↓ ['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"], qr/\bOK$/m, qr/\bFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ], |
2.3 Amavis Auto-Startup Configuration
|
1 2 3 |
# vi /etc/rc.conf Add the following description amavisd_enable="YES" |
Amavis start
|
1 |
# /usr/local/etc/rc.d/amavisd start |
2.4 Postfix Configuration
①Edit main.cf
|
1 2 3 4 |
# vi /usr/local/etc/postfix/main.cf #Add to the last line # Filter configuration content_filter = smtp-amavis:[127.0.0.1]:10024 |
➁Edit master.cf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# vi /usr/local/etc/postfix/master.cf #Add the following to the last line: # Amavis configuration smtp-amavis unix - - n - 2 smtp -o smtp_data_done_timeout=1200 -o smtp_send_xforward_command=yes -o smtp_dns_support_level=disabled -o max_use=20 127.0.0.1:10025 inet n - n - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_delay_reject=no -o smtpd_client_restrictions=permit_mynetworks,reject -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions=reject_unauth_pipelining -o smtpd_end_of_data_restrictions= -o mynetworks=127.0.0.0/8 -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks |
3. Anti-Spam with SpamAssassin
3.1 SpamAssassin Install
If you did not select spamassassin as an option when you installed Amavis, install it as follows
|
1 |
# pkg install spamassassin |
|
1 |
# chmod 644 /usr/local/etc/mail/spamassassin/v310.pre |
3.2 Configuration File Editing
|
1 2 3 4 |
# vi /usr/local/etc/mail/spamassassin/v310.pre Line 24 : Uncomment (enable TextCat) loadplugin Mail::SpamAssassin::Plugin::DCC |
3.3 Spamassassin start
|
1 2 3 4 |
# vi /etc/rc.conf Additional description below spamd_enable="YES" |
|
1 2 3 |
# sa-update # /usr/local/etc/rc.d/sa-spamd start Starting spamd. |
3.4 SpamassAssin Update
Create an update script
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# vi /etc/periodic/daily/620.spamassassin Please fill in the following information #!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin cd /usr/local/etc/mail/spamassassin wget -q https://github.com/kittyfreak/spamassassin_user_prefs/archive/refs/heads/main.zip [ $? -ne 0 ] && exit unzip main.zip >/dev/null 2>&1 [ $? -ne 0 ] && exit rm -f main.zip mv spamassassin_user_prefs-main/user_prefs . rm -rf spamassassin_user_prefs-main cp user_prefs local.cf cat << EOF >> local.cf report_safe 0 rewrite_header Subject ***SPAM*** EOF /usr/local/etc/rc.d/sa-spamd restart > /dev/null |
Grant execution rights to scripts
|
1 |
# chmod 755 /etc/periodic/daily/620.spamassassin |
When the script is executed, a local.cf is created for the date and time of execution
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# pkg install wget # /etc/periodic/daily/620.spamassassin # ls -l /usr/local/etc/mail/spamassassin total 529 -rw-r--r-- 1 root wheel 1649 Nov 29 13:06 init.pre -rw-r--r-- 1 root wheel 1649 Nov 29 13:06 init.pre.sample -rw-r--r-- 1 root wheel 500636 Dec 6 10:49 local.cf -rw-r--r-- 1 root wheel 3218 Nov 29 13:06 local.cf.sample drwx------ 2 root wheel 6 Dec 6 10:47 sa-update-keys -rw-r--r-- 1 root wheel 500588 Apr 30 2023 user_prefs -rw-r--r-- 1 root wheel 2266 Dec 6 10:47 v310.pre -rw-r--r-- 1 root wheel 2267 Nov 29 13:06 v310.pre.sample -rw-r--r-- 1 root wheel 1168 Nov 29 13:06 v312.pre -rw-r--r-- 1 root wheel 1168 Nov 29 13:06 v312.pre.sample -rw-r--r-- 1 root wheel 2416 Nov 29 13:06 v320.pre -rw-r--r-- 1 root wheel 2416 Nov 29 13:06 v320.pre.sample -rw-r--r-- 1 root wheel 1237 Nov 29 13:06 v330.pre -rw-r--r-- 1 root wheel 1237 Nov 29 13:06 v330.pre.sample -rw-r--r-- 1 root wheel 1020 Nov 29 13:06 v340.pre -rw-r--r-- 1 root wheel 1020 Nov 29 13:06 v340.pre.sample -rw-r--r-- 1 root wheel 1315 Nov 29 13:06 v341.pre -rw-r--r-- 1 root wheel 1315 Nov 29 13:06 v341.pre.sample -rw-r--r-- 1 root wheel 1519 Nov 29 13:06 v342.pre -rw-r--r-- 1 root wheel 1519 Nov 29 13:06 v342.pre.sample -rw-r--r-- 1 root wheel 1266 Nov 29 13:06 v343.pre -rw-r--r-- 1 root wheel 1266 Nov 29 13:06 v343.pre.sample -rw-r--r-- 1 root wheel 1484 Nov 29 13:06 v400.pre -rw-r--r-- 1 root wheel 1484 Nov 29 13:06 v400.pre.sample -rw-r--r-- 1 root wheel 1118 Nov 29 13:06 v401.pre -rw-r--r-- 1 root wheel 1118 Nov 29 13:06 v401.pre.sample |
3.5 postfix restart
|
1 |
# /usr/local/etc/rc.d/postfix restart |
3.6 Spam mailbox creation
When using IMAP in this case
①Create spam mailboxes for existing users
Let's assume the existing user is huong
|
1 2 3 4 5 |
# bash # mkdir -p /home/huong/Maildir/.spam/{cur,new,tmp} # chmod -R 700 /home/huong/Maildir/.spam # chown -R huong:huong /home/huong/Maildir/.spam # sh |
➁Create spam mailboxes for additional users
|
1 2 3 4 |
# bash # mkdir -p /usr/share/skel/Maildir/.spam/{cur,new,tmp} # chmod -R 700 /usr/share/skel/Maildir/.spam # sh |
3.7 Edit procmailrc (for IMAP)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# vi /usr/local/etc/procmailrc Fill in the following SHELL=/bin/sh PATH=/bin:/usr/bin:/usr/local/bin DROPPRIVS=yes MAILDIR=$HOME/Maildir DEFAULT=$MAILDIR/ SPAM=$MAILDIR/.spam/ #LOGFILE=$MAILDIR/procmail.log :0 * ^Subject:.*=\?[Ii][Ss][Oo]-2022-[Jj][Pp]\?[Bb]\?GyRCTCQ\+NUJ6OS05cCIo /dev/null # Start spamassassin if "X-Spam-***" is not in the header :0fw *!^X-Spam.* |spamassassin # If the header has "X-Spam-Status: Yes", it is stored in the ".spam" directory. :0 *^X-Spam-Status: Yes $SPAM |
3.8 Spam Mail Learning
Create spam email learning scripts
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# vi /etc/periodic/daily/620.sa-learn Fill in the following #!/bin/sh # Learning spam folder as spam /usr/local/bin/sa-learn --spam /home/*/Maildir/.spam/cur # Maildir folder learned as normal mail /usr/local/bin/sa-learn --ham /home/*/Maildir/cur # Uncomment the following to delete the spam folder #/bin/rm -f /home/*/Maildir/.spam/cur/* |
3.9 Virus and Spam Email Transmission Test
When I send a blank email to myself in Thunderbird, the following message appears in the header of the received email
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
Return-Path: xxxxx@xxxxxxxx.com
X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on Lepard
X-Spam-Level: **
X-Spam-Status: No, score=2.3 required=13.0 tests=ALL_TRUSTED,
CONTENT_TYPE_PRESENT,EMPTY_MESSAGE autolearn=no autolearn_force=no
version=4.0.1
X-Original-To: xxxxx@xxxxxxx.com
Delivered-To: xxxxx@xxxxxxx.com
Received: from localhost (localhost [127.0.0.1])
by mail.xxxxxxx.com (Postfix) with ESMTP id EEE4E2B642
for huong@xxxxxxx.com; Sat, 06 Dec 2025 11:29:21 +0900 (JST)
X-Virus-Scanned: amavis at xxxxxxx.com
Received: from mail.xxxxxxx.com ([127.0.0.1])
by localhost (mail.xxxxxxx.com [127.0.0.1]) (amavis, port 10024) with ESMTP
id 12CJjJTkIQ73 for xxxxx@xxxxxxx.com;
Sat, 6 Dec 2025 11:29:01 +0900 (JST)
------------------------------------
------------------------------------
Fill in the following in the body of the message in Thunderbird and send it to yourself.
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
The email was not delivered and was quarantined in the .spam directory (.spam/new/xxxxxxxxx). The following message appears in the header of the received email:
X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on Lepard
X-Spam-Flag: YES
X-Spam-Level: ********************************************
X-Spam-Status: Yes, score=1001.8 required=13.0 tests=ALL_TRUSTED,
CONTENT_TYPE_PRESENT,GTUBE,HTML_MESSAGE,MPART_ALT_DIFF,
MULTIPART_ALTERNATIVE autolearn=no autolearn_force=no version=4.0.1
X-Spam-Report:
* 0.1 ALL_TRUSTED Passed through trusted hosts only via SMTP
* -0.1 CONTENT_TYPE_PRESENT exists:Content-Type
* 0.1 MULTIPART_ALTERNATIVE Multipart/alternative
* 1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email
* 0.7 MPART_ALT_DIFF BODY: HTML and text parts are different
* 1.0 HTML_MESSAGE BODY: HTML included in message
