How to Secure Email Server Against Hacking with VPN (CentOS/RHEL)

In this tutorial, I’m going to share with you my tips and tricks to secure CentOS/RHEL email servers against hacking with a self-hosted VPN server. Many spammers are trying to hack into other people’s email servers. If successful, they would use the hacked email server to send large volumes of spam or steal valuable data. Why do we use a self-hosted VPN server? Because it allows you to enable whitelisting, so only trusted users connected to the VPN server can access your mail server.

Secure Email Server Against Hacking

Prerequisites

It’s assumed that you have an email server up and running. If not, follow one of the tutorials below to set up your own mail server.

It’s also assumed that you have set up a VPN server. If not, please follow one of the tutorials below. The mail server and VPN server can run on separate hosts, or on the same host.

Hint: It’s recommended to run VPN server and mail server on separate hosts to reduce operational complexities. If the mail server and VPN server run on the same host, then there are additional steps required, namely setting up a response policy zone on the VPN server to override the public DNS A record of your mail server hostname.

Let’s say the DNS A record for mail.yourdomain.com resolves to 12.34.56.78, then you need to create a record in the response policy zone to resolve it to the VPN server’s private IP address 10.10.10.1.

In the following texts, I use 12.34.56.78 as the public IP address of the VPN server. If the VPN server and mail server run on the same host, then you need to replace 12.34.56.78 with the VPN server’s private IP address 10.10.10.1.

Step 1: Add VPN Server IP Address to the Firewall Whitelist

Once you have a mail server and VPN server up and running, you should add the VPN server’s IP address to the whitelist of the mail server firewall. If you use Firewalld (CentOS/RHEL), run the following command on the mail server. Replace 12.34.56.78 with the IP address of the VPN server.

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="12.34.56.78" accept'

You can also whitelist your other servers’ IP addresses. For example, some folks might have another web server that needs to send emails through the email server. Then also add it in the whitelist.

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="IP-address-of-the-other-web-server" accept'

Reload firewalld for the changes to take effect.

sudo systemctl reload firewalld

Step 2: Close Submission Port, IMAP Port, and POP3 Port

  • Submission port: 587 and 465
  • IMAP port: 143 and 993
  • POP3 port: 110 and 995

Port 587 and 465 are used by mail clients like Mozilla Thunderbird and Microsoft Outlook to submit outgoing emails. Malicious actors can lunch brute force attack on port 587 and 465.

The following is an example found in my mail log (/var/log/maillog on CentOS/RHEL). The bad actor was trying to login, but failed SASL authentication every time.

postfix/smtps/smtpd[18071]: Anonymous TLS connection established from unknown[92.118.38.56]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
postfix/smtps/smtpd[18071]: warning: unknown[92.118.38.56]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
postfix/smtps/smtpd[18071]: lost connection after AUTH from unknown[92.118.38.56]
postfix/smtps/smtpd[18071]: disconnect from unknown[92.118.38.56] ehlo=1 auth=0/1 rset=1 commands=2/3
postfix/smtps/smtpd[18071]: connect from unknown[92.118.38.56]
postfix/smtps/smtpd[18071]: Anonymous TLS connection established from unknown[92.118.38.56]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
postfix/smtps/smtpd[18071]: warning: unknown[92.118.38.56]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
postfix/smtps/smtpd[18071]: lost connection after AUTH from unknown[92.118.38.56]
postfix/smtps/smtpd[18071]: disconnect from unknown[92.118.38.56] ehlo=1 auth=0/1 rset=1 commands=2/3
postfix/smtps/smtpd[18071]: connect from unknown[92.118.38.56]
postfix/smtps/smtpd[18071]: Anonymous TLS connection established from unknown[92.118.38.56]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
postfix/smtps/smtpd[18071]: warning: unknown[92.118.38.56]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
postfix/smtps/smtpd[18071]: lost connection after AUTH from unknown[92.118.38.56]
postfix/smtps/smtpd[18071]: disconnect from unknown[92.118.38.56] ehlo=1 auth=0/1 rset=1 commands=2/3

I don’t want to see this kind of activity in my mail log, so I simply close port 587, 465, 143, 993, 110 and 995 in the firewall. And because my VPN server’s IP address is whitelisted, so only users who are connected to my VPN server can access those ports.

On CentOS/RHEL, run the following two commands to disable imap, imaps, smtp-submission, smtps, pop3 and pop3s services.

sudo firewall-cmd --permanent --remove-service={smtp-submission,smtps,imap,imaps,pop3,pop3s}

sudo firewall-cmd --permanent --remove-port={587/tcp,465/tcp,143/tcp,993/tcp,110/tcp,995/tcp}

If you see a warning like Warning: NOT_ENABLED: smtps, you can ignore the warning. Reload firewalld for the changes to take effect.

sudo systemctl reload firewalld

Of course you need to keep port 25 open to receive emails from other SMTP servers.

Step 3: Protecting Admin Panel and Webmail

We can close port 80 and 443 to protect admin panel and webmail from hacking. However, that will forbid public access to all virtual hosts. Some folks might have virtual hosts in Apache/Nginx that need to open to the Internet. Instead of closing port 80 and 443 in the firewall, we can use the builtin access control feature in Apache/Nginx.

Nginx

Edit the virtual host file for webmail, such as

sudo nano /etc/nginx/conf.d/mail.your-domain.com.conf

Add the following lines in the server {...} context. This will allow only the IP address 12.34.56.78 to access the webmail, and deny all other IP addresses.

allow 12.34.56.78;
deny all;

webmail whitelist access nginx

If you have multiple VPN servers, you can add multiple IP addresses like so:

allow 12.34.56.78;
allow 12.34.56.79;
deny all;

Save and close the file. Then test Nginx configurations.

sudo nginx -t

If the test is successful, reload Nginx for the changes to take effect.

sudo systemctl reload nginx

Users not in the whitelist will see a 403 forbidden error.

secure email server nginx

Apache

Edit the virtual host file for webmail in the /etc/httpd/conf.d/ directory, such as

sudo nano /etc/httpd/conf.d/mail.your-domain.com-le-ssl.conf

Add the following lines between the <VirtualHost>...</VirtualHost> tags. This will allow only the IP address 12.34.56.78 to access the webmail, and deny all other IP addresses.

    <LocationMatch "^/">
       Require ip 12.34.56.78
    </LocationMatch>

apache access control webmail

If you have multiple VPN servers, you can add multiple IP addresses like so:

    <LocationMatch "^/">
       Require ip 12.34.56.78 12.34.56.79
    </LocationMatch>

Save and close the file. Then test Apache configurations.

sudo apachectl -t

If the syntax is Ok, reload Apache for the changes to take effect.

sudo systemctl reload httpd

Users not in the whitelist will see a 403 forbidden error.

Protecting Admin Panel and Webmail from hacking apache

Certbot TLS Certificate Renewal

If you enable whitelisting in Apache/Nginx virtual host, then you will also block Let’s Encrypt servers to access your web server, which is required for renewing Let’s Encrypt TLS certificate with HTTP-01 challenge. To solve this problem, we can disable whitelisting before certificate renewal and enable it again after the renewal.

Create a shell script in the /root/ directory.

sudo nano /root/certbot-renewal.sh

If you use Nginx, add the following lines to this file.

#! /bin/bash

# disable whitelisting in the Nginx virtual host
sed -i 's/deny all;/#deny all;/g' /etc/nginx/conf.d/mail.your-domain.com.conf
systemctl reload nginx

# renew TLS certificate
certbot renew --quiet

# enable whitelisting
sed -i 's/#deny all;/deny all;/g' /etc/nginx/conf.d/mail.your-domain.com.conf
systemctl reload nginx

If you use Apache, add the following lines to this file.

#! /bin/bash

# disable whitelisting in the Apache virtual host
sed -i 's/Require ip/#Require ip/g' /etc/httpd/conf.d/mail.your-domain.com-le-ssl.conf
systemctl reload apache2

# renew TLS certificate
certbot renew --quiet

# enable whitelisting
sed -i 's/#Require ip/Require ip/g' /etc/httpd/conf.d/mail.your-domain.com-le-ssl.conf
systemctl reload apache2

Save and close the file. Then add execute permission to this file.

sudo chmod +x /root/certbot-renewal.sh

Edit the root user’s crontab file.

sudo crontab -e

Add the following line at the end of the file, so the shell script will run once a day.

@daily bash /root/certbot-renewal.sh

Save and close the file.

Close SSH Port?

Since your VPN server’s IP address is whitelisted, you can also close SSH port in the firewall. However, doing so carries a risk. If your VPN server stops working, then you would lock yourself out. To protect SSH service from hacking, I recommend setting up public key authentication or two-factor authentication.

Wrapping Up

I hope this tutorial helped you secure your email server against hacking on CentOS/RHEL. As always, if you found this post useful, then subscribe to our free newsletter to get new tutorials. Take care 🙂

Rate this tutorial
[Total: 0 Average: 0]

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image.