Setting Up and Configuring Postfix as a Mail Server on Ubuntu 22.04: A Detailed Guide

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

The Real Problem: A “Silent” Server in the Middle of the Night

Imagine one night, you’re sound asleep when your phone starts vibrating incessantly. You open your eyes to find your phone screen filled with alerts from the monitoring system.

It turns out the production server encountered a critical error, but ironically, not a single notification email was sent. The entire team was bewildered, no one knew what was happening. After resolving the incident, looking back at the logs, I wondered: how can the system automatically send alerts when an incident occurs without relying on external services, especially for sensitive systems that require immediate notification?

Why Can’t the Server Send Emails?

Typically, server applications need to send emails for various purposes: from registration notifications, order confirmations, password resets, to system error alerts – these are all extremely important notifications. However, a newly installed Ubuntu server doesn’t have this capability built-in. It lacks a Mail Transfer Agent (MTA) – software responsible for sending and receiving emails.

If you try to send emails directly from the server without proper SMTP (Simple Mail Transfer Protocol) configuration, your emails are likely to encounter the following issues:

  • Immediately rejected by the destination mail server.
  • Marked as spam and landed in the recipient’s Junk folder.
  • Or worse, never reaching their destination.

The underlying reasons are the lack of necessary DNS records (such as MX, SPF, DKIM) and SMTP authentication. Personally, I’ve witnessed many cases where internal emails were considered spam simply because the sending server lacked a clear identity, which caused a lot of trouble for users.

Solution: Use External Services or Self-Host?

When facing this issue, you have two main approaches:

1. Using External SMTP Services (SendGrid, Mailgun, AWS SES…)

This is the fastest and least troublesome method. You just need to register an account, obtain an API key, or configure an SMTP relay on your server to point to the service. Key advantages include reliable email delivery, high Inbox rates, and you don’t need to worry about complex mail server infrastructure. However, it also has disadvantages:

  • Incurs costs (though there are often initial free tiers, for example, SendGrid allows sending 100 emails/day for free).
  • Reliance on a third-party for email delivery.
  • Not suitable if you want complete control over email data or have special security requirements (like banking, healthcare).

2. Self-Installing and Configuring a Mail Server

This is the solution we will focus on today. Self-hosting a mail server gives you complete control over the system, eliminates external dependencies, and avoids monthly service fees. However, it requires deeper knowledge of configuration, spam management, security, and DNS. For system notifications or internal applications, self-hosting a simple SMTP server is an excellent choice, being both efficient and cost-effective.

Optimal Choice: Setting Up and Configuring Postfix as a Mail Server on Ubuntu 22.04

After numerous trials with different MTAs, I found Postfix to be the optimal choice for a simple yet powerful mail server on Ubuntu. It’s lightweight, easy to configure, and extremely flexible. In the company’s staging environment (running Ubuntu 22.04), I thoroughly tested this configuration before deploying it to production, and it has been running stably for the past 6 months.

Step 1: Update the System

Always start by updating software packages to ensure you have the latest versions and important security patches:

sudo apt update && sudo apt upgrade -y

Step 2: Install Postfix

Installing Postfix is very straightforward. The system will ask you for some basic configuration information. During the installation process, you will be prompted to choose the configuration type. I usually select “Internet Site” for the server to send emails directly to the internet.

sudo apt install postfix -y

During installation (or if you need to reconfigure), the screen will display the following options:

  • General type of mail configuration: Select Internet Site.
  • System mail name: Enter your fully qualified domain name (e.g., yourdomain.com). This is the name Postfix will use for identification when sending emails.
  • Root and postmaster mail recipient: Leave blank or enter your local user account (e.g., youruser).
  • Other destinations to accept mail for: Defaults to your domain. You can add subdomains if desired.
  • Local networks: Defaults to 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128. Usually no changes are needed.
  • Mailbox size limit: Set to 0 if you don’t want to limit it.
  • Local address extension character: + (default).
  • Internet protocols to use: all (default).

If you want to reconfigure later, run the command:

sudo dpkg-reconfigure postfix

Step 3: Basic Postfix Configuration

The main Postfix configuration file is /etc/postfix/main.cf. We will edit a few important parameters. Remember to back up this file before editing to easily revert if errors occur:

sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
sudo nano /etc/postfix/main.cf

Below are some configuration lines I usually check and modify. You need to find and uncomment (remove the # at the beginning of the line) or add new ones if they don’t exist:

# The main domain that the server will use
myhostname = mail.yourdomain.com
mydomain = yourdomain.com

# List of domains for which the server will accept emails
# Usually includes myhostname, mydomain, and localhost
mydestination = $myhostname, $mydomain, localhost.$mydomain, localhost

# IP address or network that Postfix will listen on
# Use 0.0.0.0 to listen on all interfaces, or specify a particular one
inet_interfaces = all
inet_protocols = all

# Specifies internal networks allowed to relay emails without authentication
# Be careful when configuring, do not open too broadly, for example, limit only to your internal IP range like 192.168.1.0/24
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.1.0/24

# Directory containing user mailboxes
home_mailbox = Maildir/

# Format for outgoing email display
# This helps emails have clearer From headers, avoiding being marked as spam
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
sender_canonical_maps = hash:/etc/postfix/canonical

Note: Replace yourdomain.com with your actual domain name, and mail.yourdomain.com with the mail server’s hostname.

Next, create the /etc/postfix/canonical file to map local senders to a valid email address. This is very useful when processes on the server (like cron jobs) send emails from root@localhost or www-data@localhost, and you want them to appear as [email protected]:

sudo nano /etc/postfix/canonical

Add the following content (replace [email protected] with your desired email address):

root             [email protected]
www-data         [email protected]
# Add other users if needed (e.g., [email protected])

After editing, create the database for canonical maps using the command:

sudo postmap /etc/postfix/canonical

Step 4: Configure DNS for the Domain

This is a crucial step to prevent your emails from being marked as spam. You need to access your domain provider’s DNS management page (yourdomain.com) and add the following records:

  • A Record: Create an A record for mail.yourdomain.com pointing to your Ubuntu server’s public IP address. Example:
    Type: A
    Name: mail
    Value: YOUR_SERVER_PUBLIC_IP
  • MX Record: The Mail Exchanger (MX) record specifies which mail server is responsible for receiving emails for your domain. For example, if you have multiple MX records, prioritize this one:
    Type: MX
    Name: @ (or yourdomain.com)
    Value: mail.yourdomain.com
    Priority: 10 (smaller number, higher priority)
  • SPF Record (Sender Policy Framework): Helps recipients verify that the email truly originated from an authorized server, reducing the risk of being marked as spam. Example:
    Type: TXT
    Name: @ (or yourdomain.com)
    Value: "v=spf1 a mx ip4:YOUR_SERVER_PUBLIC_IP ~all"

    Explanation: a allows servers in the A record to send emails; mx allows mail servers specified in the MX record to send; ip4:YOUR_SERVER_PUBLIC_IP allows a specific IP address to send; ~all indicates that emails sent by other servers will be marked as “softfail” (~all should be used instead of -all initially to avoid emails being immediately rejected if there’s a configuration error).

  • DKIM Record (DomainKeys Identified Mail): Although more complex to configure with basic Postfix, DKIM helps authenticate emails with a digital signature, increasing trustworthiness and preventing spoofing. I will not delve into DKIM in this article to keep the guide simple for beginners. However, you should learn more about it after mastering the basic steps to enhance your email delivery to the Inbox.

Note: Replace YOUR_SERVER_PUBLIC_IP with your server’s exact public IP address.

Step 5: Restart Postfix and Check Status

After modifying the configuration, always restart Postfix for the changes to take effect. You can do this with the command:

sudo systemctl restart postfix
sudo systemctl status postfix

Ensure that the Postfix service is running stably (status showing active (running)).

Step 6: Test Email Sending

Now it’s time to check if the server can send emails. I usually use the mail or sendmail command for a quick test.

Using the mail command (requires mailutils installation)

sudo apt install mailutils -y

Send a test email:

echo "This is a test email from your server." | mail -s "Test Postfix Server" [email protected]

Replace [email protected] with your personal email address. Check your inbox (and spam folder!) to see if the email arrives. If it doesn’t appear after a few minutes, recheck your configuration or logs.

Using the sendmail command (usually provided by Postfix)

echo "Subject: Test Postfix via sendmail
This is another test email from the server using sendmail." | sendmail [email protected]

To better understand how the email sending process works, check the Postfix logs:

tail -f /var/log/mail.log

You will see log lines indicating that Postfix received the email, connected to the destination mail server, and successfully sent it (or reported an error if there was an issue).

Step 7: Configure Firewall (UFW)

If you are using UFW, ensure that the necessary ports for SMTP (port 25) are open. Although I recommend using port 587 (submission) with authentication and encryption for sending emails from clients, port 25 still needs to be open for your server to communicate with other mail servers. To open the port, use the command:

sudo ufw allow Postfix
# Or more specifically, open only port 25 for TCP:
sudo ufw allow 25/tcp
sudo ufw reload

Conclusion

Installing and configuring Postfix as a mail server on Ubuntu 22.04 can be a bit challenging for newcomers, especially the DNS configuration part. But once set up, you will have a reliable email sending system for internal tasks or system notifications. Personally, I find that manually configuring a simple mail server not only solves a practical problem but also brings a sense of accomplishment in controlling everything within the system.

Remember, this is a basic configuration. For a full-featured mail server (receiving emails for multiple users, robust anti-spam, SSL/TLS authentication), you will need to delve deeper into Dovecot (for IMAP/POP3), SpamAssassin, Amavisd-new, etc. But for the initial goal of sending notification emails, simple Postfix is sufficient and extremely effective.

Share: