Set Up Postfix Send-Only SMTP Server on Ubuntu 22.04/20.04/18.04

In this article, I will show you how to set up Postfix as a send-only SMTP server on Ubuntu 22.04/20.04/18.04. I will first show you how to do it for a single domain, then you can apply the steps for multiple domains if you need to.

Use Case

You have a website/web application that needs to send transactional emails to users (such as password-reset emails). Most likely, there’s no need for users to reply to these emails, 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 Kamatera VPS, which features:

  • 30 days free trial.
  • Starts at $4/month (1GB RAM)
  • High-performance KVM-based VPS
  • 9 data centers around the world, including the United States, Canada, UK, Germany, The Netherlands, Hong Kong, and Isreal.

Follow the tutorial linked below to create your Linux VPS server at Kamatera.

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: 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 2: Configure Postfix

Setting the Postfix hostname

By default, Postfix SMTP server uses the OS’s hostname to identify itself when communicating with other SMTP server. However, the OS hostname might change, and some SMTP servers will reject your email if your hostname isn’t valid. So it’s a good practice to set the hostname directly in Postfix configuration file with the following command.

sudo postconf -e "myhostname = sendonly.yourdomain.com"

This hostname should have a DNS A record pointing to the IP address of your server.

Setting $mydomain Parameter

The $mydomain parameter specifies the local internet domain name. The default is to use $myhostname minus the first component. You can display the current value of $mydomain with:

postconf mydomain

It should be your apex domain name, like

linuxbabe.com

If it’s not displaying your apex domain name, then set the $mydomain parameter with:

sudo postconf -e "mydomain = yourdomain.com"

Setting $myorigin Parameter

The $myorigin parameter specifies the default domain name that is appended to sender and recipient addresses that have no @domain part. The default is to use the value of in the /etc/mailname file, as can be seen with:

postconf myorigin

Output:

myorigin = /etc/mailname

Then you can display the value in the /etc/mailname file.

cat /etc/mailname

Its value should be yourdomain.com without any subdomain.

echo "yourdomain.com" | sudo tee /etc/mailname

Restarting Postfix

Finally, we need to restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Step 3: Set  PTR Record

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, if you use Kamatera VPS, you can set PTR record by opening a support ticket. Although you can set PTR record to any hostname, for best practice, you should use the Postfix hostname in step 2.

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 Postfix hostname and set PTR record for your IPv6 address.

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 two lines 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. The second line tells that your sub-domains will be signed by the private key as well.

*@example.com     sendonly._domainkey.example.com
*@*.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

Postfix can talk to OpenDKIM via a Unix socket file. The default socket file used by OpenDKIM is /var/run/opendkim/opendkim.sock, as shown in /etc/opendkim.conf file. But the postfix SMTP daemon shipped with Ubuntu runs in a chroot jail, which means the SMTP daemon resolves all filenames relative to the Postfix queue directory (/var/spool/postfix). So we need to change the socket file.

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. (Be careful about the functions.php file. Do not add an empty line after ?> at the end of this file, or your WordPress XML sitemap can be corrupted.)

Step 8: Enable TLS Encryption for Outgoing Emails

By default, Postfix doesn’t use TLS encryption when sending outgoing emails. To enable TLS encryption, open the /etc/postfix/main.cf file and add the following two lines at the end of this file.

smtp_tls_security_level = may
smtp_tls_loglevel = 1

The first line enables TLS encryption for the Postfix SMTP client. The second line will log the TLS connection in /var/log/mail.log file, so you can check if TLS encryption is working. Save and close the file. Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Since Postfix doesn’t receive incoming emails, there’s no need to configure a valid TLS certificate for the Postfix SMTP daemon.

Some SMTP servers require you to use TLS. If not, they will reject your emails and you will see the following error message in the mail log.

Must issue a STARTTLS command first

Step 9: 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

You can also open the /var/log/mail.log file to check if TLS encryption is used. For example, the following line shows the connection to mail-tester.com is encrypted.

Anonymous TLS connection established to mail-tester.com[94.23.206.89]:25: TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)

Email is Rejected by Microsoft Mailbox?

Microsoft uses an internal blacklist that blocks many legitimate IP addresses. If your emails are rejected by Outlook or Hotmail, you need to follow the tutorial linked below to bypass Microsoft Outlook blacklist.

What if Your Emails Are Still Being Marked as Spam?

I have more tips on email deliverability for you in this article: How to stop your emails being marked as spam. Although it will take some time and effort, your emails will eventually be placed in the inbox after applying these tips.

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 like below.

Signing table (/etc/opendkim/signing.table)

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

Key table (/etc/opendkim/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 (/etc/opendkim/trusted.hosts)

127.0.0.1
localhost

*.example.com
*.example.net

Then generate the DKIM 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.

Sending Emails From Another Server

There are two ways to allow other servers to send emails through your send-only Postfix SMTP server.

  • Use port 25 without SMTP authentication: This method requires the other server doesn’t block port 25 (outbound).
  • Use port 587 with SMTP authentication: If the other server blocks port 25 (outbound), you can use port 587.

Port 25 without SMTP Authentication

Run the following command to make Postfix listen on 0.0.0.0, so other servers can connect to the send-only Postfix SMTP server.

sudo postconf "inet_interfaces = all"

Then you need to add the IP address of the other server to the Postfix mynetworks parameter. Replace 12.34.56.78 with the real IP address.

sudo postconf "$(postconf mynetworks) 12.34.56.78"

Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Run the following commands to open port 25 (inbound) for the other server.

sudo ufw insert 1 allow in from 12.34.56.78 to any port 25 proto tcp

Now you can configure SMTP clients to use mta1.yourdomain.com and port 25 to send emails. You don’t need to specify username/password in the SMTP client.

Port 587 with SMTP Authentication

Open port 587 and 80 in firewall.

sudo ufw insert 1 allow in from 12.34.56.78 to any port 25 proto tcp
sudo ufw allow 80/tcp

Run the following command to make Postfix listen on 0.0.0.0, so other servers can connect to the send-only Postfix SMTP server.

sudo postconf "inet_interfaces = all"

Then you need to enable the submission service of Postfix so that the email client can submit emails to Postfix SMTP server. Edit the master.cf file.

sudo nano /etc/postfix/master.cf

In submission section, uncomment or add the following lines. Please allow at least one whitespace (tab or spacebar) before -o.  In postfix configurations, a preceding whitespace character means that this line is continuation of the previous line. (By default the submission section is commented out. You can copy the following lines and paste them into the file, so you don’t have to manually uncomment or add new text.)

submission     inet     n    -    y    -    -    smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_tls_wrappermode=no
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth

The above configuration enables the submission daemon of Postfix and requires TLS encryption. Plain text authentication will be rejected. The submission daemon listens on TCP port 587. STARTTLS is used to encrypt communications between SMTP client and the submission daemon.

Save and close the file. To enable SMTP authentication, we need to install Dovecot.

sudo apt install dovecot-core

Edit the authentication config file.

sudo nano /etc/dovecot/conf.d/10-auth.conf

Uncomment the following line.

disable_plaintext_auth = yes

It will disable plaintext authentication when there’s no SSL/TLS encryption. And if you want to use full email address ([email protected]) to login, add the following line in the file.

auth_username_format = %Ln

Otherwise, you are able to login with username only (without @your-domain.com). Next, find the following line.

auth_mechanisms = plain

This line only enables the PLAIN authentication mechanism. LOGIN is another authentication mechanism you probably want to add to support older email clients.

auth_mechanisms = plain login

Save and close the file. Then edit the following file.

sudo nano /etc/dovecot/conf.d/10-master.conf

Change service auth section to the following so that Postfix can find the Dovecot authentication server.

service auth {
    unix_listener /var/spool/postfix/private/auth {
      mode = 0660
      user = postfix
      group = postfix
    }
}

postfix smtp auth ubuntu

Save and close the file. Restart Dovecot for the changes to take effect.

sudo systemctl restart dovecot

Next, we need to obtain a valid TLS certificate. We can easily obtain a free TLS certificate from Let’s Encrypt. Issue the following commands to install Let’s Encrypt client (certbot) on Ubuntu.

sudo apt install certbot

Then use the standalone plugin to obtain TLS certificate (assuming there’s no web server running on the Postfix SMTP server).

sudo certbot certonly --standalone --agree-tos --email [email protected] -d sendonly.yourdomain.com

After a while, you should see the following lines which means the certificate is successfully obtained. You can also see the directory under which your cert is stored.

Next, we need to run the following two commands to specify the location of TLS certificate and private key in Postfix configuration file. Your Let’s Encrypt certificate and private key are stored under /etc/letsencrypt/live/sendonly.your-domain.com/ directory.

sudo postconf "smtpd_tls_cert_file = /etc/letsencrypt/live/sendonly.your-domain.com/fullchain.pem"

sudo postconf "smtpd_tls_key_file = /etc/letsencrypt/live/sendonly.your-domain.com/privkey.pem"

Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Now you can configure SMTP clients to use sendonly.yourdomain.com and port 587 to send emails. Use TLS encryption type and plain as authentication mode. You need to create email account on the SMTP server. That’s very simple. Use the adduser command to add a user.

sudo adduser user1 --no-create-home

Then set a password for this user.

sudo passwd user1

The email address will be [email protected].

Troubleshooting

Email not Signed by DKIM

If your message is not signed and DKIM check failed, you may want to check postfix log (/var/log/mail.log) to see what’s wrong in your configuration. If you see the following message in the mail log,

warning: connect to Milter service local:opendkim/opendkim.sock: No such file or directory

you may want to check if the opendkim systemd service is actually running.

systemctl status opendkim

If opendkim is running and you still see the above error, you might need to change smtpd_milters = local:opendkim/opendkim.sock to smtpd_milters = local:/opendkim/opendkim.sock in /etc/postfix/main.cf file.

Must Issue a STARTTLS Command First

If you see the following error in the mail log (/var/log/mail.log), it’s probably because the TLS certificate is not specified correctly in /etc/postfix/main.cf file.

Must issue a STARTTLS command first (in reply to MAIL FROM command))

fatal: no SASL authentication mechanisms

If you see the following error in the mail log (/var/log/mail.log), it’s probably because you forgot to restart dovecot (sudo systemctl restart dovecot).

warning: SASL: Connect to private/auth failed: No such file or directory
fatal: no SASL authentication mechanisms

Also, check if Dovecot is running.

sudo systemctl status dovecot

Sending Bulk or Mass Emails

Can you use this SMTP server to send bulk or mass emails?

Yes, but you should send bulk emails to legitimate subscribers only, that is to say, the recipients should have signed up for your mailing list. You should never send spam (unsolicited bulk email), or your SMTP server will surely be blacklisted. Before sending bulk emails, I highly recommended following the advice in this article: How to Stop Your Emails Being Marked as Spam.

Disable Receiving Email in Postfix

By default, the 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, you can block inbound connection to TCP port 25, so bad actors can’t send spam to it. Since we added a whitelist for port 25, legitimate users won’t be affected.

Removing Sensitive Information from Email Headers

By default, Postfix SMTP server will add a Received: email header, recording the IP address of the client, which can leak the IP address of your website (If it’s behind CDN). You can tell Postfix to ignore it. Create a header check file.

sudo nano /etc/postfix/smtp_header_checks

Put the following lines into the file.

/^Received:/            IGNORE

Save and close the file. Then edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line at the end of the file.

smtp_header_checks = regexp:/etc/postfix/smtp_header_checks

Save and close the file. Then run the following command to rebuild hash table.

sudo postmap /etc/postfix/smtp_header_checks

Reload Postfix for the change to take effect.

sudo systemctl reload postfix

Now Postfix won’t include that sensitive information in email headers.

Auto-Renew TLS Certificate

You can create Cron job to automatically renew TLS certificate. Simply open root user’s crontab file.

sudo crontab -e

Then add the following line.

@daily certbot renew --quiet

Save and close the file.

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: 12 Average: 4.8]

58 Responses to “Set Up Postfix Send-Only SMTP Server on Ubuntu 22.04/20.04/18.04

  • Daniel Gutiérrez
    5 years 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!

  • Michael
    5 years ago

    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.

    • Xiao Guo An (Admin)
      5 years ago

      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?

      • Xiao Guo An (Admin)
        5 years ago

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

  • Will most of this guide work for centos8 ?

  • Derrick
    4 years ago

    OMG! Thank you! However, I’m having trouble.

    I last ran a postfix install about 8 years ago and I’ve forgotten most of it.

    First, is I want to both send and receive mail. So, I think that’s easy enough, just leave inet_interfaces = all.

    Second, I named the keys and table entries as “sendonly._domainkey.myDomain.com” but I assume I could just name it “myDomain._domainkey”

    Regardless of those two issues, when I tested the key, “opendkim-testkey -d myDomain.com -s sendonly -vvv” the response is “record not found.”

    Any ideas?

    • Xiao Guoan (Admin)
      4 years ago

      This article is for a send-only SMTP server. If you want to set up a mail server for both sending and receiving, you can follow my mail server tutorial series.

      Maybe it will take some time for the DNS record to propagate? Can you tell me your domain name?

  • This worked great for us, we got a 10/10 score! Awesome and well done!

  • Roberto
    4 years ago

    Thank you so much for this wonderful guide!
    I followed step by step all the instructions to configure a send-only SMTP server .. but i have this problem:

    dkim=neutral (invalid public key) [email protected] header.s=sendonly header.b="mH+/+dxE";
    

    Any ideas?

    • Xiao Guoan (Admin)
      4 years ago

      Your domain name doesn’t have DKIM record, or it’s not propagated to the Internet.

      • Roberto
        4 years ago

        Thank you Xiao for you reply! 🙂
        If i test with “sudo opendkim-testkey -d aikidonomusubi.it -s sendonly -vvv”

        using default configfile /etc/opendkim.conf
        checking key 'sendonly._domainkey.aikidonomusubi.it'
        key not secure
        key OK
        

        … also using mxtoolbox the TXT record with “sendonly._domainkey.aikidonomusubi.it” seems ok.

        Thank you for your kindness.

    • Xiao Guoan (Admin)
      4 years ago

      I can only see SPF record on your domain name. No DKIM record is found.

      dig TXT aikidonomusubi.it @8.8.8.8 +short

      Output:

      "v=spf1 a mx ip4:92.222.216.116 include:eu.mailgun.org -all"
    • Xiao Guoan (Admin)
      4 years ago

      You can check DNS record propagation using this DNS propagation checker tool.

      • Roberto
        4 years ago

        Xiao….
        i found the problem… my provider DNS does not support the 2048 key ….. I created 1024 key and now it work! :/
        Thank you so much.
        I wish you good health and all the best! 🙂

  • How can I send test mail with command line?

    • I complete installation and configuration without test email. After I try on my site and I receive e-mail only gmail in spam folder. However, no emails have arrived in Outlook, Hotmail, or another domain.

    • Xiao Guoan (Admin)
      4 years ago

      Check the mail log file (/var/log/mail.log) to troubleshoot delivery problems.

    • Xiao Guoan (Admin)
      4 years ago
      • Now I resolve e-mail arrive problem but, still gmail and microsoft (hotmail, outlook etc.) going to spam folder. Specific domain and icloud no have problem.

      • When I run the command at the end of step 4

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

        it returns that : checking key sendonly._domainkey.example.com
        sendonly._domainkey.example.com record not found.

        Should I replace example.com with mydomain everywhere in the opendkin configuration, or just in the above testkey parameter I have to give my domain after -d

        Actually I wrote example.com instead of my domain as it is , trusting you bcoz you named ‘your-domain’ whenever we have to give our domain otherwise example.com

        P.s anyBody from the community know the answer pls suggest, I am running out of time. It’s a bit urgent

    • Xiao Guoan (Admin)
      4 years ago

      Please read the article linked below:
      How to Stop Your Emails Being Marked as Spam

  • Uddin Nasir
    4 years ago

    The article is the best article I have ever read about send only mail server on postfix with SPF DKIM ,
    I have done almost and my spam score 8/10 now. could you please help me how to assign SPF for other domain.
    Thank you in advance from Vietnam !!

  • Rahul Sharma
    4 years ago

    Thx for tutorial, but i have questions .

    1. How to install TLS Certificate in Postfix using let’s encrypt standalone key.?
    Like in your iredmail setup tutorial

    2. How to install & setup fail2ban in smtp server.?

    • Xiao Guoan (Admin)
      4 years ago

      There’s no need to install Let’s Encrypt TLS certificate on a send-only SMTP server.

      There’s no need to set up fail2ban for a send-only SMTP server.

  • Rahul Sharma
    4 years ago

    How to use postfix smtp in gmail ” Send mail as “.?

    • Xiao Guoan (Admin)
      4 years ago

      I don’t quite understand what you mean.

  • Hello,

    Any reason why I would be getting this error, after following steps for OpenDKIM setup?

    opendkim.service: PID file /var/run/opendkim/opendkim.pid not readable (yet?)

    Thanks
    Jay

  • The guide provided is quite detailed! But after Following your guide up until the point of checking the keys: sudo opendkim-testkey. Kept getting “No key”. DNS zone file record is perfect cos I checked to certain that key was added accurately in the zone file.

  • i did exactly what you say, all the dns records works with spf and dmarc, but detected like spam when i dont use realy. When i use realy works, without relay spam. In mail test the result with realy and without is the same.

    The IP from the server never used before in records and internet list.

    The finding in spam assasin mail-tester is

    -1.985 PYZOR_CHECK Similar message reported on Pyzor (http://pyzor.org)
    https://pyzor.readthedocs.io/en/latest/
    Please test a real content, test Newsletters will always be flagged by Pyzor
    Adjust your message or request whitelisting (http://public.pyzor.org/whitelist/)

    -0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid
    This rule is automatically applied if your email contains a DKIM signature but other positive rules will also be added if your DKIM signature is valid. See immediately below.

    but in the another section spf, dkim, dmard is ok

  • Hello everyone,
    I have a small problem I would like to know after following all this process it is possible to use this smtp server with an application like
    Atomic Mail Sender? and what are the parameters entered in the smtp part.
    thank you for the job done.

  • cat dev/random
    4 years ago

    I came here to ask exactly this…

    (Well, RHEL 8. I’m running RHEL 8, exactly the same thing.)

  • Hi there! What a great tutorial!!!
    I’ve added 2 domains to my postfix and followed the scripts to generate the second DKIM, is there anyway I can map a specific user to always send from domain2.net ?

    domain1.com
    domain2.net

    All my postfix users end up sending [email protected]

    • I think you can set same priority in your MX records and load balance the email sending, assigning a specific user to a server I would do it through software on app side but maybe there’s a configuration solution for postfix.

      Simone

  • aharown
    4 years ago

    Everything seemed to work great until the final test. Mail-tester.com fails and the mail error log shows “signing table references unknown key ‘sendonly._domainkey.www.myhost.com’

    I’ve gone over signing table and key table and can’t see any errors… but I’m not 100% clear on the logic of the variables etc., so I could be looking right at it. But it seems to match the tutorial.

    • aharown
      4 years ago

      OK, got past that one. Was missing the underscore before domainkey in the key table entry.
      But mail test says my test email was “not signed with DKIM.” So any tips on why that might be happening would be appreciated.

      • aharown
        4 years ago

        Solved. The “not signed with DKIM” was leftover from earlier attempt when key table had a typo. Retest passed.

        Thanks for the extremely helpful tutorial!

  • Hi dear xiao

    Thank you so much for these tutorials…
    These are the best…
    We used ubuntu 18.04 with your tutorials for making our full mail server and its work well… then we start using LDAP as authenticate module for our domain with sssd and we have no problem until my collaborator carelessly use do-release-upgrade and our server is 20.04 now… everything is down…
    I set up mail server tutors again… but we have a problem:
    – I can send email to my yahoo account but unable to receive a message..
    – I cannot send email to my gmail and unable to receive any mail from gmail
    but our users can mail to each other… from every where!
    we have no error in postfix and have 1 error in dovecot…

    auth[92797]: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=user rhost=127.0.0.1  user=user
    auth[92797]: pam_sss(dovecot:auth): authentication success; logname= uid=0 euid=0 tty=dovecot ruser=user rhost=127.0.0.1 user=user
    

    This is my dovecot.socket status:

    sudo systemctl status dovecot.socket 
    ● dovecot.socket - Dovecot IMAP/POP3 email server activation socket
         Loaded: loaded (/lib/systemd/system/dovecot.socket; disabled; vendor preset: enabled)
         Active: inactive (dead)
       Triggers: ● dovecot.service
         Listen: 0.0.0.0:143 (Stream)
                 [::]:143 (Stream)
                 0.0.0.0:993 (Stream)
                 [::]:993 (Stream)
    

    and this is my dovecot -n entry:

    sudo dovecot -n
    # 2.3.7.2 (3c910f64b): /etc/dovecot/dovecot.conf
    # Pigeonhole version 0.5.7.2 ()
    # OS: Linux 5.4.0-52-generic x86_64 Ubuntu 20.04.1 LTS 
    # Hostname: www.mydomain.com
    auth_mechanisms = plain login
    auth_username_format = %Ln
    mail_location = maildir:~/Maildir
    mail_privileged_group = mail
    namespace inbox {
      inbox = yes
      location = 
      mailbox Drafts {
        auto = create
        special_use = \Drafts
      }
      mailbox Junk {
        auto = create
        special_use = \Junk
      }
      mailbox Sent {
        auto = create
        special_use = \Sent
      }
      mailbox Trash {
        auto = create
        special_use = \Trash
      }
      prefix = 
    }
    passdb {
      driver = pam
    }
    protocols = imap lmtp imap lmtp pop3
    service auth {
      unix_listener /var/spool/postfix/private/auth {
        group = postfix
        mode = 0660
        user = postfix
      }
    }
    service lmtp {
      unix_listener /var/spool/postfix/private/dovecot-lmtp {
        group = postfix
        mode = 0600
        user = postfix
      }
    }
    ssl = required
    ssl_cert = </etc/letsencrypt/live/mydomain/fullchain.pem
    ssl_client_ca_dir = /etc/ssl/certs
    ssl_dh = # hidden, use -P to show it
    ssl_key = # hidden, use -P to show it
    ssl_min_protocol = TLSv1.2
    ssl_prefer_server_ciphers = yes
    userdb {
      driver = passwd
    }
    

    Please help me…

  • Hey great tutorial <3, but I am stuck at ipv6 address, how could I know my server ipv6 address?

  • Thank you so much for this tutorial!
    It is very detailed and easy to follow even for me with no experience in e-mail servers.
    All work perfect after step-by-step installation.

  • i have set up the mailsever but i dont know sent a mail with dedicated name

  • Roberto
    3 years ago

    Hi,
    First of all, thanks for this excellent tutorial!
    I already setup this on a test server with a single domain and everything is fine.
    However as I have several WordPress websites in this server, I would need to be able to send email from all domains of each WP website.
    Are you sure that I don’t need any additional setting in Postfix server in order to send emails from a different domain in respect to the first domain I setup?

    Thanks for any help!

  • The trusted hosts entry does not work as expected on 20.04

    Trusted hosts:
    
    127.0.0.1
    localhost
    
    *.example.com
    *.example.net
    

    does not sign the message — you need to remove the ‘*’ —

    Trusted hosts:
    
    127.0.0.1
    localhost
    
    .example.com
    .example.net
    

    will work

  • Harvey Hans
    2 years ago

    Hi, I’m getting a “Start request repeated too quickly” on Ubuntu 20.04

    • When I run this command at the end of step 4

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

      it returns that : checking key sendonly._domainkey.example.com
      sendonly._domainkey.example.com record not found.

      Should I replace example.com with your-domain.uk or just in the above testkey parameter I have to give my domain after -d

      Actually I wrote example.com instead of my domain as it is trusting you bcoz you named ‘your-domain’ whenever we have to give our domain.

      P.s anyBody from the community know the answer pls suggest, I am running out of time.

  • I want to setup postfix for 3 different domains running on my server. Do I need an extra IP address per domain to setup a reverse DNS entry for each according to “Step 3: Set PTR Record”? My ISP only allows one domain name entry per IP in the reverse config.

    • Xiao Guoan (Admin)
      2 years ago

      You can use one IP address all multiple domains.
      You only need to set PTR record once, using a single hostname.

  • Wild Tangent
    2 years ago

    Am I to understand correctly that the config as provided here only allows your return path to be set to a single address per domain? Is there a way to bodge SRS (Sender Rewriting Scheme) into this config?

    Understand if that’s a bit of a mouthful to chew off, but I think it would make a worthwhile addition to use this setup as a DIY SMTP gateway as one would use Sendgrid or Mailgun.. I have a few VPSes with public IPs that could be pulling double duty as extra sending IPs 🙂

    • Wild Tangent
      2 years ago

      Oh, I may have misread that first part, the setting of from and to addresses was a snippet of a WordPress mailer config. Still think SRS would be a very handy thing on a setup like this, if that’s something you have yet to cover I’d be highly interested.

  • Hi Linuxbabe!
    I have two vms on amazon, each one has postfix with a different domain. I want to merge the domains into a single vm with postfix. How can I do this?

    best regards!

  • Hi Linuxbabe

    Thanks for the Thorough Guide.
    I have used it and have had great success

    My question is related to Multiple domains and users.

    If I add multiple domains.
    can the created users send from all of them ie.
    if I add user1
    and I already have two domains.
    example.com
    prime.com
    Does that mean he can send from [email protected] and [email protected]?

    Or is there a way to lock certain domains to certain users.

    Thank you for your help

  • aharown
    1 year ago

    Awesome guide! My postfix was about 6 different kinds of broken.

  • One of the most comprehensive, simple, and detailed-oriented guides I have found on the Internet by far. Thank you so much man for doing such an excellent job explaining everything in full detail for us Linux noobs.

    More people should write like this. It is so frustrating to find lackluster guides written on the premise of the reader knowing the information already.

    Few questions

    1. I plan on just using Postfix as an smtp client for ONLY sending OUTGOING messages. If my subscriber or recipient responds to my email, I have an MX record set at namecheap hosting. So namecheap will handle ALL incoming messages and Postfix all OUTGOING messages.

    Given my use case, can I comment or disable all the parameters/entries in the etc/postfix/main.cf and etc/postfix/master.cf refering to “smtpd”?

    I only need “smtp” related entries right given the above? Will anything “break” or adversely affect my deliverability if I disable or comment the “smtpd” entries? It’s important to note I am using port 587 and tls encryption.

    2. Do I need smtpd_tls_cert_file=/etc/letsencrypt/live/example.com/fullchain.pem and smtpd_tls_key_file=/etc/letsencrypt/live/example.com/privkey.pem in the main.cf?

    3. Do I need smtp_tls_cert_file=/etc/letsencrypt/live/example.com/fullchain.pem and smtp_tls_key_file=/etc/letsencrypt/live/example.com/privkey.pem in the main.cf?

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. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here