Use Sites → Email to inspect mail-server readiness, verify the required DNS records, and provision real mailboxes into the live Postfix and Dovecot setup for the site domain.
Herne now provisions real single-server mailboxes when the server is prepared correctly. Webmail, aliases, and multi-server mail topologies remain out of scope.
Provisioning strategy
Herne Phase 2 uses a file-based single-server mail provisioning path. The panel database remains the source of truth, and Herne generates Postfix and Dovecot artifacts from that data under a dedicated managed root.
Recommended setup path
The primary supported path on a fresh server is now the unified Herne installer:
curl -fsSL https://raw.githubusercontent.com/fklavyenet/herne/main/install.sh | sudo bash
Answer yes when the installer asks whether it should install the mail stack, then provide EMAIL_HOSTING_SERVER_HOSTNAME so Herne can configure a coherent canonical mail hostname for Postfix. After the local stack is ready, use the panel Email pages to provision domains and mailboxes.
If Herne is already installed and you are adding mail later, the standalone path remains:
php artisan herne:install-mail-stack --check
php artisan herne:install-mail-stack --apply
php artisan herne:email:check-server
What Herne manages
/etc/herne-mail/generated/postfix/virtual_domains/etc/herne-mail/generated/postfix/virtual_mailboxes/etc/herne-mail/generated/dovecot/passwd/etc/herne-mail/generated/state.json/var/vmail/{domain}/{local_part}/Maildir
Herne writes the source files, runs postmap for the Postfix maps, creates Maildir directories, and reloads postfix and dovecot only after the new files are staged successfully.
Required Ubuntu packages
The installer can install these automatically on Debian and Ubuntu with noninteractive apt when the operator runs it as root or with passwordless sudo.
postfixpostfix-pcreif your server policy already expects it elsewheredovecot-coredovecot-imapddovecot-pop3ddovecot-lmtpdrspamdredis-server(recommended for Rspamd)dnsutilsopenssl
Readiness checks
Herne checks for these binaries: postfix, postconf, postmap, dovecot, doveconf, rspamd, rspamadm, openssl, systemctl, ss, and either dig or host.
Herne also checks the postfix, dovecot, rspamd, and redis-server services, the mail ports 25, 465, 587, 143, 993, 110, and 995, plus UFW rules when UFW is installed.
Phase 2 also checks integration wiring and filesystem readiness: the vmail user/group, the writable vmail root, the Herne-managed config root, and whether postconf -n / doveconf -n actually reference the Herne-managed files.
Expected virtual mail user model
Herne installs and uses a dedicated system account for mailbox storage, typically vmail:vmail. Herne expects Maildir storage under /var/vmail and archives deleted mailbox storage under /var/vmail/.trash.
Herne prefers UID/GID 5000 when free, but falls back safely if that identity is already in use.
Webmail MVP
Herne includes a lightweight first-party Webmail MVP at /webmail. This is a separate mailbox login flow and does not require a Herne panel account.
- Mailbox users sign in with the full email address and mailbox password.
- Only active, live-provisioned Herne mailboxes can sign in.
- The MVP supports Inbox, read, send, reply, and delete.
- Outgoing mail always uses the logged-in mailbox address as the sender.
- Attachments, folder management, aliases/forwarders, spam quarantine, rich text editing, and multi-server webmail are outside the MVP.
Incoming mail uses PHP's imap extension against IMAP, normally port 993 with SSL. SMTP sending uses the mailbox credentials against the configured mail host, normally EMAIL_HOSTING_SERVER_HOSTNAME or mail.{domain}, port 587 with STARTTLS.
Webmail storage vs Maildir storage
Webmail runtime data and real mailbox storage are intentionally separate:
- Webmail app/runtime storage:
/var/www/{site}/webmail - Webmail runtime subdirectories:
cache,tmp, anddrafts - Real mailbox Maildir storage:
/var/vmail/{domain}/{local_part}/Maildir
The webmail directory is not under the public web_root and is not automatically included in site file backups. The MVP does not move Dovecot mail delivery under /var/www, preserving the existing vmail permission model.
Useful server commands
php artisan herne:install-mail-stack --check
php artisan herne:install-mail-stack --apply
php artisan herne:install-mail-stack --repair
systemctl status postfix
systemctl status dovecot
systemctl status rspamd
ss -ltnp | grep -E ':25|:465|:587|:143|:993|:110|:995'
postconf -n
doveconf -n
php artisan herne:email:check-server
php artisan herne:email:health example.com
php artisan herne:email:provision-domain example.com
php artisan herne:email:provision-mailbox support@example.com
php artisan herne:email:rebuild
DNS records Herne expects
dig MX example.com
dig TXT example.com
dig TXT herne._domainkey.example.com
dig TXT _dmarc.example.com
The panel generates recommended MX, SPF, DKIM, and DMARC records for each mail domain and verifies them against public DNS. A domain is only marked DNS-ready when the required records are actually present or explicitly compatible.
Email Health and Deliverability
Phase 3 adds a diagnostics-first health layer. Herne does not calculate a fake deliverability score. Instead it stores a compact structured snapshot with explicit findings, grouped categories, and recommended fixes.
Health categories
- DNS identity: MX, SPF, DKIM, DMARC presence and basic strength
- Host identity: server hostname, Postfix HELO identity, mail-host A/AAAA resolution, PTR, and forward-confirmed reverse DNS coherence
- SMTP reachability: Postfix state plus local listeners for 25, 465, and 587
- IMAP/POP/TLS basics: Dovecot state plus local listeners for 143, 993, 110, and 995, and partial TLS sanity checks when practical
- Anti-spam prerequisites: Rspamd, Redis when expected, DMARC policy strength, SPF policy breadth, DKIM DNS readiness, Postfix milter wiring, and outbound DKIM signing selector alignment
- Provisioning integrity: panel state versus live artifact presence and generated-state drift
- Firewall visibility: UFW state and whether mail ports appear allowed when UFW is active
Status meanings
- pass: the check succeeded based on evidence Herne could gather
- warning: the setup may work, but a weakness or mismatch is visible
- fail: an expected prerequisite is clearly missing or broken
- unknown: the check could not be proven safely in the current environment
- unavailable: the tooling needed for the check does not exist locally
Why PTR matters
Many receiving systems expect the sending IP to have reverse DNS and for that PTR to line up with a sensible mail hostname. Herne checks PTR only when it can determine the public IP honestly. You can set EMAIL_HEALTH_PUBLIC_IPV4 and EMAIL_HEALTH_PUBLIC_IPV6 if local route-based discovery is ambiguous.
Healthy baseline
- MX points to the intended mail hostname
- The mail hostname resolves back to the current server IP
- PTR points to the same mail hostname or a coherent equivalent
- Postfix
myhostnameorsmtp_helo_nameuses the same canonical mail hostname - SPF is present and not overly permissive
- DKIM is published and matches the configured selector
- Postfix routes outbound mail through Rspamd and Rspamd signs with the same selector Herne displays in DNS
- DMARC exists and ideally moves beyond
p=noneonce sending flows are validated - Postfix and Dovecot are active, with the expected listeners present
- The live provisioning artifacts exist and match panel state
Common fixes
- Missing MX: publish an MX record pointing to the configured mail hostname
- Missing PTR: ask the hosting provider to set reverse DNS for the server IP
- PTR mismatch: align PTR, MX, and A/AAAA around one coherent mail hostname
- HELO mismatch: set Postfix
myhostnameorsmtp_helo_nameto the canonical mail hostname - SPF too broad: replace permissive SPF rules with a narrower sender policy
- DKIM DNS passes but Gmail still shows no DKIM: check
smtpd_milters,non_smtpd_milters, andrspamadm configdump dkim_signing - DMARC
p=none: move to quarantine or reject after validating legitimate senders - Submission missing: enable Postfix submission on port 587
- TLS uncertainty: install or fix the certificate covering the configured mail hostname
- Provisioning drift: use the domain reprovision or full rebuild action to regenerate artifacts
Gmail spam troubleshooting
If macOS Mail, Webmail, and server-side sends all reach Gmail but land in spam, treat it as a sending identity or reputation problem rather than a client setup problem.
- Run
php artisan herne:email:health example.comand fix PTR, HELO hostname, SPF, DKIM, DMARC, milter, and provisioning warnings first. - Reverse DNS should point from the sending IP to the same canonical hostname used by MX, A, Postfix, SMTP HELO, and TLS.
- Ask the user to open Gmail Show original and report the SPF, DKIM, DMARC, and Authentication-Results lines. Do not guess from inbox placement alone.
- If Gmail shows DKIM missing or failing while Herne DNS says DKIM is ready, verify the outbound signing path: Postfix milter wiring, Rspamd
dkim_signing, selector, domain block, and private-key readability. - Use Gmail Postmaster Tools and a gradual warm-up period for new IPs, new domains, or recently repaired mail identity. Authentication can pass before reputation is strong enough for inbox placement.
Postfix integration
The installer updates /etc/postfix/main.cf surgically with the Herne-managed map references and enables submission in /etc/postfix/master.cf. A reference snippet is still shipped in stubs/email/postfix-maincf-snippet.txt for operators who want to review the target wiring.
Dovecot integration
The installer switches Dovecot to a Herne-managed passwd-file include, writes the Maildir, LMTP, and Postfix auth socket snippet, and keeps backup copies before touching the live files. A reference snippet is still shipped in stubs/email/dovecot-auth-snippet.conf.
Webmail SMTP auth socket troubleshooting
If Webmail send fails with Connection to "mail.example.com:587" has been closed unexpectedly and /var/log/mail.log shows SASL: Connect to Dovecot auth socket 'private/auth' failed or no SASL authentication mechanisms, Postfix submission cannot reach Dovecot SASL auth.
php artisan herne:install-mail-stack --check
php artisan herne:install-mail-stack --repair
sudo systemctl reload dovecot
sudo systemctl reload postfix
sudo ls -la /var/spool/postfix/private/auth
sudo postconf -n | grep -E 'smtpd_sasl_type|smtpd_sasl_path|smtpd_sasl_auth_enable'
sudo doveconf -n | grep -A8 -B2 '/var/spool/postfix/private/auth'
The expected Dovecot listener is /var/spool/postfix/private/auth with mode 0660, user postfix, and group postfix. Postfix should use smtpd_sasl_type = dovecot, smtpd_sasl_path = private/auth, and smtpd_sasl_auth_enable = yes.
Backups and repair mode
Before changing system config, Herne stores timestamped backups under /etc/herne-mail/backups/{timestamp}/.... Re-run php artisan herne:install-mail-stack --repair if a previously working Herne mail stack drifted or if an operator partially edited the config by hand.
Safe refusal cases
Herne refuses automatic apply by default when it detects an apparently incompatible existing Postfix or Dovecot setup, when the canonical mail hostname is missing, or when the command does not have the root-level access required to change system config safely.
Password scheme
Herne uses SHA512-CRYPT for the live Dovecot passwd-file. Panel-side mailbox passwords remain hashed separately in the application database.
Sudoers requirements
Herne needs tightly scoped sudo access for mail provisioning operations. The exact required commands are:
www-data ALL=(root) NOPASSWD: /usr/bin/install -d *
www-data ALL=(root) NOPASSWD: /usr/bin/install -m *
www-data ALL=(root) NOPASSWD: /bin/cp -f *
www-data ALL=(root) NOPASSWD: /bin/mv *
www-data ALL=(root) NOPASSWD: /bin/rm -rf /etc/herne-mail/.staging-*, /bin/rm -rf /etc/herne-mail/.backup-*
www-data ALL=(root) NOPASSWD: /usr/sbin/postmap *
www-data ALL=(root) NOPASSWD: /usr/bin/test *
www-data ALL=(root) NOPASSWD: /usr/bin/id *
www-data ALL=(root) NOPASSWD: /usr/bin/getent group *
www-data ALL=(root) NOPASSWD: /usr/bin/systemctl reload postfix
www-data ALL=(root) NOPASSWD: /usr/bin/systemctl reload dovecot
Deletion behavior
Mailbox deletion is conservative. Herne removes the live auth/map entry, rebuilds the managed artifacts, and archives the mailbox storage into /var/vmail/.trash/{timestamp}-{domain}-{local_part} instead of deleting it permanently.
Still out of scope
- Roundcube or a full desktop-class webmail client
- Aliases and forwarders UI
- Spam quarantine UI
- Attachments and folder management in Webmail
- Multi-server mail clusters