Configuring Postfix E-Mail Gateway for MS Exchange Server 2013 with RHEL/CentOS 7

1. Overview

 

In this article, we will configure Postfix on CentOS 7 as a Mail Gateway for internal MS Exchange 2013 Server or any other back-end E-mail server.

This systems provides several advantages such as blocking unwanted traffic, virus-scanning ,spam prevention, and reduce load on the internal back-end mail server.

2. Prerequisites

 

In this article, it is presumed that:

a. You have an public domain and have access to manage the DNS record for that domain name.
b. You have a public IP address from an ISP assigned to your Cisco edge router.

3. System Architecture Diagram

 

The following diagram is the scenarios for this configuration. There is one Cisco router facing with the internet. Postfix E-Mail Gateway staying behind the Cisco router. All incoming E-mails from the internet to the internal MS Exchange 2013 server must go through Postfix Mail Gateway first to scan for virus and spam E-mails.

Likewise, Any E-mails from internal MS Exchange 2013 server going to the external recipients on the internet will come across Postfix E-Mail Gateway to scan for virus and spam first too. For any E-mail sending from internal user and destination for internal recipients, MS Exchange 2013 server will maintain it.


As my computer is not strong enough to install MS Exchange 2013 server, I will use CentOS 7 Linux box to be the internal E-Mail server instead with Postfix, Dovecot, and Squirelmail like the diagram below.

A. Public Domain and MX Record

We have a public domain name which “techspacekh.com”. The MX record, the priority number is 1,  for this domain is “smtp.techspacekh.com” and pointing to our public IP address, 1X0.X4.2X7.X43, on Cisco router interface Fa0/0.

B. Cisco Router

  • Fa0/0, 1X0.X4.2X7.X43, WAN interface connected to the internet
  • Fa0/1, 10.111.102.254, LAN interface connected to local switch

C. Postfix E-Mail Gateway

  • Hostname: mgw01
  • IP Address: 10.111.102.88
  • Sub Netmask: 255.255.255.0
  • Gateway: 10.111.102.254
  • Relay Domain: techspacekh.com
  • Operating Systems: CentOS 7
  • Applications: Postfix, Amavisd-new, Spamassassin, and ClamAV.
  • This server must be able to access to the internet

D. Internal E-Mail Server

  • Hostname: mxs01
  • IP Addresss: 10.111.102.69
  • Sub Netmask: 255.255.255.0
  • Gateway: 10.111.102.254
  • Domain: techspacekh.com
  • Operating Systems: CentOS 7
  • Applications: Postfix, Dovecot, and Squirelmail
  • After finish installed all the required packages, we can deny internet access for this server

E. End Users

For end users, they will use web browser to send and receive mail both from/to internal and external.


The following diagram illustrate the logical mail flow of both incoming and outgoing on Postfix Mail Gateway. For both incoming and outgoing E-Mail, Postfix Mail Gateway receives an E-mail on port 25, passes it to Amavisd-new on port 10024 which then invokes Spamassassin first and then ClamAV, and afterwards Amavisd-new re-injects the mail into Postfix on port 10025 which then finally delivers the E-mail if it is a clean E-Mail.

3. Configure DNS Record

 

The domain “techpacekh.com” is hosted with GoDaddy, so the following will show you how to create MX record on GoDaddy.


In the GoDaddy site, click on your registered domain. For this article, we’ll use domain “techspacekh.com”. At the bottom of the Records section, click Add.

Click the Type drop-down list and select A. In the Host field, enter “smtp”. In the Points to field, enter your public IP and then click Save.

After adding A record, we need to add MX record. Click Add again at the bottom of the Records section.  Click the Type drop-down list and select MX. In the Host field, enter “@”. In the Points to field, enter “smtp.techspacekh.com”. In the Priority field, enter 1. and then click Save.

The DNS record update process would take about three to five minutes to globally updated. After the records are updated, we can test it with the following “nslookup” command on MS Windows.

>nslookup
> server 8.8.8.8
Default Server:  google-public-dns-a.google.com
Address:  8.8.8.8
> set q=mx
> techspacekh.com
Server:  google-public-dns-a.google.com
Address:  8.8.8.8

Non-authoritative answer:
techspacekh.com MX preference = 1, mail exchanger = smtp.techspacekh.com
> set q=a
> smtp.techspacekh.com
Server:  google-public-dns-a.google.com
Address:  8.8.8.8

Non-authoritative answer:
Name:    smtp.techspacekh.com
Address:  1X0.X4.2X7.X43

We can also test MX record with “dig” command on Linux.

# dig mx techspacekh.com

; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.2 <<>> mx techspacekh.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55741
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;techspacekh.com.               IN      MX

;; ANSWER SECTION:
techspacekh.com.        3600    IN      MX      1 smtp.techspacekh.com.

;; AUTHORITY SECTION:
techspacekh.com.        172800  IN      NS      ns49.domaincontrol.com.
techspacekh.com.        172800  IN      NS      ns50.domaincontrol.com.

;; ADDITIONAL SECTION:
ns49.domaincontrol.com. 172800  IN      A       216.69.185.25
ns49.domaincontrol.com. 172800  IN      AAAA    2607:f208:206::19
ns50.domaincontrol.com. 172800  IN      A       208.109.255.25
ns50.domaincontrol.com. 172800  IN      AAAA    2607:f208:302::19

;; Query time: 272 msec
;; SERVER: 192.168.10.20#53(192.168.10.20)
;; WHEN: Tue Apr 11 22:52:11 +07 2017
;; MSG SIZE  rcvd: 205

If we want to know the A record, we can use command “dig” again as the following.

# dig a smtp.techspacekh.com

; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.2 <<>> a smtp.techspacekh.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3425
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;smtp.techspacekh.com.          IN      A

;; ANSWER SECTION:
smtp.techspacekh.com.   3600    IN      A       1X0.X4.2X7.X43

;; AUTHORITY SECTION:
techspacekh.com.        172604  IN      NS      ns50.domaincontrol.com.
techspacekh.com.        172604  IN      NS      ns49.domaincontrol.com.

;; ADDITIONAL SECTION:
ns49.domaincontrol.com. 172604  IN      A       216.69.185.25
ns49.domaincontrol.com. 172604  IN      AAAA    2607:f208:206::19
ns50.domaincontrol.com. 172604  IN      A       208.109.255.25
ns50.domaincontrol.com. 172604  IN      AAAA    2607:f208:302::19

;; Query time: 87 msec
;; SERVER: 192.168.10.20#53(192.168.10.20)
;; WHEN: Tue Apr 11 22:55:27 +07 2017
;; MSG SIZE  rcvd: 205

It is also possible to test MX record online with this link  http://mxtoolbox.com.

Google also provide a tool to check your MX record and the link is https://toolbox.googleapps.com/apps/checkmx.

Alternatively, Google also have command Dig online with this link https://toolbox.googleapps.com/apps/dig.

4. Configure Static NAT for Postfix E-Mail Gateway Server

 

Login into your public router and enter the following commands.

#sh ip int bri
Interface                  IP-Address      OK? Method Status                Protocol
FastEthernet0/0            1X0.X4.2X7.X43  YES manual up                    up
FastEthernet0/1            10.111.102.252  YES NVRAM  up                    up
#ip nat inside source static tcp 10.111.102.88 25 interface FastEthernet0/0 25

 

5. Configure Internal E-Mail Server

5.1 Postfix, Dovecot, and Squirrelmail

5.1.1 Postfix

 

After install CentOS 7, Postfix is came by default. In case that it doesn’t, we can use the following command to install it.

#yum -y install postfix

Now let do a backup of file /etc/postfix/main.cf and then edit/change it as the following

#cd /etc/postfix/
#cp main.cf main.cf.old
#vim main.cf

myhostname = mxs01.techspacekh.com
mydomain = techspacekh.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = 10.111.102.0/24, 127.0.0.0/8
home_mailbox = Maildir/
relayhost = 10.111.102.88

Restart Postfix.

#systemctl restart postfix

Start Postfix at system start up.

#systemctl enable postfix

To test Postfix, telnet port 25 to the server and enter the commands manually shown in bold text below.

#telnet 10.111.102.69 25
Trying 10.111.102.69...
Connected to 10.111.102.69.
Escape character is '^]'.
220 mxs01.techspacekh.com ESMTP Postfix
ehlo 10.111.102.69
250-mxs01.techspacekh.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:vannath@techspacekh.com
250 2.1.0 Ok
rcpt to:solida@techspacekh.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
subject: Test Email
Hi,

This is just a test email.

Thanks,
Vannath
.
250 2.0.0 Ok: queued as 8710DD42
quit
221 2.0.0 Bye
Connection closed by foreign host.

Now list the mail directory of user “Solida” and check whether the new mail has been received.

#cd /home/solida/Maildir/new/
#ll
total 4
-rw------- 1 solida solida 499 Apr 12 09:38 1491964686.Vfd02I80a08aM101541.mxs01

We can use “cat” command to read the content of the mail.

#cat 1491964686.Vfd02I80a08aM101541.mxs01
Return-Path: <vannath@techspacekh.com>
X-Original-To: solida@techspacekh.com
Delivered-To: solida@techspacekh.com
Received: from 10.111.102.69 (mxs01 [10.111.102.69])
        by mxs01.techspacekh.com (Postfix) with ESMTP id 8710DD42
        for <solida@techspacekh.com>; Wed, 12 Apr 2017 09:36:33 +0700 (+07)
subject: Test Email
Message-Id: <20170412023712.8710DD42@mxs01.techspacekh.com>
Date: Wed, 12 Apr 2017 09:36:33 +0700 (+07)
From: vannath@techspacekh.com

Hi,

This is just a test email.

Thanks,
Vannath

5.1.2 Dovecot

 

Execute the following command to install dovecot.

yum -y install dovecot

Edit file /etc/dovecot/dovecot.conf and make the changes as the following.

#vim /etc/dovecot/dovecot.conf
protocols = imap pop3 lmtp

Edit file /etc/dovecot/conf.d/10-mail.conf and make the changes as the following.

#vim /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir

Edit /etc/dovecot/conf.d/10-auth.conf and make the changes as the following.

#vim /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = no
auth_mechanisms = plain login

Edit file /etc/dovecot/conf.d/10-master.conf and make the changes as the following.

#vim /etc/dovecot/conf.d/10-master.conf
 unix_listener auth-userdb {
    user = postfix
    group = postfix
  }

Restart Postfix.

#systemctl start dovecot

Start Postfix at system start up

#systemctl enable dovecot

Enter the following command to test Dovecot configuration.

#telnet 10.111.102.69 110
Trying 10.111.102.69...
Connected to 10.111.102.69.
Escape character is '^]'.
+OK Dovecot ready.
user solida
+OK
pass P@ssword123
+OK Logged in.
retr 1
+OK 516 octets
Return-Path: <vannath@techspacekh.com>
X-Original-To: solida@techspacekh.com
Delivered-To: solida@techspacekh.com
Received: from 10.111.102.69 (mxs01 [10.111.102.69])
        by mxs01.techspacekh.com (Postfix) with ESMTP id 8710DD42
        for <solida@techspacekh.com>; Wed, 12 Apr 2017 09:36:33 +0700 (+07)
subject: Test Email
Message-Id: <20170412023712.8710DD42@mxs01.techspacekh.com>
Date: Wed, 12 Apr 2017 09:36:33 +0700 (+07)
From: vannath@techspacekh.com

Hi,

This is just a test email.

Thanks,
Vannath
.
quit
+OK Logging out.
Connection closed by foreign host.

5.1.3 Squirrelmail

 

Before installing Squirrelmail, we need to install Extra Packages for Enterprise Linux (EPEL) repository as the following.

#yum -y install epel-release

Now let install Squirrelmail with the following command.

#yum -y install squirrelmail

Navigate to /usr/share/squirrelmail/config/ directory and run the following command to configure Squirrelmail.

#cd /usr/share/squirrelmail/config
#./conf.pl

With the following wizard, enter option “1” to set your organization preferences.

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Main Menu --
1.  Organization Preferences
2.  Server Settings
3.  Folder Defaults
4.  General Options
5.  Themes
6.  Address Books
7.  Message of the Day (MOTD)
8.  Plugins
9.  Database
10. Languages

D.  Set pre-defined settings for specific IMAP servers

C   Turn color off
S   Save data
Q   Quit

Command >> 1

Another wizard will open as the following. For now just enter “1” again to modify your organization details.

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Organization Preferences
1. Organization Name : SquirrelMail
2. Organization Logo : ../images/sm_logo.png
3. Org. Logo Width/Height : (308/111)
4. Organization Title : SquirrelMail $version
5. Signout Page : 
6. Top Frame : _top
7. Provider link : http://squirrelmail.org/
8. Provider name : SquirrelMail

R Return to Main Menu
C Turn color off
S Save data
Q Quit

Command >> 1

Set your organization name and press enter.

We have tried to make the name SquirrelMail as transparent as
possible. If you set up an organization name, most places where
SquirrelMail would take credit will be credited to your organization.

If your Organization Name includes a '$', please precede it with a \. 
Other '$' will be considered the beginning of a variable that
must be defined before the $org_name is printed.
$version, for example, is included by default, and will print the
string representing the current SquirrelMail version.

[SquirrelMail]: Tech Space KH

Press “S” to save the changes, and press “R” to return back to your main menu.

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Organization Preferences
1.  Organization Name      : Tech Space KH
2.  Organization Logo      : ../images/sm_logo.png
3.  Org. Logo Width/Height : (308/111)
4.  Organization Title     : SquirrelMail $version
5.  Signout Page           :
6.  Top Frame              : _top
7.  Provider link          : http://squirrelmail.org/
8.  Provider name          : SquirrelMail

R   Return to Main Menu
C   Turn color off
S   Save data
Q   Quit

Command >> S

Now enter option “2” to setup mail server settings such as domain name and mail agent.

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Main Menu --
1.  Organization Preferences
2.  Server Settings
3.  Folder Defaults
4.  General Options
5.  Themes
6.  Address Books
7.  Message of the Day (MOTD)
8.  Plugins
9.  Database
10. Languages

D.  Set pre-defined settings for specific IMAP servers

C   Turn color off
S   Save data
Q   Quit

Command >> 2

Enter option “1” and the enter the mail domain, in our case now is “techspacekh.com”, and press Enter.

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Server Settings

General
-------
1. Domain : localhost
2. Invert Time : false
3. Sendmail or SMTP : Sendmail

A. Update IMAP Settings : localhost:143 (uw)
B. Change Sendmail Config : /usr/sbin/sendmail

R Return to Main Menu
C Turn color off
S Save data
Q Quit

Command >> 1

The domain name is the suffix at the end of all email addresses. If
for example, your email address is jdoe@example.com, then your domain
would be example.com.

[localhost]: techspacekh.com

Enter option “3” and change from sendmail to Postfix MTA (SMTP).

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Server Settings

General
-------
1.  Domain                 : techspacekh.com
2.  Invert Time            : false
3.  Sendmail or SMTP       : Sendmail

A.  Update IMAP Settings   : localhost:143 (uw)
B.  Update SMTP Settings   : 10.111.102.69:25

R   Return to Main Menu
C   Turn color off
S   Save data
Q   Quit

Command >> 3

Enter “2” to change from sendmail MTA to postfix.

You now need to choose the method that you will use for sending
messages in SquirrelMail.  You can either connect to an SMTP server
or use sendmail directly.

  1.  Sendmail
  2.  SMTP
Your choice [1/2] [1]: 2

Now enter “S” and followed by “Q” to save and exit Squirrelmail configuration.

Next step, we need to create a squirrelmail vhost in apache config file.

#vim /etc/httpd/conf/httpd.conf
Alias /webmail /usr/share/squirrelmail
<Directory /usr/share/squirrelmail>
  Options Indexes FollowSymLinks
  RewriteEngine On
  AllowOverride All
  DirectoryIndex index.php
  Order allow,deny
  Allow from all
</Directory>

Restart the Apache service.

#systemctl restart httpd

Start Apache at system start up.

#systemctl enable httpd

Now we can access to http://10.111.102.69/webmail from your browser.

Now let try to test send and receive mail internally.

5.2. MS Exchange Server 2013

5.2.1 Send Connector

 

Now let configuring a Send Connector to send outbound internet email via a Postfix E-Mail Gateway.

Login to Exchange Control Panel and navigate to Mail Flow and then click Send Connectors. Click the + button to create a new Send Connector.


Give an name for the send connector, choose Custom and then click Next.

Click the + button to create a new Send Connector.

Enter the IP of the Postfix Mail Gateway and the click Save.

5.2.2 Receive Connector

 

Receive connector allows all email to be received by the E-Mail server. By default, several receive connectors are created. Default frontend connector allows all users from the Internet to send email to this E-Mail server.

6. Configure E-Mail Gateway

6.1. Postfix

 

After install CentOS 7, Postfix is came by default. In case that it doesn’t, we can use the following command to install it.

#yum -y install postfix

Now let do a backup of file /etc/postfix/main.cf and then edit/change it as the following to act as the mail gateway for our internal mail server.

#cd /etc/postfix/
#cp main.cf main.cf.old
#vim main.cf
myhostname = mgw01.techspacekh.com
mydomain = techspacekh.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
mydestination = mgw01.techspacekh.com, localhost
relay_domains = techspacekh.com
mynetworks = 10.111.102.69
transport_maps = hash:/etc/postfix/transport

Now we need to configure Postfix to relay mail through our filter to our internal mail server. To do this we need to make sure our domain is the only place email gets forwarded to. Add this line to the file /etc/postfix/transport.

#vim /etc/postfix/transport
techspacekh.com smtp:[10.111.102.69]

This maps the domain “techspacekh.com” to internal mail server inside the network. Finally, build the hash table for Postfix to use to forward mail.

#postmap /etc/postfix/transport

Then restart Postfix to update all of the new settings

#systemctl restart postfix

Enable Postfix to start after system reboot.

#systemctl enable postfix

Now let test send mail from Gmail. We should be able to receive incoming mail from external user.

Let test send mail to external mail account.

6.2. Amavisd-new, ClamAV, and SpamAssassin

6.2.1 ClamAV

 

Execute the following command to install ClamAV Anti-Virus.

#yum -y install clamav clamav-update

Edit the following file /etc/freshclam.conf and comment the line “Example” as the following.

#vim /etc/freshclam
 #Example

Check if ClamAV is up to date with the following command.

#clamscan -V
ClamAV 0.99.2/23232/Tue Mar 11 11:45:12 2016

To update ClamAV database execute the following command.

#freshclam

Check ClamVA updated database again and now it is up to dated.

# clamscan -V
ClamAV 0.99.2/2389/Wed Apr 12 11:47:38 2017


Now let test to scan for virus in “/tmp” directory. As we can see, there is no infected file found.

#clamscan --infected --remove --recursive /tmp

----------- SCAN SUMMARY -----------
Known viruses: 6233352
Engine version: 0.99.2
Scanned directories: 10
Scanned files: 1
Infected files: 0
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 13.843 sec (0 m 13 s)

Let test download trial virus and try to run the scan again. As the result below, there is one infected file found.

#cd /tmp
#wget http://www.eicar.org/download/eicar.com
#clamscan --infected --remove --recursive /tmp
/tmp/eicar.com: Eicar-Test-Signature FOUND
/tmp/eicar.com: Removed.

----------- SCAN SUMMARY -----------
Known viruses: 6233352
Engine version: 0.99.2
Scanned directories: 10
Scanned files: 2
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 16.996 sec (0 m 16 s)

To enable the periodic update of ClamAV database, we need to comment out line FRESHCLAM_DELAY=disabled-warn in file /etc/sysconfig/freshclam as the following.

#vim /etc/sysconfig/freshclam

#FRESHCLAM_DELAY=disabled-warn

Then, the default cron job, file /etc/cron.d/clamav-update, that come along with ClamAV package will update the ClamAV database every 3 hours periodically.

#cat /etc/cron.d/clamav-update
## Adjust this line...
MAILTO=root

## It is ok to execute it as root; freshclam drops privileges and becomes
## user 'clamupdate' as soon as possible
0  */3 * * * root /usr/share/clamav/freshclam-sleep

We can verify that ClamAV database is really periodically updated every 3 hours by view the log in file /var/log/messages as the following.

#cat /var/log/messages | grep freshclam

Apr 21 09:49:28 mgw01 freshclam[11800]: ClamAV update process started at Fri Apr 21 09:49:28 2017
Apr 21 09:49:28 mgw01 freshclam[11800]: main.cvd is up to date (version: 57, sigs: 4218790, f-level: 60, builder: amishhammer)
Apr 21 09:49:29 mgw01 freshclam[11800]: Downloading daily-23310.cdiff [100%]
Apr 21 09:49:31 mgw01 freshclam[11800]: Downloading daily-23311.cdiff [100%]
Apr 21 09:49:32 mgw01 freshclam[11800]: Downloading daily-23312.cdiff [100%]
Apr 21 09:49:33 mgw01 freshclam[11800]: Downloading daily-23313.cdiff [100%]
Apr 21 09:49:34 mgw01 freshclam[11800]: Downloading daily-23314.cdiff [100%]
Apr 21 09:49:35 mgw01 freshclam[11800]: Downloading daily-23315.cdiff [100%]
Apr 21 09:49:39 mgw01 freshclam[11800]: daily.cld updated (version: 23315, sigs: 2054855, f-level: 63, builder: neo)
Apr 21 09:49:41 mgw01 freshclam[11800]: Downloading bytecode-292.cdiff [100%]
Apr 21 09:49:41 mgw01 freshclam[11800]: Downloading bytecode-293.cdiff [100%]
Apr 21 09:49:45 mgw01 freshclam[11800]: Downloading bytecode-294.cdiff [100%]
Apr 21 09:49:46 mgw01 freshclam[11800]: bytecode.cld updated (version: 294, sigs: 57, f-level: 63, builder: anvilleg)
Apr 21 09:49:51 mgw01 freshclam[11800]: Database updated (6273702 signatures) from database.clamav.net (IP: 27.96.54.66)
Apr 21 12:49:27 mgw01 freshclam[11973]: ClamAV update process started at Fri Apr 21 12:49:27 2017
Apr 21 12:49:27 mgw01 freshclam[11973]: main.cvd is up to date (version: 57, sigs: 4218790, f-level: 60, builder: amishhammer)
Apr 21 12:49:29 mgw01 freshclam[11973]: Downloading daily-23316.cdiff [100%]
Apr 21 12:49:37 mgw01 freshclam[11973]: daily.cld updated (version: 23316, sigs: 2055624, f-level: 63, builder: neo)
Apr 21 12:49:37 mgw01 freshclam[11973]: bytecode.cld is up to date (version: 294, sigs: 57, f-level: 63, builder: anvilleg)
Apr 21 12:49:44 mgw01 freshclam[11973]: Database updated (6274471 signatures) from database.clamav.net (IP: 198.148.78.4) (IP: 198.148.78.4)

6.2.2 Amavisd-new and SpamAssassin

 

Install Amavisd-new and ClamAV server. It will also install Spamassassin by default.

yum -y install amavisd-new clamav-server clamav-server-systemd

Create ClamAV and Amavisd configuration from its sample in /usr/share/doc/clamav-server-0.99.2/clamd.sysconfig.

#cp /usr/share/doc/clamav-server-0.99.2/clamd.sysconfig /etc/sysconfig/clamd.amavisd

Edit file /etc/sysconfig/clamd.amavisd as the following.

# vim /etc/sysconfig/clamd.amavisd
CLAMD_CONFIGFILE=/etc/clamd.d/amavisd.conf
CLAMD_SOCKET=/var/run/clamd.amavisd/clamd.sock

Create file /etc/tmpfiles.d/clamd.amavisd.conf and add the content as the following.

#vim /etc/tmpfiles.d/clamd.amavisd.conf
d /var/run/clamd.amavisd 0755 amavis amavis -

Edit file /usr/lib/systemd/system/clamd@.service and add these lines at the bottom as the following.

# vim /usr/lib/systemd/system/clamd@.service
[Install]
WantedBy=multi-user.target

Start Amavisd and ClamAV service.

#systemctl start clamd@amavisd

Start Amavisd and ClamAV service at system start up.

#systemctl enable clamd@amavisd

Edit /etc/amavisd/amavisd.conf file as the following.

#vim /etc/amavisd/amavisd.conf
$mydomain = 'techspacekh.com'; 
$myhostname = 'mgw01.techspacekh.com';
$notify_method  = 'smtp:[127.0.0.1]:10025';
$forward_method = 'smtp:[127.0.0.1]:10025';

Start Amavisd and Spamassasin service.

#systemctl start amavisd spamassassin

Start Amavisd and Spamassasin service at system start up.

#systemctl enable amavisd spamassassin

Ok, now we need to integrate these pieces into the postfix service. Edit file /etc/postfix/main.cf and add these lines at the bottom as the following.

#vim /etc/postfix/main.cf
content_filter=smtp-amavis:[127.0.0.1]:10024

Edit the /etc/postfix/master.cf and add these lines at the bottom.

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

Now restart Postfix service.

#systemctl restart postfix

Test virus scaning  by sending  an email from external account, for now let use Gmail, to account hosted on out internal mail server with the following content (Eicar virus).

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

When we view the email log on Postfix E-Mail Gateway with below command, we will see that the email is blocked.

#tailf /var/log/maillog

Apr 12 16:09:50 mgw01 postfix/smtpd[19249]: connect from mail-pg0-f42.google.com[74.125.83.42]
Apr 12 16:09:50 mgw01 postfix/smtpd[19249]: BB9CAE5B: client=mail-pg0-f42.google.com[74.125.83.42]
Apr 12 16:09:50 mgw01 postfix/cleanup[19252]: BB9CAE5B: message-id=<CAJZmX9=nogC8AX1KmxN7nXT=exva4KED_asz+1iBWOc3Qqc7OQ@mail.gmail.com>
Apr 12 16:09:50 mgw01 postfix/qmgr[19118]: BB9CAE5B: from=<vannathkann@gmail.com>, size=3815, nrcpt=1 (queue active)
Apr 12 16:09:51 mgw01 postfix/smtpd[19249]: disconnect from mail-pg0-f42.google.com[74.125.83.42]
Apr 12 16:09:51 mgw01 clamd[12520]: /var/spool/amavisd/tmp/amavis-20170412T090001-17866-A5gwkNy5/parts/p004: Eicar-Test-Signature FOUND
Apr 12 16:09:51 mgw01 clamd[12520]: /var/spool/amavisd/tmp/amavis-20170412T090001-17866-A5gwkNy5/parts/p001: Eicar-Test-Signature FOUND
Apr 12 16:09:51 mgw01 amavis[17866]: (17866-05) Blocked INFECTED (Eicar-Test-Signature) {DiscardedInbound,Quarantined}, [74.125.83.42]:36133 [74.125.83.42] <vannathkann@gmail.com> -> <vannath@techspacekh.com>, Queue-ID: BB9CAE5B, Message-ID: <CAJZmX9=nogC8AX1KmxN7nXT=exva4KED_asz+1iBWOc3Qqc7OQ@mail.gmail.com>, mail_id: B69Tu1rzAcou, Hits: -, size: 3815, dkim_sd=20161025:gmail.com, 292 ms
Apr 12 16:09:51 mgw01 postfix/smtp[19253]: BB9CAE5B: to=<vannath@techspacekh.com>, relay=127.0.0.1[127.0.0.1]:10024, delay=0.56, delays=0.23/0.02/0.02/0.29, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17866-05 - INFECTED: Eicar-Test-Signature)
Apr 12 16:09:51 mgw01 postfix/qmgr[19118]: BB9CAE5B: removed

Test spam mail scaning  by sending  an email from external account, for now let use Gmail, to account hosted on out internal mail server with the following content.

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

When we view the email log Postfix E-Mail Gateway with below command, we will see that the email is blocked.

#tailf /var/log/maillog

Apr 12 16:18:12 mgw01 postfix/smtpd[19259]: connect from mail-pg0-f46.google.com[74.125.83.46]
Apr 12 16:18:12 mgw01 postfix/smtpd[19259]: 7D002E5B: client=mail-pg0-f46.google.com[74.125.83.46]
Apr 12 16:18:12 mgw01 postfix/cleanup[19262]: 7D002E5B: message-id=<CAJZmX9=E95nN8UVp3QwaTOhspgCA8pVJ4KVdXxz_BJox4y=cvw@mail.gmail.com>
Apr 12 16:18:12 mgw01 postfix/qmgr[19118]: 7D002E5B: from=<vannathkann@gmail.com>, size=3645, nrcpt=1 (queue active)
Apr 12 16:18:12 mgw01 postfix/smtpd[19259]: disconnect from mail-pg0-f46.google.com[74.125.83.46]
Apr 12 16:18:16 mgw01 amavis[17867]: (17867-05) Blocked SPAM {DiscardedInbound,Quarantined}, [74.125.83.46]:36279 [74.125.83.46] <vannathkann@gmail.com> -> <vannath@techspacekh.com>, Queue-ID: 7D002E5B, Message-ID: <CAJZmX9=E95nN8UVp3QwaTOhspgCA8pVJ4KVdXxz_BJox4y=cvw@mail.gmail.com>, mail_id: BAvJOhKGgGgK, Hits: 1000.882, size: 3645, dkim_sd=20161025:gmail.com, 4095 ms
Apr 12 16:18:16 mgw01 postfix/smtp[19263]: 7D002E5B: to=<vannath@techspacekh.com>, relay=127.0.0.1[127.0.0.1]:10024, delay=4.3, delays=0.22/0.02/0.01/4.1, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17867-05 - spam)
Apr 12 16:18:16 mgw01 postfix/qmgr[19118]: 7D002E5B: removed

We have successfully test protecting incoming spam and virus E-Mail from the internet. Now, we can test outgoing virus scanning and spam scanning from internal users by sending mail from an internal mail account with the virus and spam content as above. We should get the same result.

For any normal E-Mails, Postfix Mail Gateway will relay them to the internal mail server/Internet after scanned both virus and spam by Amavisd. For the incoming E-Mail, the internal mail server will store them is their respective mail box.

#tailf /var/log/maillog

Apr 13 09:13:13 mgw01 postfix/smtpd[22346]: connect from mail-pg0-f53.google.com[74.125.83.53]
Apr 13 09:13:14 mgw01 postfix/smtpd[22346]: CCD1426023: client=mail-pg0-f53.google.com[74.125.83.53]
Apr 13 09:13:15 mgw01 postfix/cleanup[22349]: CCD1426023: message-id=<CAJZmX9mE9VPyCgh=-oX4RsutMSpfF3-h2++0n0ie7ga2Zio=tA@mail.gmail.com>
Apr 13 09:13:15 mgw01 postfix/qmgr[22002]: CCD1426023: from=<vannathkann@gmail.com>, size=3537, nrcpt=1 (queue active)
Apr 13 09:13:15 mgw01 postfix/smtpd[22346]: disconnect from mail-pg0-f53.google.com[74.125.83.53]
Apr 13 09:13:16 mgw01 postfix/smtpd[22353]: connect from localhost[127.0.0.1]
Apr 13 09:13:16 mgw01 postfix/smtpd[22353]: F36FE2602D: client=localhost[127.0.0.1]
Apr 13 09:13:17 mgw01 postfix/cleanup[22349]: F36FE2602D: message-id=<CAJZmX9mE9VPyCgh=-oX4RsutMSpfF3-h2++0n0ie7ga2Zio=tA@mail.gmail.com>
Apr 13 09:13:17 mgw01 postfix/qmgr[22002]: F36FE2602D: from=<vannathkann@gmail.com>, size=4106, nrcpt=1 (queue active)
Apr 13 09:13:17 mgw01 postfix/smtpd[22353]: disconnect from localhost[127.0.0.1]
Apr 13 09:13:17 mgw01 amavis[17867]: (17867-16) Passed CLEAN {RelayedInbound}, [74.125.83.53]:34935 [74.125.83.53] <vannathkann@gmail.com> -> <vannath@techspacekh.com>, Queue-ID: CCD1426023, Message-ID: <CAJZmX9mE9VPyCgh=-oX4RsutMSpfF3-h2++0n0ie7ga2Zio=tA@mail.gmail.com>, mail_id: C_bC8757wqPY, Hits: 1.382, size: 3537, queued_as: F36FE2602D, dkim_sd=20161025:gmail.com, 1979 ms
Apr 13 09:13:17 mgw01 postfix/smtp[22350]: CCD1426023: to=<vannath@techspacekh.com>, relay=127.0.0.1[127.0.0.1]:10024, delay=3.4, delays=1.4/0.01/0.01/2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F36FE2602D)
Apr 13 09:13:17 mgw01 postfix/qmgr[22002]: CCD1426023: removed
Apr 13 09:13:17 mgw01 postfix/smtp[22354]: F36FE2602D: to=<vannath@techspacekh.com>, relay=10.111.102.69[10.111.102.69]:25, delay=0.15, delays=0.01/0.05/0.04/0.04, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as E7EF917600)
Apr 13 09:13:17 mgw01 postfix/qmgr[22002]: F36FE2602D: removed

6.3 Postfix Security

 

A. Remove Announcement Details

By default Postfix appends a little announcement to outgoing messages saying that this email is powered by Postfix.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Postfix

It’s best to give hackers as little information as possible about your server, so you should remove the banner by finding the line for smtpd_banner in the configuration file and setting it to:

#vim main.cf
smtpd_banner = $myhostname ESMTP Welcome to Tech Space KH!
#systemctl restart postfix

Now we should get the following respond instead.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!

B. Disable the SMTP VRFY Command

This is to prevent leaking valid E-Mail addresses.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
vrfy vannath
252 2.0.0 vannath

Edit file /etc/postfix/main.cf and add these lines at the bottom as the following.

#vim /etc/postfix/main.cf
disable_vrfy_command = yes
#systemctl restart postfix

Now let test again and we should get the following error.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
vrfy vannath
502 5.5.1 VRFY command is disabled

C. Require HELO or EHLO command

Require that a remote SMTP client introduces itself at the beginning of an SMTP session with the HELO or EHLO command. Many spam bot ignores HELO/EHLO command and you save yourself from spam.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
mail from:vannath@techspacekh.com
250 2.1.0 Ok

Edit file /etc/postfix/main.cf and add these lines at the bottom as the following.

#vim /etc/postfix/main.cf
smtpd_helo_required = yes
#systemctl restart postfix

Now let test again and we should get the following error.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
mail from:vannath@techspacekh.com
503 5.5.1 Error: send HELO/EHLO first

If we try again with the EHLO or HELO command first, it should work fine.

#telnet 10.111.102.88 25
Trying 10.111.102.88...
Connected to 10.111.102.88.
Escape character is '^]'.
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
ehlo 10.111.102.88
250-mgw01.techspacekh.com
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:vannath@techspacekh.com
250 2.1.0 Ok

Following lines further restrictions on HELO/EHLO command:

#vim /etc/postfix/main.cf
smtpd_helo_restrictions = permit_mynetworks, reject_non_fqdn_helo_hostname, reject_invalid_helo_hostname
#systemctl restart postfix

D. Limit Relaying to the Local Machine Only

The default configuration of Postfix allows relaying only from other machines that are connected to the same IP subnet as Postfix server. To only forward emails for the local machine and not machines on the network, edit file /etc/postfix/main.cf as the following.

#vim /etc/postfix/main.cf
mynetworks_style = host
#systemctl restart postfix

Alternatively, you can explicitly indicate the hosts that should be allowed to relay mail by setting mynetworks. If you set mynetworks, the mynetworks_style parameter is ignored. You can list individual IP addresses as the following or specify subnets using the network/netmask notation.

mynetworks = 10.111.102.69

E. Sender Restrictions

The parameter smtpd_sender_restrictions can filters mails based on the MAIL FROM command. This command is easy faked by telneting an open relay and typing in this command, therefore mail could be sent without a valid MAIL FROM address.

#telnet smtp.techspacekh.com 25
Trying 110.74.217.143...
Connected to smtp.techspacekh.com.
Escape character is '^]'.
ehlo smtp.techspacekh.com
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
250-mgw01.techspacekh.com
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:vannath@123fff.co
250 2.1.0 Ok 
rcpt to:vannath@techspacekh.com
250 2.1.5 Ok

Edit file /etc/postfix/main.cf and add these lines at the bottom as the following.

#vim /etc/postfix/main.cf
smtpd_sender_restrictions = permit_mynetworks, reject_non_fqdn_sender, reject_unknown_sender_domain, permit
#systemctl restart postfix

Now let test again and we should get the following error.

#telnet smtp.techspacekh.com 25
Trying 110.74.217.143...
Connected to smtp.techspacekh.com.
Escape character is '^]'.
ehlo smtp.techspacekh.com
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
250-mgw01.techspacekh.com
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:vannath@123fff.co
250 2.1.0 Ok
rcpt to:vannath@techspacekh.com
450 4.1.8 <vannath@123fff.co>: Sender address rejected: Domain not found

 

G. Relay Domain Restriction

The parameter relay_domains can limit to only a certain domain to relay mail through our Postfix E-Mail Gateway. In the previous configuration, we have limited it to only “techspacekh.com” domain. So, any other domains will be rejected.

#telnet smtp.techspacekh.com 25
Trying 110.74.217.143...
Connected to smtp.techspacekh.com.
Escape character is '^]'.
ehlo smtp.techspacekh.com
220 mgw01.techspacekh.com ESMTP Welcome to Tech Space KH!
250-mgw01.techspacekh.com
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from:vannathkann@gmail.com
250 2.1.0 Ok
rcpt to:vannath123@techspacekh12345.com
454 4.7.1 <vannath123@techspacekh12345.com>: Relay access denied

H. Recipient Address Logging

Setting the  parameter smtpd_delay_reject to “yes” will allows Postfix to log recipient address information when rejecting a client name/address or sender address, so that it is possible to find out whose mail is being rejected.

#vim /etc/postfix/main.cf
smtpd_delay_reject = yes
#systemctl restart postfix

I. Postfix Limit Incoming or Receiving E-Mail Rate

When our domain which seems to be very attractive for spammers, Postfix (smtpd daemon) can enforce a number of limits on incoming email. This will stop email flooding attacks. A bot connects to our Postfix E-Mail Gateway server and sends garbage commands or spam, attempting to crash our server.


Edit file /etc/postfix/main.cf and add these lines at the bottom as the following.

#vim /etc/postfix/main.cf
smtpd_error_sleep_time = 1s
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 20
smtpd_client_connection_count_limit = 10
smtpd_client_connection_rate_limit = 60
#systemctl restart postfix

We will get the following log in file /var/log/maillog.

#tailf /var/log/maillog

Apr 20 08:37:14 mgw01 postfix/anvil[9764]: statistics: max connection rate 1/60s for (smtp:179.43.82.227) at Apr 20 08:29:04
Apr 20 08:37:14 mgw01 postfix/anvil[9764]: statistics: max connection count 1 for (smtp:179.43.82.227) at Apr 20 08:29:04
Apr 20 08:37:14 mgw01 postfix/anvil[9764]: statistics: max cache size 1 at Apr 20 08:29:04

7. Conclusion

 

Now you should be able to configure Post Mail Gateway on RHEL/CentoS 7 to be the front-end MTA for your local mail server. I hope you found this article informative. If you have any questions or suggestions you can always leave your comments below. I will try all of my best to review and reply them. Thank you and see you again in another post.

Comments

comments