Skip to content
hMailServer 6.3.8 is the current release, signed 2 November 2026. Windows and Linux, and an in-place upgrade from 5.3 or later, but for the original hMailServer's 5.7.Download 6.3.8 Documentation FAQ
  • 0 Votes
    1 Posts
    140 Views
    ProgressiverobotP
    Since 6.3.4 the delivery queue shapes what it sends. It pauses a destination that asked it to slow down, caps how many sessions it holds open to one destination and how many deliveries one tenant has in flight, and holds a new outbound address to a daily ceiling at each large provider. Everything in this topic is new in 6.3.4 except MaxOutboundPerDestinationPerMinute, a fixed per-destination rate that 6.3.3 already has. What to know first: of what this topic covers, two things change behaviour on upgrade without a switch. The back-off is on by default, and a deferral this server chose does not spend a message's retries until the message has been queued for longer than its retry schedule spans; only a failure at a remote does. The second covers every hold in this topic, and so changes an upgraded server that already sets MaxOutboundPerDestinationPerMinute. The connection ceilings, the tenant share and the warm-up do nothing until you set them. The order of the checks For each batch of recipients on one target, the server judges in this order, before any connection is opened: The remote domain policy's largest message: 5.3.4, permanent, measured on the queued message. The destination's back-off window. Held until the window ends; then one delivery goes through as the probe, and any other arriving meanwhile waits a minute. The policy's messages a minute (max_messages_per_minute). The connection ceiling: the policy's max_connections where the policy sets one, otherwise the server-wide MaxOutboundConnectionsPerDestination. The tenant share, MaxOutboundConnectionsPerTenant. The server-wide MaxOutboundPerDestinationPerMinute. DNS: the MX lookup (or the route's host) and MTA-STS; then the IP warm-up's daily ceiling; then, where DANE applies, whether the MX set is DNSSEC-validated. Gateway encryption, for a domain whose policy encrypts. The copy is made here, so a batch that is only going to be deferred is never encrypted. The connection attempts. Every one of 2 to 6 is a deferral with 4.4.5 ("mail system congestion") and a sentence naming the rule. The target each check is keyed by is what the batch is delivered to: the recipient domain of an MX delivery, or the host of a route or a relay, or its address when the route names an IP literal, lower-cased. The back-off: a destination said slow down When a destination answers a delivery with a request to slow down, it gets a back-off window: nothing is sent to it until the window ends, one delivery then probes it, and the same answer doubles the window. Deliveries to every other destination are untouched. What is read as a signal. Reply Read as Code 421, unless an exclusion below applies A signal, whatever the text, at the banner or anywhere after it A 4xx whose enhanced status is 4.7.0, 4.7.28, 4.7.500, 4.7.650, 4.7.652 or 4.3.2 A signal A 4xx whose text, lower-cased, contains one of the phrases below A signal The phrases: rate limit, rate-limit, ratelimit, too many messages, too many connections, too much, unusual rate, unexpected volume, temporarily deferred, temporarily rate, throttl, try again later, server busy, back off, slow down. They are English, and a remote that says the same in another language is read by its codes alone. The table is fixed and cannot be edited. What is deliberately not a signal, each of which wins over the text and over the 421 rule: any 5xx: a refusal is not a request to wait; 4.7.1, which greylisting and policy refusals answer, and any reply whose text says greylist or graylist; 4.2.x: one mailbox, never the destination; 4.5.3: too many recipients for one message; 4.4.x: 421 4.4.2 timeout exceeded is the remote's idle timeout on a slow DATA; a connection that was refused or timed out, a DNS failure, and this server's own deferrals. The window and the probe. The first slow-down reply opens a window of OutboundBackoffMinutes. While it is open a batch for that destination is held with 4.4.5, and the application log says: Delivery to <target> deferred: the destination asked this server to slow down at <time> (<reply>); next attempt after <time>. When the window has passed, the first delivery goes through as the probe. If it is delivered, or fails with anything that is not a slow-down reply, the window is cleared. If it is answered with a slow-down reply, the window doubles, up to OutboundBackoffMaxMinutes. A probe nobody ended - a delivery thread that died with it - goes stale after fifteen minutes and the next delivery takes it over. Setting Default Range Meaning OutboundBackoffMinutes 2 0 to 10080 The first window. 0 turns the back-off off OutboundBackoffMaxMinutes 60 1 to 10080 The ceiling a doubling window stops at The two refuse to cross each other on every surface: to move both, move the ceiling first when raising and the base first when lowering. A relay is one destination. With SMTPRelayer set, or a route through a smart host, one slow-down reply from it holds every message that goes through it for the window. One miss, stated in the document. The delivery client keeps a recipient's first non-fatal reply, so a genuine 421 from a second MX host after a plain 4xx from the first is not seen for that recipient. Connection ceilings and the tenant share Both use the same counting semaphore, and it never blocks: a delivery thread that waited for a slot would be a thread not delivering anybody else's mail. Over the ceiling the batch is deferred one to five minutes. Setting Default Range What it bounds MaxOutboundConnectionsPerDestination 0, off 0 to 1000 Sessions open at once to one target that no remote domain policy sets max_connections for MaxOutboundConnectionsPerTenant 0, off 0 to 1000 Deliveries one tenant may have in flight at once The per-domain ceilings are on the remote domain policy, whose TLS half is in Requiring TLS: Policy field 0 means Beyond it Largest message (KB) no limit of ours Not attempted: no connection is opened, and the message is bounced at once with 5.3.4, naming the policy and both sizes Simultaneous connections unlimited Deferred with 4.4.5 for one to five minutes. The count covers every domain the policy's pattern matches Messages a minute unlimited Deferred with 4.4.5 for one to five minutes. Independent of MaxOutboundPerDestinationPerMinute; both apply A policy's connection ceiling wins over the server-wide one wherever the policy sets it. Who a tenant is. The hosted domain of the envelope sender, with an alias domain resolved to its domain. A sender this server does not host - mail relayed for an IP range or a route, forwarded external mail, the null sender - is the one tenant (external), so relayed mail cannot starve the hosted domains either. The tenant share is not a volume control. It is a share of connections, bounded by MaxDeliveryThreads: a share larger than the thread count is no share at all. The per-account sending limits are the volume control. This server's own delivery reports have the null sender, so they share (external) with relayed mail. Where the settings are. The four new settings are on the Control Panel's Delivery of e-mail page beside MaxOutboundPerDestinationPerMinute (Windows), on the Deck's Settings view, over COM as Settings.OutboundBackoffMinutes, OutboundBackoffMaxMinutes, MaxOutboundConnectionsPerDestination and MaxOutboundConnectionsPerTenant (Windows), and over REST on /api/v1/settings as outbound_backoff_minutes, outbound_backoff_max_minutes, max_outbound_connections_per_destination and max_outbound_connections_per_tenant. In hm_settings the two connection rows are named MaxOutboundConnsPerDestination and MaxOutboundConnsPerTenant, because the column holds thirty characters. A deferral this server chose is not counted When every non-fatal failure of a delivery pass was one of this server's own deferrals, the message's next try is set to the longest deferral of the pass with the tries counter untouched, and the log says so: Delivery deferred by this server's own shaping, not by a remote server. Scheduling it for later delivery in N minute(s); the attempt is not counted against the retry limit. When any recipient of the pass failed at a remote, the counted path runs as it always has. Before this, with a small retry count, a message could be bounced having never been offered to anybody. The hold is bounded. A message queued for longer than the span its counted schedule would have allowed - (retries + 1) times the minutes between tries, from the time it was accepted - takes the counted path from then on, so that a destination that says "slow down" for ever still ends in a bounce: Deferred by this server's own shaping, but it has been queued for N minute(s), longer than the M minute(s) its retry schedule spans. This deferral is counted, so that the message is not held for ever. A held pass is a first pass only once. DKIM and ARC signing, the mirror copy and a rule's policy notice happen once, however many passes a message is held through. Nor does a held pass forward, copy, reply or call a rule's script function again: those four actions run once per counted attempt. IP warm-up Schema 6093. A schedule holds one outbound address to a daily ceiling of recipients per provider, rising day by day along a fixed plan; the queue sends up to the ceiling and holds the rest, usually until the next UTC day. Nothing is held until an administrator makes a schedule. A schedule is about one address, and the address has to be bound. It is the local address a delivery leaves from: a global rule's bind to address action when one applies, otherwise SMTPDeliveryBindToIP (Bind outbound connections to IP, smtp_delivery_bind_to_ip). A delivery that binds no address leaves from whatever the operating system chooses, and no schedule is consulted for it. So a schedule does nothing, even enabled, until the address is configured on the host and one of those binds it. The server can check the setting and nothing else: the listing says in_bind_setting, and the Deck warns when it is false. The provider is decided from the mail host, never from the recipient's domain. A company on Google Workspace is reached through Google's MX hosts, and it is Google that judges the address. The first host the batch will try decides. Provider Key Mail host names Google google google.com, googlemail.com, aspmx.l.google.com Microsoft microsoft outlook.com, hotmail.com, protection.outlook.com, olc.protection.outlook.com Yahoo yahoo yahoodns.net, yahoo.com, aol.com Apple apple icloud.com, apple.com Proton proton protonmail.ch, proton.me Every other provider other everything else, counted together at five times the named providers' ceiling Mail relayed through a smart host that is not one of those names is other, whoever the smart host delivers it to. The plans, in recipients per named provider per day. After a plan's last day there is no ceiling, and the schedule holds and counts nothing. Day of standard Ceiling other 1 50 250 2 100 500 3 200 1,000 4 500 2,500 5 1,000 5,000 6 2,000 10,000 7 5,000 25,000 8 to 10 10,000 50,000 11 to 14 20,000 100,000 15 to 21 50,000 250,000 22 to 30 100,000 500,000 The plans side by side: Plan Length Day 1 Last day Rule standard 30 days 50 100,000 the table above gentle 60 days 25 50,000 half of each ceiling, twice the days fast 15 days 100 200,000 twice each ceiling, half the days Days are UTC days, whatever the server's time zone, and a start later than today is refused. Recipients, not messages. A message to forty people at Gmail is forty to Google. Before a delivery connects, its recipients reserve room out of the day's allowance; when the attempts are over, every recipient that was delivered is added to sent and the reservation is let go. A recipient that was not delivered is not counted. So a provider that refuses the warming address is offered as many recipients a day as the queue has; its slow-down replies are answered by the back-off. The counts are written to hm_warmupcounts at every change, so a restart resumes the day. Local delivery is not counted. The hold. Recipients that do not fit - the last of the batch, not chosen by any priority - are marked 4.4.5. When the day's ceiling was reached, the next try is one to five minutes after the next midnight UTC: SMTPDeliverer - Message 1234: 1 recipient(s) held by the IP warm-up of 192.0.2.10: day 1 of its standard schedule allows 50 recipient(s) a day at Google, and today's have been sent. Next attempt after midnight UTC, in 723 minute(s); the attempt is not counted against the retry limit. How long a backlog is carried. With the default schedule - four retries, sixty minutes apart, a five-hour span - a recipient queued in the morning comes back on each of the next five UTC days and is returned if the fifth still has no room. Send no more from a warming address than the sum of those days' ceilings, or raise the retry count for the duration of the warm-up. Managing schedules. On the Control Deck's Delivery queue page, in the Warm-up box, or over REST. The desktop Control Panel has nothing for it, and there is no COM interface. Route What it does GET /api/v1/warmup Today's UTC date and the schedules, each with its day, in_bind_setting, and per provider sent, deferred and ceiling POST /api/v1/warmup Adds one: address (required), plan (standard by default), started (YYYY-MM-DD, today by default), enabled PUT /api/v1/warmup/{id} Changes plan, started or enabled. The address cannot be changed DELETE /api/v1/warmup/{id} Removes a schedule and its counts GET /api/v1/warmup/{id}/history The counts, newest first, with the day and ceiling in force then Reading takes view_queue and changing takes manage_queue; a credential confined to named domains is refused. A second schedule for one address is 409. Back up settings carries the schedules but not the counts. When the database does not answer, the queue does not stop: schedules that cannot be read (7210) and a day's count that cannot be read or started (7211, 7212) leave the delivery going as though the address had no schedule. A count that cannot be saved (7213) is kept in memory; if the service restarts first, the day can go past its ceiling by that much. Where to see it GET /api/v1/queue/shaping (view_queue, server-wide): the open back-off windows - destination, since, until, the window's minutes, the reply and the host that gave it, how many deliveries it has held, whether a probe is out - and the connections open under each ceiling and each tenant. DELETE /api/v1/queue/shaping/{destination} (manage_queue) clears one window once you have fixed the cause: 200 with {"cleared":true}, 404 when no window is open for that name, and an event on the audit trail. The Deck's Delivery queue shows the same as Slowed destinations, with a Resume button, and the connection counts as they were when the page was drawn. The application log says, for each batch held, which rule held it and until when. What is per process. The windows and the connection counts live in memory. A restart forgets every window, which costs at most one more slow-down reply per destination. Nothing is shared between the nodes of a warm-standby pair. What it does not do The signal phrases, the providers and the plans are fixed. A sixth provider, or a plan of your own, is not possible. No per-tenant volume quota beyond the per-account one: this shares connections, not messages a day. No pool of addresses. A schedule is about one address, and mail that did not fit waits. No reputation feedback. The ceilings rise by the calendar, not by how the providers are answering. No delayed delivery report. A sender learns of a long hold only when it ends in a bounce. A deferral by a rate or a ceiling costs one delivery pass per message every one to five minutes for as long as the backlog lasts. The warm-up counts are not exported as metrics. Not proved by any test, according to IpWarmup.md: room held by deliveries in progress; a later host of the other address family skipped for being reached from another warming address; what a database failure does (7210 to 7213); the audit trail's entry; the configuration backup's round trip of the schedules; and an MX lookup's own host names reaching the classification, since every delivery in the fixture goes through a route. Where to read more Operator documents at the v6.3.4 tag: OutboundShaping.md, IpWarmup.md and RemoteDomains.md. Wiki: Outbound Shaping and Routes and Relays. Public documentation: 26.7 The delivery queue and the retry schedule and 14.1 Sending through a smart host. On this forum: The Control Deck, Upgrading to 6.3.4, Requiring TLS for the remote domain policy's TLS half, and DKIM rotation, DMARC and TLS reports, complaints, bounces and the reputation watch for bounces, complaints and block lists.
  • 0 Votes
    1 Posts
    119 Views
    ProgressiverobotP
    Written for 6.3.4. hMailServer 6.3.7 (17 October 2026) no longer signs mail from outside whose From names a domain hosted here with that domain's DKIM key, and signs an authenticated submission as another hosted domain only when its account may send as the address its From names (CVE-2026-107567); the upgrade stops the signing, and only rotating the domain's key, as this topic describes, ends the signatures already made. See the 6.3.7 announcement. Five things new in 6.3.4 keep your signing keys fresh or read how the world is answering the mail your domains send: DKIM key rotation, the DMARC and TLS reports your domains receive, the providers' complaint feedback loops, bounce classification with a suppression list, and a daily check of your own addresses against block lists. The one thing to know first: each is its own switch and each is off until you turn it on - the reputation watch is the exception, on in a new installation and off after an upgrade - and only one of them, the suppression list, ever stops a message. The DKIM and DMARC records themselves are in Being trusted by the servers you send to. The Control Panel and the COM API named below are Windows-only. The Control Deck, the REST API and hmctl work against a Windows or a Linux server; the Linux packages install hmctl, and the Windows installer does not carry it. DKIM keys that rotate Schema 6048. A rotation policy per domain does, on a schedule or on Rotate now, what used to be done by hand. It is off on every domain until switched on, and it never edits DNS: it says what to publish, checks it, and waits. The walk. Three slots, each a selector with a key file: current (the only key that signs), next (published and waiting; it never signs before the switch) and retiring (kept for mail still on its way). The schedule starts a rotation when the current key is older than the interval, or somebody presses Rotate now. An RSA key is generated under a new selector: the one you give, or s and today's UTC date (s20260915, then s20260915b if that is taken). You publish a TXT record at <selector>._domainkey.<domain> with the value v=DKIM1; k=rsa; p=.... Every pass - every fifteen minutes, and on Check DNS now - looks the record up. The first pass that finds exactly the new key records the moment. Any pass that does not find it matching sends that moment back to zero. Signing moves once the record has matched for the whole propagation period and the retiring slot is free. The old selector's record stays published for the retention period. The old selector is retired. A key file the rotation generated is deleted; one it did not generate is left. The status lists the record with the action remove, and removing it is yours. Signing itself is still the domain's DKIM signing switch: the rotation moves keys, it does not switch signing on. Setting REST key Default Range Rotate on a schedule dkim_rotation_enabled off Days between rotations dkim_rotation_interval_days 180 1 to 3650 Propagation period, hours dkim_rotation_propagation_hours 72 1 to 720 Retention period, days dkim_rotation_retention_days 7 1 to 365 Key size, bits dkim_rotation_key_bits 2048 2048, 3072 or 4096 Every interface refuses a value out of range rather than clamping it. Set them in the Control Panel's domain dialog (DKIM tab), the Deck's domain editor, PUT /api/v1/domains/{domain}, or hmctl domain update example.com --set dkim_rotation_enabled=true. Nothing is written to hMailServer.ini. What the status says. GET /api/v1/domains/{domain}/dkim/rotation answers the phase (off, idle, awaiting_dns, propagating, ready, waiting_for_retiring_slot) and each slot's last check: unchecked, matches, not_found, different, lookup_failed or key_unreadable. different means a record exists and none carries this key, and waiting will not fix it. A match proves that this server's resolver sees the key, not that every receiver's does. Where the keys are, and who can read them. <DataDirectory>/DKIM, as <selector>._domainkey.<domain>.pem. Windows Linux Default directory C:\Program Files\hMailServer\Data\DKIM /var/lib/hmailserver/DKIM Protection A protected security descriptor naming only SYSTEM, the Administrators group and the service account; it does not inherit the data directory's permissions Created with mode 0600, never widened On Windows, a Control Panel that is not elevated cannot read a generated key; the records it shows come from the status document. A managed domain refuses a blind save. While rotation is on, or a next or retiring selector is in flight, a save that would change the selector or key file is refused: over COM with an error, over REST with 409. When it goes wrong. The dkim.rotation.stalled alert, on by default and held for the daily digest, is raised when a next key's record has not been seen for the rule's threshold (7 days by default) or the last attempt to move a running rotation failed. A record that is missing or different is never an error. The error log is for faults, codes 6610 to 6615. A key that has been compromised. If an earlier old selector is still being kept, Retire the old key now first. Rotate now, and publish the new record at once. Check DNS now until the record matches, then Switch now with the box that skips the propagation period (hmctl dkim switch example.com --force). Force skips the period and never the check. Retire the old key now again, which deletes the compromised key's file if the rotation made it. Do not remove the old record. Publish it with an empty key, v=DKIM1; p=, which says the key is revoked rather than missing. Backups. A backup that includes the data directory includes the key files. Since 6.3.4 an archive can be encrypted (7-Zip AES-256, headers included), but encryption is off until a backup passphrase is set, and until then the archive holds the private keys in the clear: treat it as you treat the keys. Set it on the Control Panel's Backup & restore → Encryption, the Deck's Backup view, PUT /api/v1/settings/backup (encryption_passphrase) or hmctl backup passphrase set. Lose the passphrase and everything in every archive written with it is lost. Not done: generating Ed25519 keys; signing twice during the switch; publishing a revocation. The reports your domains receive Schema 6070. Receivers send a DMARC aggregate report once a day, and senders that honour TLS-RPT report on their sessions to your MX hosts. Name the mailbox. Each domain has one report mailbox: the Reports received tab of the Control Panel's domain dialog, the Reports the domain receives group of the Deck's domain editor, or report_mailbox on PUT /api/v1/domains/{domain}. It is empty by default, and empty means nothing is read. The address has to be in a domain this server hosts, and is refused otherwise. Then publish it: _dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]" _smtp._tls.example.com. TXT "v=TLSRPTv1; rua=mailto:[email protected]" Keep the p= your domain already publishes: this step adds only the rua= address. The wiki's DNS page says to start at p=none and tighten only once the reports show all your legitimate mail passes SPF and DKIM. What is read. A message is opened only when it is addressed to a report mailbox and to nothing else of this server's, and it is delivered to the mailbox unchanged, read or not. Each candidate part is unwrapped by its bytes (gzip, zip or plain), and the first character decides: < is a DMARC aggregate report, { a TLS-RPT report. The same report twice is one row. Nothing read here acts. No list is fed, no mail is refused, no setting changes. What carried a report is kept too. Nothing inside a report proves who sent it, so the dmarc= verdict and header.from= domain this server wrote on the carrying message are kept on the row (message_dmarc, message_from). Both are empty unless AuthenticationResultsEnabled is on; with it off, the reporter is shown as Not checked. The bounds. A message is not read past 32 MB, and an attachment is not inflated past 16 MB. A report keeps at most 2,000 records, and the log says when the chart under-counts. A domain takes in at most 20,000 records and 1,000 TLS-RPT rows in any twenty-four hours; a report past either ceiling is refused whole. The chart. GET /api/v1/domains/{domain}/dmarc-reports/summary?days=30, drawn by the Deck's DMARC page and hmctl dmarc summary: messages passed and failed, what receivers quarantined and rejected, the reporters, and up to 200 sources that sent as the domain. DomainReportRetentionDays (365 by default; 0 keeps for ever) decides how long a report is kept. The rows are not in the backup; the reports are still in the mailbox, which is. Not done: no reverse DNS or geography for a source; no forensic (ruf=) reports; no alert when the pass rate falls. The chart is how you see whether it is safe to move from p=none to p=quarantine to p=reject. Complaints: the feedback loops Schema 6055. The large mailbox providers post an abuse report (RFC 5965) to an address you registered with them whenever a reader presses this is spam. With processing on and a mailbox named, a report is recorded against the sending domain and account, counted, and past a threshold puts the address on the domain's suppression list. It is off by default, and inert without a mailbox. Why only a configured mailbox is an intake. A feedback report carries nothing known only to the provider. What tells a genuine report from a forged one is that it arrived where the provider was told to send it. So use a dedicated address the loops know and nobody else does - [email protected] rather than [email protected] - and do not publish it. Setting REST key Default Meaning ComplaintProcessingEnabled processing_enabled off The whole feature ComplaintMailbox mailbox empty The address the loops are registered against, or several separated by commas. Each must be one this server hosts ComplaintSuppressionThreshold suppression_threshold 0 0 to 100. 0 records and counts every report and lists nobody. Raise it to 1 once the entries have been read ComplaintRetentionDays retention_days 180 0 keeps for ever; at most 3650. It does not remove a suppression entry a complaint made They are keys of /api/v1/settings/complaints, a group on the Deck's Settings page, and hmctl settings get complaints. Three gates that are not settings. The report must be addressed to the complaint mailbox and to nothing else. The domain it is about must be one this server hosts. And an Original-Rcpt-To that this server hosts lists nobody. A complaint is not a bounce. It has a counter of its own, hm_bouncecounts.bccomplaints. Its list entry carries source complaint, and the refusal a sender meets uses 5.7.1, never 5.1.1. not-spam is recorded and counts towards neither the rate nor the list; every other feedback type counts. It is the same suppression list the bounces feed, and the list is applied whenever either feature is on. The rate is complaints divided by messages delivered, over a seven-day window that is not a setting, in parts per million. A domain that has sent fewer than 100 messages in the window is not judged. The complaints.rate.high alert ships on, seeded at 1000, with a cooldown of a day, held for the digest. With MetricsPerDomainEnabled set, the gauge hmailserver_domain_complaint_rate{domain} is exposed with two others. Reading them. The Deck's domain row has a Complaints button; GET /api/v1/domains/{domain}/complaints needs view_configuration and view_message_trace; hmctl complaint list --domain example.com and hmctl complaints rates do the same from a shell. A backup does not carry the complaints. Bounces read, and a suppression list Schema 6049. With bounce processing on, every refusal met while delivering and every RFC 3464 delivery report that arrives later is classified against its enhanced status code and counted per recipient and per sending domain. An address that hard-bounces as many times in a row as the threshold says goes on that domain's suppression list. It is off by default. Setting REST key Default BounceProcessingEnabled processing_enabled off BounceHardBounceThreshold hard_bounce_threshold 1 (1 to 100) BounceMailboxFullIsHard mailbox_full_is_hard off BounceSuppressionAction suppression_action 0 refuse; 1 drop; 2 observe BounceSuppressionExpiryDays suppression_expiry_days 0, entries kept until removed BounceReadDeliveryReports read_delivery_reports on BounceCountRetentionDays count_retention_days 90 BounceReportWindowDays report_window_days 7 (1 to 30) They are on the Control Panel's Delivery of e-mail page (the Bounces and the suppression list card), the Deck's Settings page, /api/v1/settings/bounces and hmctl settings get bounces. The safe way to start is suppression_action=observe for a week. The server classifies, counts and lists, delivers everything, and logs every message that would have been stopped. Read the list, then switch to refuse. What counts as which. Code Category Counts towards the list 4.2.2 or 5.2.2 mailbox_full only with BounceMailboxFullIsHard any other 4.x.x soft no 5.7.x policy never 5.1.1, 5.1.2, 5.1.3, 5.1.6, 5.1.10, 5.2.1 hard yes any other 5.x.x other no A bare 550 is not a dead address. The classifier never believes a code this server worked out for itself. When a remote's reply carries no enhanced code of its own, the words decide, policy words first: 550 Recipient address rejected: Access denied is policy, 550 No such user here is hard, and 550 <[email protected]> is other. hmctl bounces classify "550 5.1.1 User unknown" shows how a reply would be read, and changes nothing. A delivery report has to prove itself. It is counted only when it passes six checks, among them: its envelope sender is null, it was not classified as spam, it arrived over SMTP here and not from a signed-in user, and it reproduces a row of hm_bouncereportkeys, a SHA-256 of the Message-ID, recipient and envelope sender of a message this server really sent. What that does not stop: one recipient in To or Cc could forge a report for another visible recipient. Such an entry says source: report, and read_delivery_reports can be turned off. What the list does. Action At RCPT TO and on the webmail At delivery refuse Refused with 550 and the status that listed the address, with a sentence saying why The recipient is removed and returned to the sender in an ordinary non-delivery report drop Accepted Removed silently; a log line says so observe Accepted Delivered; a log line says it would have been stopped Mail already in the queue meets the list at its next attempt. If the list cannot be read, the message is sent as if the address were not listed, and HM6622 is reported at most once an hour. Looking at it. Control Panel → Monitoring & troubleshooting → Suppression list; Deck → Domains → Suppressions ›; GET /api/v1/domains/{domain}/suppressions; hmctl suppression list|create|delete --domain. The list's document says processing_enabled when bounces are read and list_applies when the entries act. Removing an entry lets the next message through at once and starts the run of hard bounces again from none. The reputation watch Schema 6057. Once a day the server asks the block lists about the addresses it sends from, and raises reputation.listed when one is listed. On in a new installation, off after an upgrade: an upgraded server may already have a delivery bind address, and switching this on beneath it would send that address to four third parties every day without anybody choosing it. Turn it on with reputation_watch_enabled, on the Deck's Settings page, PUT /api/v1/settings or hmctl settings set; switching it off clears a standing reputation.listed. Which addresses. SMTPDeliveryBindToIP, the bind to address action of any active global rule, and ReputationWatchAddresses, which exists for a server behind NAT. A private, loopback, link-local or shared address is never looked up. At most 32 addresses are checked; one past that is reported as too_many. Which lists. ReputationWatchLists ships with ipv4:zen.spamhaus.org, ipv4:bl.spamcop.net, ipv4:psbl.surriel.com and ipv4:bl.mailspike.net. Nothing shipped covers IPv6, on purpose: an IPv6 outbound address reads not_applicable against all four until you name a zone whose IPv6 coverage you have read. A subscriber key put in this setting is readable by everybody who can read the configuration. A refusal is not a listing, and neither is clean. Before any address is looked up, each list is asked about 127.0.0.2, which must be listed, and 127.0.0.1, which must not be. What comes back Status An answer in 127.255.255.0/24 refused The lookup failed lookup_failed 127.0.0.2 is not listed list_not_answering 127.0.0.1 is listed list_lists_everything An answer outside 127.0.0.0/8 unexpected_answer If DNSServer is one of the large public resolvers, Spamhaus will be refused every day, and the report says so rather than calling the server clean. Point DNSServer at a resolver of your own. A lookup that fails never clears a listing. After a week with no definite answer a pair becomes unknown, not clean: hmctl still exits 1, and the report answers listed as null. Where and when. GET /api/v1/reputation; POST /api/v1/reputation/check, answered 409 while a check is running; the Deck's Outbound reputation view; hmctl reputation status. A check is bounded to 120 seconds; pairs it does not reach are written as lookup_failed. The alert is sent at once rather than held for the digest. Not done: delisting; domain-based lists; watching between checks; seeing behind a smart host. Where to read more Operator documents at the v6.3.4 tag: DkimKeyRotation.md, DmarcReports.md, Complaints.md, BounceSuppression.md and ReputationWatch.md. Wiki: DNS for Your Domain, Outbound Shaping and Monitoring and Health. Public documentation: 8.5 DKIM and 8.6 DMARC. On this forum: Being trusted by the servers you send to, The Control Deck, Requiring TLS for the reports your server sends, and Alerts, the audit trail, syslog for how an alert reaches you.
  • 0 Votes
    1 Posts
    123 Views
    ProgressiverobotP
    Written for 6.3.4. hMailServer 6.3.7 (17 October 2026) fixes DANE enforcement deferring mail to a DNSSEC-signed domain whose MX answer came compressed, live.com among them (work item 80), and treats a DNS lookup that fails as a failure rather than a name with no addresses: a delivery whose mail servers' lookup failed tells the sender that the DNS query failed (4.4.4) and retries, a DNSSEC validation that fails says where and why in the debug log, and the application log's lines for a skipped host end with the reason in brackets. The ACME HTTP-01 challenge responder, which served one connection at a time so that idle clients could make a certificate's issuance or renewal fail, now serves up to 64 connections at once (work item 97). See the 6.3.7 announcement. In hMailServer 6.3.8 (2 November 2026) the web services listener refuses an address an auto-ban or an IP range bans (work item 105), so an IP range of your own that allows some addresses none of SMTP, POP3 and IMAP now closes that listener to them, and with it the MTA-STS policy this topic publishes and ACME's http-01 validation where that listener answers it: check that the sending MTAs and the certificate authority do not come from such a range. See the 6.3.8 announcement. This topic is about mail travelling encrypted between servers, in both directions, and about being able to show that it did: honouring the MTA-STS and DANE policies other domains publish, publishing your own, adding a requirement of your own for a partner that publishes nothing, and sending the TLS-RPT and DMARC reports that tell other operators what became of their mail. It assumes a certificate is already installed and the listeners already use it; that is Let's Encrypt certificates are automatic, and the basics of SPF, DKIM and DMARC are in Being trusted by the servers you send to. The one thing to know first: the three outbound policies - MtaStsEnabled, DaneEnforcementEnabled and DnssecValidationEnabled - are on by default, and every outbound path described here that cannot get the encryption it requires defers the message with 4.7.0. Where encryption is required, nothing falls back to sending in the clear. What is on already, and what is yours to do Mechanism Which mail State as shipped What you do Honouring other domains' MTA-STS policies mail you send on, MtaStsEnabled=1 nothing Honouring other domains' DANE records mail you send on, DaneEnforcementEnabled=1 and DnssecValidationEnabled=1 nothing Publishing your own MTA-STS policy mail you receive MtaStsHostingEnabled=1, but inert until WebServicesHttpsPort is set set the port, have a certificate for mta-sts.<domain>, publish the _mta-sts TXT record Publishing your own TLSA record mail you receive nothing to switch on publish the record the ACME log prints, in a DNSSEC-signed zone Remote domain policies (since 6.3.4) both directions none exist create one per partner TLS-RPT and DMARC aggregate reports you send reports to other operators inert until a sender address is set set TlsRptFromAddress and DmarcRptFromAddress The three outbound policies, the authentication-results headers and the two reporters are on the Control Panel's TLS & certificates → Transport security page (Windows-only); on either platform, PUT /api/v1/settings/ini/{name} and hmctl ini set write them. Of the keys in this topic, WebServicesHttpsPort and AcmeEnabled wait for a reinitialise (Apply now) and the rest apply when saved. Do not edit hMailServer.ini for them: since 6.3.4 the database holds these keys, and a line edited in the file is ignored and named in the error log as HM5804. Settings: when a save takes effect explains the store and [SettingsOverride]. Honouring another domain's MTA-STS policy It applies to an MX delivery, not to a fixed relay. For each message due for a domain, the server looks up the TXT record at _mta-sts under that domain. With no record, "no policy" is cached for 30 minutes and the message is delivered as usual. With a record, the policy is fetched over HTTPS from mta-sts.<domain> at /.well-known/mta-sts.txt, and its mode decides: mode What the server does none Delivers as usual testing Writes a debug log line only; nothing is enforced enforce Drops every MX host the policy does not name. If none is left, the message is deferred with 4.7.0. Otherwise TLS with certificate verification is required to the hosts that remain How long a policy is believed. A policy is cached until its own max_age and revalidated by re-reading the DNS record's policy id at most once an hour. A DNS failure or a failed fetch during revalidation keeps the cached policy (RFC 8461 §5.1). The mx: patterns match either exactly or with a leading *. that matches exactly one label. What you see in the log. SMTPDeliverer - Message 4711: MTA-STS policy mode 'enforce' active for example.com. TLS with certificate validation is required. SMTPDeliverer - Message 4711: Skipping MX host mx9.example.com - not permitted by the MTA-STS policy of example.com. SMTPDeliverer - Message 4711: Delivery to example.com deferred. No MX host matches the domain's MTA-STS policy. Honouring DANE DANE applies to an MX delivery when DaneEnforcementEnabled=1. The MX lookup for the recipient domain is DNSSEC-validated, and the chain status of the MX RRset decides what happens next. Step Status What happens The MX RRset insecure Delivered as usual The MX RRset bogus The host is skipped entirely The MX RRset secure A TLSA lookup is made per host, at _25._tcp.<mx-host> The TLSA lookup bogus The host is skipped The TLSA lookup no records Delivered as usual The TLSA lookup validated TLS is required and the certificate is pinned to the TLSA records If no host could be attempted, the message is deferred with 4.7.0. Three points that matter when you read a log: The MX RRset must be DNSSEC-validated too, not only the TLSA record (RFC 7672 §2.2). A TLSA record found under a host name learned from a forged MX answer proves nothing, so the server validates the MX RRset and checks that the host it is about to contact is one of the names that RRset published. Only DANE-EE, usage 3, is honoured. A record of any other usage is skipped, issuer certificates are ignored, and the leaf is matched against selector 0 (whole certificate) or 1 (SubjectPublicKeyInfo) with matching type 0 (exact), 1 (SHA-256) or 2 (SHA-512). It fails open except for one value. Bogus - a published DNSSEC chain that does not validate - is the only status that can stop a delivery. Every other outcome lands on the ordinary delivery path. An empty DnssecTrustAnchors means the built-in IANA root anchors. Setting DnssecValidationEnabled=0 reverts to opportunistic, unvalidated TLSA use. With enforcement on, a recipient whose DNSSEC chain is bogus will not receive your mail rather than receive it unencrypted. SMTPDeliverer - Message 4712: DNSSEC-validated DANE-EE TLSA records found for mx1.example.com. TLS with TLSA certificate matching is required. SMTPDeliverer - Message 4712: TLSA records for mx1.example.com failed DNSSEC validation. Skipping this host (RFC 7672). SMTPDeliverer - Message 4712: Delivery to example.com deferred. TLSA records of all MX hosts failed DNSSEC validation. And in the TCP/IP log, per handshake: DANE: Session 812: Certificate matched DANE-EE TLSA record (selector 1, matching type 1). DANE: Session 813: Certificate did not match any DANE-EE TLSA record. Failing TLS handshake. Both deferral paths use 4.7.0, "other or undefined security status" (RFC 3463). Publishing your own MTA-STS policy MtaStsHostingEnabled defaults to 1. The built-in web services server serves /.well-known/mta-sts.txt for any hosted, active domain when the request's Host is mta-sts.<domain>, and generates the body from your live MX records unless MtaStsPolicyMx overrides them: version: STSv1 mode: enforce mx: mail.yourcompany.com max_age: 604800 Setting Default Notes MtaStsHostingEnabled 1 On, but inert until the HTTPS listener exists MtaStsPolicyMode enforce enforce, testing or none; anything else is read as enforce MtaStsPolicyMaxAge 604800 (7 days) Clamped to 86400 … 31557600 MtaStsPolicyMx empty Comma-separated override; empty derives the list from live MX records WebServicesHttpsPort 0 Must be set. RFC 8461 §3.3 requires the policy to be fetched over HTTPS WebServicesHttpsPort is what makes it live. While it is 0 the server logs that the policy cannot be served and that sending servers will treat the domain as having no policy. Set WebServicesHttpsPort. Add mta-sts.yourcompany.com to AcmeDomains, so that the HTTPS listener has a certificate for the name it will be asked for. Every name in AcmeDomains becomes a SAN on one certificate, and each must already resolve to this server (Let's Encrypt certificates are automatic). Decide MtaStsPolicyMode. The default is enforce, under which a sender that cannot verify the certificate on your MX host defers its mail to you. The wiki's DNS page says to start at testing, which, once you publish a _smtp._tls TXT record (v=TLSRPTv1; rua=mailto:...), gives you TLS-RPT reports without losing mail while you find out whether every sender can reach you over TLS; then move to enforce. Publish _mta-sts.yourcompany.com. IN TXT "v=STSv1; id=20260908000000Z". Bump the id whenever you change the policy. DANE for your own server, with ACME Every successful ACME issuance writes the exact record to publish into the log: ACME: DANE TLSA record for this certificate: _25._tcp.<mx-host>. IN TLSA 3 1 1 3b1f… That is 3 1 1: DANE-EE, SubjectPublicKeyInfo, SHA-256. The digest is over the key, so the record stays valid across a renewal only when the key is kept, which is what AcmeReuseKey (default 1) does. When it is on and a privkey.pem already exists, the log says ACME: Reusing the existing certificate key (keeps published TLSA records valid). Otherwise a fresh 2048-bit RSA key is generated. Leave it on if you publish TLSA records. The wiki's DNS page adds three things. Your zone must be DNSSEC-signed for the record to mean anything. Publish the record for every host named in your MX records. And re-publish before you rotate a certificate, never after. The Control Panel's DNS records page does not generate the TLSA value. A requirement of your own: remote domain policies Since 6.3.4 (schema 6045). In 6.3.3 the only ways to insist on TLS to a destination are the server-wide delivery security setting, a route's own connection security, and the MTA-STS or DANE policy the domain publishes itself. A remote domain policy is you saying the same for a domain that publishes nothing: a partner, a bank. Where it lives. Policies are rows of hm_remotedomainpolicies, take effect for the next message without a restart, are part of the configuration backup, and have nothing in hMailServer.ini. Four surfaces write the same records: Where How Control Panel (Windows) Mail flow & delivery → Remote domains, beside Routes Control Deck Remote domains in the navigation REST API GET/POST /api/v1/remote-domains, PUT/DELETE /api/v1/remote-domains/{id}, GET /api/v1/remote-domains/effective?domain=... COM (Windows) Application.Settings.RemoteDomainPolicies All are server-administrator only. An API key restricted to named domains is refused, because a policy names somebody else's domain and decides this server's posture. A policy is not a route. A route says where mail for a domain goes and replaces the MX lookup. A policy says what this server will and will not do when it gets there, however the server was found. A domain may have both, and the policy applies to a routed delivery exactly as it applies to an MX one. Which policy applies. A policy names a domain (bank.example) or a pattern (*.example, *), and the most specific active one governs: an exact name beats any pattern, however long the pattern; between two patterns, the one with more literal characters wins; an inactive policy is skipped, and the next most specific active one governs in its place. Switching off the entry for one domain beneath a * that requires TLS removes an exception; it does not exempt that domain. GET /api/v1/remote-domains/effective?domain=mail.bank.example (and PolicyForDomain over COM) answers which record a delivery will use, before a message has to find out. When one connection carries recipients of several domains, the strictest combination applies: the highest TLS requirement, and the smallest of each non-zero limit. Outbound TLS. Value What delivery to the domain requires none (default) Nothing beyond what the server does anyway: the delivery security setting, a route's security, and MTA-STS or DANE if the domain publishes them encrypted STARTTLS must be offered and the handshake must succeed. The certificate is not judged - the level for a partner with a self-signed or internal certificate verified Encrypted, and the certificate must chain to a trusted root and name the host connected to - what MTA-STS enforce asks dane Encrypted, and the certificate must match a DNSSEC-validated TLSA record. The TLSA lookup is made even with DANE enforcement off and even for a routed delivery; a host with no validated record is skipped, so with DnssecValidationEnabled=0 every delivery under the policy is deferred It can only raise the requirement. The policy, MTA-STS enforce and a usable TLSA record combine as the strictest of the three, never the newest. A domain that publishes MTA-STS enforce and is named here at encrypted still gets certificate verification. No value here weakens what a domain published for itself. A delivery it cannot satisfy is deferred, never sent in the clear. The recipient's status is 4.7.0, the message stays queued and is retried on the usual schedule, and the log line - and the bounce, if the retries run out - names the rule: Delivery deferred: the remote domain policy for bank.example requires TLS with a certificate that verifies to this destination, and it could not be established. The message has NOT been sent in the clear. It is a deferral rather than a bounce on purpose: the far end may fix its STARTTLS or its certificate before the queue gives up, which is how RFC 8461 §5 reasons about MTA-STS. Inbound. With Require TLS on mail from this domain set, an unencrypted session whose envelope sender is at the domain is answered 530 5.7.0 Must issue STARTTLS first at MAIL FROM. It is not applied to an authenticated submission, nor to a connection from a configured incoming relay: behind a front-end filter the hop the policy is about happened before that machine, and TLS has to be required there. The envelope sender is whatever the connecting server claims, so this keeps honest partners encrypted and is not an anti-spoofing control. The rest of the record. The same row carries the largest message this server will send to the domain (beyond it no connection is opened and the message is bounced at once with 5.3.4), the simultaneous connections and the messages a minute (beyond either, deferred with 4.4.5 for one to five minutes), whether automatic replies and forwards may go there, a backup-MX recipient callout, and since 6.3.4 (schema 6094) Encrypt mail to this domain at this server. The ceilings are in Outbound shaping and IP warm-up, gateway encryption in End-to-end encryption. Telling other operators what happened: the reports you send Two aggregate reporters, both scheduled hourly and both inert until a sender address is set. They flush their statistics either way, so switching one on does not start with an empty history. TLS-RPT (RFC 8460) DMARC aggregate (RFC 7489) Address setting TlsRptFromAddress DmarcRptFromAddress Organisation name TlsRptOrganizationName, default hMailServer DmarcRptOrganizationName, default hMailServer Recorded by ExternalDelivery, per delivery attempt, classified tlsa, sts or no-policy-found SpamTestDMARC, for every message evaluated against a published policy, passes included Schema - DmarcRptSchemaVersion, default 1 = RFC 7489 Appendix C; 2 = RFC 9990 DMARC reports are sent to an address outside the policy domain only when that address's own DNS says it wants them, so a domain cannot use its DMARC record to aim this server's reports at somebody else. Recording what this server concluded. Three related settings, the first two off by default: Setting Default What it writes AuthenticationResultsEnabled off One Authentication-Results header per accepted inbound message (RFC 8601), with the SPF, DKIM and DMARC verdicts this server reached. Only checks that ran are reported ReceivedSpfHeaderEnabled off A Received-SPF header (RFC 7208 §9.1), written only when the SPF check ran AuthenticationResultsIdentity empty = this computer's name The authserv-id, always lower-cased An arriving message that carries an Authentication-Results header claiming this server's identity has that header removed before the server writes its own; a header naming any other identity is left untouched. The reports other servers send about your domains go to the rua= address in your _dmarc and _smtp._tls records. Since 6.3.4 a domain's report mailbox reads them: see DKIM rotation, DMARC and TLS reports. A checklist AcmeEnabled=1, AcmeDomains naming mail., mta-sts. and autoconfig., and port 80 reachable (the ACME topic). Check TLS & certificates → Transport encryption overview, which says whether anything still carries a password in the clear. Leave MtaStsEnabled, DaneEnforcementEnabled and DnssecValidationEnabled at 1. Set WebServicesHttpsPort, start MtaStsPolicyMode at testing, and publish _mta-sts and _smtp._tls in DNS. Publish the TLSA record the ACME log prints, if your zone is signed. Since 6.3.4, name the partners that must never get mail in the clear as remote domain policies at encrypted or verified. Turn on AuthenticationResultsEnabled, and set TlsRptFromAddress and DmarcRptFromAddress. Diary the first renewal: it falls two-thirds of the way through the certificate's life, and the log line to look for is ACME: Certificate issued successfully. What this topic does not cover The connection to the database ([Database] TlsMode and TlsCaFile, since 6.3.4): Choosing a database and encrypting the link. Protocol versions, cipher suites, session resumption and client certificates: TLS on the listeners. Encrypting the message rather than the connection. TLS ends at the next server; End-to-end encryption is about what happens after that. Where to read more Wiki: Encryption and Certificates, §9.6 to §9.10; DNS for Your Domain, for the records themselves; Routes and Relays, §14.2a, for the whole remote domain record. Operator document at the v6.3.4 tag: RemoteDomains.md. Public documentation: 9.4 Outbound transport security and 8.7 MTA-STS. On this forum: Let's Encrypt certificates are automatic, Being trusted by the servers you send to, and Upgrading to 6.3.4 for what changes about hMailServer.ini.
  • 0 Votes
    1 Posts
    125 Views
    ProgressiverobotP
    Written for 6.3.4. hMailServer 6.3.6 (6 October 2026) carries Linux packages for x86-64 and AArch64 and one for each of ten distribution releases, both AppImages, an ARM64 Windows installer (a preview) and the first container image. See the 6.3.6 announcement. hMailServer 6.3.7 (17 October 2026) is a security release: mail from outside whose From names a domain hosted here is no longer signed with that domain's DKIM key, an authenticated submission is signed as another hosted domain only when its account may send as the address its From names, and a forward of outside mail is given an envelope sender in the forwarding domain's organisation only when the message passed DMARC for it on arrival. See the 6.3.7 announcement. hMailServer 6.3.8 (2 November 2026), the current release, is a security release: it fixes vulnerabilities the project found in its own code, so upgrade every server running 6.3.7 or earlier. See the 6.3.8 announcement. This tutorial is for someone who has not run a mail server before. It follows a message from one person to another, shows where hMailServer sits on that journey, and says what the software does and does not do. The one thing to know first: port 25 has no password, and it has to be that way. Any server on the internet may connect to your port 25 and offer you mail for your own domains, or nobody could write to you. Your own users send through a different door, port 587, which requires a login. Most of what follows is about keeping those two doors apart. What hMailServer is hMailServer is a mail server: the software that owns an email domain. When someone sends a message to [email protected], their mail server looks up where yourcompany.com receives mail and delivers it to whatever is listening there. If you run hMailServer, that is your machine. Progressive Robot Ltd forked hMailServer in 2026 and maintains the hMailServer 6 line; the current release is 6.3.8, of 2 November 2026. Job Protocol What it means Accept mail from the world SMTP Other mail servers connect and hand you messages for your users Let your users read mail IMAP and POP3 Outlook, Thunderbird, Apple Mail and phones connect to fetch messages Let your users send mail SMTP submission Your users hand you messages and you deliver them onward Where it sits, and what is not yours Running your own mail server means owning the middle of three boxes. DNS is your registrar's, and the mail clients are your users'. The wiki puts it plainly: almost every problem people describe as "hMailServer is broken" turns out to be in one of the two boxes it does not own. You provide hMailServer provides A machine reachable from the internet The SMTP, IMAP and POP3 servers, and the whole delivery pipeline A host name with an A record, and an MX record pointing at it The MTA-STS policy derived from that MX, and a live check of every record A PTR record, which only your ISP can set Nothing can substitute for it SPF, DKIM and DMARC records in your zone The DKIM key generation with a copyable record, the signing, and the inbound evaluation of everyone else's Port 25 reachable inbound, and outbound (many consumer ISPs block outbound 25) Nothing can work around a blocked port; a smart host is the usual answer A certificate, or nothing, and let ACME get one Built-in Let's Encrypt issuance and hourly renewal Somebody who will read a log occasionally The logs, the diagnostics, the message trace and the metrics to read A message's journey You send mail to [email protected]. This is what happens: Your mail client submits the message to your hMailServer on port 587. You log in first. hMailServer answers 250 Queued. It asks DNS who receives mail for example.com. The MX record answers: mail.example.com. It looks up the A and AAAA records for that host, plus TLSA and the MTA-STS policy. It delivers the message by SMTP on port 25: no login, TLS if offered. The recipient's server answers 250 OK and stores the message in Alice's mailbox. Alice's mail client reads it over IMAP. An open relay is the thing to avoid. Never let an unauthenticated stranger send mail through you to the outside world. The wiki's warning is that it will get your server blacklisted within hours. hMailServer refuses this by default. A note on ports. A fresh install seeds ports 25, 587, 110 and 143. The TLS ports 465, 993 and 995 exist only after you create them on the TCP/IP ports page. A submission, and the checks in the order the server runs them The order matters, because it decides when a sender is told no: before the message body is transferred, or after. Stage What is checked Reply when it fails Any command On a STARTTLS required port, everything but NOOP, EHLO, STARTTLS and QUIT 530 Must issue STARTTLS first. MAIL FROM Free disk space: MinimumFreeDiskSpaceMB, default 100 452 4.3.1 Insufficient system storage MAIL FROM Send-As, only when SmtpAuthenticatedSenderCheck=1 (default 0) 550 5.7.1 Sender address rejected MAIL FROM Per-IP rate: MaxSubmissionsPerIPPerMinute (default 0, unlimited) 421 Too many messages from your IP address MAIL FROM Declared SIZE against the domain's maximum message size (default 20480 KB) 552 5.3.4 Message size exceeds fixed maximum message size RCPT TO Is the address deliverable at all? 550 Unknown user, or 451 4.3.2 Unable to verify the recipient at the moment RCPT TO Mailbox full 452 4.2.2 RCPT TO Relay permission for this IP range 550 Delivery is not allowed to this address. RCPT TO Authentication required and not supplied 530 SMTP authentication is required. RCPT TO Greylisting, when it is on (default off) 451 Please try again later. end of data Actual size, bare LF check, post-transmission spam tests 552 5.3.4, 554 5.6.0 Rejected - Message containing bare LF's, 554 5.7.1 4xx and 5xx. A 4xx reply always means "come back later", while a 5xx means "never". The difference decides whether a legitimate sender's message waits in their queue or is destroyed, which is why a full mailbox is 452 and not 550. Refusing early. Every check at MAIL FROM and RCPT TO happens before a single byte of the message crosses the wire. Refusing early costs the sender nothing, and it generates no bounce to an address a spammer only claimed to be. The timing in the last reply is real. A submission ends with a line such as 250 2.0.0 Queued (0.412 seconds): the server times the accept-and-save stage and reports it. A number that climbs into whole seconds is the first sign of a slow spam test, a stalled virus scanner or a saturated work queue. Since 6.3.4 the same session has more places to say no, each of them off until an administrator sets it: country blocking, a domain white and black list, restricted delivery, mail flow rules and others. One thing differs without a switch, and only on a new installation, not an upgrade: the Internet IP range requires TLS for authentication, so from another machine AUTH is not offered before STARTTLS. Who may send through you This is the decision that separates a mail server from an open relay, and hMailServer makes it per IP range. Mail from other domains to yours is taken on port 25 without a password, or nobody could write to you. From the Internet range, mail that gives one of your own domains as its sender needs a login, whoever it is for, and relaying from one remote address to another is allowed on both shipped ranges only with authentication: a stranger who has not logged in is answered 530 SMTP authentication is required. A range that allows relaying without authentication must never exist (the Control Panel's status page warns of one as an open relay). Ranges are matched by priority, highest first, so a narrow range for your own network can sit in front of the broad Internet range; IP ranges, auto-ban, lockout and the rest has the whole grid and the shipped values. After "250 Queued": the delivery pipeline Acceptance and delivery are separate. The 250 means the message is on disk and in the database; delivery happens on the delivery threads afterwards, in this order: The OnDeliveryStart script event. Virus scanning. Global rules. The OnDeliverMessage script event. DKIM signing, then mirroring, each on the first attempt only. Local delivery: account rules, Sieve, forwarding, distribution lists, public folders. External delivery for any recipient outside this server: routes or an MX lookup, MTA-STS, DANE, TLS, then SMTP. A temporary failure is rescheduled: 4 tries, 60 minutes apart by default. A permanent failure, or retries exhausted, produces a delivery status notification to the sender. Where the filters sit Anti-spam runs in two phases, before and after the message is transmitted, and a test's phase is fixed by the test. Two thresholds decide what a score means: mark (default 5) adds spam headers, and delete (default 20) refuses the message, or quarantines it when the quarantine is on. On a fresh install almost every test is off. zen.spamhaus.org, bl.spamcop.net and multi.surbl.org are seeded but inactive; the HELO, PTR, MX and SPF tests are off; SpamAssassin is off; greylisting is off. DMARC is on (ASDMARCEnabled 1), and it evaluates SPF and DKIM itself for its own purposes. Anti-spam does not run at all for an authenticated session, for a whitelisted sender, or for an IP range with spam protection switched off. Reading mail back: IMAP or POP3 IMAP POP3 Mail lives on the server on one device Folders yes, and shared/public folders too INBOX only Read/unread, flags shared across devices per device New-mail notification IDLE pushes it polling only Server-side search yes no Concurrent sessions many one at a time; a second gets -ERR [IN-USE] Default ports here 143, and 993 once you create it 110, and 995 once you create it The wiki's advice is short: use IMAP. The three records that make mail arrive SPF: a list of the servers allowed to send mail for your domain. DKIM: a cryptographic signature proving the message really came from you and was not altered. DMARC: a policy saying what to do when SPF and DKIM disagree, and where to send reports. Without them your mail will go to spam. The wiki calls this the most common reason a new mail server "doesn't work". Note the asymmetry: hMailServer signs your outgoing mail with DKIM as soon as you configure a key, but checking SPF on incoming mail is off by default. Being trusted by the servers you send to has the detail. What hMailServer is not It was not a webmail client; since 6.3.2 it is one. The page at /portal on the REST listener became a mail client in 6.3.2, and a separate webmail such as Roundcube is no longer needed, though it still works over IMAP. Of 6.3.4's paging of a folder of a hundred thousand messages, the wiki says: built, and not yet measured. See The webmail portal at /portal. It is not a spam filter you can point at someone else's mail. It filters mail it receives, for domains it hosts. It is not Exchange. There is no ActiveSync, no MAPI and no Teams integration, so Outlook connects over IMAP and SMTP like any other client. Since 6.3.4 it carries the pieces of groupware that ride on standards, such as calendars over CalDAV. Who should run it: a small business that wants its own mail on its own server; a developer who needs a real SMTP/IMAP endpoint for testing; a hosting provider running mail for many domains. Who should not: if nobody in your organisation is comfortable editing DNS records and watching a log file occasionally, a hosted mailbox provider will serve you better. What you run it on Windows Linux Platform 64-bit Windows 10 1607 / Server 2016 or later Since 6.3.0. 6.3.4's packages are x86-64 only: a .deb for Ubuntu 26.04 and 24.04, an .rpm for Fedora 43 and 44 and Enterprise Linux 10 Administration The Control Panel, the COM API, the Control Deck and the REST API The Control Deck and the REST API. The Control Panel and the COM API are Windows-only Event scripts VBScript or JScript JavaScript, since 6.3.4 The AArch64 packages and the AppImage were last published with 6.3.3. 6.3.4 is installed by hand; no live update installs it. hMailServer on Linux: what you get and what you do not and First install on Linux go further. "Additive and off by default" The design rule is that an existing installation upgrades without behaving differently until you turn something on. Category State on a fresh install Optional listeners: the REST API and /portal, web services, metrics, ManageSieve Off. Each stays inert until its port setting is non-zero Optional features: quarantine, message trace, full-text index, archive Off Outbound transport security: MTA-STS, DANE, DNSSEC validation On (MtaStsEnabled, DaneEnforcementEnabled, DnssecValidationEnabled). Each can be switched off A new installation of 6.3.4, not an upgrade A self-signed certificate, STARTTLS offered on 25, 587, 110 and 143, TLS required for authentication from the Internet range: see Hardening a public mail server Since 6.3.4 the database is the settings store: a [Settings] line edited in hMailServer.ini is ignored in favour of the stored value, and put back where the service can write the file. Words you will meet Term Meaning MTA Mail Transfer Agent: a mail server that accepts and forwards messages. hMailServer is one MSA Message Submission Agent: the server your own users hand mail to, normally on port 587, normally with authentication MUA Mail User Agent: the mail client Relay Accepting a message for a domain you do not host and passing it on Smart host Another server you send all your outbound mail through, often your ISP's STARTTLS Upgrading a plaintext connection to an encrypted one, in-band Implicit TLS TLS from the first byte, no upgrade step: ports 465, 993, 995 Envelope vs header The MAIL FROM/RCPT TO addresses the servers use, versus the From:/To: a person reads. They need not match Deferral Holding a message for a later attempt after a temporary failure Backscatter Bounces sent to a forged sender address MX record The DNS record saying which server receives a domain's mail PTR record Reverse DNS: maps an IP back to a host name Where to read more Wiki: How Email Works, What hMailServer Is and Is Not and the Glossary. The public documentation: chapter 1, chapter 2 and the glossary. On this forum: Read this before you post and Where to post what; for the next steps, Your first domain and mailbox, and the DNS records your domain needs, Connecting a mail client, The anti-spam stack end to end and Every port hMailServer listens on.
  • 0 Votes
    1 Posts
    144 Views
    ProgressiverobotP
    This topic takes a freshly installed hMailServer 6.3.4 to its first working mailbox, proves it locally, and then lists the DNS records without which its mail either does not arrive or is filed as spam. The one thing to know first: the domain's Postmaster address box is the catch-all, not the postmaster@ mailbox the email standards ask for. Create postmaster@ as an account, and leave that box empty unless you want every misaddressed message accepted and stored. The paths below are the Windows Control Panel's; on Linux, which has no Control Panel, the same is done in the Control Deck or over the REST API. If you are learning, make the sample domain first (since 6.3.4) One button, on the Control Panel's Welcome page and on the Control Deck's Checklist view, or one command (hmctl sample-domain create, hmailserver --sample-domain create on Linux, POST /api/v1/setup/sample-domain) makes a throwaway example.test: three mailboxes, a distribution list of the three, one rule and eight delivered messages. The same button, or ... remove, takes it away and says what it removed; a domain called example.test that it did not make is never touched. All three mailboxes sign in with one password, which the server mints when it makes the sample: twenty characters of Crockford base32, grouped in fives. It is shown once, in the answer to the call that made the sample, and is stored nowhere, so write it down; if you lose it, remove the sample and make it again. Older wiki text that speaks of "one documented password" describes an earlier version of the feature and is out of date. Remove the sample before the server takes real mail. Its mailboxes are ordinary accounts that can sign in and relay. Add your domain Go to Accounts & domains → Domains, type the name and press Add domain, then select it and press Properties. On Linux, use the Deck's Domains view, or: curl -u Administrator -H "Content-Type: application/json" \ -d '{"name":"example.com","active":true}' \ http://127.0.0.1:8045/api/v1/domains postmaster is optional in that body and is left out here, because it is the same catch-all field. The call answers 400 if the name is not a valid domain name and 409 if it already exists. Since 6.3.4 the Control Panel's domain editor has fourteen tabs; the seven that 6.3.4 added are each off, or empty, until set. The fields that matter on the first day: Tab Field Default What happens when it is wrong General Domain enabled ticked Unticked: every RCPT TO is answered 550 Domain has been disabled. General Domain name The part after the @. Setting it to the host name (mail.example.com) is the classic first-day mistake General Postmaster address empty The catch-all. Set: no address in the domain can be refused. Empty: unknown recipients get 550 Unknown user Limits Maximum message size (KB) 0 0 falls back to the server-wide maxmessagesize, seeded at 20480 KB Limits Enable plus addressing off, + Off: alice+invoices@ is an unknown recipient Relay Relay host empty Where mail from this domain leaves through. This is not a route DKIM Enable signing off Enabling before the DNS record is live makes every message fail DKIM at the receiver In RecipientParser::CheckDeliveryPossibility, an address that matches no account, alias, distribution list or route falls through to the postmaster address and the resolution restarts with it. That is why the box is a catch-all. Add a mailbox Select the domain, type the address and a password under the account list, and press Create account; then Edit for the full editor. Field Value to use Notes Password Press Generate strong password 16 characters from a cryptographic RNG, shown once and copied to the clipboard Administration level Normal user Server administrator can manage everything. Give it only to yourself Quota (MB) 0 for unlimited Account enabled ticked Unticked: 550 Account is not active. at RCPT TO On Linux, make the account on the Control Deck or with POST /api/v1/domains/{domain}/accounts. Create at least [email protected] and your own mailbox. A full mailbox is refused during the SMTP conversation, not bounced: with RejectFullMailboxAtRcpt on, as it is by default, RCPT TO is answered 452 4.2.2 Mailbox is full., a temporary refusal, so the sending server holds the message and no backscatter is sent. Since 6.3.4, accounts can be imported from a CSV file over REST, with hmctl and with the PowerShell module, with a dry run that changes nothing; and an identity provider can make and remove them over SCIM. Three things about an account are set only on the Control Deck and over REST, not in the Control Panel: its kind (a person, a room or equipment), encryption at rest, and a webhook route. How an address is resolved Every RCPT TO is answered by one function, in a fixed order that ends at the domain's postmaster address; the full order, with domain aliases, plus addressing and the webhook route, is in Aliases, distribution lists and public folders. What it means on the first day: Question Answer Why did mail to a mistyped address get delivered? The domain has a postmaster address, so it fell through to the catch-all Why does alice+anything@ not work? Plus addressing is off by default and is per domain Why does an alias to an external address still count as local? Only at the first hop, so that it is treated as inbound mail and not as relaying Test it locally, before touching DNS The test below works because a fresh database's My computer IP range lets the server itself, on 127.0.0.1, send as one of its own domains without a password, while anyone may send you mail and nobody may relay through you without logging in. A refused direction is 550 Delivery is not allowed to this address.; one that needs authentication is 530 SMTP authentication is required. The two seeded ranges and what each allows are in IP ranges, auto-ban, lockout and sending limits. Send-MailMessage -SmtpServer localhost -Port 25 ` -From "[email protected]" -To "[email protected]" ` -Subject "First test" -Body "If you can read this, hMailServer is working." Or by hand with telnet localhost 25. The replies worth recognising: Line What it tells you 250-SIZE 20971520 The server-wide maxmessagesize, 20480 KB, in bytes 250-STARTTLS Present only when the port's connection security is STARTTLS optional or required 250 AUTH … Absent when the port requires TLS, or the connecting range requires TLS when authenticating 250 2.0.0 Queued (0.016 seconds) The message is on disk and in the database 250 2.0.0 Queued for delivery Not the same reply: the message was quarantined Then check Monitoring & troubleshooting → Delivery queue, which should be empty, and look on disk: a delivered message is one file, C:\Program Files\hMailServer\Data\yourcompany.com\you\a3\{a3f01e6c-....eml}. Its first Received header reads with ESMTP, and with ESMTPSA for an authenticated submission over TLS. The DNS records your domain needs Do them in this order. Replace yourcompany.com and 203.0.113.10 with your own. Record Example Without it A / AAAA mail.yourcompany.com. IN A 203.0.113.10 Nothing resolves; the MX points at nothing MX yourcompany.com. IN MX 10 mail.yourcompany.com. Inbound mail bounces as "no mail server for this domain" PTR 10.113.0.203.in-addr.arpa. IN PTR mail.yourcompany.com. Google and Microsoft refuse or spam-folder outbound mail SPF yourcompany.com. IN TXT "v=spf1 mx a:mail.yourcompany.com ~all" Anybody can forge your domain; DMARC cannot pass on the SPF side DKIM dkim._domainkey.yourcompany.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..." Forwarded mail fails everything, because forwarding breaks SPF DMARC _dmarc.yourcompany.com. IN TXT "v=DMARC1; p=none; rua=mailto:[email protected]" No policy and no reports A / AAAA and MX. Add an AAAA only if the machine has a public IPv6 address that answers. An MX must point at a host name, never an IP address, and that name must not be a CNAME. The MX name is what MTA-STS matches, what TLSA records hang off, and what the certificate on port 25 should be issued for. PTR. Only your ISP or hosting provider can set it. It should name the same host as your HELO/EHLO, which hMailServer takes from Connections & protocols → Protocols → SMTP, Host name (HELO/EHLO greeting), falling back to the Windows computer name when blank. The Control Panel's DNS records page does not check it, and says so. SPF. Start with ~all; move to -all once the DMARC reports have shown you every system that sends as you. Publish exactly one SPF record per name: two beginning v=spf1 is a permanent error at every receiver. RFC 7208 caps the DNS-querying mechanisms at ten. In the other direction, checking SPF on incoming mail as a scored test is off by default (usespf is seeded 0), but DMARC checking is on by default and evaluates SPF and DKIM itself. DKIM. On the domain's DKIM tab click Generate key pair…: it creates an RSA-2048 key, saves the private key and shows the exact record, with a Copy DNS value button. dkim is the default selector. Switching signing on is gated on the published record matching. Ed25519 is supported too, with a key you supply. Since 6.3.4 a rotation policy per domain generates the new key under a dated selector (s20260915), checks the record every fifteen minutes and switches signing only once it has carried that key for a propagation period. It never edits DNS, and it is off until switched on. DMARC. Start with p=none, read the reports for a few weeks, then tighten to p=quarantine and p=reject. Do not start at p=reject. The DNS records page pre-fills rua= with the domain's postmaster address and omits the tag when there is none. Since 6.3.4, name that mailbox as the domain's report mailbox and the server parses the DMARC and TLS-RPT reports that arrive there and charts them on the Control Deck's DMARC page. Nothing read there acts on any mail. Optional hardening, at any point afterwards: Record Name Notes MTA-STS _mta-sts.yourcompany.com. IN TXT "v=STSv1; id=20260908120000" hMailServer serves the policy itself once WebServicesHttpsPort is set and the listener has a certificate for mta-sts.yourcompany.com; MtaStsPolicyMode defaults to enforce, so set it to testing to start TLS-RPT _smtp._tls.yourcompany.com. IN TXT "v=TLSRPTv1; rua=mailto:[email protected]" Asks other servers to tell you when TLS to you failed TLSA _25._tcp.mail.yourcompany.com. IN TLSA 3 1 1 <sha256 of the certificate public key> Only meaningful if your zone is DNSSEC-signed. Re-publish before you rotate a certificate, never after CNAME autoconfig, autodiscover, mta-sts → mail.yourcompany.com. For client autoconfiguration and the policy host A / AAAA / CNAME openpgpkey.yourcompany.com Since 6.3.4, only if you publish OpenPGP keys BIMI is read, not published: since 6.3.4 the webmail shows a sender's logo, but this server publishes no BIMI record for your domains. Checking your work Give DNS an hour to propagate. Monitoring & troubleshooting → DNS records lists, per domain, the exact SPF, DKIM, DMARC, MTA-STS and TLS-RPT records to publish, with a Check button per record: Verdict What to do Not published Publish it Published but different Compare the two; the page shows what is there Published and correct Nothing Lookup failed A resolver or network problem, not a DNS-content one. Retry On Linux the Control Deck has a DNS records view. On either platform the first-hour checklist (since 6.3.4) judges the spf, dkim and dmarc items itself, for the first twenty active domains. From a command line: Resolve-DnsName yourcompany.com -Type MX Resolve-DnsName yourcompany.com -Type TXT Resolve-DnsName dkim._domainkey.yourcompany.com -Type TXT Resolve-DnsName _dmarc.yourcompany.com -Type TXT Resolve-DnsName 10.113.0.203.in-addr.arpa -Type PTR Being trusted by the servers you send to takes deliverability further. The ports your users will need The create scripts seed four listeners, SMTP 25 and 587, POP3 110 and IMAP 143, with no encryption. Since 6.3.4 a new installation sets all four to STARTTLS optional with the self-signed certificate and requires TLS for authentication from the Internet IP range; an upgraded server is left as it was (Hardening a public mail server). Ports 465, 993 and 995 are not created for you: add them on Connections & protocols → TCP/IP ports once you have a certificate. A TLS port with no certificate selected does not start (HM5113, Error initializing SSL. Certificate not set.); a port already in use is HM4316. Which connection security each port should have, and why STARTTLS optional belongs on port 25 alone, is in Connecting a mail client; which ports to open in the firewall is in Every port hMailServer listens on. Before you tell anyone the address postmaster@ exists as a real account. MX, SPF, DKIM and DMARC are published and verified. A certificate is installed and the client ports created: Let's Encrypt certificates are automatic. The administrator password is a PBKDF2 one. 6.3.4's installer writes it so; the wiki's checklist item about changing it from "the installer's MD5" describes 6.3.3 and earlier. A backup that you have restored once. What it does not do, and where to read more Nothing here publishes a DNS record for you: the Control Panel builds the text and checks it, and the DKIM rotation never edits DNS. The PTR record is your provider's to set. More on the records above: DKIM rotation, DMARC and TLS reports, and Requiring TLS for MTA-STS, TLS-RPT and DANE. The webmail and browser administration are separate topics: The webmail portal at /portal and The Control Deck. Sources: the wiki's Your First Domain and Mailbox, DNS for Your Domain and Ports Reference; SampleDomain.md and SetupChecklist.md; and chapters 6, 8 and 22 of the public documentation.
  • 0 Votes
    1 Posts
    103 Views
    ProgressiverobotP
    Written for 6.3.4. hMailServer 6.3.7 (17 October 2026) signs a message as a hosted domain only when the server is entitled to: mail from outside whose From names a domain hosted here is no longer signed with that domain's DKIM key, and an authenticated submission is signed as another hosted domain only when its account may send as the address its From names (CVE-2026-107567); the upgrade stops the signing, and only rotating the domain's key ends the signatures already made. A forward of outside mail whose From names the forwarding domain's own organisation is given an SRS or rewritten envelope sender only when the message passed DMARC for it on arrival; with SRS on, mail to an SRS address this server handed out is held to the relay rules unless it is a bounce; and an ARC seal this server makes attests its own SPF result and names the domains its results are for. See the 6.3.7 announcement. Getting mail accepted is mostly DNS. hMailServer does the cryptography and the protocol work. It cannot publish records for you. This is the split. What the server does on its own DKIM signing. Open the domain's DKIM tab in the Control Panel and click Generate key. It creates an RSA-2048 key, saves the private key, fills in the path and shows the exact TXT record with a Copy button. Once the record is published it signs the domain's outgoing mail - a signed-in account's submission and every copy of it, a message the server makes itself, and mail an IP range lets in as one of this server's domains - but since 6.3.7 not mail from outside whose From names the domain: such mail leaves with the signature it came with. Since 6.3.7 an authenticated submission is signed as another hosted domain only when its account may send as the address its From names (CVE-2026-107567). Ed25519 DKIM (RFC 8463) is supported alongside RSA, for shorter keys. Since 6.3.4 a domain's DKIM keys can also rotate on a policy, off by default. DkimOversignHeaders over-signs the header fields you name. DkimAcceptSha1=0 refuses rsa-sha1 signatures on inbound mail. SPF and DMARC inbound. SPF is checked as part of anti-spam scoring, with SpfVoidLookupLimit=2. Since 6.3.4 it follows RFC 7208: mail from 127.0.0.0/8 and ::1 no longer passes unconditionally, so a content filter that hands mail back should authenticate, or connect from an IP range with anti-spam off. DMARC policy is evaluated on inbound mail and the DMARCbis tree walk is on by default (DmarcTreeWalkEnabled=1). Aggregate reporting stays off until you set DmarcRptFromAddress. Outbound transport security. MtaStsEnabled=1, DaneEnforcementEnabled=1 and DnssecValidationEnabled=1 are all on by default, under TLS & certificates → Transport security. A recipient whose DNSSEC chain is bogus does not receive your mail rather than receiving it unencrypted. That is the point of enforcement, so read the logs before you reach for the switch. TLS-RPT. Off until you set TlsRptFromAddress. After that the server sends daily reports to recipient domains about TLS failures it hit delivering to them. SRS and BATV. Off by default. If you forward mail, set SRSEnabled=1 and a SRSSecret to keep forwarded mail SPF-aligned. The secret must be stable. Outstanding SRS addresses remain valid for 21 days, so changing it loses bounces for mail you forwarded recently. BATV (prvs) signs your envelope sender so you can recognise and drop backscatter. Neither ever became an RFC. Both follow the widely deployed drafts, as does everything that interoperates with them. What you must publish yourself PTR, and your ISP sets that one, not you. Missing PTR is the single biggest cause of spam-foldering. Then SPF, the DKIM TXT record, and DMARC. For MTA-STS on the inbound side, point mta-sts.<domain> at the server, set MtaStsHostingEnabled=1 and WebServicesHttpsPort=443, and publish the _mta-sts.<domain> TXT record. If you publish TLSA records for inbound DANE, keep AcmeReuseKey=1 so renewals do not invalidate them. Start DMARC at p=none. Read the reports for a few weeks and confirm all your legitimate mail passes SPF and DKIM before moving to p=quarantine, then p=reject. Starting at p=reject silently loses mail from the sender you had forgotten about. Still incomplete ARC sealing (RFC 8617) covers mail from hosted DKIM-enabled domains. Relayed third-party mail is not sealed yet. Chapter 8, the DNS records with example syntax: https://www.progressiverobot.com/hmailserver-documentation/#8-making-the-internet-trust-you-dns Chapter 9.4, outbound transport security: https://www.progressiverobot.com/hmailserver-documentation/#94-outbound-transport-security Chapter 17.6, SRS and BATV: https://www.progressiverobot.com/hmailserver-documentation/#176-srs-and-batv