Server security guide · Romania

How do I secure a mail server with SPF, DKIM and DMARC?

Without SPF, DKIM and DMARC, anyone can send email that appears to come from your domain, while your genuine messages land in spam. The three DNS records are free, take an afternoon to set up, and the large mailbox providers expect them from bulk senders.

Updated:

Short answer

  1. 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.
  2. Sign every message with DKIM using a 2048-bit key that you rotate regularly, with the selector published in DNS.
  3. 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.
  4. 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
MechanismWhere it is configuredRecommended valueWhat it prevents
SPFTXT on the domainv=spf1 ip4:203.0.113.25 include:relay.example.net ~all, with DMARC p=rejectSending from unauthorised servers
DKIMTXT on selector._domainkey + signing in the MTARSA 2048, yearly rotationContent tampering, sender forgery
DMARCTXT on _dmarcp=reject after a p=none period with ruaForging the visible From address
PTR (rDNS)At the IP providermail.example.ro → IP → mail.example.roRejection before any other check
TLSPostfix / MailuValid certificate on 25, 587, 465Interception of passwords and messages
Relaysmtpd_relay_restrictionsAuthenticated or own networks onlyOpen relay, blocklists

Commands and configuration

DNS records (TXT) for example.ro
example.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 outside
dig +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.

Request a security review

A production server starts getting attacked within minutes of receiving a public IP address, however small the project is. This guide ranks the controls by impact, from SSH access to incident response, with the Romanian rules that apply along the way. Every topic has its own page with a short answer, examples and ready-to-use configuration.