Set Up Postfix Send-Only SMTP Server for Multiple Domains on Ubuntu 18.04, 16.04, 19.04

A reader asked me: “Hi LinuxBabe! I love your tutorials! I couldn’t find any good tutorial on the web about setting up Postfix as a send-only mail server using multiple domains. Do you know how to do it? Thx in advance!” In this article, I will show you how to do that on Ubuntu 18.04, 16.04, 19.04 server.

Use Case

You have a website/web application that needs to send transactional emails to users (such as password-reset email). Mostly likely, there’s no need for users to reply to these email, or if they reply, the reply emails will be sent to your dedicated mail server. In this case, you can set up a send-only SMTP server on the web server using Postfix, which is a popular SMTP server software.

Prerequisites

In order to send emails from your server, port 25 (outbound) must be open. Many ISPs and hosting companies such as DigitalOcean block port 25 to control spam. I recommend using Linode, because it doesn’t block port 25 (outbound). Once you have a Linode server, install Ubuntu on it and follow the instructions below.

Setting up Postfix send-only SMTP server for multiple domains isn’t difficult, actually. First, we need to configure it for one domain, then set it up for multiple domains.

Step 1: Set Hostname and PTR Record

By default, Postfix uses your server’s hostname to identify itself when communicating with other SMTP Servers. Some SMTP servers will reject your email if your hostname isn’t valid. You should set a full-qualified domain name (FQDN) like below.

sudo hostnamectl set-hostname www.linuxbabe.com

To check the hostname of your server, run

hostname -f

You need to log out and log back in to see hostname change at the command prompt. This hostname should have a DNS A record pointing to the IP address of your server.

Also, you need to set a PTR record (aka, pointer record), which maps an IP address to an FQDN. It’s the counterpart to the A record. Many SMTP server will reject your email if your server’s IP address doesn’t have PTR record.

Because you get IP address from your hosting provider or ISP, not from your domain registrar, so you must set PTR record for your IP in the control panel of your hosting provider, or ask your ISP. For example, in Linode, you can set PTR record by selecting one of your server, then clicking the Networking tab and clicking the Edit RDNS link. Although you can set PTR record to any hostname, for best practice, you should use the FQDN you just set.

To see if your PTR record is set properly, run the following command. Replace 12.34.56.78 with your own IP address.

host 12.34.56.78

Note that if your server uses IPv6 address, it’s also a good idea to add AAAA record for your FQDN and set PTR record for your IPv6 address.

Step 2: Install Postfix on Ubuntu

Run the following commands to install Postfix from the default Ubuntu repository.

sudo apt-get update

sudo apt-get install postfix -y

You will be asked to choose a mail server configuration type. Press the Tab key, then press Enter.

postfix send only smtp server

In the next screen, press Enter to select the default option: Internet Site.

postfix send only ubuntu

Next, enter your domain name for the system mail name, i.e. the domain name after @ symbol.

postfix send only multiple domains

Step 3: Disable Receiving Email in Postfix

By default, Postfix SMTP server listens on all active interfaces on the machine. Since the Postfix SMTP server is only used for sending transactional emails to users, we can make it listens on localhost only, so bad actors can’t send spam to it.

Edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Find the following line.

inet_interfaces = all

Change it to:

inet_interfaces = loopback-only

Save and close the file. Restart Postfix for the change to take effect.

sudo systemctl restart postfix

Step 4: Install and Configure OpenDKIM

DKIM stands for DomainKeys Identified Mail. You can install OpenDKIM on your server and use it to add signatures to emails sent from your domain, with your private key. Receiving SMTP servers verify the signature by using the corresponding public key, which is published by you in the DNS. Adding DKIM signature is a must if you want your emails get into recipient’s inbox.

First install OpenDKIM from the default Ubuntu repository.

sudo apt-get install opendkim opendkim-tools

Then add postfix user to opendkim group.

sudo adduser postfix opendkim

Edit OpenDKIM main configuration file.

sudo nano /etc/opendkim.conf

Find the following lines.

#Canonicalization     simple
#Mode                 sv
#SubDomains           no

Uncomment them and replace simple with relaxed/simple. Change the mode from sv to s, because there’s no inbound email to verify signature.

Canonicalization     relaxed/simple
Mode                 s
SubDomains           no

Add the following lines at the end of this file. (On Ubuntu 18.04, the UserID is already set to opendkim)

#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID             opendkim

# Map domains in From addresses to keys used to sign messages
KeyTable           refile:/etc/opendkim/key.table
SigningTable       refile:/etc/opendkim/signing.table

# A set of internal hosts whose mail should be signed
InternalHosts       /etc/opendkim/trusted.hosts

Save and close the file.

Create Signing Table, key Table and Trusted Hosts File

Create a directory structure for OpenDKIM.

sudo mkdir /etc/opendkim

sudo mkdir /etc/opendkim/keys

Change owner from root to opendkim and make sure only opendkim user can read and write to the keys directory.

sudo chown -R opendkim:opendkim /etc/opendkim

sudo chmod go-rw /etc/opendkim/keys

Create the signing table.

sudo nano /etc/opendkim/signing.table

Add the following line to the file. This means that if the From: header in an email contains example.com, then use the sendonly DKIM selector. You can change sendonly to your preferred DKIM selector name and it should be unique in your DNS.

*@example.com     sendonly._domainkey.example.com

Save and close the file. Then create the key table.

sudo nano /etc/opendkim/key.table

Add the following line. This means that for the sendonly DKIM selector, use the private key saved in /etc/opendkim/keys/example.com/sendonly.private to sign the email.

sendonly._domainkey.example.com    example.com:sendonly:/etc/opendkim/keys/example.com/sendonly.private

Save and close the file. Next, create the trusted hosts file.

sudo nano /etc/opendkim/trusted.hosts

Add the following lines to the newly created file.

127.0.0.1
localhost

*.example.com

The above means that messages coming from the above IP addresses and domains will be trusted and signed.

Generate Private/Public Keypair

We need to generate a private key to sign outgoing emails and a public key for receiving SMTP servers to verify the DKIM signature. Public key will be published in DNS.

Create a separate folder for the domain.

sudo mkdir /etc/opendkim/keys/example.com

Generate keys using opendkim-genkey tool.

sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s sendonly -v

The above command will create 2048 bits keys. -d (domain) specifies the domain. -D (directory) specifies the directory where the keys will be stored and we use sendonly as the selector (-s). Once the command is executed, the private key will be saved in sendonly.private and sendonly.txt will be the TXT record that contains public key.

Make opendkim as the owner of the private key.

sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/sendonly.private

Add Public Key in DNS Records

Display the public key

sudo cat /etc/opendkim/keys/example.com/sendonly.txt

The string after the p parameter is the public key. In your DNS manager, create a TXT record for the second domain. Enter sendonly._domainkey in the Name field. Copy everything in the parentheses and paste into the value field. Delete all double quotes. (You can paste it into a text editor first, delete all double quotes, the copy it to your DNS manager. Your DNS manager may require you to delete other invalid characters, such as carriage return.)

postfix send only DKIM

Once the DNS record is published, enter the following command on your Ubuntu server to test your key.

sudo opendkim-testkey -d example.com -s sendonly -vvv

If everything is OK, you will see

key OK

If you see key not secure message, don’t panic. This is because DNSSEC isn’t enabled on your domain name.

Step 5: Connect Postfix with OpenDKIM

Edit the OpenDKIM main configuration file.

sudo nano /etc/opendkim.conf

Find the following line:

Socket local:/var/run/opendkim/opendkim.sock

Replace it with the following line. (If you can’t find the above line, then add the following line.)

Socket local:/var/spool/postfix/opendkim/opendkim.sock

Create a directory to hold the OpenDKIM socket file and only allow opendkim user and postfix group to access it.

sudo mkdir /var/spool/postfix/opendkim

sudo chown opendkim:postfix /var/spool/postfix/opendkim

If you can find the following line in /etc/default/opendkim file.

SOCKET="local:/var/run/opendkim/opendkim.sock"

or

SOCKET=local:$RUNDIR/opendkim.sock

Change it to

SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"

After that, we need to edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following lines at the end of this file to connect Postfix with OpenDKIM.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Save and close the file. Restart OpenDKIM and Postfix.

sudo systemctl restart opendkim postfix

OpenDKIM won’t produce any message if it fails to restart. Run the following command to check its status. Make sure it’s running.

systemctl status opendkim

Step 6: Create SPF DNS Record

SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. In your DNS management interface, create a new TXT record like below. Use your own IPv4 address and IPv6 address of your server.

TXT  @   v=spf1 mx ip4:12.34.56.78 ip6:2600:3c01::f03c:93d8:f2c6:78ad ~all

Step 7: Set the From Address, From Name and Return-Path

You can set custom From address, From name and Return-Path in your website/web application. Let’s use WordPress as an example. You can add the following lines in your WordPress theme’s functions.php file to override the default From address, From name and return-path. Replace the red text as necessary.

// Function to change From email address
function wpb_sender_email( $original_email_address ) {
    return '[email protected]';
}

// Function to change sender name
function wpb_sender_name( $original_email_from ) {
    return 'LinuxBabe';
}

// Set return-path the same as From address
function fix_my_email_return_path( $phpmailer ) {
    $phpmailer->Sender = $phpmailer->From;
}

// Hooking up our functions to WordPress filters
add_filter( 'wp_mail_from', 'wpb_sender_email' );
add_filter( 'wp_mail_from_name', 'wpb_sender_name' );
add_action( 'phpmailer_init', 'fix_my_email_return_path' );

Save the file and you are done.

Step 8: Testing Sender Score

Now go to https://www.mail-tester.com. You will see a unique email address. Send an email from your website on the Postfix SMTP server to this address and then check your score. As you can see, I got a perfect score. In the test result, you should check if your PTR record, SPF and DKIM record is valid.

imporve-email-server-reputation-dkim

How to Configure Postfix Send-only SMTP Server For Multiple Domains

By default, Postfix allows you to use any domain name in the From header and return path address to send outgoing emails. If your server hosts multiple websites, you just need to create SPF DNS record for your other domains, which is very easy to do, and configure OpenDKIM for your other domains.

To configure OpenDKIM for other domains, you need to add the other domains in the signing table, key table and trusted hosts file.

Signing table:

*@example.com       sendonly._domainkey.example.com
*@example.net       sendonly._domainkey.example.net

Key table:

sendonly._domainkey.example.com     example.com:sendonly:/etc/opendkim/keys/example.com/sendonly.private
sendonly._domainkey.example.net     example.net:sendonly:/etc/opendkim/keys/example.net/sendonly.private

Trusted hosts:

127.0.0.1
localhost

*.example.com
*.example.net

Then generate Private/Public keypair by following the same steps as mentioned above for other domains and add the DKIM public key in DNS. Restart OpenDKIM and you are done. Don’t forget to test your sender score.

Conclusion

I hope this tutorial helped you set up a Postfix send-only SMTP server on Ubuntu for multiple domains. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 3 Average: 5]

7 Responses to “Set Up Postfix Send-Only SMTP Server for Multiple Domains on Ubuntu 18.04, 16.04, 19.04

  • Daniel Gutiérrez
    5 months ago

    Wow wow!! Thx LinuxBabe!!!! You’re the best in the world!! Thanks four your kindness, I will follow your excellent tutorial and let you know!

  • Very informative, I learn something new each time you post something!

    Also, the service https://www.mail-tester.com is something that I didn’t know about, very nice.

  • Loved the walkthrough, went perfectly for me. I just wanted to correct 1 item in your tutorial. In the section where you specify the SPF records, the formatting is incorrect. It should not be ipv4:12.34.56.78, it should be ip4:12.34.56.78. If you use the wrong one, the SPF record declares your server is not authorized to send from that address and it is -3 points in the mailtester site. Figured you and your readers would want to know. Again, excellent tutorial.

    • Thanks. Corrected this mistake.

    • Thank you for this Conner. My score went from -1/10 to 9/10 simply by making the edit you suggested.

      However, mail from my second domain was being sent unencrypted, causing Google to show a warning “This message wasn’t encrypted”.

      To fix that I had to edit my /etc/postfix/main.cf file by replacing
      smtpd_use_tls=yes with smtp_use_tls=yes.

      Now the messages are sent with TLS encryption and the from address is correctly showing [email protected]

      However, Google still shows that the message was mailed by first-domain.com.
      Any ideas hot to fix that if possible?

      • That’s because you are stilling using the first domain’s DKIM key to sign email for the second domain. Have you followed the “multiple domains” section at the end of this article?

  • BigDaddy
    3 weeks ago

    Sorry for noob question how can i export the backup files from iredmail? cp: -r not specified; omitting directory im getting this error.

    Best Regards Bro

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.
  • If my answer helped you, please consider supporting this site. Thanks :)