What a receiver actually decides, and in what order
A receiving mail server makes a series of decisions, and it makes most of them before it has read a single byte of your message. The ordering is the useful part, because a problem at the connection stage cannot be fixed with better content, and a beautifully authenticated message from an address with no history still lands in Junk. Reading the chain in order tells you where your effort belongs — which is almost never where people put it.
The first decision happens on the TCP connection: who is this, and should I talk to them at all? At that moment the receiver has your IP address, its reverse DNS, and whatever reputation it or its blocklist providers attach to that address. The second happens on the SMTP envelope — HELO and MAIL FROM — where SPF is evaluated against the connecting IP. The third arrives with the message data, where DKIM signatures are verified and DMARC decides whether either authentication result aligns with the domain in the visible From: header. Only after all of that does anything resembling content filtering begin, and by then most of the outcome is already fixed.
| Stage | What the receiver checks | Typical failure | What it costs you |
|---|---|---|---|
| TCP connection | IP reputation, reverse DNS, blocklist membership | No PTR record, or a generic provider PTR | Outright 5xx rejection at several large receivers |
| HELO / EHLO | Whether the announced name is an FQDN that resolves to the connecting address | localhost, a short hostname, or a name with no A record | Spam score, sometimes rejection |
| MAIL FROM | SPF for the envelope domain | No record, +all, or more than ten DNS lookups | SPF permerror, and DMARC failure if DKIM is absent |
| DATA | DKIM signature validity and DMARC alignment | Unsigned mail, or a signature a mailing list has broken | Junk folder at best |
| After acceptance | Complaint rate, engagement, domain reputation | Complaints above 0.3%, dead addresses, sudden volume | Silent decay across the whole domain |
Two things follow. The cheapest wins are at the top of the chain: a correct PTR record costs one field in a control panel and removes an entire class of rejection. And the bottom of the chain — the part everyone worries about, the wording of the message — is the part you have least leverage over, and the part that only starts to matter once everything above it is clean.
Port 25 is the cheapest part of the problem
Almost every large cloud blocks outbound port 25 by default, and unblocking it means asking. AWS, Google Cloud, Azure, Oracle Cloud and most of the big VPS brands ship with egress on 25 filtered, and the removal request is a form attached to an account that already carries your identity, your card and your phone number. That is where a self-hosting plan most often dies quietly, and it is why the search that brings most people to a page like this one is some version of which VPS has port 25 open.
It helps to be precise about which port does what, because the three are constantly confused. Port 25 is server-to-server: it is how one MX hands a message to another, it is never authenticated, and it is the only port that matters for delivering mail to people who are not your users. Port 587 is submission — your own clients authenticating to your server before it relays for them. Port 465 is the same thing with TLS from the first byte; it was deprecated in the nineties, then formally brought back by RFC 8314, and it is the sane default today. Losing outbound 25 stops you sending to the world; losing inbound 25 stops the world sending to you, and it is entirely possible to have one without the other and spend an afternoon blaming DNS.
On BitVPS outbound 25 is unblocked by default on every plan and in every location. There is no form and no exception process because there is nothing to lift. Inbound 25, 465 and 587 sit behind mail-aware scrubbing rather than a generic layer-3 filter, which is the distinction that matters during an attack: a filter that understands SMTP can shed a flood without also shedding the legitimate MX conversation behind it. The mail-server page has the specifics, and the DDoS explainer covers what scrubbing does and does not mean in general.
An open port 25 is a necessary condition and nowhere near a sufficient one — which is the entire reason this guide continues for another three thousand words.
The address you are handed decides more than your configuration does
Your configuration is a handful of DNS records and a day of work. The IP address is history you did not write. A /24 that spent 2019 sending pharmacy spam is remembered; an address recycled from a customer who was terminated last month arrives pre-judged; a range whose neighbours are noisy is judged by association at receivers that score at the /24 level. None of that is visible from inside the machine, and none of it responds to a better main.cf.
So check before you commit rather than after. The public blocklists tell you part of the story: Spamhaus is the one that actually moves delivery, with the SBL and CSS listing observed senders, the PBL listing ranges whose operator has declared they should not be sending mail directly, and the DBL listing domains rather than addresses. Barracuda and SpamCop are worth a look and are fast to clear when the cause is fixed. The two reputations that decide most of your outcome, though, are private: Google and Microsoft each maintain per-IP and per-domain scores you cannot query at all except through Postmaster Tools and SNDS, and only once you are sending enough for them to have an opinion.
Two warnings about the checklists you will find elsewhere. Half of them still tell you to check SORBS: SORBS was decommissioned by its owner on 5 June 2024 and its zones now answer with nothing, so a lookup against it is not a clean bill of health but a dead query. And treat UCEPROTECT level 2 and level 3 with scepticism — they list neighbours and entire autonomous systems by association and then invite you to pay for expedited removal, which is why most serious receivers ignore them. Chasing a level 3 listing is a way to spend a weekend achieving nothing. Spamhaus's own reputation portal is the one to take seriously.
| List | What it actually lists | Who consults it | What to do about it |
|---|---|---|---|
| Spamhaus SBL / CSS | Addresses observed sending spam; CSS targets low-volume snowshoe patterns | Very widely, including large receivers | Fix the cause, then request removal — relisting after a fake fix is worse than the first listing |
| Spamhaus PBL | Ranges whose operator says should not send mail directly | Widely | Not an accusation; the range policy has to be corrected by the host |
| Spamhaus DBL | Domains, not addresses | Widely | A domain reputation problem — moving IP will not help |
| Barracuda, SpamCop | Recent observed spam, trap-driven, short-lived | Appliances and mid-sized receivers | Self-service delisting; a second listing means the cause is still there |
| UCEPROTECT L2 / L3 | Neighbours and whole ASNs by association | Almost nobody who matters | Ignore it, and never pay to be removed |
| SORBS | Nothing — decommissioned in June 2024 | Nobody | Delete it from your checklist |
| Google and Microsoft internal | Private per-IP and per-domain reputation | The two receivers that decide most of your mail | Visible only through Postmaster Tools and SNDS |
This is also the part where a host either helps or does not. BitVPS checks every address against the major lists at provisioning and swaps it before you ever log in if it shows up, allocates mail customers out of /29s that have not been recycled from a previous mail customer within twelve months, and will move a /29 between machines in the same datacentre without re-IPing you — which matters enormously once an address has a reputation you spent six months building. None of that makes an address good; it makes it neutral, which is the most any host can honestly offer.
PTR, HELO and the A record have to tell the same story
This is the single most common reason a competently installed mail server is rejected, and it is the cheapest thing on this page to get right. Three names have to agree. Your server announces a hostname in HELO; that hostname has an A record pointing at the address it is connecting from; and that address has a PTR record pointing back at the hostname. Resolve it forwards and you arrive at the address; resolve it backwards and you arrive at the name. That round trip is called forward-confirmed reverse DNS, and since February 2024 a valid PTR record is not a nicety at Gmail but a stated requirement for every sender, bulk or not.
Four ways it goes wrong, in descending order of frequency. There is no PTR at all, because the host does not offer the field. There is a PTR, but it is the provider's generic one — something ending in the hosting company's domain, which announces to every receiver that this is a rented address in a range that mostly does not send mail. The HELO name is wrong: the default from the installer, a short unqualified hostname, or localhost, none of which resolve. And the one that catches careful people: the machine has IPv6, the MTA prefers IPv6 when the receiver publishes an AAAA record, and there is no PTR on the v6 address — so mail to Gmail over IPv4 works perfectly while the same mail over IPv6 is rejected. Either set the v6 PTR properly or pin the transport with smtp_address_preference = ipv4 until you have.
On BitVPS the PTR field is self-serve in the panel for every IPv4 and IPv6 address, it accepts any FQDN you want with no forced provider suffix, changes propagate globally in under five minutes, and bulk edits cover up to ten addresses at once. The network page has the details, and the reason to care is exactly this section: a host that makes you open a ticket to set reverse DNS is a host that will make you open a ticket every time you rebuild.
SPF, DKIM and DMARC: what each one proves, and what alignment means
These three are published as DNS records, they take an hour to set up, and they are described badly almost everywhere — usually as three interchangeable spam charms rather than three different assertions. SPF (RFC 7208) says which addresses may send mail carrying a given envelope sender. DKIM (RFC 6376) attaches a cryptographic signature over the headers and body, so the message can prove which domain took responsibility for it. Neither of them says anything at all about the address your recipient actually sees.
That is the job of DMARC (RFC 7489), and it is why alignment is the word that matters. DMARC passes when SPF or DKIM passes and the domain it authenticated matches the domain in the visible From: header. This is where the classic failure lives: your mail passes SPF because the bounce address is on a domain the sending host controls, but that domain is not the one in From:, so it does not align, and with no DKIM signature to fall back on, DMARC fails on a message that looked perfectly authenticated in the logs. The other classic is publishing p=reject on day one, before a single report has been read, and discovering a month later that the invoicing system has been silently rejected the whole time. Start at p=none with an rua address, read what arrives, and tighten afterwards.
| Mechanism | What it authenticates | Survives forwarding | Aligns with | Most common mistake |
|---|---|---|---|---|
| SPF | The envelope sender domain against the connecting address | No — the forwarder becomes the sender | The Return-Path domain | More than ten DNS lookups, or a lazy +all |
| DKIM | The message itself, via a signature over selected headers and the body | Usually yes, unless a list rewrites the body | The d= domain in the signature | 1024-bit keys, a selector published in the wrong place, too few headers signed |
| DMARC | Nothing on its own — it requires SPF or DKIM to pass and align | Inherits whichever one survived | The visible From: header | Publishing p=reject before reading a single report |
| ARC | The chain of custody across forwarders and mailing lists | Designed precisely for that case | Nothing directly — it preserves earlier results | Assuming every receiver honours it; many still do not |
Two operational notes worth more than they look. Keep the SPF record inside ten DNS lookups — every include: costs one, and nesting three SaaS vendors blows the limit and turns into a permanent error rather than a soft failure. And rotate DKIM selectors occasionally rather than never: a selector is cheap to add, and having a second one already published is the difference between a five-minute key rotation and an outage.
The floor moved in 2024, and again in 2025
For twenty years the baseline for sending mail was roughly "have a PTR and do not be on Spamhaus". That changed in February 2024, when Google and Yahoo published near-identical sender requirements and started enforcing them. Every sender — including you, sending four messages a day — now needs a valid forward-confirmed PTR record, TLS on the connection, and at least one of SPF or DKIM. Senders above roughly five thousand messages a day to a single receiver need SPF and DKIM and a DMARC record, a working one-click unsubscribe header per RFC 8058, and a spam complaint rate kept under 0.3%.
Microsoft followed on 5 May 2025 with the same shape of rule for Outlook.com, Hotmail and Live: domains sending more than five thousand messages a day to those consumer mailboxes must have SPF, DKIM and DMARC, with non-compliant mail routed to Junk first and rejected outright afterwards. Microsoft's sender support and Yahoo's best practices are both worth ten minutes of reading before you send anything.
| Requirement | Gmail, since Feb 2024 | Yahoo, since Feb 2024 | Outlook.com, since May 2025 | Does it apply to a small self-hoster? |
|---|---|---|---|---|
| Forward-confirmed PTR record | All senders | All senders | Expected | Yes — do this one first |
| TLS on the connection | All senders | All senders | Expected | Yes, and it is one line of config |
| SPF or DKIM | All senders | All senders | Expected | Yes |
| SPF and DKIM and DMARC | Above ~5,000/day | Above ~5,000/day | Above ~5,000/day | Below the threshold, but do it anyway |
| One-click unsubscribe | Bulk senders | Bulk senders | Recommended | Only if you send bulk mail at all |
| Complaints under 0.3% | Bulk senders | Bulk senders | Enforced in practice | Yes, in effect |
The practical consequence for a personal or small-team server is not that the thresholds catch you — they will not — but that the unauthenticated baseline is now genuinely anomalous. Mail with no DMARC record from an address with no history used to be ordinary. In 2026 it looks like the profile of everything the filters were built to stop. Configure as though you were a bulk sender even though you are not, because the cost is an afternoon and the alternative is being scored against a population you do not belong to.
Warming an address nobody has ever seen
A new address does not start neutral so much as start unknown, and unknown is treated with suspicion in proportion to how much you send. The ramp that works is boring: begin with genuine correspondence to people who will actually open and reply, keep daily volume roughly stable and let it grow gradually rather than in steps, and never point a list you bought or exported from somewhere at a fresh address. Engagement is the signal that converts unknown into trusted, and there is no shortcut that produces it.
Measure with the tools the receivers give you rather than by looking at your own inbox. Google's Postmaster Tools shows domain and IP reputation, spam complaint rates and authentication pass rates once you have verified the domain — though it stays empty until you send enough for it to aggregate anything, which for a personal server can mean never, and that is fine. Microsoft's SNDS does the same for Outlook.com and pairs with the Junk Mail Reporting Program, which forwards complaints straight to you. A one-shot scoring service is useful for catching a broken record in ten seconds, and useless for anything else — it tells you nothing about reputation, because it has no history with you either.
Set expectations honestly about the hardest receiver. Outlook.com is where a new address struggles longest: it is common for a correctly configured server with perfect authentication to be filed in Junk there for weeks while Gmail accepts it from the first message. The fix is time, consistency and recipients who move the message out of Junk — not another DNS record. If Outlook.com deliverability on day one is a business requirement rather than a preference, that is one of the signals that you want a relay rather than a self-hosted sender, which is the subject of the last section.
What to run, and how much machine it needs
Four shapes cover almost everyone. Postfix paired with Dovecot for IMAP and rspamd for filtering is the reference deployment: three daemons, plain-text configuration, and every error message you will ever see already answered somewhere. OpenSMTPD does the same job with a configuration file you can read in one sitting, which is worth more than it sounds at three in the morning. Stalwart is a single binary that speaks SMTP, IMAP and JMAP with filtering built in, and is the most pleasant greenfield option today. And Mailcow or Mail-in-a-Box assemble the whole thing for you, webmail included, at the price of a stack you did not choose and cannot easily take apart.
Sizing is less about mailboxes than about what you bolt onto the front. SMTP and IMAP themselves are cheap; a few dozen mailboxes are a rounding error on any modern machine. The memory goes to filtering. rspamd is modest, a few hundred megabytes with its maps loaded. ClamAV is not: the signature database alone pushes it well past a gigabyte of resident memory, and it is the single component most likely to make a small instance start swapping — which on a mail server means the queue backs up and delivery slows to the point that receivers start deferring you. Run it if you have the RAM, skip it if you do not, and let rspamd carry the load.
| Stack | Configuration surface | What you get | Realistic memory floor | Suits |
|---|---|---|---|---|
| Postfix + Dovecot + rspamd | Three daemons, plain text | The reference deployment, documented everywhere | ~1 GB without ClamAV, ~2.5 GB with | Anyone who wants to understand the parts |
| OpenSMTPD + Dovecot | One short, readable file | Small, auditable, OpenBSD lineage | ~512 MB | Small setups and people who dislike Postfix syntax |
| Stalwart | One binary, one config, a web UI | SMTP, IMAP, JMAP and filtering in a single process | ~1 GB | New deployments with no legacy to carry |
| Mailcow | A compose file | Everything wired together, webmail included | 6 GB, per its own documentation | People who want it finished today |
| Mail-in-a-Box | One install script on a clean box | Opinionated all-in-one, DNS included | ~2 GB | A personal domain, set up once |
Mapped onto real plans: a Starter at $8.50 with 2 vCPU, 4 GB of RAM and 60 GB of NVMe runs Postfix, Dovecot and rspamd for a personal domain comfortably, provided you leave ClamAV out. A Growth at $13.50 with 4 vCPU, 8 GB and 120 GB is the size at which you stop thinking about it — twenty to thirty mailboxes with full filtering, plenty of headroom for a mail store that grows for years. Storage is the axis that actually runs out first, because mail is kept forever by everyone who has ever received any.
Bringing it up in the right order
1. Point the domain and deploy the instance. Decide the hostname the server will identify itself as — mail.example.com is the convention — publish its A record, add AAAA only if you intend to send over IPv6, and publish the domain's MX pointing at that name. Choose the location nearest the people you correspond with; on BitVPS the instance is live about sixty seconds after payment confirms, with outbound 25 already open.
2. Set reverse DNS to match. Set the PTR of the IPv4 address — and of the IPv6 address, if you published an AAAA — to exactly the hostname from step one. Forward and reverse must agree in both directions. This is one panel field and it is the highest-value minute of the whole procedure.
3. Open the right ports both ways. Outbound 25 to deliver, inbound 25 to receive, 587 and 465 for your own users to submit, 993 for IMAP, everything else closed. A firewall that allows outbound 25 but not inbound looks exactly like a DNS problem for the first hour of debugging, and it is not one.
4. Install the MTA and give it a real identity. Postfix, OpenSMTPD or Stalwart; set the HELO name to the hostname from step one; enable TLS with a certificate for that name. Let's Encrypt is free and is what most of the internet presents. Send yourself a message and read the headers before continuing — every later step assumes this one worked.
5. Publish SPF, DKIM and DMARC. An SPF record listing the sending address, ending in ~all while you test. A 2048-bit DKIM key with its selector published and signing enabled. A DMARC record at p=none with an rua address so reports start arriving. Three DNS records, no cost, an hour at most.
6. Read the authentication results, not the inbox. Send to Gmail, to Outlook.com and to one corporate receiver, then open Authentication-Results on each. You want spf=pass, dkim=pass, dmarc=pass, and the alignment to be against the domain in the visible From:. Junk with three passes is a reputation problem; Junk with a failure is a configuration problem. They are fixed in completely different ways, and confusing them wastes weeks.
7. Tighten once the reports are clean. After a week or two of DMARC reports in which no legitimate source is failing, move to p=quarantine, then later to p=reject, and change SPF from ~all to -all. Tightening before reading reports is how people block their own invoices for a month without noticing.
8. Add the parts everyone forgets. Publish MTA-STS and TLS-RPT so other senders know to insist on TLS with you, add DANE if your zone is signed, put rspamd in front of the inbox, back the mail store up somewhere that is not this machine, and encrypt it at rest — the full-disk encryption walkthrough covers what that does and does not protect. Then watch the outbound queue: a queue that is quietly growing is the first symptom of a reputation problem, and it shows up days before you notice missing replies.
When self-hosting is the wrong tool
There are cases where running your own sender is a bad trade, and being clear about them is more useful than another paragraph of encouragement. Cold-start bulk marketing is the obvious one: a fresh address with no history sending thousands of messages is the exact signature the filters exist to catch, and no configuration rescues it. Transactional mail where a lost message costs money — password resets, order confirmations, two-factor codes — belongs on infrastructure with an established reputation, because the two weeks a new address spends proving itself are two weeks of support tickets. And any team without someone who will look at a mail queue on a Sunday is a team that will discover its outbound has been deferred since Friday.
There is also an anonymity trade that gets skipped in most write-ups. A mail server is the least anonymous thing you can run. It publishes a domain, a stable address, a PTR record naming that domain, an MX record tying them together, and it hands every recipient a full set of headers describing the path. Anonymity and a public MX pull in opposite directions, and if the reason you are here is privacy rather than control, read how traceable crypto hosting really is before you build. Self-hosting genuinely does remove a third party from your stored mail and its metadata, which is a real and worthwhile gain — it does not make the mail itself anonymous, and it cannot, because half of every conversation lives in somebody else's mailbox.
The arrangement that works for most people is a split. Keep the mail that must arrive at a provider with a reputation, self-host a second domain for the correspondence you want off third-party infrastructure, and let each carry the load it is good at. It costs one extra DNS zone, it means neither system is doing a job it is bad at, and it is what a large share of the people running a mail server on BitVPS actually do. Whatever you send, opt-in only — purchased lists are outside our acceptable use policy and they are the fastest way to burn an address that was clean when we handed it to you.