Ubuntu Server 20.04 Anti-virus & mail server

1. Introduction of Clamav anti-virus software

1.1 Install

# apt install clamav clamav-daemon

Clamav-related configuration files are installed in the /etc/clamav/ folder

1.2 Update your virus definitions

# freshclam
The above command will update the virus definitions, but if you get the following error, change the log settings and run it again
ERROR: /var/log/clamav/freshclam.log is locked by another process
ERROR: Problem with internal logger (UpdateLogFile = /var/log/clamav/freshclam.log)

⚫The default settings are prone to log-related errors during freshclam (virus definition update).
Therefore, once you have deleted the log file and changed the logrotate settings

# rm /var/log/clamav/freshclam.log
# touch /var/log/clamav/freshclam.log
# chown clamav:clamav /var/log/clamav/freshclam.log
Update virus definitions again
# freshclam
Wed Dec 15 12:35:18 2021 -> daily.cvd database is up-to-date (version: 26387, sigs: 1950745, f-level: 90, builder: raynman)
Wed Dec 15 12:35:18 2021 -> main.cvd database is up-to-date (version: 62, sigs: 6647427, f-level: 90, builder: sigmgr)
Wed Dec 15 12:35:18 2021 -> bytecode.cvd database is up-to-date (version: 333, sigs: 92, f-level: 63, builder: awillia2)

⚫Change configuration file

# vi /etc/logrotate.d/clamav-freshclam
create 640 clamav adm

create 640 clamav clamav

1.3 Check for automatic virus definition updates

Installing the clamav package will automatically update your virus definitions.
Check if the service is registered

# service clamav-freshclam status

When you run the above command, you will get the following message.

● clamav-freshclam.service – ClamAV virus database updater
Loaded: loaded (/lib/systemd/system/clamav-freshclam.service; enabled; ven>
Active: active (running)since Wed 2021-12-15 12:31:40 JST; 8min ago
Docs: man:freshclam(1)
Main PID: 72577 (freshclam)
Tasks: 1 (limit: 4583)
Memory: 232.2M
CGroup: /system.slice/clamav-freshclam.service
mq72577 /usr/bin/freshclam -d –foreground=true
Dec 15 12:31:51 Lepard freshclam[72577]: Wed Dec 15 12:31:51 2021 -> daily.cvd >
Dec 15 12:31:51 Lepard freshclam[72577]: Wed Dec 15 12:31:51 2021 -> main datab>
Dec 15 12:31:56 Lepard freshclam[72577]: Wed Dec 15 12:31:56 2021 -> Testing da>
Dec 15 12:32:05 Lepard freshclam[72577]: Wed Dec 15 12:32:05 2021 -> Database t>

Active: active (running), automatic updates are active
Logging will be done in /var/log/clamav/freshclam.log file

1.3 Check your virus check

①Run a manual virus check

# clamscan –infected –remove –recursive /home
———– SCAN SUMMARY ———–
Known viruses: 8582908
Engine version: 0.103.2
Scanned directories: 4
Scanned files: 8
Infected files: 0
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 22.055 sec (0 m 22 s)
Start Date: 2021:12:15 12:41:54
End Date: 2021:12:15 12:42:16

Infected files: 0, so there is no virus

②Virus detection by downloading a test virus
Download a harmless virus and test it for detection
Check by logging in as a general user

# su – <user name>
$ wget http://www.eicar.org/download/eicar.com
$ clamscan –infected –remove –recursive /home
/home/<user name>/eicar.com: Win.Test.EICAR_HDB-1 FOUND
/home/<user name>/eicar.com: Removed.
———– SCAN SUMMARY ———–
Known viruses: 8582908
Engine version: 0.103.2
Scanned directories: 4
Scanned files: 9
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 19.850 sec (0 m 19 s)
Start Date: 2021:12:15 12:45:23
End Date: 2021:12:15 12:45:43

It will notify you of the virus with the message “FOUND” and the message “Infected files: 1”.
Also, the “–remove” option has been added, so the test virus has been removed

1.4 Create a script file for a full scan

$ su –
# mkdir /opt/script (/opt/scriptがない場合)
# cd /opt/script
# vi clam-full.sh

①Contents of clam-full.sh (new)

echo =========================================
clamscan / \
–infected \
–recursive \
–log=/var/log/clamav/clamscan.log \
–move=/var/log/clamav/virus \
–exclude-dir=^/boot \
–exclude-dir=^/sys \
–exclude-dir=^/proc \
–exclude-dir=^/dev \
# –infected  #Only files that have been detected as infected are included in the results
# –recursive   Checks recursively under a given directory.  Compressed files must be decompressed and inspected
# –log=FILE   Log files
# –move=DIR    Where to quarantine the files detected as infected
# –remove    Delete files where infection is detected
# –exclude=FILE   Files excluded from inspection (specified by pattern)
# –exclude-dir=DIR Inspection exclusion directory (specified by pattern)
if [ $? = 0 ]; then
echo “Virus not detected.”
echo “Virus detection!!”

②Grant execution permissions

# chmod +x /opt/script/clam-full.sh

③Create a virus quarantine folder
(If it already exists, it’s OK, but if it doesn’t, you’ll get a runtime error because you’ve specified it as an excluded directory in the script above)

# mkdir /var/log/clamav/virus

④Try it out and run it

# /opt/script/clam-full.sh

⑤Regularly run virus scans with cron

# crontab -e
0 2 * * mon /opt/script/clam-full.sh >> /var/log/clamav/clamascan.log

2. Mail server installation

2.1 Postfix : Installation/Configuration

Install Postfix and build an SMTP server.      SMTP uses 25/TCP.
To prevent mail from being relayed illegally, use the SASL function of Dovecot described below, and configure Postfix to require authentication for sending mail.


# apt -y install postfix sasl2-bin

Installation status screen
You will be asked to select a general configuration setting, select ‘No Configuration’ to set it manually later.

+——+ Postfix Configuration +——-+
| General type of mail configuration: |
| No configuration |
| Internet Site |
| Internet with smarthost |
| Satellite system |
| Local only |
| |
| |
| <Ok> <Cancel> |
| |

②Edit configuration file

# cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf
# vi /etc/postfix/main.cf

Editorial content

# Line 78:Uncomment
mail_owner = postfix
# Line 94:Uncomment and specify hostname
myhostname = mail.marchan-na.com
# Line 102:Uncomment and specify domain name
mydomain = marchan-na.com
# Line 123:Uncomment
myorigin = $mydomain
# Line 137:Uncomment
inet_interfaces = all
# Line 185:Uncomment
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# Line 228:Uncomment
local_recipient_maps = unix:passwd.byname $alias_maps
# Line 270:Uncomment
mynetworks_style = subnet
# Line 287:Add your own network
mynetworks =,
# Line 407:Uncomment
alias_maps = hash:/etc/aliases
# Line 418:Uncomment
alias_database = hash:/etc/aliases
# Line 440:Uncomment
home_mailbox = Maildir/
# Line 576:Make a comment and add it below
#smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_banner = $myhostname ESMTP
# Line 650:Additional entries
sendmail_path = /usr/sbin/postfix
# Line 655:Additional entries
newaliases_path = /usr/bin/newaliases
# Line 660:Additional entries
mailq_path = /usr/bin/mailq
# Line 666:Additional entries
setgid_group = postdrop
# Line 670:comment
#html_directory =
# Line 674:comment
#manpage_directory =
# Line 679:comment
#sample_directory =
# Line 683:comment
#readme_directory =
# Add to last line:Limit incoming and outgoing mail size to 10M
message_size_limit = 10485760
# Limit mailbox size to 1G
mailbox_size_limit = 1073741824
# SMTP-Auth
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_mynetworks, permit_auth_destination, permit_sasl_authenticated, reject

②The content of the setting reflects

# newaliases
# systemctl restart postfix

2.2 Dovecot : Installation/Configuration

Install Dovecot and set up a POP/IMAP server.  110/TCP for POP, 143/TCP for IMAP
①Configure Dovecot so that Postfix can provide SASL functionality

# apt -y install dovecot-core dovecot-pop3d dovecot-imapd
# vi /etc/dovecot/dovecot.conf
Line 30:Uncommen
listen = *, ::
# vi /etc/dovecot/conf.d/10-auth.conf
Line 10:Uncomment and change (also allow plain text authentication)
disable_plaintext_auth = no
Line 100:add
auth_mechanisms = plain login
# vi /etc/dovecot/conf.d/10-mail.conf
Line 30:Change to Maildir format
mail_location = maildir:~/Maildir
# vi /etc/dovecot/conf.d/10-master.conf
Line 107-109:Comments removed and added
# Postfix smtp-authi
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix

②Settings reflect

# systemctl restart dovecot

2.3 Email user account registration

Register a user account for your email.
If you want to use a user account on the operating system for email as well, here are the settings
If you want to use email with a user account on your operating system, no additional configuration is required, just register the OS user.

①Mail client installation

# apt -y install mailutils

②Mailboxes are configured to refer to Maildir

# echo ‘export MAIL=$HOME/Maildir/’ >> /etc/profile.d/mail.sh

③Test sending an email
Send a test email to yourself [mail (user name)@(host name)]

# su – <user name>
$ mail <user name>@localhost
Subject: Test Mail
This is the first mail.

Ctrl + D to exit the main text

④Check incoming mail

$ mail
“/home/<user name>/Maildir/”: 1 message 1 new
>N 1 <user name> 13/450 Test Mail

2.4 ClamAV applied to mail server Postfix

Configure Postfix and Clamav to scan incoming and outgoing emails in real time

①Install Amavisd and Clamav Daemon
Start Clamav Daemon

$ su –
# apt -y install clamav-daemon amavisd-new

If you get an error when installing “amavisd-new”
Edit “/etc/amavis/conf.d/05-node_id” and install again
Change the code as follows

# vi /etc/amavis/conf.d/05-node_id

# This file was automatically installed on 2019-12-07T03:53:33.896891
use strict;
# $myhostname is used by amavisd-new for node identification, and it is
# important to get it right (e.g. for ESMTP EHLO, loop detection, and so on).
# chomp($myhostname = `hostname –fqdn`);
# To manually set $myhostname, edit the following line with the correct Fully
# Qualified Domain Name (FQDN) and remove the # at the beginning of the line.
#$myhostname = “sample-domain-was-here”;
1; # ensure a defined return

Change “sample-domain-was-here” in blue above to “mail.<yourdomain>” in red below

# This file was automatically installed on 2019-12-07T03:53:33.896891
use strict;
# $myhostname is used by amavisd-new for node identification, and it is
# important to get it right (e.g. for ESMTP EHLO, loop detection, and so on).
# chomp($myhostname = `hostname –fqdn`);
# To manually set $myhostname, edit the following line with the correct Fully
# Qualified Domain Name (FQDN) and remove the # at the beginning of the line.
$myhostname = “mail.<yourdomain>”;
1; # ensure a defined return

②Edit “15-content_filter_mode”.

# vi /etc/amavis/conf.d/15-content_filter_mode
Uncomment and enable virus scanning
@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);

③Register your own domain name

# echo ‘<yourDomain>’ > /etc/mailname

④Edit “Main.cf”.

# vi /etc/postfix/main.cf
Add to last line

⑤Edit “master.cf”

# vi /etc/postfix/master.cf

Editorial content

smtp inet n – y – – smtpd
#smtp inet n – y – 1 postscreen
#smtpd pass – – y – – smtpd
#dnsblog unix – – y – 0 dnsblog
#tlsproxy unix – – y – 0 tlsproxy
submission inet n – y – – smtpd
# -o syslog_name=postfix/submission
# -o smtpd_tls_security_level=encrypt
 -o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes

#Add the following full line to the last line
smtp-amavis unix – – n – 2 smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes inet n – n – – smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=
        -o strict_rfc821_envelopes=yes
        -o smtpd_error_sleep_time=0
        -o smtpd_soft_error_limit=1001
        -o smtpd_hard_error_limit=1000

⑥Settings reflect

# usermod -G clamav amavis
# usermod -G amavis clamav
# systemctl restart clamav-daemon amavis postfix

2.5 Apply spamassassin to mail server Postfix

①Install spamassassin

# apt update
# apt upgrade
# apt install spamassassin

②Configuring SpamAssassin
The configuration file is “/etc/mail/spamassassin/local.cf”.

  • Use the default settings without any additional configuration
  • Create a Maildir for storing spam mails
  • Create a directory for storing spam mails in Maildir format
  • Create a directory “.Spam” in Maildir format for storing spam mails.
  • Creation is done by the target user
# su – <user name>
$ cd ~
Create a directory named “.Spam”.
$ cd Maildir
$ /usr/bin/maildirmake.dovecot .Spam
$ su –

2.6 Prep for Procmail

①Installing Procmail

# apt install procmail

If it is installed, the following results will be returned

# which procmail

②Procmail configuration
If you put it in “/etc/procmailrc”, which controls the whole mail filter, it will be applied to all users.
If you put this in the mail filter file for each user, “/home/username/.procmailrc”, the filter will be applied only to that user.
In this case, to apply it to all users, it is written in “/etc/procmailrc”.

# vi /etc/procmailrc

procmailrc contents (new)

# Set path
PATH=/bin:/usr/bin:/usr/local/bin   # Mailbox settings
# Specify the output destination for Procmail log files.
#Specify the path to the lock file
# If there is no “X-Spam-***” in the mail header, spamassassin will be started.
# If there is an “X-Spam-Status: Yes” in the mail header, the mail will be stored in the “.Spam” directory.
* ^X-Spam-Status: Yes

2.7 Postfix Configuration

① Edit main.cf

# vi /etc/postfix/main.cf
Add to last line
mailbox_command = /usr/bin/procmail

②Reflection and activation of settings

# systemctl start spamassassin
# systemctl restart postfix

2.8 Learning about spam emails

Makes all the contents of the “.Spam” directory of all users be learned as spam mail
①Learning about spam emails

# /usr/bin/sa-learn –spam /home/*/Maildir/.Spam/cur
Learned from 89 message(s) (89 message(s) examined).  <– 89 emails learnt as spam

②Learning about normal email

# /usr/bin/sa-learn –ham /home/*/Maildir/cur
Learned from 157 message(s) (157 message(s) examined).  <– Learning 157 emails as normal emails

③Create a learning script and subscribe to Cron
Name the file “spam-learns.sh” and put it under /opt/script/.
After saving the script, give it executable access as “chmod 750 spam-learns.sh”.

# vi /opt/script/spam-learns.sh

spam-learns.sh Contents

#! /bin/sh
# Learning about spam emails
/usr/bin/sa-learn –spam /home/*/Maildir/.Spam/cur
# Learning to send normal emails
/usr/bin/sa-learn –ham /home/*/Maildir/cur
# If you want to force the deletion of the contents of the spam mail storage directory, add the following statement
/bin/rm -f /home/*/Maildir/.Spam/cur
# chmod 750 /opt/script/spam-learns.sh

When spam-learns.sh is created, create the definition file directly under /lib/systemd/system.
The name should end in .service, such as spam-learns.service.
Type is defined by simple

# cd /lib/systemd/system
# vi spam-learns.service

Contents of spam-learns.service

[Unit] Description=demo sample node.js program
[Service] Type=simple
ExecStart= /opt/script/spam-learns.sh
[Install] WantedBy=multi-user.target
Subscribe to Cron and run periodically
# crontab -e
0 4 * * * /opt/script/spam-learns.sh
# systemctl enable spam-learns