Skip to main content

Postfix on a VPS: Sending Email From Your Own Server

VDS / VPS · 10.02.2026 · 5 min read
Illustration for “Postfix on a VPS: Sending Email From Your Own Server”
Important on ZevsHost servers: outbound SMTP ports 25, 465 and 587 are closed by default on VDS — this keeps the network clear of spam. The direct delivery described below will not work on a fresh server, and neither will external relays over SMTP. We open the ports for established customers on request through support, case by case. If you need mail right away, send it through your provider’s HTTP API: it runs over 443 and is not affected. Shared hosting and dedicated servers have no such restriction.

If your application on a VPS needs to send emails (registration, passwords, notifications), Postfix is the standard choice. Configure it correctly, or your emails will end up in spam.

Installing Postfix

sudo apt update
sudo apt install -y postfix
# Type: "Internet Site"
# Mail name: mail.example.com

Basic /etc/postfix/main.cf

myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = loopback-only  # Local sending only
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost
relayhost =
smtpd_banner = $myhostname ESMTP

# Restrictions
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination

Configuring DKIM via OpenDKIM

sudo apt install -y opendkim opendkim-tools

# Generate keys
sudo opendkim-genkey -s mail -d example.com -D /etc/opendkim/keys/example.com/

# Add to DNS TXT:
# mail._domainkey.example.com → content of mail.txt

# /etc/opendkim.conf:
Domain example.com
KeyFile /etc/opendkim/keys/example.com/mail.private
Selector mail
✅ Without DKIM, most mail providers will mark your emails as spam.

Testing delivery

sudo apt install -y mailutils

# Test
echo "Test email from VPS" | mail -s "Test" your@gmail.com

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

Alternative: SMTP Relay via an External Service

ServiceFree limitPros
SendGrid100 emails/dayHigh deliverability
Mailgun5000 emails/monthGood API
Amazon SES62000 emails/monthCheapest option
⚠️ Many hosting providers block port 25 for new VPS instances. Use port 587 (submission) or an external SMTP relay.

Common relay configuration mistakes

Most messages stuck in the Postfix queue on a ZevsHost VPS trace back to one of three causes.

status=deferred (delivery temporarily suspended: connect to gmail-smtp-in.l.google.com[...]:25: Connection timed out)

This is exactly how the outbound port block on 25/465/587 described above shows up in practice: Postfix tries to deliver the message directly, the connection hangs, and the message ends up stuck in the queue. If the port for an external relay hasn't been opened via a ticket yet, messages pile up in the queue instead of failing immediately with an error — which makes it confusing to diagnose.

SASL authentication failed; server smtp.sendgrid.net[...] said: 535 Authentication failed

Wrong login or password in /etc/postfix/sasl_passwd for the external relay, or the file wasn't rebuilt after editing: after any change, always run postmap /etc/postfix/sasl_passwd — Postfix reads the compiled .db database next to the file, not the file itself.

Client host rejected: cannot find your reverse hostname, [203.0.113.10]

The receiving server couldn't find a PTR record for your VPS's IP address and rejected the connection — a separate problem from the firewall block, and one that shows up even with the ports open. PTR is configured through hosting support, not through the domain's DNS panel.

Ports for sending mail

PortProtocolWhen it's usedEncryption
25SMTPServer-to-server, direct deliverySTARTTLS optional
465SMTPSSending from an application (implicit TLS)TLS from the start of the connection
587SubmissionRecommended port for applicationsSTARTTLS required

For relaying through an external service, use 587 or 465 — port 25 is only needed for direct delivery between mail servers, and on ZevsHost VDS it's closed by default along with the other two; see the warning at the top of the article.

When running your own Postfix doesn't fit

If your application sends marketing or bulk mail rather than transactional messages, Postfix plus an SMTP relay only solves part of the problem: without unsubscribe management, bounce handling, and sender reputation, a mailing quickly lands in recipients' spam filters. Use a dedicated mailing service's HTTP API for that instead of SMTP altogether. And if the application can already send mail through a mail provider's HTTP API, don't deploy Postfix at all — it's one more component to monitor and patch for no benefit.

How to verify the result

Check more than whether one message went out — check that the queue isn't growing and mail is actually flowing through the relay:

# Queue: the deferred count shouldn't keep growing
mailq | tail -20

# Test SASL authentication against the relay
swaks --to test@example.com --from you@example.com   --server smtp.sendgrid.net:587 --auth LOGIN   --auth-user apikey --auth-password YOUR_API_KEY --tls

# Check that the message actually went through the relay, not directly
grep "relay=" /var/log/mail.log | tail -5

After a successful send through the relay, the log line should contain relay=smtp.sendgrid.net[...]:587, not the recipient's IP directly. If you see the recipient's IP instead of the relay host, relayhost in main.cf didn't take effect — check the syntax and restart Postfix.

Was this article helpful?
← Back to Knowledge Base Ask Support