2026年11月12日

2026年11月12日

How to Install Postfix on Ubuntu (Send-Only, External SMTP Relay)

This article is a localized edition of the Japanese original. Read the Japanese original

Postfix is the mail transfer agent (MTA) commonly used on Ubuntu. Installing it on a web server lets WordPress send contact-form and password-reset emails through PHP's mail() (the method WordPress's wp_mail() uses by default).

This article uses Ubuntu 24.04 LTS / 26.04 LTS to show how to set up Postfix to only send mail out from the server (as of November 2026; Postfix is version 3.8 on 24.04 and 3.10 on 26.04). A full mail server with mailboxes that receives mail also needs Dovecot, TLS certificates, inbound spam filtering and more, which is beyond the scope of this article.

Decide how to send

Approach How it works Best when
Direct delivery Postfix delivers straight to the recipient's mail server You can set up your domain's DNS (SPF, reverse DNS) yourself and outbound port 25 is available
Relay through an external SMTP server Postfix authenticates to the SMTP server of a mail service you subscribe to and hands mail over You want to avoid landing in spam, or port 25 is restricted

Many cloud and VPS providers restrict outbound TCP port 25 as an anti-spam measure. If you're considering direct delivery, check this first.

nc -vz -w 5 gmail-smtp-in.l.google.com 25

If you see succeeded, the connection works. If it times out, port 25 is restricted: either relay through an external SMTP server (port 587) or check your provider's procedure for lifting the restriction.

Install Postfix

sudo apt update
sudo apt install postfix

A configuration screen appears during installation. On the first screen, "General type of mail configuration," choose one of the following.

Option What it does
No configuration Doesn't create a configuration file
Internet Site Sends and receives mail directly
Internet with smarthost Sends outgoing mail through a specified SMTP server (the smarthost) and delivers local mail itself
Satellite system Sends all mail to the smarthost and delivers nothing itself
Local only Exchanges mail only between users on the server
  • For direct delivery, choose Internet Site.
  • To relay through an external SMTP server, choose Internet with smarthost. You'll then be asked for the relay host, but this article sets relayhost later, so you can continue without changing it. Authentication is also added later.

In the next screen, "System mail name," enter the sender's domain name (for example, example.com). This value is saved in /etc/mailname and is added to recipients and senders that have no domain.

If you want to choose again, you can open the same screens at any time with the following command.

sudo dpkg-reconfigure postfix

Review the main settings in main.cf

The settings live in /etc/postfix/main.cf. You can edit it by hand, but postconf -e rewrites the existing line, so the same setting never appears twice.

# Show only the settings that differ from the defaults
sudo postconf -n

A send-only server doesn't need to accept SMTP connections from outside. Make it listen only locally.

sudo postconf -e 'inet_interfaces = loopback-only'
sudo postconf -e 'myhostname = web1.example.com'
sudo postconf -e 'mydestination = localhost.localdomain, localhost'
sudo systemctl restart postfix

Right after installation, mydestination includes the domain you entered as "System mail name." Unless you limit it to the localhost entries as shown above, mail addressed to that domain never leaves the server.

Setting Meaning
myhostname The server's host name (FQDN). Used to identify the server when sending
myorigin The domain added to senders that have none. Ubuntu's default is /etc/mailname
mydestination Domains the server accepts as its own. If the site's domain is included, mail to that domain (such as the administrator's address) is delivered inside the server instead of going out, so on a send-only server keep only the localhost entries
inet_interfaces Addresses to listen on. loopback-only accepts local connections only
relayhost Where to send mail when relaying through an external SMTP server

After changing inet_interfaces, you need a restart, not a reload.

Relay through an external SMTP server (with authentication)

This setup sends mail through the SMTP server of a mail service you subscribe to, authenticating with a username and password. Use the host name, port and credentials given by your service.

Install the authentication modules

Ubuntu's postfix package lists libsasl2-modules, which SMTP authentication needs, as "Suggests" rather than "Recommends," so it may not be installed automatically. Without it, authentication fails with an error such as no mechanism available.

sudo apt install libsasl2-modules

Create the credentials file

Create /etc/postfix/sasl_passwd. Write the left-hand side exactly the same way as the relayhost you set next.

[smtp.example.net]:587 username:password
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd

postmap creates the lookup file sasl_passwd.db. Run postmap again every time you change the file.

Add the settings to main.cf

sudo postconf -e 'relayhost = [smtp.example.net]:587'
sudo postconf -e 'smtp_sasl_auth_enable = yes'
sudo postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'
sudo postconf -e 'smtp_sasl_security_options = noanonymous'
sudo postconf -e 'smtp_sasl_tls_security_options = noanonymous'
sudo postconf -e 'smtp_tls_security_level = encrypt'
sudo systemctl reload postfix
  • Wrapping the host name in [ ] makes Postfix connect to that host directly without looking up MX records.
  • smtp_tls_security_level = encrypt makes TLS mandatory for the connection to the relay, so the password is never sent unencrypted.
  • If you're told to use port 465 (TLS from the moment of connection), you need smtp_tls_wrappermode = yes in addition to relayhost = [smtp.example.net]:465.

Test sending

Send a message with the sendmail command that comes with Postfix. No extra packages are needed.

printf 'Subject: Postfix test\n\nThis is a test.\n' | sudo /usr/sbin/sendmail -f wordpress@example.com you@example.net

Check the delivery result in the log.

sudo tail -f /var/log/mail.log

If /var/log/mail.log doesn't exist, check the journal instead.

sudo journalctl -u 'postfix*' -f
Log entry Meaning
status=sent (250 ...) The recipient's server accepted the message
status=deferred A temporary failure. The message stays in the queue and is retried later
status=bounced A permanent failure. The reason follows
SASL authentication failed Authentication to the relay failed (check the username, password and left-hand side of sasl_passwd)

Use postqueue -p to list messages left in the queue and sudo postqueue -f to retry them. Queue operations are explained in detail in How to manage the Postfix mail queue.

You can check configuration syntax and file permissions with the following command. If there are no problems, it prints nothing.

sudo postfix check

Let WordPress send mail

By default, WordPress's wp_mail() uses PHP's mail(), and PHP on Ubuntu calls /usr/sbin/sendmail. Once Postfix is installed, WordPress can send mail with no further configuration.

Check that mail arrives, for example by creating a test user under Users → Add New in the admin or by trying a password reset. By default, WordPress sends from wordpress@your site's domain.

Avoid being marked as spam

If the sender's domain has no SPF, DKIM and DMARC, Gmail and other providers may file your mail as spam or reject it.

  • For direct delivery: include the sending server's IP address in SPF and make its reverse DNS (PTR) match the host name. DKIM signing needs additional setup, such as OpenDKIM.
  • For relaying through an external SMTP server: register the SPF and DKIM DNS records as instructed by the service you use.

How to check these settings is explained in How to check your SPF, DKIM and DMARC settings.

Things to watch out for

  • If you widen mynetworks while leaving inet_interfaces = all, the server may become an "open relay" that third parties can use to pass mail through. On a send-only server, keep it at loopback-only.
  • sasl_passwd and sasl_passwd.db contain the password. Set their permissions to 600 and don't let them leave the server in backups or elsewhere.
  • You don't need to open inbound port 25 in your firewall (ufw or similar). On a send-only server, keep it closed.

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲