
Email can be “working” and still fail in the only way that matters. Your messages land in spam or get rejected. This email deliverability setup guide tutorial gives you a clean, production-ready baseline for sending mail from a VPS in 2026. It covers SPF, DKIM, DMARC, reverse DNS, hostname/HELO, and TLS.
You’ll finish with a checklist you can reuse every time you provision a new server.
The steps assume a Linux VPS running Postfix for outbound mail. If you use cPanel/WHM (Exim) or DirectAdmin, the DNS pieces are the same. The signing setup differs.
If your team doesn’t want to run and monitor mail daemons, keep outbound transactional mail with a specialist. Use your VPS for web hosting only.
If you do run mail, set it up with intention.
What you’ll build (and why it fixes inbox placement)
Mailbox providers score your domain and IP on identity, authentication, and consistency. New VPS IPs often struggle because they look “uncertain” or mismatched.
The configuration below focuses on the signals that most often trigger spam placement or outright rejection.
- FQDN hostname + correct HELO/EHLO so your server introduces itself consistently.
- Reverse DNS (PTR) so your IP points back to the same hostname used in SMTP.
- SPF to declare which servers are allowed to send for your domain.
- DKIM to sign messages and protect headers/body from tampering.
- DMARC to enforce alignment and receive reports when spoofing happens.
- TLS with a valid certificate so STARTTLS works cleanly and predictably.
If you’re provisioning a server for mail plus websites, start with a VPS that gives you steady performance and full root access.
A HostMyCode VPS is a practical fit for a small business mail stack or a reseller lab where you need control over rDNS, firewall rules, and system packages.
Prerequisites before you touch DNS
Do these checks first. If you send a lot of mail with a broken identity chain, cleanup takes longer than doing it right up front.
- A domain you control (example:
example.com). - A VPS with a dedicated IPv4 address (still the most compatible for outbound SMTP in 2026).
- Access to manage DNS records (at your registrar or a DNS provider).
- Ubuntu 24.04 LTS / Debian 12/13 / AlmaLinux 10 are all fine; commands below show Ubuntu/Debian style.
Pick your mail hostname now. A standard pattern is mail.example.com for the SMTP banner and PTR. User email addresses stay you@example.com.
Email deliverability setup guide tutorial: set hostname, HELO, and forward DNS
Start by making your server’s identity boring and consistent. In mail, boring is exactly what you want.
1) Set the system hostname
sudo hostnamectl set-hostname mail.example.com
hostnamectl status
Check /etc/hosts. Don’t map your mail hostname to 127.0.1.1 in a way that breaks lookups.
A safe pattern:
127.0.0.1 localhost
YOUR.SERVER.IP mail.example.com mail
2) Create the forward DNS record
In DNS for example.com, create:
- A record:
mail.example.com→YOUR.SERVER.IP - MX record (if you will receive mail too):
example.com→mail.example.com(priority 10)
If you’re only sending (no inbound), you can skip MX for now.
For outbound deliverability, SPF/DKIM/DMARC plus rDNS matter far more than MX.
3) Verify DNS resolves from the VPS
dig +short mail.example.com A
dig +short example.com MX
If DNS doesn’t return what you expect, stop and fix it before continuing.
If you’re planning a migration or lowering TTLs before a cutover, this walkthrough is a good reference: DNS cutover tutorial.
Set reverse DNS (PTR) the right way
Reverse DNS is set at your hosting provider. It lives on the IP owner’s nameservers.
The target is simple:
YOUR.SERVER.IPPTR →mail.example.com
After you request/set PTR, verify it:
dig +short -x YOUR.SERVER.IP
Rule you should not break: forward-confirmed reverse DNS.
In practice that means:
- PTR points to
mail.example.com mail.example.comA record points back to the same IP
If you want a more detailed rDNS walkthrough, see PTR record setup tutorial.
Install Postfix and basic tools (Ubuntu/Debian)
If Postfix is already installed, skip the install. Go straight to the configuration checks.
sudo apt update
sudo apt install -y postfix mailutils libsasl2-modules ca-certificates
During the Postfix prompt:
- Select Internet Site
- System mail name: example.com (not
mail.example.com)
Confirm Postfix identity settings
sudo postconf -n | egrep '^(myhostname|mydomain|myorigin|smtpd_banner)'
A sane baseline looks like:
myhostname = mail.example.commydomain = example.commyorigin = $mydomainsmtpd_banner = $myhostname ESMTP
If you need to adjust anything:
sudo postconf -e 'myhostname = mail.example.com'
sudo postconf -e 'mydomain = example.com'
sudo postconf -e 'myorigin = $mydomain'
sudo systemctl restart postfix
Publish SPF with a tight policy
SPF is a TXT record on the domain that appears in the SMTP envelope. It often matches your visible From domain.
Keep SPF tight from the start. Loose records are easy to forget. They’re also easy to abuse and hard to audit later.
1) Decide what is allowed to send
Most setups fall into one of these buckets:
- Only this VPS sends for
example.com. - This VPS + Google/Microsoft (hybrid setups).
- This VPS + a transactional provider (receipts/alerts via a vendor).
2) Create the SPF TXT record
If only your VPS sends mail and it uses the server IP:
Host/Name: example.com
Type: TXT
Value: v=spf1 ip4:YOUR.SERVER.IP -all
If you send from the hostname and want to reference its A record:
Value: v=spf1 a:mail.example.com -all
Avoid +all.
Avoid ~all unless you’re mid-migration and actively measuring. In 2026, strict SPF is normal for small domains.
3) Check SPF is published
dig +short TXT example.com
DKIM signing with OpenDKIM (practical, repeatable)
DKIM is one of the fastest ways to stop looking “anonymous” to mailbox providers. It also gives DMARC something real to enforce.
This section stays focused.
If you want the full deep walk-through (test commands, troubleshooting, and common mistakes), use: DKIM setup guide tutorial.
1) Install OpenDKIM
sudo apt install -y opendkim opendkim-tools
2) Create a DKIM key
Choose a selector you can rotate later. Using a year or year/quarter keeps rotations straightforward. For example: s2026.
sudo mkdir -p /etc/opendkim/keys/example.com
cd /etc/opendkim/keys/example.com
sudo opendkim-genkey -s s2026 -d example.com
sudo chown -R opendkim:opendkim /etc/opendkim/keys
sudo chmod 0700 /etc/opendkim/keys/example.com
You should now have:
s2026.private(keep secret)s2026.txt(DNS record template)
3) Configure OpenDKIM (key table + signing table)
Edit (or create) these files:
/etc/opendkim/key.table/etc/opendkim/signing.table/etc/opendkim/trusted.hosts
# /etc/opendkim/key.table
s2026._domainkey.example.com example.com:s2026:/etc/opendkim/keys/example.com/s2026.private
# /etc/opendkim/signing.table
*@example.com s2026._domainkey.example.com
# /etc/opendkim/trusted.hosts
127.0.0.1
localhost
mail.example.com
Now update /etc/opendkim.conf (key lines):
Syslog yes
UMask 002
Canonicalization relaxed/simple
Mode sv
SubDomains no
Socket inet:12301@localhost
KeyTable /etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
ExternalIgnoreList /etc/opendkim/trusted.hosts
InternalHosts /etc/opendkim/trusted.hosts
4) Connect Postfix to OpenDKIM via milter
sudo postconf -e 'milter_default_action = accept'
sudo postconf -e 'milter_protocol = 6'
sudo postconf -e 'smtpd_milters = inet:localhost:12301'
sudo postconf -e 'non_smtpd_milters = inet:localhost:12301'
Restart services:
sudo systemctl restart opendkim
sudo systemctl restart postfix
sudo systemctl status opendkim --no-pager
5) Publish the DKIM DNS record
Open /etc/opendkim/keys/example.com/s2026.txt and publish it as a TXT record at:
s2026._domainkey.example.com
Then confirm it resolves:
dig +short TXT s2026._domainkey.example.com
Publish DMARC with alignment that matches your real sending
DMARC is your policy engine. It tells receivers what to do when SPF/DKIM fail.
It also enforces alignment between the visible “From:” domain and the domain that authenticated.
Start with monitoring (p=none) for 48–72 hours
Create a TXT record:
Host/Name: _dmarc.example.com
Type: TXT
Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensics@example.com; fo=1; adkim=s; aspf=s
Notes:
adkim=sandaspf=s(strict) reduce spoofing but leave less room for misconfiguration.- Create the mailboxes (or aliases) for DMARC reports. They can get noisy.
Move to enforcement once you confirm alignment
After you see DKIM pass and align for legitimate traffic, move in steps:
p=quarantine; pct=25p=quarantine; pct=100p=reject; pct=100
This is where domains often break marketing tools, ticketing systems, and “send as” features.
Audit everything that sends as @example.com before you go to reject.
Enable TLS for SMTP (Let’s Encrypt + correct ports)
TLS won’t magically fix deliverability. But missing or broken STARTTLS does you no favors.
At a minimum, use a valid certificate and consistent TLS negotiation on port 25.
1) Get a certificate for the mail hostname
Install Certbot and request a cert. For a simple mail hostname, HTTP validation is easiest if port 80 is reachable.
sudo apt install -y certbot
sudo certbot certonly --standalone -d mail.example.com
Certificates land in:
/etc/letsencrypt/live/mail.example.com/fullchain.pem
/etc/letsencrypt/live/mail.example.com/privkey.pem
2) Point Postfix to the certificate
sudo postconf -e 'smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem'
sudo postconf -e 'smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem'
sudo postconf -e 'smtpd_tls_security_level=may'
sudo postconf -e 'smtp_tls_security_level=may'
sudo postconf -e 'smtpd_tls_loglevel=1'
Restart:
sudo systemctl restart postfix
3) Verify STARTTLS is offered
openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com
If you see certificate name mismatches, treat it as an identity problem.
Align PTR, hostname, and certificate names. Don’t swap certs until it “looks” right.
If renewals fail later, keep this guide bookmarked: Let’s Encrypt renewal troubleshooting tutorial.
Open the right firewall ports (and only those)
Deliverability includes basic reachability. Remote providers must be able to accept your connections (for outbound).
If you receive mail, you must accept theirs.
Outbound SMTP blocks are common on some networks. Confirm your provider allows it.
On Ubuntu/Debian with UFW:
sudo ufw allow 22/tcp
sudo ufw allow 25/tcp
sudo ufw allow 587/tcp
sudo ufw allow 465/tcp
sudo ufw status verbose
If the same VPS hosts websites, you’ll also need 80/443.
For safer SSH rules and layered firewalling, follow: VPS firewall setup guide tutorial.
Send a test email and read the headers like an operator
Don’t guess. Send a message to a mailbox you control (Gmail, Outlook, Proton, or a corporate mailbox).
Then inspect the received headers.
1) Send a message from the VPS
echo "Deliverability test $(date -Is)" | mail -s "Test from VPS" you@yourmailbox.com
2) Check Postfix logs
sudo journalctl -u postfix -n 200 --no-pager
3) Verify header results
In the received message headers, look for results like:
spf=passdkim=passdmarc=pass
If SPF passes but DMARC fails, you’re usually looking at alignment problems.
The visible From domain doesn’t match the authenticated domain. Another common cause is DKIM signing not being applied to the domain shown in From.
Common deliverability mistakes that waste days
- PTR points to a different name than your SMTP banner. Receivers flag the mismatch quickly.
- Using the bare domain as PTR (
example.com) while HELO saysmail.example.com. Choose one identity and keep it consistent. - SPF too broad (stale includes, old services still authorized, or living on
~allforever). - DMARC at reject before you’ve audited senders. Password resets, invoices, and CRM mail are the first casualties.
- Sending bulk mail from a fresh IP. Warm up slowly, or use a specialist sender for campaigns.
Operational checklist: what to verify after every change
- DNS: A record for
mail.example.compoints to the server IP. - rDNS:
dig -x IPreturnsmail.example.com. - Forward-confirmed reverse:
dig mail.example.com Areturns the same IP. - SPF: TXT record exists and matches your real senders.
- DKIM: selector TXT record resolves; headers show
dkim=pass. - DMARC: record exists; reports are arriving; alignment passes.
- TLS:
openssl s_client -starttls smtpshows a valid cert chain and correct hostname. - Logs: no repeated deferrals, auth failures, or policy rejections.
Where HostMyCode fits (hosting choices that make mail easier)
Mail identity depends on basics you can control: stable IPs, predictable networking, and the ability to set rDNS correctly.
If you’re running a small business mail server alongside your sites, a managed VPS hosting plan helps when you want an operator to sanity-check DNS, TLS renewals, and firewall rules.
If you mainly host websites (WordPress, WooCommerce, or client sites) and just need clean domain and DNS control, keep the mail stack out of your VPS.
Manage domains centrally via HostMyCode domains. It’s easier to keep SPF/DKIM/DMARC consistent across projects when DNS lives in one place.
If you want email sending that stays predictable, start with infrastructure that lets you set clean rDNS, maintain stable networking, and administer Linux without surprises. A HostMyCode VPS gives you full control for SPF/DKIM/DMARC and TLS, while managed VPS hosting makes sense if you want an expert to double-check the identity baseline and keep it tidy over time.
FAQ
Do I need MX records to improve outbound deliverability?
No. MX is for inbound routing. Outbound deliverability mostly comes down to SPF/DKIM/DMARC alignment, plus rDNS and consistent hostname/HELO.
Should I use p=reject in DMARC immediately?
Not on day one. Start with p=none, confirm alignment for all legitimate senders, then move to quarantine/reject in phases.
Can I send from my VPS IP if it’s “new”?
You can, but warm up slowly and keep volumes low at first. For bulk campaigns, a dedicated sending service is usually safer than a fresh VPS IP.
Why does SPF pass but messages still land in spam?
SPF alone is weak. Add DKIM + DMARC, fix rDNS/hostname consistency, and avoid sudden spikes in sending volume.
What’s the quickest way to confirm my identity is consistent?
Check that PTR → hostname and hostname A → IP match, then send a test and confirm spf=pass, dkim=pass, and dmarc=pass in the received headers.
Summary: a clean mail identity beats “tuning”
Most VPS mail deliverability problems aren’t caused by mysterious filters. They come from mismatched names, missing rDNS, and half-finished authentication records.
Keep the chain consistent—hostname, PTR, SPF, DKIM, DMARC, and TLS. You’ll see fewer rejections and far fewer spam-folder surprises.
If you’re setting this up for a business domain and want infrastructure you can operate without constant babysitting, start with a HostMyCode VPS and keep your DNS changes documented and repeatable.