Setup Email Server From Scratch On FreeBSD #2 - 12 Amavis Clam AntiVirus
11 SpamAssassin <- Intro -> 13 Postscreen
We believe in data independence, and support others who want data independence.
This tutorial is complete 2025-08-14 except there is no page for setting up postscreen.
This is version 2 and everthing works.
##################################################### # Installing Antivirus Amavis and ClamAV on FreeBSD # #####################################################
Install Amavisd and Clam Anti Virus
pkg install amavisd-new clamav
pkg install p5-Mail-SPF p5-Net-DNS p5-Digest-SHA1 p5-IO-Stringy py311-pyzor razor-agents
pkg install cabextract gcpio rpm2cpio file lhasa nomarch pax-utils bzip2 gzip rar
pkg install arj unrar 7-zip unzip zip lrzip lzip liblz4 lzop unrar file
sysrc amavisd_enable="YES"
sysrc amavisd_pidfile="/var/amavis/amavisd.pid"
sysrc amavisd_ram="512m"
sysrc amavisd_ram="1g"
Check Amavis Version
amavisd -V
amavis-2.13.1 (20240304)
Create a 1G memory mapped tmp filesystem for amavis, amavis on FreeBSD creates user and group vscan
grep vscan /etc/group /etc/passwd
/etc/group:vscan:*:110:
/etc/passwd:vscan:*:110:110:Scanning Virus Account:/var/maiad:/bin/sh
mkdir -p /var/amavis/tmp
chown -R vscan:vscan /var/amavis/tmp
nano /etc/fstab
echo 'tmpfs /var/amavis/tmp tmpfs rw,noexec,nosuid,size=1G,mode=1750,uid=110,gid=110 0 0' >> /etc/fstab
mount /var/amavis/tmp
Configure Amavis
SpamAssassin headers can get removed by amavis if run separately so I enable spamassassin in amavis and disable it it postfix. This will retain the X-Spam-Score and have X-Virus-Scanned, otherwise if run SpamAssassin from postfix amavis will remove the X-Virus-Scanned headers.
Check how many cpu are available.
sysctl hw.ncpu
hw.ncpu: 8
When trying to restart amavis fails to start and logs show that port 10024 is already in use. Some child processes may not be killed and seems to be caused if max_servers is set too high.
If amavis doesn't restart use ...
pkill -U vscan
service amavisd start
Please note that for some reason amavis has problems opening berkley db file and
will crash unless we disable with $enable_db = 0; in /usr/local/etc/amavis.conf.
nano /usr/local/etc/amavisd.conf
--- add or change ignore the ... ---
@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
@bypass_spam_checks_maps = (
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
# disable db or else will crash
$enable_db = 0;
$max_servers = 4; # num of pre-forked children (2..30 is common), -m
$mydomain = 'okbsd.com'; # a convenient default for other settings
$X_HEADER_LINE = "by smtp.$mydomain";
...
$enable_dkim_verification = 0;
@local_domains_maps = ( [".$mydomain", ".coragarden.com"] ); # list of all local domains
# $inet_socket_port = 10024; # listen on this local TCP port(s)
$inet_socket_port = [10024,10026]; # listen on multiple TCP ports
$sa_tag_level_deflt = -999.0; # add spam info headers if at, or above that level
virus_admin_maps => ["postmaster\@$mydomain"],
spam_admin_maps => ["postmaster\@$mydomain"],
#forward_method => 'smtp:[127.0.0.1]:10027',
Confirm it is running
service amavisd start
service amavisd status
amavisd is running as pid 8078.
sockstat -l | grep 10024
vscan perl 8083 8 tcp4 127.0.0.1:10024 *:*
vscan perl 8083 9 tcp6 ::1:10024 *:*
Add Amavis to Postfix main.cf / spamass will be run my amavis so remove from smtpd_milters
nano /usr/local/etc/postfix/main.cf
--- add to bottom of file ---
# amavisd
smtpd_proxy_options = speed_adjust
content_filter = smtp-amavis:[127.0.0.1]:10024
nano /usr/local/etc/postfix/master.cf
--- add to end of file, -- cores - v ---
smtp-amavis unix - - n - 4 smtp
-o syslog_name=postfix/amavis
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o smtp_dns_support_level=disabled
-o max_use=20
-o smtp_tls_security_level=none
127.0.0.1:10025 inet n - n - - smtpd
-o syslog_name=postfix/10025
-o content_filter=
-o mynetworks_style=host
-o mynetworks=127.0.0.0/8
-o local_recipient_maps=
-o relay_recipient_maps=
-o strict_rfc821_envelopes=yes
-o smtp_tls_security_level=none
-o smtpd_tls_security_level=none
-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_end_of_data_restrictions=
-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,no_address_mappings
service postfix restart
Configure FreshClam
nano /usr/local/etc/freshclam.conf
NotifyClamd /usr/local/etc/clamd.conf
nano /usr/local/etc/freshclam.conf
NotifyClamd /usr/local/etc/clamd.conf
sysrc clamav_clamd_enable="YES"
service clamav_clamd start
service clamav_clamd status
clamav_clamd is running as pid 8785.
Update FreshClam Database
freshclam
sysrc clamav_freshclam_enable="YES"
service clamav_freshclam start
service clamav_freshclam status
clamav_freshclam is running as pid 8803.
pw groupmod vscan -m clamav
adduser clamav amavis
service clamav_clamd restart
service clamav_clamd status
service amavisd restart
service amavisd status
Use a dedicated port for submissions, max_servers should be the number of cores on the server, I have 4 virtual cores.
nano /usr/local/etc/amavisd.conf
$max_servers = 4;
$enable_dkim_verification = 0;
$sa_tag_level_deflt = -999.0;
$X_HEADER_LINE = "by smtp.$mydomain";
# Fix amavis to scan other virtual domains
@local_domains_maps = ( [".$mydomain"], ".coragarden.com" ); # list of all local domains
$inet_socket_port = [10024, 10026];
$interface_policy{'10026'} = 'ORIGINATING';
$policy_bank{'ORIGINATING'} = { # mail supposedly originating from our users
originating => 1, # declare that mail was submitted by our smtp client
allow_disclaimers => 1, # enables disclaimer insertion if available
# notify administrator of locally originating malware
virus_admin_maps => ["postmaster\@okbsd.com"],
spam_admin_maps => ["postmaster\@okbsd.com"],
warnbadhsender => 1,
# forward to a smtpd service providing DKIM signing service
# forward_method => 'smtp:[127.0.0.1]:10027',
# force MTA conversion to 7-bit (e.g. before DKIM signing)
smtpd_discard_ehlo_keywords => ['8BITMIME'],
bypass_banned_checks_maps => [1], # allow sending any file names and types
terminate_dsn_on_notify_success => 0, # don't remove NOTIFY=SUCCESS option
};
Add the following 2 line to /usr/local/etc/postfix/master.cf submission and smtps sections Add the no_milters or else outgoing gets DKIM signed twice!
-o content_filter=smtp-amavis:[127.0.0.1]:10026
-o receive_override_options=no_milters
nano /usr/local/etc/postfix/master.cf
--- add the content_filter line in 2 places like this ---
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_wrappermode=no
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o content_filter=smtp-amavis:[127.0.0.1]:10026
-o receive_override_options=no_milters
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o content_filter=smtp-amavis:[127.0.0.1]:10026
-o receive_override_options=no_milters
service postfix restart
Remove SpamAssasin socket in smtpd_milters, it is running in amavis
nano /usr/local/etc/postfix/main.cf
#smtpd_milters = unix:opendkim/opendkim.sock,unix:opendmarc/opendmarc.sock,unix:spamass/spamass.sock
smtpd_milters = unix:opendkim/opendkim.sock,unix:opendmarc/opendmarc.sock
service amavisd restart
service postfix restart
Adjust your style of spf header if desired.
nano /usr/local/etc/python-policyd-spf/policyd-spf.conf
# default = Recieved-SPF
# Header_Type = Received-SPF
#Header_Type = SPF
# AR requires Authserv_Id
#Authserv_Id = smtp.okbsd.com
#Header_Type = AR
service pyspf-milter restart
Check your incoming mail headers by sending a test mail to jack@okbsd.com. You may need to adjust to following to get X-Spam-Score to show up.
$remove_existing_spam_headers = 0;
$sa_tag_level_deflt = -999.0;
nano /usr/local/etc/postfix/header_checks
/To:.*<>/ REJECT "5.7.1 Rejected, invalid To: header."
/From:.*<>/ REJECT "5.7.1 Rejected, invalid From: header."
/free mortgage quote/ REJECT
/repair your credit/ REJECT
/^Received:/ IGNORE
postmap /usr/local/etc/postfix/header_checks
service postfix restart
service amavisd restart
service sa-spamd restart
service spamass-milter restart
service amavisd status
If amavisd is not running use pkill.
pkill -U vscan
service amavisd start
################################################ # Next Up Reducing Server Load With Postscreen # ################################################