• rvskin new control
  • rvskin mobile
  • rvskin smart engine

SUBVERSION   1.7.4   rvskin mobile NOW SUPPORTED Click

RVSkin >> Spam & Virus Protection

Spam & Virus Protection

Howto

Spam+Virus Protection for cPanel server using
Exim+Exiscan+Clamav+RBL+Spamassassin+SARE+Razor+DCC


SpamAssassin v3.2 Note

- 70_sare_adult.cf is not compatible. It will create a huge maillog, spamd maybe down and /tmp will run out of space. Please remove it in /etc/mail/spamassassin, and restart EXIM.
- Ruledujour seems to not work. Please change it to sa-update.

cPanel11 Note

We don't test it on cPanel11. If you know EXIM, you can follow below instruction as a guideline. Don't copy it all.

Disclaimer/Copyright

No Warranty
Whilst this document is provided in good faith in the hope that it will be useful, the author provides NO WARRANTY WHATSOEVER as to the accuracy or otherwise of any of its contents. Use of any information provided in this document is entirely at your own risk.

Copyright
This document is copyright ©2004-2007 Pairote Manunphol (pairote@rvskin.com).

Spamassassin is a resource hog, if you decide to run this solution you should prepare to upgrade your RAM:

  • Server relays email about 20,000 emails/day should upgrade RAM to 1 GB.
  • Server relays email about 40,000 emails/day should upgrade RAM to 2 GB.

More than 40,000 spam mails were filterred out on one of my server/day. Download the report script here.

If you want to disable the Server-Wide Scanning. Just run the command below, so you will not lose the hard work modifying EXIM.

rm -f /etc/exim.conf.rvspam.local
mv /etc/exim.conf.local /etc/exim.conf.rvspam.local
rm -f /etc/exim.conf.rvspam.localopts
mv /etc/exim.conf.localopts /etc/exim.conf.rvspam.localopts
/scripts/eximup --force


When you want to apply the rules again run this.

cp /etc/exim.conf.rvspam.local /etc/exim.conf.local
cp /etc/exim.conf.rvspam.localopts /etc/exim.conf.localopts
/scripts/eximup --force


The Instruction separate to 8 sections, use it at your own risk:-
Last updated: Jun 29, 2007. Changlog is here.

  1. Install required software and scripts
    1. Upgrade cPanel and Exim
    2. Vipul's Razor
    3. DCC
    4. SARE rules
    5. Server-wide Spamassassin
  2. log_selector
  3. Virus Protection
    1. Configure Exim to reject virus at SMTP time
    2. Configure Exim to reject virus + sender whitelist + receiver whitelist
  4. Blacklists, HELO tests and RBL
    1. Sender blacklist and remote mail server blacklist
    2. Dictionary attack prevention
    3. HELO test
    4. RBL setting + sender whitelist + receiver whitelist + remote mail server whitelist
  5. Spam Protection
  6. Integrate into user's cPanel allowing user enable/disable server-wide Virus and Spam Protection
  7. Testing
  8. Maintenance
  1. Install required software and scripts
    1. Upgrade cPanel and Exim
    2. Vipul's Razor
    3. DCC
    4. SARE rules
    5. Server-wide Spamassassin
  2. log_selector
  3. Virus Protection
    1. Configure Exim to reject virus at SMTP time
    2. Configure Exim to reject virus + sender whitelist + receiver whitelist
  4. Blacklists, HELO tests and RBL
    1. Sender blacklist and remote mail server blacklist
    2. Dictionary attack prevention
    3. HELO test
    4. RBL setting + sender whitelist + receiver whitelist + remote mail server whitelist
  5. Spam Protection
  6. Integrate into user's cPanel allowing user enable/disable server-wide Virus and Spam Protection
  7. Testing
  8. Maintenance

1. Install required software and scripts

  • Upgrade cPanel to latest version

    /scripts/updatenow
    /scripts/upcp

  • Upgrade Exim to at least exim-4.42-80_cpanel_stmpcontrol_antivirus_rewrite_mailman2_maskedmailtrap_exiscan

    /scripts/exim4 –latest

  • Activate cPanelPro at http://pro.cpanel.net/activate/
  • Install cPanelPro and Clamavconnector. Log in into root WHM / Addon Modules.
    Installing clamavconnector will remove MailScanner functionality if exist.



    Tick the checkboxes and click 'save'.

  • Install Vipul's Razor (http://razor.sourceforge.net/) - Skip it if you don't want a good spam solution.

    Configure firewalls to allow TCP packets for port 2703 outbound. The instruction is depend on your firewall. Please consult your firewall vendor. In my case I use APF.

    pico /etc/apf/conf.apf

    Add port 2703 in these lines.

  • EG_TCP_CPORTS="....,2703"
    /etc/rc.d/init.d/apf restart 

    Download the latest versions of razor-agents and razor-agents-sdk packages from http://razor.sourceforge.net/download/
    # Change the version number to the latest one
    tar –zxvf razor-agents-sdk-2.07.tar.gz cd razor-agents-sdk-2.07/ perl Makefile.PL make make test make install # Change the version number to the latest one tar –zxvf razor-agents-2.84.tar.gz cd razor-agents-2.84/ # Update Digest::SHA1 before compile razor-agents /scripts/perlinstaller --force Digest::SHA1 perl Makefile.PL make make test make install razor-admin –create mkdir /var/spool/mqueue chown mailnull:mail /var/spool/mqueue razor-admin -d -create -home=/var/spool/mqueue/.razor/ razor-admin -register -home=/var/spool/mqueue/.razor/ chmod 755 /var/spool/mqueue/.razor chown -R mailnull:mail /var/spool/mqueue/.razor cd /var/spool/mqueue/.razor touch razor-whitelist

    Configure razor-agent.conf

    pico /var/spool/mqueue/.razor/razor-agent.conf

    Change or add these configurations.

    debuglevel = 1
    razorhome = /var/spool/mqueue/.razor/
    • Install DCC (http://www.rhyolite.com/anti-spam/dcc/) - Skip it if you don't want a good spam solution.

      Configure firewalls to allow outbound UDP packets for port 6277. The instruction is depend on your firewall. Please consult your firewall vendor. In my case I use APF.

      pico /etc/apf/conf.apf

      Add port 6277 in these lines.

    IG_UDP_CPORTS="37,53,873,6277"
    EG_UDP_CPORTS="20,21,53,2703,6277"
    /etc/rc.d/init.d/apf restart 

    Install DCC

    cd /usr/local/src
    rm -f dcc-dccd.tar.Z
    wget http://www.rhyolite.com/anti-spam/dcc/source/dcc-dccd.tar.Z
    tar -zxvf dcc-dccd.tar.Z
    # Change the version number to the latest one
    cd dcc-dccd-1.3.1
    ./configure
    make
    make install

    Change DCC to run as daemon

    cd /var/dcc
    pico dcc_conf

    Change DCCD_ENABLE to off, and DCCIFD_ENABLE to on.

    DCCD_ENABLE=off
    DCCIFD_ENABLE=on

    Copy the service startup script to init.d

    cd /etc/rc.d/init.d
    ln -s /var/dcc/libexec/rcDCC DCC
    chkconfig --add DCC /etc/rc.d/init.d/DCC start

    Install a cron job to clean up temp file on daily basis

    cd /etc/cron.daily
    ln -s /var/dcc/libexec/cron-dccd
  • Install SARE - Skip it if you don't want a good spam solution. I recommend to install the following rules in /etc/mail/spamassassin/:

  • - 72_sare_redirect_post3.0.0.cf
    - 70_sare_html0.cf
    - 70_sare_header0.cf
    - 70_sare_specific.cf
    - 99_sare_fraud_post25x.cf
    - 70_sare_random.cf
    - 70_sare_oem.cf
    - 70_sare_uri0.cf
    - 70_sare_stocks.cf
    - 70_sare_spoof.cf

    To install just run the following command.

    cd /etc/mail
    rm -f spamassassin/*_sare_*
    rm -rf rulesdujour
    rm -rf spamassassin/RulesDuJour
    echo 72_sare_redirect_post3.0.0.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_html0.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_header0.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_specific.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 99_sare_fraud_post25x.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_random.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_uri0.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_stocks.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    echo 70_sare_spoof.cf.sare.sa-update.dostech.net >> sare-sa-update-channels.txt
    wget http://daryl.dostech.ca/sa-update/sare/GPG.KEY
    sa-update
    sa-update --import GPG.KEY
    sa-update --channelfile /etc/mail/sare-sa-update-channels.txt --gpgkey 856AA88A --updatedir /etc/mail/spamassassin -D
    /scripts/restartsrv_spamd
    
  • Configure cron to update SARE rules automatically. Run crontab -e and add the following command. Change XX to your desired time.
  • XX X * * * sa-update --channelfile /etc/mail/sare-sa-update-channels.txt --gpgkey 856AA88A --updatedir /etc/mail/spamassassin -D
    
  • Configure server-wide Spamassassin
  • pico /etc/mail/spamassassin/local.cf 

    Add this:

    report_safe       0
    required_score    12
     
    # The default score for BAYES and SURBL is too low compare to my reject threshold(see section5) at 15
    score BAYES_99 6.00 # Check here for the detail of the URIBL data sources # http://answers.google.com/answers/threadview?id=422251 score URIBL_SBL 4.50 score URIBL_AB_SURBL 6.50 score URIBL_OB_SURBL 4.50 score URIBL_SC_SURBL 6.00 score URIBL_WS_SURBL 4.50 score URIBL_PH_SURBL 6.00 score URIBL_JP_SURBL 6.50 score URIBL_BLACK 4.50 # Enable server-wide Vipul's Razor in Spamassassin # Remove razor_config line if you want to disable Vipul's Razor
    razor_config /var/spool/mqueue/.razor/razor-agent.conf
    # Enable server-wide DCC in Spamassassin # Remove dcc_home line if you want to disable DCC
    dcc_home /var/dcc
    For SpamAssassin version 3.10:
    pico /etc/mail/spamassassin/v310.pre

    To enable Razor and DCC, you have to uncomment the loadplugin line for the Razor and DCC.

    # DCC is disabled here because it is not open source.  See the DCC
    # license for more details.
    #
    loadplugin Mail::SpamAssassin::Plugin::DCC

    # Razor2 is disabled here because it is not available for unlimited free
    # use. It is currently free for personal use, subject to capacity
    # constraints. See the Cloudmark SpamNet Service Policy for more details.
    #
    loadplugin Mail::SpamAssassin::Plugin::Razor2

2. LOG_SELECTOR

Suppress some of useless warnings.

2005-05-03 03:46:54 no IP address found for host ptil-26-132-del.primus-india.net (during SMTP connection from (comcast.net) [203.196.132.26])
2005-05-03 03:45:43 unexpected disconnection while reading SMTP command from 168-226-70-177.speedy.com.ar [168.226.70.177]

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

Add this:

log_selector = -host_lookup_failed -lost_incoming_connection
# For debugging purpose add +subject  and +argument.
# It will show the subject of email and the folder of the script invoking sendmail. 
#
# 200c-04-22 00:50:19 cwd=/home/username/public_html/spamsource 3 args: /usr/sbin/sendmail -t -i
#
# You will find spammer on your server easier.
# log_selector = +subject +arguments -host_lookup_failed -lost_incoming_connection

3. Virus Protection

Choose only one of these methods.

i. Configure Exim to reject virus at SMTP time

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

Add this:

av_scanner = clamd:/var/clamd

Scroll down to the begin acl section as shown in this picture.

In the middle textarea, scroll to the bottom of the box and under check_message ACL change from

#!!# ACL that is used after the DATA command
check_message:
require verify = header_sender
accept

To

#!!# ACL that is used after the DATA command
check_message:
require verify = header_sender

##
# Reject messages with serious MIME container errors
##
deny message = This message contains malformed MIME ($demime_reason).
demime = *
condition = ${if >{$demime_errorlevel}{2}{1}{0}}

##
# Reject messages attach attach a file with a CLSID in the name 
# which causes Windows to hide the file extension.
## 
deny message = Hiding of file extensions(CLSID hidden) is not allowed.
regex = ^(?i)Content-Disposition::(.*?)filename=\\s*"+((\{[a-hA-H0-9-]{25,}\})|((.*?)\\s{10,}(.*?)))"+\$

##
# Reject messages attach illegal extension files
##
deny message = We do not accept ".$found_extension" attachments here. If you meant to send this file then please package it up as a zip file and resend it.
# You might need to remove some of these extensions if you want to allow your user get these files
demime = ade:adp:bas:bat:chm:cmd:com:cpl:crt:eml:exe:hlp:hta:inf:ins:isp:jse:lnk:mdb:mde:msc:msi:msp:pcd:pif:reg:scr:sct:shs:url:vbs:vbe:wsf:wsh:wsc

##
# Reject email contains Virus
##
deny message = This message contains a virus or other harmful content ($malware_name)
demime = *
malware = */defer_ok

##
# Add X-Scanned Header
##
warn message = X-Antivirus-Scanner: Clean mail though you should still use an Antivirus

accept

ii. Configure Exim to reject virus + sender whitelist + receiver whitelist

Create whitelists

mkdir /usr/local/cpanel/base/eximacl
cd /usr/local/cpanel/base/eximacl
touch rv_virus_receiver_domain_whitelist
echo '# Virus receiver Domain Name Whitelist' >> rv_virus_receiver_domain_whitelist
echo '# Format: *@domain.com in lowercase listed line by line' >> rv_virus_receiver_domain_whitelist
echo '# Although it is a domain list, you need to put in the address format' >> rv_virus_receiver_domain_whitelist
echo '# Examples:' >> rv_virus_receiver_domain_whitelist
echo '# *@example.com' >> rv_virus_receiver_domain_whitelist

touch rv_virus_sender_address_whitelist
echo '# Virus Sender Address Whitelist' >> rv_virus_sender_address_whitelist
echo '# Format: email address in lowercase listed line by line, asterisk is allowed' >> rv_virus_sender_address_whitelist
echo '# Examples:' >> rv_virus_sender_address_whitelist
echo '# *@example.com' >> rv_virus_sender_address_whitelist
echo '# address@example.com' >> rv_virus_sender_address_whitelist

touch rv_filetype_receiver_domain_whitelist
echo '# File Type Scanning receiver Domain Name Whitelist' >> rv_filetype_receiver_domain_whitelist
echo '# Format: *@domain.com in lowercase listed line by line' >> rv_filetype_receiver_domain_whitelist
echo '# Although it is a domain list, you need to put in the address format' >> rv_filetype_receiver_domain_whitelist
echo '# Examples:' >> rv_filetype_receiver_domain_whitelist
echo '# *@example.com' >> rv_filetype_receiver_domain_whitelist

touch rv_filetype_sender_address_whitelist
echo '# File Type Scanning Sender Address Whitelist' >> rv_filetype_sender_address_whitelist
echo '# Format: email address in lowercase listed line by line, asterisk is allowed' >> rv_filetype_sender_address_whitelist
echo '# Examples:' >> rv_filetype_sender_address_whitelist
echo '# *@example.com' >> rv_filetype_sender_address_whitelist
echo '# address@example.com' >> rv_filetype_sender_address_whitelist

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

Add these lines.

av_scanner = clamd:/var/clamd

Scroll down to the begin acl section as shown in this picture.

In the middle textarea, scroll to the bottom of the box and under check_message ACL change from

#!!# ACL that is used after the DATA command
check_message:
require verify = header_sender
accept

To

#!!# ACL that is used after the DATA command
check_message:
require verify = header_sender
## # Reject messages with serious MIME container errors ## deny message = This message contains malformed MIME ($demime_reason). demime = * condition = ${if >{$demime_errorlevel}{2}{1}{0}} ## # Reject messages attach illegal extension files ## deny message = We do not accept ".$found_extension" attachments here. If you meant to send this file then please package it up as a zip file and resend it. # You might need to remove some of these extensions if you want to allow your user get these files demime = bat:cmd:com:cpl:pif:reg:scr ## # Reject messages attach attach a file with a CLSID in the name # which causes Windows to hide the file extension. ## deny message = Hiding of file extensions(CLSID hidden) is not allowed. regex = ^(?i)Content-Disposition::(.*?)filename=\\s*"+((\{[a-hA-H0-9-]{25,}\})|((.*?)\\s{10,}(.*?)))"+\$ ## # Add a warning header if email contains illegal extension files but acccept the message ## warn message = X-Antivirus-Filetype: Infected - $found_extension # You might need to remove some of these extensions if you want to allow your user get these files demime = ade:adp:bas:bat:chm:cmd:com:cpl:crt:eml:exe:hlp:hta:inf:ins:isp:jse:lnk:mdb:mde:msc:msi:msp:pcd:pif:reg:scr:sct:shs:url:vbs:vbe:wsf:wsh:wsc ## # Add a warning header if email contains Virus but acccept the message ## warn message = X-Antivirus-Scanner: Infected - $malware_name demime = * malware = */defer_ok accept

Scroll down to the bottom of the page and save the new configuration.

Login into WHM / Exim Configuration Editor, under options section change the system filter file to the new one preventing cPanel overwrite you file.

In my case I use /usr/local/cpanel/base/eximacl/antivirusandspam.exim as my Exim system filter file.

SSH to the server as root and edit exim system filter.

cp /etc/antivirus.exim /usr/local/cpanel/base/eximacl/antivirusandspam.exim
pico /usr/local/cpanel/base/eximacl/antivirusandspam.exim

Remove this:

## -----------------------------------------------------------------------
# Look for single part MIME messages with suspicious name extensions
# Check Content-Type header using quoted filename [content_type_quoted_fn_match]
if $header_content-type: matches "(?:file)?name=(\"[^\"]+\\\\.(?:ad[ep]|ba[st]|chm|cmd|com|cpl|crt|eml|exe|hlp|hta|in[fs]|isp|jse?|lnk|md[be]|ms[cipt]|pcd|pif|reg|scr|sct|shs|url|vb[se]|ws[fhc])\")"
then
  fail text "This message has been rejected because it has\n\
             potentially executable content $1\n\
             This form of attachment has been used by\n\
             recent viruses or other malware.\n\
             If you meant to send this file then please\n\
             package it up as a zip file and resend it."
  seen finish
endif
# same again using unquoted filename [content_type_unquoted_fn_match]
if $header_content-type: matches "(?:file)?name=(\\\\S+\\\\.(?:ad[ep]|ba[st]|chm|cmd|com|cpl|crt|eml|exe|hlp|hta|in[fs]|isp|jse?|lnk|md[be]|ms[cipt]|pcd|pif|reg|scr|sct|shs|url|vb[se]|ws[fhc]))"
then
  fail text "This message has been rejected because it has\n\
             potentially executable content $1\n\
             This form of attachment has been used by\n\
             recent viruses or other malware.\n\
             If you meant to send this file then please\n\
             package it up as a zip file and resend it."
  seen finish
endif


## -----------------------------------------------------------------------
# Attempt to catch embedded VBS attachments
# in emails.   These were used as the basis for 
# the ILOVEYOU virus and its variants - many many varients
# Quoted filename - [body_quoted_fn_match]
if $message_body matches "(?:Content-(?:Type:(?>\\\\s*)[\\\\w-]+/[\\\\w-]+|Disposition:(?>\\\\s*)attachment);(?>\\\\s*)(?:file)?name=|begin(?>\\\\s+)[0-7]{3,4}(?>\\\\s+))(\"[^\"]+\\\\.(?:ad[ep]|ba[st]|chm|cmd|com|cpl|crt|eml|exe|hlp|hta|in[fs]|isp|jse?|lnk|md[be]|ms[cipt]|pcd|pif|reg|scr|sct|shs|url|vb[se]|ws[fhc])\")[\\\\s;]"
then
  fail text "This message has been rejected because it has\n\
             a potentially executable attachment $1\n\
             This form of attachment has been used by\n\
             recent viruses or other malware.\n\
             If you meant to send this file then please\n\
             package it up as a zip file and resend it."
  seen finish
endif
# same again using unquoted filename [body_unquoted_fn_match]
if $message_body matches "(?:Content-(?:Type:(?>\\\\s*)[\\\\w-]+/[\\\\w-]+|Disposition:(?>\\\\s*)attachment);(?>\\\\s*)(?:file)?name=|begin(?>\\\\s+)[0-7]{3,4}(?>\\\\s+))(\\\\S+\\\\.(?:ad[ep]|ba[st]|chm|cmd|com|cpl|crt|eml|exe|hlp|hta|in[fs]|isp|jse?|lnk|md[be]|ms[cipt]|pcd|pif|reg|scr|sct|shs|url|vb[se]|ws[fhc]))[\\\\s;]"
then
  fail text "This message has been rejected because it has\n\
             a potentially executable attachment $1\n\
             This form of attachment has been used by\n\
             recent viruses or other malware.\n\
             If you meant to send this file then please\n\
             package it up as a zip file and resend it."
  seen finish
endif
## -----------------------------------------------------------------------

Find #### Version history, above it add this:

##
# Let email get through user inbox if it matches the whitelist rules for Virus Scanning
# Otherwise discard the email
##
if
$h_X-Antivirus-Scanner: matches "Infected - (.*)" and ("${lookup{${lc:$sender_address}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_virus_sender_address_whitelist}{1}{fail}}" is "fail") # A message may have many recipients, so many local parts and domains, but # the system filter is run only once. If the domains are different, all domains MUST listed in the whitelist, # otherwise email will be rejected. and foranyaddress ${lc:$recipients}("${lookup{${thisaddress}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_virus_receiver_domain_whitelist}{1}{fail}}" is "fail") then seen # If you want to bounce message, comment 2 lines below and uncomment the line begin with fail. logfile /var/log/exim_mainlog logwrite "$tod_log $message_id ** F=${lc:$sender_address} [$sender_host_address] discarded: This message contains a virus or other harmful content ($1)" # Bounce it, but the sender is often forged, in which case the bounce will either bounce # and end up frozen in your queue, or go to some innocent bystander. # Highly NOT recommend. # fail text "This message contains a virus or other harmful content ($1)" finish endif ## # Let email get through user inbox if it matches the whitelist rules for File Type Scanning # Otherwise discard the email ##
if
$h_X-Antivirus-Filetype: matches "Infected - (.*)" and ("${lookup{${lc:$sender_address}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_filetype_sender_address_whitelist}{1}{fail}}" is "fail") # A message may have many recipients, so many local parts and domains, but # the system filter is run only once. If the domains are different, all domains MUST listed in the whitelist,
# otherwise email will be rejected.
and foranyaddress ${lc:$recipients}("${lookup{${thisaddress}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_filetype_receiver_domain_whitelist}{1}{fail}}" is "fail") then seen # If you want to bounce message, comment 2 lines below and uncomment the line begin with fail. logfile /var/log/exim_mainlog logwrite "$tod_log $message_id ** F=${lc:$sender_address} [$sender_host_address] discarded: We do not accept \".$1\" attachments here. If you meant to send this file then please package it up as a zip file and resend it." # Bounce it, but the sender is often forged, in which case the bounce will either bounce # and end up frozen in your queue, or go to some innocent bystander. # Highly NOT recommend. # fail text "We do not accept \".$1\" attachments here. If you meant to send this file then please package it up as a zip file and resend it." finish endif #### Version history #
# 0.01 5 May 2000
# Initial release

4. Blacklists, HELO tests and RBL

You don't need to add all of ACLs here, use only the one you want.

i. Sender blacklist and remote mail server blacklist

Create blacklist files

mkdir /usr/local/cpanel/base/eximacl
cd /usr/local/cpanel/base/eximacl
touch rv_sender_address_blacklist
echo '# Envelope Sender Address Blacklist' >> rv_sender_address_blacklist
echo '# Format: email address listed line by line, asterisk is allowed' >> rv_sender_address_blacklist
echo '# Examples:' >> rv_sender_address_blacklist
echo '# *@example.com' >> rv_sender_address_blacklist
echo '# address@example.com' >> rv_sender_address_blacklist

touch rv_server_ip_blacklist
echo '# Remote Mail Server IP Blacklist' >> rv_server_ip_blacklist
echo '# Format: mail server IP address listed line by line' >> rv_server_ip_blacklist
echo '# Examples:' >> rv_server_ip_blacklist
echo '# 111.111.111.111' >> rv_server_ip_blacklist

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

At the bottom of the first box, add this.

acl_smtp_connect = acl_check_host

acl_smtp_mail = acl_check_sender
Scroll down to the begin acl section as shown in this picture.

In the first textarea, add this.

#!!# This ACL is used at the start of an incoming connection.
#!!# The tests are run in order until the connection is
#!!# either accepted or denied.
acl_check_host:

##
# Reject email sent from mail server IP listed in the blacklist
##
deny message = Host $sender_host_address is blocked
hosts = /usr/local/cpanel/base/eximacl/rv_server_ip_blacklist
delay = 3s

accept

#!!# This ACL is used for the MAIL FROM: command in an
#!!# incoming SMTP transaction. The tests are run in order until the
#!!# sender address is either accepted or denied.
acl_check_sender:

##
# Reject email sent from sender listed in the blacklist
## 
deny message = Sender $sender_address is blocked
senders = /usr/local/cpanel/base/eximacl/rv_sender_address_blacklist
delay = 3s

accept

ii. Dictionary attack prevention

Please follow the instruction from http://www.configserver.com/free/eximdeny.html

iii. HELO tests

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

Add this line.

hostlist rv_relay_hosts = net-iplsearch;/etc/relayhosts

Scroll down to the begin acl section as shown in this picture.

In the middle textarea, Above 'require verify = sender' add this.

##
# Be polite and say HELO. Reject anything from hosts that haven't given
# a valid HELO/EHLO to us.
##
deny message = Bad HELO: Empty HELO, please see RFC 2821 section 4.1.1.1
condition = ${if eq{$sender_helo_name}{}{yes}{no}}
delay = 3s

##
#  Forged hostname -HELOs as one of my own IPs
##
# Forged HELO (our ip/hostname)
deny message = Forged HELO: you are not $sender_helo_name as that is our IP Address and you are not allowed to use it in HELO/EHLO as per RFC Standards.
!hosts = @[]
!hosts = +rv_relay_hosts
!authenticated = *
condition = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
delay = 3s

##
# Forged hostname - HELOs as my own hostname or domain
##
deny message = Forged HELO: you are not $sender_helo_name our local domain and you are not allowed to use as per RFC Standards.
# accept helo which is in local_domain if we relay or had smtp auth
!hosts = @[]
!hosts = +rv_relay_hosts
!authenticated = *
condition = ${if match_domain{$sender_helo_name}{+local_domains}{yes}{no}}
delay = 3s

##
# Hacked HELO (DOMAIN.com) (constructed by viruses)
##
deny message = Hacked HELO: you are not $sender_helo_name
condition = ${if match {$sender_helo_name}{\N^[A-Z0-9]+\.[a-z]+$\N}{yes}{no}}
condition = ${if match {$sender_helo_name}{\N^[0-9]+\.[a-z]+$\N}{no}{yes}}
!hosts = @[]
!hosts = +rv_relay_hosts
!authenticated = *
delay = 3s

iv. RBL setting + Sender whitelist + receiver whitelist + Remote mail server whitelist

SSH as root and create whitelist files

mkdir /usr/local/cpanel/base/eximacl
cd /usr/local/cpanel/base/eximacl
touch rv_rbl_receiver_domain_whitelist
echo '# receiver Domain Name Whitelist for RBL filtering' >> rv_rbl_receiver_domain_whitelist
echo '# Format: domain name listed line by line' >> rv_rbl_receiver_domain_whitelist
echo '# Examples:' >> rv_rbl_receiver_domain_whitelist
echo '# localdomain.com' >> rv_rbl_receiver_domain_whitelist

touch rv_rbl_server_ip_whitelist
echo '# Remote Mail Server IP Whitelist for RBL filtering' >> rv_rbl_server_ip_whitelist
echo '# Format: mail server IP addresses, or IP addresses with CIDR masks listed line by line' >> rv_rbl_server_ip_whitelist
echo '# Examples:' >> rv_rbl_server_ip_whitelist
echo '# 111.111.111.111' >> rv_rbl_server_ip_whitelist
echo '# 192.168.0.0/16' >> rv_rbl_server_ip_whitelist

touch rv_rbl_sender_address_whitelist
echo '# Envelope Sender Address Whitelist for RBL filtering' >> rv_rbl_sender_address_whitelist
echo '# Format: email address listed line by line, asterisk is allowed' >> rv_rbl_sender_address_whitelist
echo '# Examples:' >> rv_rbl_sender_address_whitelist
echo '# *@example.com' >> rv_rbl_sender_address_whitelist
echo '# address@example.com' >> rv_rbl_sender_address_whitelist

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

At the bottom of the first box, add this.

domainlist rv_rbl_receiver_domain_whitelist = lsearch;/usr/local/cpanel/base/eximacl/rv_rbl_receiver_domain_whitelist
  
hostlist rv_rbl_server_ip_whitelist = net-iplsearch;/usr/local/cpanel/base/eximacl/rv_rbl_server_ip_whitelist
  
addresslist rv_rbl_sender_address_whitelist= lsearch*@;/usr/local/cpanel/base/eximacl/rv_rbl_sender_address_whitelist


# If you implement HELO test, skip these 3 lines.
# If you don't implement HELO test, you need to remove # in a line below to declare rv_relay_host.
# hostlist rv_relay_hosts = net-iplsearch;/etc/relayhosts

Scroll down to the begin acl section, in the middle textarea as shown in this picture.

In the middle textarea, under 'require verify = sender', replace the following red lines

##
# ...
# HELO ACL
# ...
##

#sender verifications are required for all messages that are not sent to lists                                                                                                                                           
require verify = sender
accept  domains = +local_domains
endpass
                                                                                                                                           
#recipient verifications are required for all messages that are not sent to the local machine
#this was done at multiple users requests
                                                                                                                                           
message = "The recipient cannot be verified.  Please check all recipients of this message to verify they are valid."
verify = recipient
                                                                                                                                          
accept  domains = +relay_domains

with this.

##
# ...
# HELO ACL
# ...
##

# sender verifications are required for all messages that are not sent to lists 
require verify = sender

##
# Reject email sent from server listed in DNS blacklists.
## 
deny message = Message rejected because $sender_fullhost is blacklisted at $dnslist_domain see $dnslist_text
!hosts = @[]
!hosts = +rv_relay_hosts
!authenticated = *
# RBL Bypass Local Domain List
!domains = +rv_rbl_receiver_domain_whitelist
# RBL Whitelist Incoming hosts
!hosts = +rv_rbl_server_ip_whitelist
# RBL Bypass Sender Domain List
!senders = +rv_rbl_sender_address_whitelist
# The following is a list of RBL to check for spam.
dnslists = list.dsbl.org : \
sbl.spamhaus.org : \
pbl.spamhaus.org
delay = 3s
##
# If the receiver domain is on this server, accept only the receiver email addresses that exist.
# Default address for the receiver domain have to set to :fail: to work with this ACL.
# If the default address set to :blackhole: or /dev/null, Exim will always think that email exist.
# Domains being attacked by dictionary attack spam are suggested to set default address to :fail:.
##
accept domains = +local_domains
       endpass
       message = "The recipient cannot be verified.  Please check all recipients of this message to verify they are valid."
log_message = unknown user verify = recipient accept domains = +relay_domains

5. Spam Protection

Exiscan allow exim invoking SpamAssassin to obtain $spam_score and $spam_report. If you install all programs in the section1, scored will calculate from Spamassassin+SARE+Razor+DCC. Since the false positive rate with spam scanning is high compared to virus scanning, it is wise to implement a scheme with multiple spam thresholds with different actions. As my preferences, I set score at 15 for reject thresholds, 12

Create whitelists

mkdir /usr/local/cpanel/base/eximacl
cd /usr/local/cpanel/base/eximacl
touch rv_spam_receiver_domain_whitelist
echo '# Spam receiver Domain Name Whitelist' >> rv_spam_receiver_domain_whitelist
echo '# Format: *@domain.com in lowercase listed line by line' >> rv_spam_receiver_domain_whitelist
echo '# Although it is a domain list, you need to put in the address format' >> rv_spam_receiver_domain_whitelist
echo '# Examples:' >> rv_spam_receiver_domain_whitelist
echo '# *@example.com' >> rv_spam_receiver_domain_whitelist

touch rv_spam_sender_address_whitelist
echo '# Spam Sender Address Whitelist' >> rv_spam_sender_address_whitelist
echo '# Format: email address in lowercase listed line by line, asterisk is allowed' >> rv_spam_sender_address_whitelist
echo '# Examples:' >> rv_spam_sender_address_whitelist
echo '# *@example.com' >> rv_spam_sender_address_whitelist
echo '# address@example.com' >> rv_spam_sender_address_whitelist

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. In the first textarea as shown in this picture:

At the bottom of the first box, add this.

addresslist rv_spam_sender_address_whitelist= lsearch*@;/usr/local/cpanel/base/eximacl/rv_spam_sender_address_whitelist

Login into WHM / Exim Configuration Editor, switch to Advanced Mode. Scroll down to the begin acl section as shown in this picture.

In the middle textarea, scroll to the bottom of the box and under check_message ACL change from

#!!# ACL that is used after the DATA command
check_message:
require verify = header_sender
##
# ...
# ...
# Virus Scanning stuffs you have added from section 2i or 2ii.
# ...
# ...
##
accept

To

#!!# ACL that is used after the DATA command
check_message:
require verify = header_sender

##
# ...
# ...
# Virus Scanning stuffs you have added from section 2i or 2ii.
# ...
# ...
##

# Messages larger than 200k are accepted without spam scanning to reduce spamd load
accept condition = ${if >{$message_size}{200k}{true}}

##
# Reject spam messages with score over 15. 
# Keep in mind that $spam_score_int is the messages score multiplied by ten.
##
deny message = Spam score too high ($spam_score)
# Bypass Sender that usually send a lot of emails to reduce spamd load
!senders = +rv_spam_sender_address_whitelist spam = mailnull:true/defer_ok condition = ${if >{$spam_score_int}{150}{1}{0}} ## # Add a warning header if email scored between 12 and 15. # Delete email in the System Filter File, if sender or receiver is not listed in the whitelists. ## warn message = X-Exiscan-SA-Spam: Yes # Bypass Sender that usually send a lot of emails to reduce spamd load
!senders = +rv_spam_sender_address_whitelist spam = mailnull:true/defer_ok condition = ${if >{$spam_score_int}{120}{1}{0}} ## # Rewrite subject if email scored between 9 and 15. ## # Always put X-Spam-Score header in the message. # It looks like this: # X-Exiscan-SA-Score: 6.6 (++++++) # When a MUA cannot match numbers, it can match for an # equivalent number of '+' signs. warn message = X-Exiscan-SA-Score: $spam_score ($spam_bar)\ # Put X-Spam-Report header in the message. # This is a multiline header that informs the user # which tests a message has "hit", and how much a # test has contributed to the score. \nX-Exiscan-SA-Report: $spam_report\ # For the subject tag, we prepare a new subject header in the # ACL, then swap it with the original Subject in the system filter. \nX-Exiscan-SA-New-Subject: *SPAM* $h_subject: # Bypass Sender that usually send a lot of emails to reduce spamd load
!senders = +rv_spam_sender_address_whitelist spam = mailnull:true/defer_ok condition = ${if >{$spam_score_int}{90}{1}{0}} accept

Scroll down to the bottom of the page and save the new configuration.

SSH to the server as root and edit the system filter file. If you didn't create file /usr/local/cpanel/base/eximacl/antivirusandspam.exim, please use the instruction same as in the step2.ii.

pico /usr/local/cpanel/base/eximacl/antivirusandspam.exim

Find #### Version history, above it add this:

##
# Let email get through user inbox if it matches the whitelist rules
# Otherwise bounce the email to the sender and delete the email
##
if
    $h_X-Exiscan-SA-Spam: contains "Yes"
    and $h_X-Exiscan-SA-Score matches "(.*) \\\\("
    and ("${lookup{${lc:$sender_address}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_spam_sender_address_whitelist}{1}{fail}}" is "fail")
# A message may have many recipients, so many local parts and domains, but
# the system filter is run only once. If the domains are different, all domains MUST listed in the whitelist,
# otherwise email will be rejected.
    and foranyaddress ${lc:$recipients}("${lookup{${thisaddress}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_spam_receiver_domain_whitelist}{1}{fail}}" is "fail")
then
    seen
# If you want to bounce message, comment 2 lines below and uncomment the line begin with fail.
    logfile /var/log/exim_mainlog
    logwrite "$tod_log $message_id ** F=${lc:$sender_address} [$sender_host_address] discarded: Spam score too high ($1)"
# Bounce it, but the sender is often forged, in which case the bounce will either bounce 
# and end up frozen in your queue, or go to some innocent bystander.
# Highly NOT recommend.
#   fail text "Spam score too high ($1)"
    finish
endif

##
# Rewrite subject if email scored between 9 and 15.
##
if 
    "${if def:header_X-Exiscan-SA-New-Subject: {there}}" is "there"
    and ("${lookup{${lc:$sender_address}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_spam_sender_address_whitelist}{1}{fail}}" is "fail")
# A message may have many recipients, so many local parts and domains, but
# the system filter is run only once. If the domains are different, all domains MUST listed in the whitelist,
# otherwise email will be rejected.
    and foranyaddress ${lc:$recipients}("${lookup{${thisaddress}}lsearch*@{/usr/local/cpanel/base/eximacl/rv_spam_receiver_domain_whitelist}{1}{fail}}" is "fail")
then
    headers remove Subject
    headers add "Subject: $h_X-Exiscan-SA-New-Subject:"
    headers remove X-Exiscan-SA-New-Subject
endif

#### Version history
#
# 0.01 5 May 2000
# Initial release

6. Integrate it into user's cPanel allowing user enable/disable server-wide Virus and Spam Protection

For RVSkin users:

  1. Upgrade RVSkin to lastest version. If you have done section 1-4, Virus and Spam Protection will enable for all accounts even if you don't see the feature in cPanel Skin.
  2. Go to rvadmin Skin Manager / Tweak / Server-Wide Spam & Virus Protection. Follow instruction in the page.
  3. Go to rvadmin Skin Manager / Package-Feature Manager. Choose the Feature List you want user to control the feature, find the feature 'Server-Wide Spam & Virus Protection' and enable it.

The benefit for RVSkin users over other themes users:

  1. You can hide spamassassin page to avoid users unnecessary enable per-user spamassassin and don't confuse your users.
  2. Multi-lingual supports (Most languages still not translated, if you want to do it. You can translate in Skin Manager / Message Editor.)
  3. You can manage all whitelists and blacklists directly inside rvadmin Skin Manager. For other themes you have to SSH to server and change it from the SSH shell.

For X, X2 and non-RVSkin themes users:

  1. If you have done section 1-4, Virus and Spam Protection will enable for all accounts even if you don't see the feature in cPanel Skin. To allow user enable/disable feature in X skin, you need to install rvantispam addon module.
    cd /usr/local/cpanel/base/eximacl/
    chmod 777 /usr/local/cpanel/base/eximacl/*
    chmod 644 /usr/local/cpanel/base/eximacl/antivirusandspam.exim
    wget http://www.rvskin.com/download/rvantispam.tgz
    tar -xvzf rvantispam.tgz
    cd rvantispam
    perl install.pl
    
    To allow user enable/disable server-wide spam protection
    touch /usr/local/cpanel/base/eximacl/.rvspam

    To allow user enable/disable server-wide virus protection (You have to configure Exim to reject virus + sender whitelist + receiver whitelist as describe in section 2ii in the instruction.)

    touch /usr/local/cpanel/base/eximacl/.rvvirus
    touch /usr/local/cpanel/base/eximacl/.rvfiletype

    To allow user enable/disable RBL checking

    touch /usr/local/cpanel/base/eximacl/.rvrbl
  2. WHM > Feature Manager > Edit Feature Set. Check the checkbox for rv_antispam_virus and save.

7.Testing

  • Testing your ACLs, you can simulate the email sending from another server using this command.

    exim_checkaccess 192.168.53.23 recip@my.domain -f sender@some.domain

    Where 192.168.53.23 is a remote mail server IP address.

  • Testing Exim system filter without actually add it using this command.

    exim -bF /etc/antivirus.exim < sample-message.txt

  • Testing Virus Protection

    A good test is the Eicar test signature (http://www.eicar.org), which is a 'pretend' virus recognized by most anti-virus software.

    1. SSH to server as root and do tail on the /var/log/exim_mainlog file.

    tail -f /var/log/exim_mainlog

    2. Email yourself

    X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

    in 1 line, in the body. And watch your log, you should see something like this

    2004-10-19 18:25:52 1CJs7J-0007hx-EP H=(host.server.com) [203.145.146.217] F=<your@domain.com> rejected after DATA: This message contains a virus or other harmful content (Eicar-Test-Signature)

  • Testing Spam Protection

    * Testing message scores more than the rejection threshold set in Exim, and is rejected at DATA time.

    There is also a 'magic' test phrase (called 'GTUBE') which, if used in a mail, will trigger SpamAssassin to reject it, in a similar fashion to the EICAR anti-virus test file.

    1. SSH to server as root and do tail on the /var/log/exim_mainlog file.

    tail -f /var/log/exim_mainlog

    2. Email yourself

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

    in 1 line, in the body. And watch your log, you should see something like this

    2004-10-21 14:30:17 1CKXOo-0002AC-9F H=(pairote) [203.156.82.2] F=<your@domain.com> rejected after DATA: This message scored 997.8 spam points

    * Testing message scores at the different threshold

    Change the GTUBE scores in server-wide Spamassassin configuration.

    pico /etc/mail/spamassassin/local.cf

    Add this:

    # Change the number to the score you want to test
    score GTUBE 13
    #score GTUBE 11
    #score GTUBE 6

    Restart Exim

    /etc/rc.d/init.d/exim restart

    Email yourself GTUBE code, and watch the log.

8.Maintenance

Whitelisting and Minimizing spamd resource usages:

  • In case you choose to install RBL ACL, you might need to WHITELIST few mail servers or disable RBL checking for certain hosting account. Whitelist file is /usr/local/cpanel/base/eximacl/rv_rbl_server_ip_whitelist.
  • In case you choose to install Server-Wide Spam Protection, you might need to WHITELIST few senders that always send email to or from your server to reduce unnecessary spamd usage.Whitelist file is /usr/local/cpanel/base/eximacl/rv_spam_sender_address_whitelist.

There are several whitelist and blacklist, please check in /usr/local/cpanel/base/eximacl/.

  • Default email for the account that don't want to get the email for unroutable of email address MUST be :fail: (in /etc/valiases/*). Setting to :blackhole: or /dev/null will cause your server process unnecessary emails and consume a lot of CPU. Run this command to convert all your default emails.

    replace ':blackhole:' ':fail:' -- /etc/valiases/*
    replace '/dev/null' ':fail:' -- /etc/valiases/*

    You can find the accounts that don't set :fail: by running this command:

    grep '*:' /etc/valiases/* | egrep -v ':fail:'

    All these domains are suggested to change to :fail:. You have to make sure your users understand how it affect thier email relaying.
     
  • All your clients are recommended to disable spamassassin. This will save your CPU a lots. As most spam are filter out at server level. Per-domain Spamassassin (the one you enable/disable in cPanel) should be enabled only the account that has a serious problem. Enable per-domain Spamassassin will increase your CPU usage.

    To remove all users to disable spamassassin, you just need to run this:

    ls /home/*/.spamassassinenable
    rm /home/*/.spamassassinenable

    Users will be able to enable it again in cPanel.

The Software update:

  • Spamassassin: updated by cPanel as a standard perl Module.
  • ClamAV: updated by cPanel if you check the checkbox to keep clamavconnector module up-to-date.
  • ClamAV virus signature: will be updated itself daily. You can monitor its log at /var/log/clam-update.log. If you want to update manually just run `freshclam' (no quote) on SSH shell.
  • DCC: in case you want to update please run /var/dcc/libexec/updatedcc. It will recomplile DCC on your server. You should run it periodically.
  • Razor: this need to manual update. Recompile the Razor in the same way as installing.

    Error message found in /var/log/maillog

  • auto-whitelist: open of auto-whitelist file failed: locker: safe_lock: cannot create tmp lockfile /root/

    This error comes from the checksrvd that try to check spamd whether it is running. The errors pop up since SA v3.10. Nothing to worry about it. You may report the error to cPanel bugzilla.

  • Can't locate LMAP/CID2SPF.pm in @INC

    Run /scripts/perlinstaller --force Mail::SPF::Query.

  • Can't locate Mail/SPF/Query.pm in @INC

    Run /scripts/perlinstaller --force Mail::SPF::Query.

  • dcc: dccifd -> check skipped: Can't call method "print" on an undefined value at /usr/lib/perl5/site_perl/5.8.1/Mail/SpamAssassin/Plugin/DCC.pm

    Run /var/dcc/libexec/updatedcc.

  • prefork: server reached --max-clients setting, consider raising it

    Go to WHM / cPanel xx.x.x-xxx / Addon Modules, and install spamdconf. Close your WHM, and reopen it again. You will find the menu 'Setup Spamd Startup Configuration' at the bottom of the left menu. Change the Maximum Children to suitable your need. Mine set it to 10.

References: