DNS setup
Two independent sets of records matter to a SithBit operator: the classic mail records that let the rest of the internet find and trust your server — and let your users’ mail clients locate its POP/IMAP/ submission ports — and the SithBit-specific record that proves you control a domain before it is authorized on-chain.
Throughout, example.com is the mail domain (the part after @) and
mail.example.com is the host running sithbitd.
Receiving mail: MX
example.com. MX 10 mail.example.com.
mail.example.com. A 203.0.113.25
The MX target must be an A/AAAA name, not a CNAME. Add
example.com to [smtp] local_domains in sithbitd.toml so the MX
listener accepts mail for it, and set [smtp] hostname (and
[spooler] hostname) to mail.example.com so the EHLO greeting
matches DNS — many receivers score a mismatch as spam.
One server may host several mail domains: point each domain’s MX at the
same host and list them all —
local_domains = ["example.com", "example.net"]. Each domain needs its
own on-chain authorization (below) under the same authority key,
its own DKIM record and [[spooler.dkim]] entry, and the daemon warns
at startup about any listed domain whose on-chain authority doesn’t
match (see the
configuration reference).
Inbound sender checks (sender_auth = "spf", the default, or
"dmarc-lite") need nothing from your DNS; they query the sender’s
records.
Sending mail: SPF, DKIM, DMARC, PTR
Receivers judge your outbound mail by these records; without them, expect the spam folder.
SPF — authorize your relay host to send for the domain:
example.com. TXT "v=spf1 mx -all"
mx authorizes whatever your MX records point at; add ip4:/ip6:
mechanisms if outbound mail leaves from other addresses, or
include: your smarthost provider when [spooler.smarthost] routes
mail through one.
DKIM — sithbitd signs authenticated submissions (rsa-sha256,
RFC 6376) when [spooler.dkim] is configured. Generate a key and
publish its public half at {selector}._domainkey.{domain}:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out dkim.pem
openssl rsa -in dkim.pem -pubout -outform DER | openssl base64 -A
[spooler.dkim]
domain = "example.com"
selector = "mail"
key_file = "dkim.pem" # PEM, PKCS#8 or PKCS#1
mail._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=<the base64 output>"
Only authenticated submission is signed — mail arriving at the MX from other servers relays unsigned, which is correct: it isn’t yours.
DMARC — tell receivers what to do when SPF/DKIM fail, and where to send reports:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
Add a ruf= address (and fo=1 to request a report on any failure) to
also receive per-message failure/forensic reports — a copy of each failing
message, so point it at a mailbox you control:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; fo=1; rua=mailto:[email protected]; ruf=mailto:[email protected]"
Start with p=none while you confirm SPF and DKIM pass, then tighten.
The rua= address can be your own SithBit deployment — other operators’
aggregate reports about example.com are how you confirm your SPF and
DKIM actually align in the wild. Point the record at your postmaster
mailbox:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
Two settings pair up on this receiving side, both off by default (rows
in the configuration reference).
[smtp] postmaster_wallet names the wallet that mail for bare
postmaster / postmaster@<local-domain> is delivered to, exempting it
from the frombox/postage gate — without it an external reporter, who
never holds a prepaid frombox, is refused like any other stranger.
And [spooler.dmarc_rua_ingest] parses each delivered report (the
message still lands in the mailbox as ordinary mail) and stores the
result as JSON for the account API’s admin reader,
GET /v1/admin/dmarc-reports — see
account-api for the routes and the
conformance appendix
for exactly what ingestion does and doesn’t do with the data.
MTA-STS — downgrade-resistant TLS for server-to-server delivery
(RFC 8461). For outbound mail there is nothing to configure:
sithbitd‘s relay discovers and honors recipients’ published policies
automatically (the mta_sts switch in the
[spooler] reference).
To protect mail inbound to your own domain, publish the discovery
record and serve the policy — domain-sithbit publishes the policy for
you from its [mta_sts] config
section (see
domain-sithbit: publishing the MTA-STS
policy):
_mta-sts.example.com. TXT "v=STSv1; id=20260716T000000"
Senders fetch the policy as
https://mta-sts.example.com/.well-known/mta-sts.txt, so point an
mta-sts.example.com A (or CNAME) record at your domain-sithbit
deployment, fronted by a TLS proxy holding a certificate for that
hostname; the service serves the configured policy at that well-known
path:
version: STSv1
mode: enforce
mx: mail.example.com
max_age: 604800
The mx patterns must cover every host your MX records name, and the
TXT record’s id must change whenever the policy content does — bump
it every time you edit the [mta_sts] section, since senders cache the
policy by that id. Start with mode: testing (the config default)
while you confirm your MX serves STARTTLS with a certificate valid for
its hostname, then move to enforce.
DANE — DNSSEC-pinned TLS for server-to-server delivery
(RFC 7672),
the stronger sibling of MTA-STS. For outbound mail there is nothing
to configure: sithbitd‘s relay looks up and honors recipient MX
hosts’ DNSSEC-validated TLSA records automatically (the dane switch in
the [spooler] reference),
preferring them over MTA-STS. To protect mail inbound to your own
domain, your zone must be DNSSEC-signed (unsigned TLSA records
are ignored by every DANE sender); then publish a TLSA record for each
MX host:
_25._tcp.mail.example.com. TLSA 3 1 1 <sha256-of-the-SPKI>
3 1 1 — DANE-EE, SPKI selector, SHA-256 — is the recommended form: it
pins the certificate’s public key, so ordinary renewals that keep the
key don’t touch DNS. Compute the digest from your certificate:
openssl x509 -in fullchain.pem -pubkey -noout \
| openssl pkey -pubin -outform DER | sha256sum
When rotating to a new key, publish the new record alongside the old
one, swap the certificate, then drop the old record (senders accept a
match against any published record). If your certificate chain rotates
keys on every renewal, pin the issuing CA instead (2 1 1, DANE-TA) —
but note the presented chain must then include that CA certificate.
A signed domain that receives mail on the implicit-A fallback — no MX record, mail delivered to the domain host itself — gets DANE too: DNSSEC proves the absence of the MX record to senders (SithBit’s relay validates the denial from the negative answer’s SOA), so publish the TLSA record at the domain’s own name, no MX required:
_25._tcp.example.com. TLSA 3 1 1 <sha256-of-the-SPKI>
TLS-RPT — feedback on how MTA-STS and DANE hold up in practice (RFC 8460). Publishing a TLSRPT record asks sending MTAs to aggregate the TLS outcomes of their deliveries to your domain — successes, STARTTLS stripping, certificate failures — and report them daily to an address you name:
_smtp._tls.example.com. TXT "v=TLSRPTv1; rua=mailto:[email protected]"
(https: report targets are also allowed.) This is how a downgrade
attack against your domain becomes visible instead of just delaying
senders’ mail. On the sending side there is one switch: with
[spooler.tlsrpt]
enabled, sithbitd records its own outbound TLS results and sends these
reports to every recipient domain that publishes the record — see the
conformance appendix
for exactly what is recorded and reported.
PTR — the reverse record for your outbound IP must resolve to your
EHLO hostname (203.0.113.25 → mail.example.com). This is set with
your hosting provider, not in your zone; several large receivers
refuse mail from IPs without a matching PTR.
Client access: POP, IMAP, and submission SRV records (RFC 6186)
MX tells other servers where to deliver mail; these SRV records tell
your users’ mail clients which host and port to reach for POP3, IMAP,
and message submission — so a client that knows only an address and
password can configure the rest. RFC 6186 defines the labels and RFC 8314
adds the implicit-TLS variants clients should prefer; publish only the
ones matching listeners your sithbitd stack actually runs.
Implicit TLS (preferred — RFC 8314). SithBit’s production posture is
TLS-on-connect on the standard secure ports, matching the
[mail_hosts]
defaults:
_imaps._tcp.example.com. SRV 0 1 993 mail.example.com.
_pop3s._tcp.example.com. SRV 0 1 995 mail.example.com.
_submissions._tcp.example.com. SRV 0 1 465 mail.example.com.
STARTTLS (secondary). If you also run the opportunistic-upgrade
listeners, advertise them at a higher priority number (lower
preference) so compliant clients still reach for implicit TLS first. The
shipped [mail_hosts] submission default is now implicit TLS on 465 (per
RFC 8314); STARTTLS on 587 is an opt-in you configure and advertise only
if you run that listener:
_imap._tcp.example.com. SRV 10 1 143 mail.example.com.
_pop3._tcp.example.com. SRV 10 1 110 mail.example.com.
_submission._tcp.example.com. SRV 10 1 587 mail.example.com.
The four fields after SRV are RFC 2782 priority weight port target:
the lowest priority wins, weight load-balances ties among equal
priorities, and — as with MX — the target must be an A/AAAA host, never a
CNAME. Point it at the same mail.example.com your other records use.
Advertising only what you serve
Publish a record only for a protocol you actually run. To tell clients a
protocol is not offered — e.g. an IMAP-only server with no POP —
publish a single record with target . and port 0:
_pop3s._tcp.example.com. SRV 0 0 0 .
SRV is advisory and one of three autoconfiguration paths: a client that
ignores it falls back to the autoconfig/autodiscover
documents
domain-sithbit serves, or to manual setup
(Thunderbird,
Outlook) — keep the ports and transport security
here consistent with what those advertise. SithBit clients can also skip
DNS for access-server discovery entirely and resolve authorized POP/IMAP
nodes over the DHT (see decentralized service
discovery).
The autoconfig and autodiscover hostnames
The document fallback above only works if the wizard can reach
domain-sithbit at the well-known hostnames it probes: Thunderbird
fetches https://autoconfig.<domain>/mail/config-v1.1.xml (and, as a
second try, /.well-known/autoconfig/mail/config-v1.1.xml on the mail
domain itself), while Outlook posts to
https://autodiscover.<domain>/autodiscover/autodiscover.xml. Publish
both names, pointed at the host where your domain-sithbit instance is
reachable — a plain A/AAAA or, since these are HTTP hosts (not SRV
targets), a CNAME is fine:
autoconfig.example.com. CNAME mail.example.com.
autodiscover.example.com. CNAME mail.example.com.
The wizard fetches over HTTPS, so the service’s TLS certificate must
cover these names too (add them as SANs, or use a wildcard). The
documents themselves are rendered from
[mail_hosts] —
no per-domain zone content beyond the two records.
Authorizing a domain on-chain
Before wallets can register aliases and mailboxes under
@example.com, the domain must exist as an on-chain Domain account —
created by the postoffice’s delegate for a
claimed authority key. The
domain-sithbit service automates the claim with a DNS proof:
-
The domain owner generates (or picks) an ed25519 keypair and publishes its public key, base58-encoded, as a TXT record:
_solana.authority.example.com. TXT "<base58 ed25519 public key>" -
POST /domainon thedomain-sithbitservice with the domain name as the body. The service resolves that TXT record, validates the key, and — signing with its configured delegate key — submitsCreateDomainnaming the key as the domain’s authority. -
GETon the same service answers what the TXT record currently claims, which is useful for checking propagation before posting.
Operational notes:
- Without a configured
delegate_key_file,POST /domainreplies 503 — DNS lookups still work. See the configuration reference. - The TXT lookup goes to a public resolver, so freshly published records may take a propagation delay to become visible.
- The authority key is a real signing key — the mail server submits
SendMailwith it — so store it like a wallet, not like a DNS token. The TXT record can be removed after authorization; the on-chain account is what matters from then on. - The same authority key can claim any number of domains: publish the same public key in each domain’s TXT record and POST each claim. A multi-domain server authorizes every domain it serves under its one gateway key this way.
See Domains for what a domain account contains and the CLI flows the delegate holder can drive by hand.