Skip to content
CitexNode
All guides

Sending mail from your VPS

Why the mail ports are blocked, how to request unblocking, SPF, DKIM and DMARC, and sending through an external mail service.

7 min read

Contact forms, notifications, your own mail server: at some point your VPS needs to send mail. This guide explains why that does not work right away and which options you have.

Commands cover Debian 12 and 13, Ubuntu 22.04 and 24.04, AlmaLinux 9 and Rocky Linux 9 and run as root.

Why the mail ports are blocked

Outgoing ports 25, 465 and 587 are blocked. These are the ports used to send mail. A single hacked or misconfigured server can send thousands of spam mails in a short time. Our addresses then end up on blocklists and nobody's mail gets through any more. So the block also protects your own mail.

The block only applies to outgoing connections on these three ports. Other ports such as 443 for HTTPS are not affected.

To check whether the ports are closed for you:

bash
timeout 5 bash -c '</dev/tcp/smtp.gmail.com/587' && echo open || echo blocked

Option 1: request unblocking

For your own mail server, or if you have to send directly via 25, 465 or 587.

Before you start

  • Set reverse DNS on the IPv4 to your mail server's name, e.g. mail.example.com, and add an A record for it. See IPv6 and reverse DNS.
  • Set up SPF, DKIM and DMARC (see below). Without them your mail lands in spam or is rejected.

Submit the request

  1. In the dashboard, open your VPS, Network tab, Mail ports section.
  2. Fill in the form:
    • Mail server software, e.g. Postfix, mailcow or Mailu.
    • Mail server hostname, e.g. mail.example.com. It should be set as reverse DNS on the IPv4.
    • What are the emails for? Briefly describe your project and who receives the emails.
    • Expected volume, e.g. 200 emails per day.
  3. Confirm the rules: no spam, no unsolicited advertising. In case of abuse, the ports will be blocked again.
  4. Click Send request.

The request creates a ticket. The section then says "Your request is being reviewed. Any questions will come via the ticket." with Go to ticket next to it. We review every request individually; there is no fixed processing time.

If the request is approved, it says "The mail ports are open for this server." You can close them yourself with Block again when you no longer need them. If it was rejected, that is shown there, often with a reason, and you can submit a new request.

If the section says "Your plan does not block the mail ports.", you do not need to request anything.

Keep an eye on blocklists

Under Spam blocklists in the same tab you see whether your addresses are on known blocklists. Check now queries them again. If an address is listed, mail from it will not reach many receivers. Find the cause (hacked form, open relay) before you send more.

Option 2: send through an external mail service

For forms and notifications this is often the easier way. A mail delivery provider (an SMTP relay) takes care of deliverability, blocklists and DKIM; your server just hands the mail over.

Your provider's guide explains the details. Many applications (WordPress with an SMTP plugin, Nextcloud, Gitea) have their own SMTP settings; enter server, port 2525 and credentials there and you need nothing else on the VPS.

Postfix as a relay to the service

If every program on the server should be able to send mail via sendmail, set up Postfix as a relay only. Replace smtp.provider.example with your provider's server.

Debian and Ubuntu (when asked for the type of configuration, choose Internet with smarthost, or No configuration and set everything with the commands below):

bash
apt install -y postfix libsasl2-modules

AlmaLinux and Rocky Linux:

bash
dnf install -y postfix cyrus-sasl-plain
systemctl enable --now postfix

Set the options:

bash
postconf -e 'relayhost = [smtp.provider.example]:2525'
postconf -e 'smtp_sasl_auth_enable = yes'
postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'
postconf -e 'smtp_sasl_security_options = noanonymous'
postconf -e 'smtp_tls_security_level = encrypt'
postconf -e 'inet_interfaces = loopback-only'

inet_interfaces = loopback-only makes Postfix accept mail only from the server itself, so it never becomes an open relay.

Credentials in /etc/postfix/sasl_passwd:

text
[smtp.provider.example]:2525 USERNAME:PASSWORD
bash
chmod 600 /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd
systemctl restart postfix

Check that it worked

Send a test mail to yourself:

bash
printf 'Subject: Test from the VPS\n\nIt works.\n' | sendmail you@example.com

Then look at the log:

bash
journalctl -u postfix -n 30 --no-pager

If it says status=sent, the service accepted the mail. mailq shows mail that is still waiting. If the mail lands in spam, SPF or DKIM for the sender domain are usually missing.

SPF, DKIM and DMARC

Three DNS records tell receivers that mail from your domain is genuine. How to create TXT records is in Managing DNS records.

SPF lists who may send for your domain. A TXT record on the domain itself, e.g. for your own mail server:

text
v=spf1 ip4:203.0.113.5 ip6:2001:db8::5 -all

If you use a mail service, it tells you the right part, usually an include:…. There is only one SPF record per domain; several senders go into the same line.

DKIM signs every mail. Your mail server (mailcow, Mailu and rspamd can do this) or the mail service creates the key; you add the public part as a TXT record under a name like dkim._domainkey.example.com. You get name and value from there.

DMARC tells receivers what to do with mail that fails SPF and DKIM. A TXT record on _dmarc.example.com. To start, just monitor:

text
v=DMARC1; p=none; rua=mailto:dmarc@example.com

Once the reports look clean for a few weeks, switch to p=quarantine and later p=reject.

Check the records with:

bash
dig TXT example.com +short
dig TXT _dmarc.example.com +short
dig TXT dkim._domainkey.example.com +short

Common errors

  • Connection timed out to port 25, 465 or 587. The ports are blocked. Request unblocking, or use port 2525 or the service's HTTP API.
  • SASL authentication failed. Wrong username or password in sasl_passwd, postmap forgotten, or libsasl2-modules missing on Debian (cyrus-sasl-plain on Alma/Rocky).
  • Mail lands in spam. SPF or DKIM missing, or reverse DNS does not match the hostname. Many receivers show in the mail headers what failed (Authentication-Results).
  • Receiver rejects with "listed" or "blocked". The address is on a blocklist. Check under Spam blocklists.
  • Suddenly lots of mail in mailq. A hacked form may be sending spam. Stop Postfix (systemctl stop postfix), find the cause, clear the queue with postsuper -d ALL.

What next

If you get stuck, open a ticket.