Back to tutorials
Tutorial

SMTP relay setup guide tutorial (2026): Send WordPress & app mail safely from a VPS via a trusted provider

SMTP relay setup guide tutorial (2026) for a VPS: configure Postfix as a relay, add SPF/DKIM/DMARC, and test delivery.

By Anurag Singh
Updated on Aug 26, 2026
Category: Tutorial
Share article
SMTP relay setup guide tutorial (2026): Send WordPress & app mail safely from a VPS via a trusted provider

Email from a fresh VPS fails for predictable reasons. You may have no reverse DNS, weak auth, or an IP with no sending history.

In 2026, the low-risk fix for most stacks is an SMTP relay. Your server submits mail to a trusted provider. Your apps still send locally.

This SMTP relay setup guide tutorial walks through a clean Postfix relay on Ubuntu. It also covers DNS records and tests that prevent the usual “550/554” surprises.

This is for VPS (or dedicated) admins who want WordPress contact forms, WooCommerce receipts, app alerts, and cron reports to arrive consistently.

If you run a multi-tenant cPanel box, the ideas still apply. You will usually enable relaying in the control panel instead of editing Postfix directly.

What you’ll build: a local Postfix “send-only” relay

You’ll configure Postfix to accept mail from local apps. Postfix then forwards it to an upstream SMTP provider (a smart host).

The provider handles outbound reputation and deliverability. Your VPS stays boring. That’s exactly what you want.

  • Apps send to: localhost:25 (or sendmail)
  • Postfix forwards to: smtp.provider.example:587 using STARTTLS + authentication
  • DNS you’ll set: SPF + DKIM + DMARC aligned to your From domain

If you’re starting from a brand-new VPS, build on a hardened baseline first.

HostMyCode customers usually pair this with sane SSH and firewall defaults.

See our internal guide: Server hardening tutorial (2026).

Prerequisites (keep this tight)

  • Ubuntu 24.04 LTS or Ubuntu 22.04 LTS VPS (root or sudo access)
  • A domain you control (example.com) and access to its DNS zone
  • Credentials for an SMTP relay provider (hostname, port, username, password or API key)
  • Outbound connectivity from your VPS on port 587 (and optionally 465)

If you need a stable host for this setup, a HostMyCode VPS gives you root access for Postfix, DNS verification, and log-driven troubleshooting—without shared-hosting constraints.

Step 1: Pick the right relay mode (and avoid the common trap)

Most relay setups fall into one of these patterns:

  1. Provider-managed DKIM (recommended): You send through the provider and publish the DKIM key(s) they give you. This is the default choice for most teams.
  2. Self-managed DKIM on your VPS: You sign mail locally with OpenDKIM, then relay it. Choose this if you need DKIM keys to live on your server.

The trap is alignment. You can’t casually mix “From: yourdomain.com” with provider-managed “MAIL FROM” domains that don’t align.

DMARC checks alignment. Misalignment is a fast path to spam placement or rejections.

If your provider uses a different bounce domain, configure a custom return-path domain with them.

If you can’t, keep DMARC at p=none while you confirm alignment. Tighten it later.

Step 2: Install Postfix and set it to “Internet Site” (send-only)

Postfix installs cleanly on Ubuntu. Even for a relay-only box, you typically select “Internet Site”.

After that, block inbound SMTP from the internet with firewall rules and Postfix settings.

sudo apt update
sudo apt install -y postfix mailutils ca-certificates

During the Postfix prompt:

  • General type of mail configuration: Internet Site
  • System mail name: example.com (or a hostname like mail.example.com)

Confirm Postfix is running:

systemctl status postfix --no-pager

Step 3: Configure Postfix to relay through your SMTP provider

Edit /etc/postfix/main.cf. The goal is simple.

Set the relayhost, force TLS, enable auth, and accept mail only from localhost.

sudo nano /etc/postfix/main.cf

Add (or adjust) these lines. Replace values in brackets with your provider details.

# Identity
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain

# Only listen locally (prevents public inbound SMTP)
inet_interfaces = loopback-only

# Relay all outbound mail through provider
relayhost = [smtp.provider.example]:587

# Restrict local clients (localhost only)
mynetworks = 127.0.0.0/8 [::1]/128

# TLS settings for outbound
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_loglevel = 1

# SASL auth for relay
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous

# Sensible limits
message_size_limit = 26214400

Create the password map file /etc/postfix/sasl_passwd:

sudo nano /etc/postfix/sasl_passwd

Example (use the provider’s exact host/port and credentials):

[smtp.provider.example]:587 relay-user@example.com:YOUR_APP_PASSWORD_OR_API_KEY

Secure it and build the hash database:

sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd

Reload Postfix:

sudo systemctl restart postfix

Step 4: Open only what you need (UFW example)

If Postfix only listens on loopback, you don’t need inbound port 25 open to the internet.

You do need outbound 587 to the provider. Outbound traffic is usually allowed by default.

Check UFW status:

sudo ufw status verbose

If you previously allowed public SMTP, remove it:

sudo ufw delete allow 25/tcp

It’s easy to over-tighten a firewall on a new VPS. That can break mail. It can also break SSH.

If you need a safe recovery path, see: UFW firewall troubleshooting tutorial (2026).

Step 5: Publish SPF for your domain (minimum viable, then refine)

SPF tells receivers which systems may send mail for your domain. If you relay through a provider, SPF should authorize the provider.

In most cases, SPF should not authorize your VPS IP.

Create (or update) a TXT record for example.com:

Type: TXT
Name: @
Value: v=spf1 include:spf.provider.example -all

Notes:

  • Use the provider’s SPF include string (they document it). Don’t guess.
  • Only use -all once you’re sure nothing else sends as your domain.
  • If you also send from Google Workspace / Microsoft 365, include them too (and watch the 10-DNS-lookup SPF limit).

Step 6: DKIM signing (provider-managed first, then optional OpenDKIM)

For most relay providers, DKIM is a DNS change. You publish their public key, and they handle signing.

It’s also the quickest way to pass authentication checks.

Option A (recommended): provider-managed DKIM

Your provider will give you a selector and a TXT record, something like:

Type: TXT
Name: s1._domainkey
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqh...IDAQAB

Once DNS propagates, you’ll confirm it with a mailbox test in Step 8.

Option B: sign mail on your VPS with OpenDKIM (advanced, but practical)

Choose this if your provider can’t manage DKIM for your domain.

It also fits policies where keys must stay on your server.

sudo apt install -y opendkim opendkim-tools

Create a key directory:

sudo mkdir -p /etc/opendkim/keys/example.com
sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod go-rwx /etc/opendkim/keys

Generate a 2048-bit key (good default in 2026):

cd /etc/opendkim/keys/example.com
sudo opendkim-genkey -b 2048 -s s1 -d example.com
sudo chown opendkim:opendkim s1.private s1.txt

Wire OpenDKIM config:

sudo nano /etc/opendkim.conf
Syslog                  yes
UMask                   002
Canonicalization        relaxed/simple
Mode                    sv
SubDomains              no
AutoRestart             yes
AutoRestartRate         10/1h
OversignHeaders         From
KeyTable                /etc/opendkim/key.table
SigningTable            /etc/opendkim/signing.table
ExternalIgnoreList      /etc/opendkim/trusted.hosts
InternalHosts           /etc/opendkim/trusted.hosts
Socket                  local:/run/opendkim/opendkim.sock

Create the tables:

sudo nano /etc/opendkim/trusted.hosts
127.0.0.1
localhost
*.example.com
sudo nano /etc/opendkim/key.table
s1._domainkey.example.com example.com:s1:/etc/opendkim/keys/example.com/s1.private
sudo nano /etc/opendkim/signing.table
*@example.com s1._domainkey.example.com

Connect Postfix to OpenDKIM by adding to /etc/postfix/main.cf:

# OpenDKIM milter
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/run/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Enable and restart services:

sudo systemctl enable --now opendkim
sudo systemctl restart postfix

Publish the DKIM TXT record shown in /etc/opendkim/keys/example.com/s1.txt.

Step 7: Add DMARC (start with monitoring, then enforce)

DMARC tells receivers what to do if SPF or DKIM fails. Start in monitor mode first.

Review reports, then enforce once you see clean alignment.

Create a TXT record for _dmarc.example.com:

Type: TXT
Name: _dmarc
Value: v=DMARC1; p=none; adkim=s; aspf=s; rua=mailto:dmarc@example.com; fo=1

Practical tips:

  • p=none keeps delivery stable while you validate alignment.
  • Create dmarc@example.com first, or point rua to a mailbox you actually read.
  • After things settle, move to p=quarantine, then p=reject.

Step 8: Send test mail and read the logs like an operator

Send a quick message from the VPS:

echo "SMTP relay test $(date -Is)" | mail -s "Relay test" you@yourmailbox.com

Watch mail logs in real time:

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

You’re looking for:

  • Successful TLS negotiation to the relay host
  • Authentication success (SASL)
  • A status=sent line with the provider’s response

If mail stalls, check the queue:

mailq

Then inspect a stuck message:

postcat -q QUEUEID

For timeouts, auth errors, and TLS issues that don’t resolve quickly, follow the diagnostic flow here: SMTP troubleshooting tutorial (2026).

Step 9: Make WordPress use your relay (two clean approaches)

WordPress defaults to PHP’s mail(). On many VPS stacks, that already routes into Postfix.

The rough edge is consistency. “From” headers can vary. Some plugins produce odd Return-Path values.

Approach A: Leave WordPress alone (uses local Postfix)

This is the lowest-friction option if your apps already use /usr/sbin/sendmail.

It also works best when your From domain matches your DNS records.

Confirm PHP knows the sendmail path:

php -i | grep -i sendmail_path

Approach B: Use an SMTP plugin to set consistent From + TLS

If you need per-site credentials, enforced From addresses, or you’re dealing with a mixed environment, use an SMTP plugin.

Point it to localhost (Postfix) or to the provider directly.

On a VPS, localhost is often simpler because credentials stay on the server.

If you’re still building your WordPress VPS stack, this pairs well with the relay steps above: WordPress VPS setup guide tutorial (2026).

Step 10: Add safety rails (rate limits, sender control, and secrets hygiene)

Mail systems attract abuse. Even a relay-only host needs guardrails.

The goal is simple. One mistake should not become a billing problem or a reputation problem.

Lock down who can submit mail

Setting inet_interfaces = loopback-only is the big one. It stops the public internet from talking to your Postfix SMTP daemon.

If you must accept mail from another internal host (for example, a separate app server), do it deliberately.

Use private networking plus explicit IP allowlists. Don’t open SMTP publicly “just to test”.

Protect relay credentials

  • Keep /etc/postfix/sasl_passwd at 0600.
  • Use provider “app passwords” or restricted API keys where possible.
  • Rotate credentials if the server is compromised.

Stop noisy scripts from flooding your relay

On multi-site servers, a broken contact form can send thousands of messages in minutes.

Add application-level throttling where you can. Also watch for queue spikes.

On cPanel/WHM servers, rely on the built-in limits. That helps one account avoid torching your reputation.

If you sell shared hosting plans, also review which features clients can toggle.

This guide helps reduce “creative” plugin installs: WHM Feature Manager Tutorial (2026).

Step 11: Quick deliverability checklist (use this before you blame the provider)

  • From domain matches: your visible From header is @example.com
  • SPF passes: includes your relay provider
  • DKIM passes: provider DKIM record published (or OpenDKIM signing works)
  • DMARC starts at p=none: then tighten after validation
  • PTR isn’t required for relay-only: but your VPS hostname should still be sane
  • No public SMTP exposure: Postfix listens on loopback or private IP only
  • Logs are clean: no auth failures, no repeated deferrals

Common errors and fixes (fast mapping)

  • 535 Authentication failed: wrong username/password, or provider requires an app password; re-check /etc/postfix/sasl_passwd and rebuild with postmap.
  • Connect to smtp.provider:587 timed out: outbound port blocked by firewall or upstream network; verify nc -vz smtp.provider.example 587.
  • “TLS is required” or handshake errors: ensure smtp_tls_security_level = encrypt and your CA bundle exists at /etc/ssl/certs/ca-certificates.crt.
  • Mail lands in spam: SPF/DKIM/DMARC alignment issue, or From address mismatch; inspect headers in the received message.

For bounces and rejections, it helps to map the exact error codes to fixes.

This guide focuses on the 550/554 patterns you’ll see in logs: Email bounce troubleshooting tutorial (2026).

If you want reliable outbound mail without operating a full mail server, run this relay on a VPS you control. Start on a HostMyCode VPS, or hand it to our team with managed VPS hosting if you’d rather have a monitored, maintained configuration.

FAQ

Do I need reverse DNS (PTR) if I use an SMTP relay?

Usually no. Receivers evaluate the relay provider’s sending IPs and PTR. PTR still matters if you send directly from your VPS IP.

Should Postfix listen on the public interface?

Not for a relay-only setup. Keep inet_interfaces = loopback-only so the internet can’t submit mail to your server.

Can I use this on a dedicated server with multiple websites?

Yes. It’s a common pattern for multi-site hosting. Add monitoring for queue growth and consider per-app rate limiting to prevent accidental floods.

What’s the safest DMARC policy to start with?

p=none. Once SPF and DKIM pass consistently for your real traffic, move to p=quarantine and then p=reject.

Summary: stable mail delivery without turning your VPS into a mail platform

An SMTP relay keeps your server focused on running apps, not building email reputation.

Your apps send locally. Postfix forwards securely. Your domain proves authenticity with SPF/DKIM/DMARC.

If something breaks, you get clear logs and a tight failure surface.

If this is for production sites, run it on a VPS with predictable resources and full root access.

A HostMyCode VPS fits well here, and managed VPS hosting is a good option if you want ongoing patching and operator-level troubleshooting.