Contents
1. Antivirus software Clamav installed
Install Clam AntiVirus, a free anti-virus software for Linux, as an anti-virus measure.
By installing this anti-virus software, you can not only scan the entire server for viruses, but also scan incoming and outgoing mail for viruses if you build and configure a mail server.
1.1 Install
1 |
# apt install clamav clamav-daemon |
The clamav-related configuration files are installed in the /etc/clamav/ folder.
1.2 Virus Definition Update
1 |
# systemctl stop clamav-freshclam |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# freshclam Sun Apr 6 09:20:35 2025 -> ClamAV update process started at Sun Apr 6 09:20:35 2025 WARNING: Sun Apr 6 09:20:35 2025 -> Your ClamAV installation is OUTDATED! WARNING: Sun Apr 6 09:20:35 2025 -> Local version: 1.0.7 Recommended version: 1.0.8 Sun Apr 6 09:20:35 2025 -> DON'T PANIC! Read https://docs.clamav.net/manual/Installing.html Sun Apr 6 09:20:35 2025 -> daily database available for download (remote version: 27599) Time: 0.8s, ETA: 0.0s [========================>] 61.63MiB/61.63MiB Sun Apr 6 09:20:37 2025 -> Testing database: '/var/lib/clamav/tmp.0a506bff82/clamav-fad1f39aed4b00bd4a0b4df75a8a28b9.tmp-daily.cvd' ... Sun Apr 6 09:20:43 2025 -> Database test passed. Sun Apr 6 09:20:43 2025 -> daily.cvd updated (version: 27599, sigs: 2074412, f-level: 90, builder: raynman) Sun Apr 6 09:20:43 2025 -> main database available for download (remote version: 62) Time: 2.6s, ETA: 0.0s [========================>] 162.58MiB/162.58MiB Sun Apr 6 09:20:47 2025 -> Testing database: '/var/lib/clamav/tmp.0a506bff82/clamav-aa2618a41f48920e78562228394c09a6.tmp-main.cvd' ... Sun Apr 6 09:20:53 2025 -> Database test passed. Sun Apr 6 09:20:53 2025 -> main.cvd updated (version: 62, sigs: 6647427, f-level: 90, builder: sigmgr) Sun Apr 6 09:20:53 2025 -> bytecode database available for download (remote version: 336) Time: 0.2s, ETA: 0.0s [========================>] 277.52KiB/277.52KiB Sun Apr 6 09:20:53 2025 -> Testing database: '/var/lib/clamav/tmp.0a506bff82/clamav-035427f577ebea49961c1fd8506d3050.tmp-bytecode.cvd' ... Sun Apr 6 09:20:53 2025 -> Database test passed. Sun Apr 6 09:20:53 2025 -> bytecode.cvd updated (version: 336, sigs: 83, f-level: 90, builder: nrandolp) WARNING: Sun Apr 6 09:20:53 2025 -> Clamd was NOT notified: Can't connect to clamd through /var/run/clamav/clamd.ctl: No such file or directory |
1 |
# systemctl start clamav-freshclam |
Edit configuration file
1 2 3 4 |
# vi /etc/logrotate.d/clamav-freshclam create 640 clamav adm ↓ create 640 clamav clamav |
Automatic virus definition update confirmation
Ensure that the service is registered for automatic virus definition updates.
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 |
# service clamav-freshclam status It appears as follows ● clamav-freshclam.service - ClamAV virus database updater Loaded: loaded (/lib/systemd/system/clamav-freshclam.service; disabled; ve> Active: active (running) since Sun 2025-04-06 09:23:20 JST; 44s ago Docs: man:freshclam(1) man:freshclam.conf(5) https://docs.clamav.net/ Main PID: 1538 (freshclam) Tasks: 1 (limit: 2280) Memory: 2.5M CPU: 11ms CGroup: /system.slice/clamav-freshclam.service mq1538 /usr/bin/freshclam -d --foreground=true Apr 06 09:23:20 Lepard systemd[1]: Started ClamAV virus database updater. Apr 06 09:23:20 Lepard freshclam[1538]: Sun Apr 6 09:23:20 2025 -> ClamAV upda> Apr 06 09:23:20 Lepard freshclam[1538]: WARNING: Sun Apr 6 09:23:20 2025 -> Yo> Apr 06 09:23:20 Lepard freshclam[1538]: WARNING: Sun Apr 6 09:23:20 2025 -> Lo> Apr 06 09:23:20 Lepard freshclam[1538]: Sun Apr 6 09:23:20 2025 -> DON'T PANIC> Apr 06 09:23:20 Lepard freshclam[1538]: Sun Apr 6 09:23:20 2025 -> daily.cvd d> Apr 06 09:23:20 Lepard freshclam[1538]: Sun Apr 6 09:23:20 2025 -> main.cvd da> Apr 06 09:23:20 Lepard freshclam[1538]: Sun Apr 6 09:23:20 2025 -> bytecode.cv |
Logs are recorded in the file /var/log/clamav/freshclam.log.
1.3 Virus Check Confirmation
①Running manual virus checks
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# clamscan --infected --remove --recursive /home ----------- SCAN SUMMARY ----------- Known viruses: 8706185 Engine version: 1.0.7 Scanned directories: 3 Scanned files: 7 Infected files: 0 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 18.093 sec (0 m 18 s) Start Date: 2025:04:06 09:25:09 End Date: 2025:04:06 09:25:27 |
Infected files: 0, so no virus
②Virus detection by downloading test viruses
Download a harmless virus and test it for detection.
Log in as a general user and check
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# su - <user name> $ wget https://secure.eicar.org/eicar.com.txt $ clamscan --infected --remove --recursive /home /home/huong/eicar.com.txt: Win.Test.EICAR_HDB-1 FOUND /home/huong/eicar.com.txt: Removed. ----------- SCAN SUMMARY ----------- Known viruses: 8706185 Engine version: 1.0.7 Scanned directories: 3 Scanned files: 9 Infected files: 1 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 14.024 sec (0 m 14 s) Start Date: 2025:04:06 09:27:18 End Date: 2025:04:06 09:27:32 |
As you can see, the virus is notified with the message "FOUND" and "Infected files: 1". The "--remove" option was also added, so the test virus was removed.
1.4 Create a script file to do a full scan
①Create a script file storage directory (/opt/script) in advance.
1 2 3 |
$ su - Password: # mkdir /opt/script |
②Create script file
1 |
# vi /opt/script/clam-full.sh |
Contents of clam-full.sh (new)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/bin/sh echo ========================================= date hostname 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 \ --exclude-dir=^/var/log/clamav/virus if [ $? = 0 ]; then echo “Virus undetected.” else echo “Virus detection!!” fi |
③execute authorization
1 |
# chmod +x /opt/script/clam-full.sh |
④Create a folder for virus quarantine
If not, a runtime error will occur because the above script specifies it as an excluded directory.
1 |
# mkdir /var/log/clamav/virus |
⑤Script Execution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# /opt/script/clam-full.sh ========================================= Sun 06 Apr 2025 09:31:15 AM JST Lepard ----------- SCAN SUMMARY ----------- Known viruses: 8706185 Engine version: 1.0.7 Scanned directories: 4592 Scanned files: 32947 Infected files: 0 Data scanned: 2228.80 MB Data read: 1612.32 MB (ratio 1.38:1) Time: 352.113 sec (5 m 52 s) Start Date: 2025:04:06 09:31:15 End Date: 2025:04:06 09:37:08 “Virus undetected.” |
Takes quite a long time to complete.
Logs are recorded in the /var/log/clamav/clamscan.log file.
⑤Scheduled virus scan execution with cron
1 2 |
# crontab -e 0 2 * * mon /opt/script/clam-full.sh >> /var/log/clamav/clamascan.log |
In the above example, it runs regularly every Monday at 2:00 AM.
2. Mail server installation
Postfix was developed as a Mail Transport Agent (MTA) to replace sendmail, and is a mail server that is highly compatible with sendmail, secure, easy to maintain, and fast.
In addition, since Postfix only functions as an SMTP server for sending mail, the POP server Dovecot for receiving mail will be installed separately in the latter half.
2.1 Postfix : Installation Configuration
①Install Postfix
Install Postfix and build an SMTP server; SMTP uses 25/TCP.
To prevent unauthorized mail relay, use the SASL function of Dovecot, described below, and configure Postfix so that authentication is also required for sending.
1 |
# apt -y install postfix sasl2-bin |
You will be asked to select general configuration settings, select "No configuration " to set them manually later


②Edit configuration file (main.cf)
1 2 |
# cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf # vi /etc/postfix/main.cf |
Editorial content
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# Line 78: Uncomment mail_owner = postfix # Line 94: Uncomment and specify host name myhostname = mail.<domain name> # Line 102: Uncomment and specify domain name mydomain = <domain name> # Line 123: Uncomment myorigin = $mydomain # Line 137: Uncomment inet_interfaces = all # Line 185: Uncomment185 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: Own network addition mynetworks = 127.0.0.0/8, 192.168.11.0/24 # Line 407: Uncomment alias_maps = hash:/etc/aliases # Line 418: Uncomment alias_database = hash:/etc/aliases # Line 440: Uncomment440 home_mailbox = Maildir/ # Line 576: Make it a comment and add below it #smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) smtpd_banner = $myhostname ESMTP # Line 650:add sendmail_path = /usr/sbin/postfix # Line 655:add newaliases_path = /usr/bin/newaliases # Line 660:add mailq_path = /usr/bin/mailq # Line 666:add 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 # SMTP VRFY command is disabled disable_vrfy_command = yes # Requests a HELO command from the client smtpd_helo_required = yes # Limit sent/received mail size to 10M message_size_limit = 10485760 # Limit mailbox size to 1G mailbox_size_limit = 1073741824 # SMTP-Auth Settings 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 |
③Edit configuration file (master.cf)
1 |
# vi /etc/postfix/master.cf |
Editorial content
1 2 3 4 5 6 7 8 9 10 |
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 |
Reflect settings, reboot
1 2 |
# newaliases # systemctl restart postfix |
2.2 Dovecot : Installation Configuration
①Install Dovecot
Install Dovecot and build a POP/IMAP server, using 110/TCP for POP and 143/TCP for IMAP.
②Configure Dovecot to provide SASL functionality for Postfix
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# apt -y install dovecot-core dovecot-pop3d dovecot-imapd # vi /etc/dovecot/dovecot.conf Line 30:Uncomment 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:Uncommented and added # Postfix smtp-authi unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } |
③Reflect settings, reboot
1 |
# systemctl restart dovecot |
2.3 Email User Account Registration
Register a user account for e-mail.
This setting is for when a user account on the OS is also used for e-mail.
If you want to use mail with a user account on the OS, no additional configuration is required, just register the OS user
①Mail client installed
1 |
# apt -y install mailutils |
②Mailboxes are set to refer to Maildir
1 |
# echo 'export MAIL=$HOME/Maildir/' >> /etc/profile.d/mail.sh |
2.4 Opening Ports
1 2 3 4 |
# ufw allow pop3 # ufw allow imap # ufw allow smtp # ufw reload |
2.5 operation check ①
①Send test mail to yourself [mail (user name)@(host name)].
user name : huong
1 2 3 4 5 |
# su - huong $ mail huong@localhost Cc: Subject: Test Mail This is the first mail. |
Ctrl + D key to exit the main text
Check incoming mail
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ mail "/home/huong/Maildir/": 1 message 1 new >N 1 huong Sun Apr 6 00:55 13/431 Test Mail ? 1 Return-Path: <huong@Lepard> X-Original-To: huong@localhost Delivered-To: huong@localhost Received: by mail.korodes.com (Postfix, from userid 1000) id C0F3AA0015; Sun, 6 Apr 2025 09:55:37 +0900 (JST) To: <huong@localhost> Subject: Test Mail X-Mailer: mail (GNU Mailutils 3.10) Message-Id: <20250406005537.C0F3AA0015@mail.korodes.com> Date: Sun, 6 Apr 2025 09:55:37 +0900 (JST) From: huong <huong@Lepard> This is the first mail. ? q Saved 1 message in /home/huong/mbox Held 0 messages in /home/huong/Maildir/ |
2.6 operation check ②
Set up and confirm your account in Mozilla Thunderbird
①Start Thunderbird, and click "Tools", "Account Settings".

②「Account Actions」「Add Mail Account」

③Your full name" is an optional name
Email addtess" is "huong@korodes.com" added earlier
Password" is the password for user huong
Click on "Configure manually"

④Set "INCOMMING SERVER" and "OUTGOING SERVER" as shown below and click "Re-test".

⑤The "Server Found" message appears.(The following settings were found by probinfg the given server)

After clicking "Done," the following "Warning" appears, but there is no problem, so click "Confirm.

⑥Click "Finish" when "Account syccessfuly created" is displayed.

3.Anti-virus and anti-spam measures(ClamAV + SpamAssassin)
Postfix is integrated with ClamAV for virus scanning and spam filtering.
3.1 ClamAV daemon, amavisd-new, SpamAssassin Install
1 |
# apt -y install clamav-daemon amavisd-new spamassassin |
3.2 SpamAssassin Editing Configuration Files
1 2 3 |
# vi /etc/default/spamassassin Add ENABLED=1 |
3.3 amavisd-new Editing Configuration Files
Integrate Postfix with ClamAV and SpamAssassin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# cp /usr/share/doc/amavisd-new/examples/amavisd.conf-default /etc/amavis/amavisd.conf # vi /etc/amavis/amavisd.conf Line 18 : Uncomment and change $myhostname = 'mail.domain-name'; Line 19 : Uncomment and change $mydomain = 'domain-name'; Line 22 : Uncomment and change $daemon_user = 'amavis'; Line 23 : Uncomment and change $daemon_group = 'amavis'; Line 24 : Uncomment and change $MYHOME = '/var/lib/amavis'; Per Line229 : Ensure that it is commented # $virus_admin = undef; |
3.4 Edit 15-content_filter_mode
1 2 3 4 5 6 7 |
# vi /etc/amavis/conf.d/15-content_filter_mode Line 13-14 : Uncomment @bypass_virus_checks_maps = ( \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); Line 24-25 : Uncomment @bypass_spam_checks_maps = ( \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); |
3.5 Edit 15-av_scanners
1 2 3 4 |
# vi /etc/amavis/conf.d/15-av_scanners Line 419 : Comment and add below. #['ClamAV-clamscan', 'clamscan', ['ClamAV-clamscan', 'clamdscan', |
3.6 Edit Postfix - main.cf
1 2 3 4 |
# vi /etc/postfix/main.cf # Add to last line content_filter=smtp-amavis:[[127.0.0.1]]:10024 |
3.7 Edit Postfix - master.cf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# vi /etc/postfix/master.cf # Add to 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 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_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks=127.0.0.0/8 -o strict_rfc821_envelopes=yes -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 |
3.8 Register your domain name
1 |
# echo '<yourDomain>' > /etc/mailname |
3.9 Setting Reflection
1 2 3 4 |
# usermod -G clamav amavis # usermod -G amavis clamav # systemctl restart clamav-daemon amavis postfix # systemctl start spamassassin |
Auto-Startup
1 |
# systemctl enable spamassassin |
When you send a blank email, the header will show the following
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
Return-Path: xxxxx@korodes.com
X-Original-To: xxxxx@korodes.com
Delivered-To: xxxxx@korodes.com
Received: from localhost (localhost [127.0.0.1])
by mail.korodes.com (Postfix) with ESMTP id 8F707DFABA
for xxxxx@korodes.com; Sun, 6 Apr 2025 21:25:54 +0900 (JST)
X-Virus-Scanned: Debian amavisd-new at korodes.com
X-Spam-Flag: NO
X-Spam-Score: 5.111
X-Spam-Level: *
X-Spam-Status: No, score=5.111 tagged_above=2 required=6.31
tests=[ALL_TRUSTED=-1, EMPTY_MESSAGE=2.344, MISSING_SUBJECT=1.767,
PDS_TONAME_EQ_TOLOCAL_SHORT=1, PDS_TONAME_EQ_TOLOCAL_VSHORT=1]
autolearn=no autolearn_force=no
Received: from mail.korodes.com ([127.0.0.1])
by localhost (mail.korodes.com [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id 4et2CYHS88HK for xxxxx@korodes.com;
Sun, 6 Apr 2025 21:25:53 +0900 (JST)
Received: from [192.168.11.8] (xxxxxx.setup [192.168.11.1])
by mail.korodes.com (Postfix) with ESMTPA id 7A03BDFAA9
for xxxxx@korodes.com; Sun, 6 Apr 2025 21:25:53 +0900 (JST)
Message-ID: e898a2db-9903-4846-90da-2db1af012d7a@korodes.com
Date: Sun, 6 Apr 2025 21:25:53 +0900
MIME-Version: 1.0
User-Agent: Mozilla Thunderbird
From: xxxxx xxxxx@korodes.com
Content-Language: en-US
To: xxxxx xxxxx@korodes.com
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit