1. Introduction

Setting up a mail server on Linux can be difficult at first. However, with the proper instructions, it becomes a straightforward process. Ultimately, by configuring a Domain Name Server (DNS) server and installing a mail server, we can establish a reliable platform for email communication.

In this tutorial, we’ll focus on a simple method to install a mail server on Linux. In particular, we’ll start by configuring a DNS server. Further, we’ll install and set up Postfix as the mail server. Finally, we’ll test the functionalities of the mail server. Notably, these commands were tested on Debian Kali Linux 2024.1. However, the same process applies to other Linux distributions as well.

2. Configuring DNS Server

Configuring the DNS server lays the foundation for smooth email communication. Additionally, ensuring that the system is up-to-date is a good practice before proceeding with the installation.

2.1. Updating System Packages

First, let’s update the system to ensure we have the latest packages and dependencies:

$ sudo apt install update

The update subcommand fetches the latest package information from all configured sources.

2.2. Installing BIND

Once the update is complete, we install BIND, a widely used DNS server software.

Let’s install bind with the apt command:

$ sudo apt install bind9

This command installs the BIND DNS server software in the Linux system, enabling effective configuration and management of DNS services.

2.3. Configure /var/cache/db.test

The next step is to configure the DNS server. To start, we determine the IP address of the Linux system. Furthermore, this is used as the DNS server address.

However, before proceeding, we ensure that the necessary tools are installed.

On some Linux distros, the ifconfig command may require the installation of the net-tools package. If that is the case, we install net-tools using the apt command:

$ sudo apt install net-tools

Once installed, let’s use the ifconfig command to find the IP address on the Linux system:

$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:35:6d:2c:1e  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.128  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fe80::acc3:1099:5156:7b6a  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:16:48:81  txqueuelen 1000  (Ethernet)
        RX packets 181502  bytes 214098613 (204.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 53386  bytes 4640185 (4.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 3847  bytes 403111 (393.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3847  bytes 403111 (393.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

In the result, the IP address is 192.168.11.128 which is found in the eth0 section.

Next, we create a new file named db.test in the /var/cache/bind directory. Let’s use the nano command to create and edit the file:

$ sudo nano /var/cache/bind/db.test

Then, we add several lines to the file:

$ORIGIN test.com.
$TTL 1D
@       IN SOA     ns1.test.com. root.test.com. (
                1       ; serial
                1D      ; refresh
                2H      ; retry
                2W      ; expire
                5H )    ; minimum

@       IN        NS ns1.test.com.
ns1     IN        A 192.168.11.128
mail    IN        A 192.168.11.128
@       IN        MX 5 mail

In this example, we’re using test.com as the domain name.

Furthermore, let’s understand the content of the file:

  • $ORIGIN test.com.: sets the origin for the zone to test.com
  • $TTL 1D: sets the Time To Live (TTL) for records to 1 day
  • @ IN SOA ns1.root …: Start of Authority (SOA) record, specifying the primary name server (ns1)
  • @ IN NS ns1: declares ns1 as the authoritative nameserver for the domain.
  • ns1 IN A 192.168.11.128: specifies the IP address of the nameserver (ns1)
  • mail IN A 192.168.11.128: assigns the IP address 192.168.11.128 to the hostname mail
  • @ IN MX 5 mail: sets the mail exchange (MX) record, indicating that mail should be delivered to the hostname mail with a preference value of 5

Additionally, the configuration file specifies the DNS records for the domain test.com. In particular, it defines the Start of Authority (SOA), name server (NS), mail exchanger (MX), and address (A) records for the domain.

2.4. Adding New Zone to BIND Configuration

Before enabling the newly created zone, it’s important to verify the configuration of the file. Furthermore, we use the named-checkzone command for verification:

$ sudo named-checkzone test.com. /var/cache/bind/db.test
[sudo] password for kali: 
zone test.com/IN: loaded serial 1
OK

In the result, it confirms the zone configuration is correct and ready to be added to the BIND zone configuration file.

Next, we add the new zone to the BIND zone configuration file. Further, we achieve this by editing the named-conf.default-zones file:

$ sudo nano /etc/bind/named.conf.default-zones

Inside the editor, we include the following lines at the end of the file:

zone "test.com." {
       type master;
       file "db.test";
};

This instructs BIND to treat test.com as a master zone and to load its configuration from the db.test file located in the /var/cache/bind directory.

2.5. Configure /etc/bind/named.conf.options

Now, in the file /etc/bind/named.conf.options, we ensure the DNS forwarding is configured properly. This involves uncommenting the forwarders line and adding Google DNS (8.8.8.8) as a forwarder.

$ sudo nano /etc/bind/named.conf.options

Afterward, within the editor, we locate the forwarders section. Additionally, we uncomment the line that begins with forwarders and add Google DNS (8.8.8.8) as a forwarder:

forwarders {
    8.8.8.8;
};

This configuration tells BIND to forward DNS queries to the specified IP address (8.8.8.8), which is Google’s public DNS server.

2.6. Restart BIND

With the DNS configuration updated, we restart the BIND service to apply the changes:

$ sudo systemctl restart bind9

The command restarts the BIND service, ensuring that the changes we made to the configuration take effect.

Now, the DNS server is properly configured with forwarding enabled, allowing it to efficiently resolve domain names by forwarding queries to Google’s DNS server.

3. Install and Setup Mail Server

Now that we’ve configured the DNS server, the next step is to install and set up Postfix as the mail server.

3.1. Install Postfix

Postfix is a popular mail transfer agent (MTA) used for routing and delivering email. Furthermore, it’s lightweight, fast, and highly configurable.

Let’s install Postfix in the Linux system:

$ sudo apt install postfix

The command installs the Postfix MTA.

3.2. Setup Postfix

Once Postfix is installed, it’s crucial to configure it properly to meet the specific requirements of our mail server. Further, let’s ensure Postfix knows which domain it’s responsible for delivering mail to.

To do this, we edit the main configuration file of Postfix:

$ sudo nano /etc/postfix/main.cf

Inside the file, we locate mydestination parameter and add test.com to the list of domains. Additionally, this informs Postfix that it should consider itself responsible for handling email destined for addresses within the test.com domain.

Finally, we restart the Postfix service to apply the new configuration:

$ sudo systemctl restart postfix

We have now configured Postfix to handle email traffic for the test.com domain.

3.3. Add User to Mail Group

To ensure that users can send and receive emails effectively, let’s add them to the mail group. Further, this grants them the necessary permissions to interact with the mail server.

Let’s add the current user to the mail group:

$ sudo usermod -aG mail $(whoami)

Next, we create a new user named jimmy and add the user to the mail group. Additionally, let’s create a password for the user using the passwd command:

$ sudo useradd -m -G mail -s /bin/bash/ jimmy
$ sudo passwd jimmy

This ensures the appropriate permissions to send and receive emails via the created mail server.

4. Test Mail Server

Now that we’ve set up the mail server, let’s ensure it’s functioning correctly by sending and receiving an email directly from the terminal.

To perform this test, first, we install the mailutils package, which provides a set of utilities for managing mail:

$ sudo apt install mailutils

Further, we proceed to send an email to the created user on the system. we send an email to the user named jimmy:

$ mail -s "Test Email" [email protected] 

Cc: 
This is a test mail

In this command, we use -s to specify the subject of the mail as Test Email. We are then prompted to enter the optional Cc field. We press Enter and type the body of the mail as This is a test mail. Finally, we press Enter and then Ctrl-D to send the mail.

Now, let’s switch to the jimmy user to verify that the email was successfully received:

$ su - jimmy
$ mail
 Inbox
  1 new message
1 unread message

The output of the mail command shows our test email was successful.

However, deploying a production-grade mail server involves additional considerations such as security, scalability, and maintenance. It’s essential to assess the potential limitations and requirements of a solution before deploying it in a real-world scenario.

5. Conclusion

In this article, we explored the process of setting up a mail server on Linux, starting from configuring the DNS server to installing and configuring Postfix. Further, we ensured smooth email communication by establishing a solid foundation with BIND for DNS resolution and Postfix for mail routing and delivery. Finally, we tested the functionalities of the mail server through sending and receiving emails directly from the terminal.