Back to tutorials
Tutorial

Email relay setup tutorial (2026): Send WordPress and app mail through a VPS SMTP relay with Postfix + TLS

Email relay setup tutorial for 2026: configure a VPS SMTP relay with Postfix, TLS, and rate limits to improve delivery and logs.

By Anurag Singh
Updated on Jun 18, 2026
Category: Tutorial
Share article
Email relay setup tutorial (2026): Send WordPress and app mail through a VPS SMTP relay with Postfix + TLS

Most “email problems” on websites aren’t bugs in WordPress or your app. They’re routing and identity problems. PHP hands mail to a local sendmail binary. The server has no credible hostname, and major inbox providers flag the traffic.

This email relay setup tutorial shows a practical 2026 approach. You’ll run a small SMTP relay on a VPS. You’ll send all site mail through it using authenticated SMTP + TLS. You also get one place to inspect queues, logs, and DNS.

This setup fits agencies, resellers, and developers who manage multiple sites. It gives predictable outbound behavior without running a full mailbox platform.

You’ll configure Postfix for authenticated submission, lock it down to prevent abuse, and point WordPress and other apps at it.

What you’re building (and what you’re not)

You’re building a mail relay that accepts outbound mail from your sites and forwards it to recipients on the internet. Think “outbound SMTP gateway.”

It’s not an IMAP server. It’s also not intended to receive inbound mail for your domains (unless you deliberately add that later).

  • Good for: WordPress contact forms, WooCommerce order mail, password resets, app notifications, cron output.
  • Not for: hosting mailboxes for users (IMAP/POP), groupware, inbound filtering pipelines.

If your goal is a full mail server, use HostMyCode’s dedicated mail-server tutorial instead: mail server setup tutorial for Postfix + Dovecot. This guide stays focused on outbound reliability and control.

Prerequisites checklist (10 minutes to verify)

Before you touch Postfix, verify the fundamentals. These details decide whether your mail lands in an inbox or bounces at the door.

  • VPS with a static IPv4 (recommended). NATed or rotating IPs make delivery unpredictable.
  • Hostname (FQDN) set to something like relay1.yourdomain.com.
  • Reverse DNS (PTR) for the VPS IP points to that hostname.
  • Port access: outbound TCP/25 allowed from the VPS; inbound TCP/587 allowed to the VPS from your web servers.

On Ubuntu 24.04 LTS (still a common choice in 2026 hosting), set the hostname:

sudo hostnamectl set-hostname relay1.yourdomain.com
hostname -f

Check your current PTR:

dig +short -x YOUR_SERVER_IP

If PTR is wrong or missing, fix it before you go further. It’s the quickest way to avoid “IP has no PTR” rejections.

Use: rDNS setup tutorial.

Need a clean VPS for the relay? A small instance is usually plenty for many sites. Start with a HostMyCode VPS and scale if your queue volume grows.

Email relay setup tutorial: Install Postfix and open only the right ports

This tutorial uses Ubuntu and UFW because it’s a common admin stack. If you run AlmaLinux/Rocky, the Postfix concepts are the same.

The paths and firewall tooling will differ.

1) Install Postfix and supporting packages

sudo apt update
sudo apt install -y postfix libsasl2-modules ca-certificates

During the Postfix prompt:

  • Select Internet Site
  • System mail name: relay1.yourdomain.com

Confirm versions and service status:

postconf mail_version
systemctl status postfix --no-pager

2) Lock down firewall: allow 22 and 587; be careful with 25

For a pure relay, you usually want inbound SMTP submission on 587 (from your app servers). You typically do not want inbound port 25 from the public internet.

sudo ufw allow 22/tcp
sudo ufw allow 587/tcp
sudo ufw deny 25/tcp
sudo ufw enable
sudo ufw status numbered

Outbound TCP/25 must be allowed from the server so it can deliver to recipient MX hosts. That’s typically permitted by default.

If you lock yourself out after firewall changes, use: firewall troubleshooting tutorial.

Configure Postfix for authenticated submission (587) with TLS

Your target state is simple. Accept mail only from authenticated users (or trusted IPs). Protect credentials with TLS. Avoid creating an open relay.

1) Enable submission service on 587

Edit /etc/postfix/master.cf. Find the submission block. On Ubuntu it’s usually present but commented out.

Enable it and apply strict options.

sudo nano /etc/postfix/master.cf

Use a block like this (uncomment or add):

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

This forces TLS on submission and rejects recipients unless the client authenticates.

2) Set core relay-safe defaults in main.cf

sudo nano /etc/postfix/main.cf

Add or adjust the following. Replace relay1.yourdomain.com and your IP/network values.

# Identity
myhostname = relay1.yourdomain.com
mydomain = yourdomain.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4

# Never be an open relay
smtpd_relay_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
mynetworks = 127.0.0.0/8 [::1]/128

# Submission auth (SASL)
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes

# TLS
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/relay1.yourdomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/relay1.yourdomain.com/privkey.pem
smtpd_tls_loglevel = 1

# Harder-to-abuse defaults
smtpd_helo_required = yes
disable_vrfy_command = yes
smtpd_delay_reject = yes

# Logging
maillog_file = /var/log/mail.log

Why “may” for smtpd_tls_security_level? On port 25 you may not even be listening inbound. On 587, encryption is enforced in master.cf.

This split is common in day-to-day hosting operations.

3) Get a TLS certificate (Let’s Encrypt)

You need a certificate that matches your relay hostname. The simplest route is certbot in standalone mode. It temporarily uses port 80.

If port 80 is busy, use DNS validation instead.

sudo apt install -y certbot
sudo systemctl stop postfix
sudo certbot certonly --standalone -d relay1.yourdomain.com
sudo systemctl start postfix

Test renewal:

sudo certbot renew --dry-run

If you already manage certificates through a control panel workflow, keep it consistent. For cPanel servers, see: cPanel SSL certificate management tutorial.

4) Create SMTP users for your websites

For a relay, create one SMTP user per site or per environment (production/staging). Separate credentials help contain a compromise without breaking every site.

sudo adduser --disabled-login --gecos "SMTP user" smtp_site1
sudo passwd smtp_site1

Postfix on Ubuntu commonly uses SASL via Dovecot or Cyrus. A stable option for submission auth is Dovecot as the SASL provider.

Configure it for auth only (no IMAP exposure).

sudo apt install -y dovecot-core

Edit /etc/dovecot/conf.d/10-master.conf and enable the auth socket for Postfix:

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

Inside the service auth block, add:

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

Then point Postfix to Dovecot SASL by adding to /etc/postfix/main.cf:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

Restart both:

sudo systemctl restart dovecot
sudo systemctl restart postfix

Connect WordPress (and other apps) to the relay

Once the relay is up, stop relying on PHP mail(). Use authenticated SMTP from the app to the relay. Then the relay delivers to the internet.

WordPress: configure SMTP with a plugin (the pragmatic approach)

Most WordPress sites use a maintained SMTP plugin. The labels vary by plugin, but the values don’t.

  • SMTP Host: relay1.yourdomain.com
  • SMTP Port: 587
  • Encryption: STARTTLS
  • Authentication: On
  • Username: smtp_site1
  • Password: (the password you set)
  • From address: use a domain you control (example: no-reply@yourdomain.com)

If you host WordPress on VPS and want more headroom, pair the relay with tuned PHP-FPM and caching. See PHP-FPM performance tuning tutorial and Nginx caching configuration tutorial.

Linux apps: relay via msmtp (lightweight and easy to audit)

For cron jobs and small apps, msmtp keeps things simple. You get one config file and avoid a local sendmail stack entirely.

sudo apt install -y msmtp msmtp-mta

Create /etc/msmtprc on the app server (not the relay server):

sudo nano /etc/msmtprc
defaults
auth           on
tls            on
tls_starttls   on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        /var/log/msmtp.log

account        relay
host           relay1.yourdomain.com
port           587
user           smtp_site1
password       YOUR_STRONG_PASSWORD
from           no-reply@yourdomain.com

account default : relay

Lock permissions:

sudo chown root:root /etc/msmtprc
sudo chmod 600 /etc/msmtprc

Send a test email:

printf "Subject: relay test\n\nHello from msmtp.\n" | sendmail -v you@yourmailbox.com

Add DNS records that reduce spam scoring (SPF + DKIM + DMARC)

A relay improves consistency, but DNS alignment still determines where messages land. If you do only one deliverability task after this guide, do SPF properly.

SPF: authorize the relay IP

For the domain you use in the From address, add an SPF TXT record that includes the relay’s IP.

yourdomain.com.  TXT  "v=spf1 ip4:YOUR_SERVER_IP -all"

If you also send through a third-party service (for example, a marketing platform), include it explicitly. Don’t “fix” deliverability by weakening policy to ~all without a reason.

DKIM: sign mail so it survives forwarding and filtering

DKIM signing typically uses OpenDKIM or Rspamd. It’s a separate layer. Small mistakes can break signing or alignment.

For full 2026 steps on deliverability DNS, use: SPF, DKIM, and DMARC setup guide.

DMARC: get reports before enforcing

Start with monitoring. You want to see what fails alignment before you tighten policy.

_dmarc.yourdomain.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s"

Anti-abuse controls: rate limits, relay restrictions, and safer defaults

A working relay attracts the wrong kind of attention. Expect credential stuffing on 587. Expect compromised sites trying to blast spam. Expect apps that retry too aggressively.

Put guardrails in place while things are quiet.

1) Limit who can authenticate

If your sites live on known IPs (your web VPS, your cPanel server, your office), restrict 587 to those sources at the firewall. Example:

sudo ufw deny 587/tcp
sudo ufw allow from 203.0.113.10 to any port 587 proto tcp
sudo ufw allow from 203.0.113.11 to any port 587 proto tcp
sudo ufw status

2) Basic Postfix rate limiting

Postfix isn’t a full anti-spam gateway, but it can slow down obvious abuse. In /etc/postfix/main.cf:

# Size and connection limits (tune to your workload)
message_size_limit = 26214400
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 30
smtpd_client_message_rate_limit = 60

Reload Postfix:

sudo postfix reload

If you run dozens of WooCommerce stores, these limits may be too tight during promotions. Start conservative. Watch the logs. Then loosen only what you have to.

3) Fail2Ban for submission brute-force attempts

TLS protects the connection, not your password. Fail2Ban blocks IPs that repeatedly fail authentication.

HostMyCode has a dedicated tutorial: Fail2Ban setup tutorial. Apply the same approach to Postfix and Dovecot auth failures.

Verification: prove the relay isn’t open and mail actually delivers

A running service doesn’t mean a safe or correct service. Do a few quick checks. You’ll catch the common mistakes early.

1) Confirm Postfix is listening only where expected

sudo ss -lntp | egrep ':(25|587)\s'

You should see 587. You might see 25 if you intentionally left it enabled for internal use.

Don’t expose 25 unless you mean to.

2) Test STARTTLS and auth from a client machine

From a web server or your workstation (anything that can reach 587):

openssl s_client -starttls smtp -connect relay1.yourdomain.com:587 -servername relay1.yourdomain.com

Look for a clean handshake and a valid certificate chain.

3) Send a real message and watch logs

On the relay:

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

Send a test from WordPress or msmtp. Confirm you see:

  • SASL authentication success
  • Queue ID assignment
  • Successful delivery to recipient MX (or a clear bounce reason)

Troubleshooting quick hits (the issues you’ll actually see)

“Relay access denied”

  • On the client: confirm you’re using port 587 with auth enabled.
  • On the relay: ensure smtpd_recipient_restrictions on submission includes permit_sasl_authenticated.
  • Confirm Dovecot auth socket exists: ls -la /var/spool/postfix/private/auth

“TLS handshake failed” or “certificate verify failed”

  • Confirm the cert paths in main.cf match your Let’s Encrypt live directory.
  • Run: postfix check then sudo systemctl restart postfix.
  • Verify hostname and certificate CN/SAN match (relay1.yourdomain.com).

Mail is sent but lands in spam

  • Fix PTR and HELO alignment first (PTR → hostname → A record).
  • Make sure SPF includes the relay IP for the From domain.
  • Add DKIM signing and DMARC reporting.

If you want a structured workflow for deliverability, logs, and reputation basics, use: email deliverability troubleshooting tutorial.

Queue builds up (deferred mail)

  • Check outbound connectivity: nc -vz gmail-smtp-in.l.google.com 25
  • Look for rate limits or blocks in logs: grep -i deferred /var/log/mail.log | tail -n 50
  • Inspect queue: mailq

For hands-on queue fixes and safe flushing, see: email queue troubleshooting tutorial.

Operational checklist: keep the relay healthy

Save this list somewhere obvious. Run it once a month.

  • Patch cadence: apply security updates weekly; reboot when the kernel requires it.
  • Credential hygiene: rotate SMTP passwords after staff changes or any compromise.
  • Log review: look for repeated auth failures, spikes in volume, and unusual recipients.
  • Queue sanity: queue size should return to near-zero after bursts.
  • DNS drift: confirm PTR, SPF, DKIM, DMARC remain intact after IP changes or migrations.

If you want a repeatable maintenance routine on Ubuntu, adapt: Linux server maintenance tutorial.

Summary: a cleaner mail path with fewer surprises

A VPS-based SMTP relay gives you what shared hosting often can’t. You get a consistent identity (PTR/HELO). You get one place to inspect logs and queues. You also get a reliable way to enforce TLS + authentication across every site.

It also migrates cleanly. Your apps keep submitting to the same host.

If you want the relay to run with predictable performance and full root access, start on a HostMyCode VPS. If you don’t want to manage updates, TLS renewals, and security defaults yourself, consider managed VPS hosting from HostMyCode.

If your sites send mail from mixed environments (WordPress, PHP apps, cron jobs), a dedicated SMTP relay VPS keeps delivery rules and troubleshooting in one place. HostMyCode can provision a right-sized HostMyCode VPS for the relay, or run it for you on managed VPS hosting so you can focus on the sites instead of the mail plumbing.

FAQ

Do I need port 25 open inbound on the relay?

Not for this tutorial. Your apps should submit on 587 with auth + TLS. Keep inbound 25 closed unless you have a specific requirement.

Can I point multiple WordPress sites at the same relay?

Yes. Create separate SMTP users per site (or per client) so you can revoke credentials without affecting everyone.

What if my VPS provider blocks outbound port 25?

Use a provider that allows it for legitimate mail use, or relay upstream to a smarthost that accepts authenticated submission. If outbound 25 is blocked, direct internet delivery won’t work reliably.

How do I keep the relay from being abused if one site is compromised?

Restrict 587 by source IP, use per-site credentials, apply rate limits, and monitor auth failures. If volume spikes, disable the affected SMTP user immediately.

Should the “From” address match the SMTP user?

Not strictly, but align domains whenever possible. Many providers score mail higher when SPF/DKIM/DMARC align with the From domain you actually use.

Email relay setup tutorial (2026): Send WordPress and app mail through a VPS SMTP relay with Postfix + TLS | HostMyCode