domains

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package domains manages the mail domains lfr serves: their DKIM keys, the postmaster mailbox every domain must have, and the exact DNS records an operator has to publish for mail and websites to work.

Index

Constants

View Source
const (
	DMARCReports = "dmarc-reports"
	TLSReports   = "tls-reports"
)

Reserved local parts that lfr answers itself on every domain.

Variables

View Source
var ErrExists = errors.New("already exists")

ErrExists reports a duplicate.

Functions

func MTASTSID

func MTASTSID(inst Instance) string

MTASTSID changes whenever the policy does, as RFC 8461 §3.1 requires; senders refetch the policy only when the id changes.

func MTASTSPolicy

func MTASTSPolicy(inst Instance) string

MTASTSPolicy is the policy file served at https://mta-sts.<domain>/.well-known/mta-sts.txt.

func SPF

func SPF(inst Instance) string

SPF is the SPF record value of a domain.

func Zone

func Zone(records []Record) string

Zone renders records in BIND zone file syntax, which Cloudflare and most DNS hosts can import. Long TXT values are split into 255-byte strings.

Types

type Domain

type Domain struct {
	ID       int64     `json:"id"`
	Name     string    `json:"name"`
	Selector string    `json:"selector"`
	Catchall string    `json:"catchall,omitempty"` // local part of the catch-all mailbox
	Created  time.Time `json:"created"`
	Next     *Domain   `json:"next,omitempty"` // keys of a rotation in progress: Selector and keys only
	// contains filtered or unexported fields
}

Domain is one served domain.

func (*Domain) EdPublic

func (d *Domain) EdPublic() string

EdPublic is the p= value of the Ed25519 DKIM record (RFC 8463: the raw key).

func (*Domain) EdSelector

func (d *Domain) EdSelector() string

func (*Domain) RSAPublic

func (d *Domain) RSAPublic() string

RSAPublic is the p= value of the RSA DKIM record.

func (*Domain) RSASelector

func (d *Domain) RSASelector() string

RSASelector and EdSelector are the DKIM selectors of the two keys.

func (*Domain) Signers

func (d *Domain) Signers() []crypto.Signer

Signers returns the DKIM keys, Ed25519 first.

type Instance

type Instance struct {
	Hostname string // mail host name, e.g. mail.example.com
	IPv4     string
	IPv6     string
	RelaySPF string // e.g. "include:amazonses.com", empty for direct delivery
	STSMode  string // MTA-STS mode: testing or enforce
}

Instance is what the DNS records of every domain point at.

type Record

type Record struct {
	Type     string `json:"type"`
	Name     string `json:"name"` // fully qualified, without trailing dot
	Value    string `json:"value"`
	Priority int    `json:"priority,omitempty"`
	Purpose  string `json:"purpose"`
	Proxy    bool   `json:"proxy_allowed"` // may sit behind the Cloudflare proxy
}

Record is one DNS record to publish.

func Records

func Records(d *Domain, inst Instance, hosts []string) []Record

Records lists everything d needs in DNS. hosts are the web hosts of the domain's lists; they point at this server too.

type Service

type Service struct {
	DB  *store.DB
	Now func() time.Time
}

Service is the domain store.

func (*Service) Add

func (s *Service) Add(ctx context.Context, name string) (*Domain, error)

Add creates a domain with fresh DKIM keys and a postmaster mailbox (with abuse@ as alias), as RFC 5321 and 2142 require.

func (*Service) ByID

func (s *Service) ByID(ctx context.Context, id int64) (*Domain, error)

ByID loads a domain by ID.

func (*Service) Get

func (s *Service) Get(ctx context.Context, name string) (*Domain, error)

Get loads a domain by name.

func (*Service) List

func (s *Service) List(ctx context.Context) ([]*Domain, error)

List returns every domain by name.

func (*Service) PrepareRotation

func (s *Service) PrepareRotation(ctx context.Context, name string) (*Domain, error)

PrepareRotation creates the next pair of DKIM keys under a new selector. They do not sign anything until Rotate switches to them, which the caller does once their records are visible in DNS (RFC 6376 §3.6.1: publish first, sign after). A rotation in progress is returned unchanged.

func (*Service) Remove

func (s *Service) Remove(ctx context.Context, name string) error

Remove deletes a domain with its mailboxes, messages and lists. Blobs of the deleted messages are left for the next blob sweep.

func (*Service) Rotate

func (s *Service) Rotate(ctx context.Context, name string) (*Domain, error)

Rotate makes the prepared keys the signing keys. The old records stay in DNS a few days, until mail signed with them has been delivered and read.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL