Short answer
- Publish an SPF record that lists exactly the servers allowed to send, ending in -all for domains that never send mail and in ~all, together with DMARC p=reject, for those that do.
- Sign every message with DKIM using a 2048-bit key that you rotate regularly, with the selector published in DNS.
- Publish DMARC starting at p=none with rua reports so you can see who sends in your name, then move to p=quarantine and p=reject.
- Give the server a correct PTR record, TLS on ports 25, 587 and 465, no open relay and a send-rate limit, and send transactional mail through a separate relay.
- SPF
- ~all with DMARC p=reject; -all if the domain never sends; max 10 DNS lookups
- DKIM
- RSA 2048 key, selector rotated at least yearly
- DMARC
- p=none, then p=quarantine, then p=reject, with rua=
- TLS ports
- 25 STARTTLS, 587 STARTTLS, 465 implicit TLS
What each of the three records does
SPF tells the receiving server which IP addresses may send for your domain; -all means any other source is rejected, while ~all only marks it. DKIM adds a cryptographic signature to the message header, checked against the public key in DNS, so a changed body or a sender without the key fails verification. DMARC ties both to the domain visible in the From field and tells receivers what to do on failure and where to send reports. Without DMARC, SPF and DKIM are hints; with it, they become policy.
The server itself: PTR, TLS, relay and separation
Large providers first check that the sending IP has a PTR record that resolves back to the server's name; without it, the message can be rejected before SPF is even evaluated. TLS must be on for every submission port, with a valid certificate, so passwords never travel in clear text. The server relays mail only for authenticated users or your own networks, because an open relay lands on blocklists within hours. Limit the send rate per account so one stolen password cannot send ten thousand messages. Transactional mail leaves through a separate relay, on its own subdomain.
- Read DMARC reports for a few weeks at p=none before tightening the policy
- MTA-STS and TLS-RPT are an optional next step to enforce TLS on inbound mail
- A domain that sends no mail gets SPF v=spf1 -all and DMARC p=reject
What Romanian law expects
Mail on a company domain almost always contains personal data, so GDPR Article 32 applies. A compromised mailbox sending phishing to your customers is an incident you must assess and, if data was accessed, report to ANSPDCP within 72 hours. For entities under OUG 155/2024, protection of communications and multi-factor authentication are explicit minimum measures. Invoices sent by email are accounting documents: an IBAN swapped in a forged invoice sent in your name is exactly the scenario DMARC p=reject stops.
DNS records and server settings for trustworthy email| Mechanism | Where it is configured | Recommended value | What it prevents |
|---|
| SPF | TXT on the domain | v=spf1 ip4:203.0.113.25 include:relay.example.net ~all, with DMARC p=reject | Sending from unauthorised servers |
|---|
| DKIM | TXT on selector._domainkey + signing in the MTA | RSA 2048, yearly rotation | Content tampering, sender forgery |
|---|
| DMARC | TXT on _dmarc | p=reject after a p=none period with rua | Forging the visible From address |
|---|
| PTR (rDNS) | At the IP provider | mail.example.ro → IP → mail.example.ro | Rejection before any other check |
|---|
| TLS | Postfix / Mailu | Valid certificate on 25, 587, 465 | Interception of passwords and messages |
|---|
| Relay | smtpd_relay_restrictions | Authenticated or own networks only | Open relay, blocklists |
|---|
Commands and configuration
DNS records (TXT) for example.roexample.ro. TXT "v=spf1 ip4:203.0.113.25 include:relay.example.net ~all"
s2026._domainkey.example.ro. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq...public-key...IDAQAB"
_dmarc.example.ro. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.ro; adkim=s; aspf=s; pct=100"
Postfix: opportunistic TLS on 25, mandatory TLS on submission, no open relay# /etc/postfix/main.cf (fragment) — port 25, server to server: opportunistic TLS
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.ro/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.ro/privkey.pem
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_client_connection_rate_limit = 30
# /etc/postfix/master.cf — submission (587): TLS REQUIRED and authenticated users only
submission inet n - y - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
Verify from the outsidedig +short TXT example.ro
dig +short TXT _dmarc.example.ro
dig +short -x 203.0.113.25
openssl s_client -starttls smtp -connect mail.example.ro:587 -servername mail.example.ro </dev/null | grep -E "Verify|subject="
Practical examples
SaaS company in Iasi sending password-reset emails
The application sent reset emails through the same server as the staff. One poorly received marketing campaign damaged the sender reputation and resets began landing in spam. Moving the application to a separate relay, with its own subdomain and DKIM key, isolated the two flows.
Accounting firm in Timisoara whose domain was used for phishing
Clients received fake invoices 'from' the firm with a different IBAN, and the domain had no DMARC. SPF, DKIM and DMARC at p=none with reports exposed three unauthorised sources in the first week; after the move to p=reject the forged messages stopped reaching inboxes.
Common mistakes
- Stopping at SPF, with ~all or -all, and publishing no DMARC: without a p=reject policy, both variants still let a forged message reach the recipient.
- Exceeding ten DNS lookups in SPF through chained includes, which makes the record invalid.
- Publishing DMARC p=reject on day one, without reports, and blocking your own invoicing system.
- Having no PTR record for the server's IP, or a PTR that shows the provider's generic name.
How 4hosting helps
- Mailu & SMTP Relay installs self-hosted Mailu on your domain with SPF, DKIM and DMARC configured, plus a separate relay for transactional mail. The documentation section has a Mailu and SMTP relay guide.
- The same service covers migration from cPanel or Google Workspace, within your included hours: 1–8 h a month on VPS, 5–10 h on dedicated servers (depending on plan), 10 h on GPU servers. You request them from the client panel; unused hours are not carried over.
- cPanel plans include email; you add the DMARC record in your DNS zone yourself.
Related questions
How long should I stay at p=none before moving to reject?
Until the DMARC reports show that every legitimate source, meaning your own server, the application, the newsletter tool and invoicing, passes SPF or aligned DKIM. That usually takes two to four weeks. Move to p=quarantine first, perhaps with pct=25, then to p=reject.
Is it worth running my own mail server?
Yes, if you want control over your data and a fixed cost, and someone will maintain it: updates, sender reputation, DMARC reports. Mailu bundles Postfix, Dovecot, antispam and webmail into a manageable Docker installation. If nobody can maintain it, a hosted service is the safer choice.
Why should transactional mail be separate from people's mail?
Because reputation is calculated per domain and per IP. A badly received campaign or one compromised account hurts the delivery of everything sent from the same source. With a dedicated subdomain and relay, password resets and invoices reach the inbox whatever happens to the newsletter.