Configure Dovecot virtual users, Maildir storage, and quotas
Create a single storage identity, define virtual passdb/userdb, map domains safely, build Maildir permissions, enable quotas, and test enforcement and reporting.
Host mailbox identities independent of Unix users with deterministic storage and enforceable limits.
- Dovecot CE 2.4
- Authoritative DNS and stable identity Control forward and reverse DNS, choose the canonical mail hostname and domains, and verify the host is not behind an outbound SMTP-blocking network.
hostname -f; getent ahosts $(hostname -f); dig +short -x {{publicIp}} - Recovery and queue safety Keep console access, back up active configuration, and record queue state before changing routing, authentication, filters, or mailbox delivery.
- Abuse and deliverability plan Define relay boundaries, account owners, rate limits, bounce handling, postmaster address, monitoring, and how compromised credentials will be revoked.
OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.
Full guide
What you will build
- A production Dovecot implementation of “Configure Dovecot virtual users, Maildir storage, and quotas” with explicit SMTP/IMAP boundaries, identity, durable state and observable delivery evidence.
- A read-only baseline, staged candidate and end-to-end canary covering DNS, TLS, authentication, recipient or route policy, queue/mailbox state and logs.
- A security and rollback procedure that avoids open relay, backscatter, plaintext credentials, world-readable keys/mail and unreviewed bulk queue actions.
- Host mailbox identities independent of Unix users with deterministic storage and enforceable limits. The intended success path is visible in native status, protocol transcript, headers or mailbox evidence.
- Expected unauthorized relay, unknown-recipient, wrong-sender, invalid-authentication or wrong-certificate tests fail at the declared boundary without harming unrelated mail.
Architecture
How the parts fit together
The MTA validates virtual recipients and maps accepted addresses to a non-login virtual-mail identity and Maildir path. Dovecot authenticates users, reads the same mailbox namespace, applies quotas and exposes IMAP over TLS. Lookup maps, filesystem ownership and LMTP/LDA delivery must agree exactly. Unknown recipients are rejected during SMTP rather than backscattering after acceptance, and quota/mailbox tests prove durable delivery.
- Inventory hostname/DNS, listeners, certificates, identities, recipient/relay maps, queue/mailbox state, logs and a recoverable configuration/data baseline.
- Prepare the virtual mail candidate with official Dovecot syntax, protected secrets and one explicit service/data boundary at a time.
- Run native configuration validation and immediate read-only checkpoint before reload or acceptance of new messages.
- Use controlled local and external canaries plus an expected-denial test, preserve message identifiers/headers, and retain the prior configuration for rollback.
Assumptions
- The public mail hostname, forward/reverse DNS ownership, supported package version and responsibility for ports 25/587/993 are known.
- A maintenance or canary window, console recovery and current protected backup of configuration, keys, identity mappings and relevant mailbox/queue data exist.
- Test sender and recipient addresses are owned by the operator; no unsolicited or third-party traffic is generated during verification.
- Secrets and private keys are delivered outside shell history and have narrowly defined service ownership and rotation plans.
Key concepts
- envelope identity
- SMTP sender and recipient used for routing, delivery status and SPF; it is distinct from visible message headers.
- open relay
- An MTA that accepts unauthorized third-party sender-to-recipient forwarding, enabling abuse and reputation damage.
- backscatter
- A later non-delivery report sent to a forged sender because an invalid recipient was accepted instead of rejected during SMTP.
- alignment
- DMARC relationship between visible From domain and authenticated SPF or DKIM domain.
- Maildir
- A mailbox format storing messages as individual files in cur/new/tmp directories with strict ownership.
Before you copy
Values used in this guide
{{domain}}Fully qualified public or internal hostname served by this configuration.
Example: example.com{{mailRoot}}Operator-reviewed value used by this tutorial for mailRoot; derive it from the target environment and never from untrusted request data.
Example: /srv/vmail{{protectedSecret}}Operator-reviewed value used by this tutorial for protectedSecret; derive it from the target environment and never from untrusted request data.
Example: secret-manager-reference{{safeMessage}}Operator-reviewed value used by this tutorial for safeMessage; derive it from the target environment and never from untrusted request data.
Example: /srv/mail-fixtures/safe-message.eml{{testAddress}}Operator-reviewed value used by this tutorial for testAddress; derive it from the target environment and never from untrusted request data.
Example: alice@example.com{{user}}Operator-reviewed value used by this tutorial for user; derive it from the target environment and never from untrusted request data.
Example: alice@example.comSecurity and production boundaries
- Never weaken relay/recipient checks, publish private DKIM/TLS keys, enable plaintext authentication, or expose web/IMAP administration broadly to make a test pass.
- Mail content, credentials, queues, logs and backups contain personal or confidential data; restrict, encrypt, minimize and retain them under an explicit policy.
- Use dedicated service identities and root-readable credential maps; verify logs and configuration output are redacted before sharing.
Stop before continuing if
- Stop if a test permits unauthorized relay, accepts unknown recipients for later bounce, sends credentials without verified TLS, or exposes private keys/mailbox files.
- Do not continue when hostname/PTR ownership, package/config version, recipient map, route, queue, mailbox ownership or rollback backup is ambiguous.
- Immediately quarantine the candidate when unrelated mail is rerouted, deleted, multiply delivered, signed by the wrong domain, or inaccessible after reload.
command
Create the virtual mail storage identity
Use one non-login vmail UID/GID outside normal user ranges and a root-owned top-level mail directory.
Why this step matters
Create the virtual mail storage identity is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Use one non-login vmail UID/GID outside normal user ranges and a root-owned top-level mail directory. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Create the virtual mail storage identity”. The scope must remain limited to the selected application and supported host.
Syntax explained
groupadd- Invokes the principal tool or configuration operation for “Create the virtual mail storage identity”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}- Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Values stay on this page and are never sent or saved.
sudo groupadd --system vmail; sudo useradd --system --gid vmail --home-dir {{mailRoot}} --shell /usr/sbin/nologin vmail; sudo install -d -o vmail -g vmail -m 0750 {{mailRoot}}vmail exists with no shell and owns the mail root.
Checkpoint: Checkpoint: Create the virtual mail storage identity
Continue whenvmail exists with no shell and owns the mail root. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when groupadd reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Create the virtual mail storage identity” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v groupadd 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
instruction
Define canonical mailbox identifiers and paths
Normalize login as full address, lowercase domains according to policy, reject path separators, and map to domain/user/Maildir without user-controlled traversal.
Why this step matters
Define canonical mailbox identifiers and paths is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Normalize login as full address, lowercase domains according to policy, reject path separators, and map to domain/user/Maildir without user-controlled traversal. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Define canonical mailbox identifiers and paths”. The scope must remain limited to the selected application and supported host.
Syntax explained
printf- Invokes the principal tool or configuration operation for “Define canonical mailbox identifiers and paths”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}- Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Values stay on this page and are never sent or saved.
printf 'login=%s path=%s\n' '{{user}}@{{domain}}' '{{mailRoot}}/{{domain}}/{{user}}/Maildir'The identity-to-path rule is deterministic and documented.
Checkpoint: Checkpoint: Define canonical mailbox identifiers and paths
Continue whenThe identity-to-path rule is deterministic and documented. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when printf reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Define canonical mailbox identifiers and paths” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v printf 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
config
Configure a protected virtual passdb
Use SQL/LDAP or a root-readable passwd-file containing modern password hashes; never store cleartext credentials.
Why this step matters
Configure a protected virtual passdb is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Use SQL/LDAP or a root-readable passwd-file containing modern password hashes; never store cleartext credentials. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Configure a protected virtual passdb”. The scope must remain limited to the selected application and supported host.
Syntax explained
sudoedit- Invokes the principal tool or configuration operation for “Configure a protected virtual passdb”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
/etc/dovecot/users- Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
/etc/dovecot/userssudoedit /etc/dovecot/users; sudo chown root:dovecot /etc/dovecot/users; sudo chmod 0640 /etc/dovecot/users; sudo doveadm pw -s ARGON2IDThe passdb is protected and contains supported hashes.
Checkpoint: Checkpoint: Configure a protected virtual passdb
Continue whenThe passdb is protected and contains supported hashes. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when sudoedit reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Configure a protected virtual passdb” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v sudoedit 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
config
Return fixed UID/GID and mailbox home safely
Configure static or query-backed userdb to return vmail ownership, home, mail path, and per-user quota rule.
Why this step matters
Return fixed UID/GID and mailbox home safely is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Configure static or query-backed userdb to return vmail ownership, home, mail path, and per-user quota rule. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Return fixed UID/GID and mailbox home safely”. The scope must remain limited to the selected application and supported host.
Syntax explained
sudoedit- Invokes the principal tool or configuration operation for “Return fixed UID/GID and mailbox home safely”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
|- Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
/etc/dovecot/conf.d/auth-virtual.conf.ext- Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
/etc/dovecot/conf.d/auth-virtual.conf.extsudoedit /etc/dovecot/conf.d/auth-virtual.conf.ext; sudo doveconf -n | grep -A12 -E 'passdb|userdb'Virtual users resolve to vmail and a domain-scoped home.
Checkpoint: Checkpoint: Return fixed UID/GID and mailbox home safely
Continue whenVirtual users resolve to vmail and a domain-scoped home. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when sudoedit reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Return fixed UID/GID and mailbox home safely” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v sudoedit 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
config
Configure Maildir namespace and permissions
Set the mailbox driver/path, inbox namespace, subscriptions, indexes, and umask so one mailbox cannot read another.
Why this step matters
Configure Maildir namespace and permissions is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Set the mailbox driver/path, inbox namespace, subscriptions, indexes, and umask so one mailbox cannot read another. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Configure Maildir namespace and permissions”. The scope must remain limited to the selected application and supported host.
Syntax explained
sudoedit- Invokes the principal tool or configuration operation for “Configure Maildir namespace and permissions”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
|- Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
configuration file- Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
sudoedit /etc/dovecot/conf.d/10-mail.conf; sudo doveconf -n | grep -E 'mail_driver|mail_path|mail_location|mail_home|mail_access_groups'Maildir paths and access groups are explicit.
Checkpoint: Checkpoint: Configure Maildir namespace and permissions
Continue whenMaildir paths and access groups are explicit. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when sudoedit reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Configure Maildir namespace and permissions” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v sudoedit 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
config
Enable quota counting and warnings
Load quota plugin for IMAP and LMTP, set per-user storage/messages limits, warning thresholds, and a protected warning handler.
Why this step matters
Enable quota counting and warnings is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Load quota plugin for IMAP and LMTP, set per-user storage/messages limits, warning thresholds, and a protected warning handler. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Enable quota counting and warnings”. The scope must remain limited to the selected application and supported host.
Syntax explained
sudoedit- Invokes the principal tool or configuration operation for “Enable quota counting and warnings”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
|- Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
/etc/dovecot/conf.d/90-quota.conf- Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
/etc/dovecot/conf.d/90-quota.confsudoedit /etc/dovecot/conf.d/90-quota.conf; sudo doveconf -n | grep -A20 quotaQuota root, rule, and warning thresholds are loaded.
Checkpoint: Checkpoint: Enable quota counting and warnings
Continue whenQuota root, rule, and warning thresholds are loaded. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when sudoedit reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Enable quota counting and warnings” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v sudoedit 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
command
Initialize one test mailbox and recalculate quota
Create Maildir through doveadm or delivery as vmail, verify ownership, then recalculate quota for a controlled test user.
Why this step matters
Initialize one test mailbox and recalculate quota is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Create Maildir through doveadm or delivery as vmail, verify ownership, then recalculate quota for a controlled test user. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Initialize one test mailbox and recalculate quota”. The scope must remain limited to the selected application and supported host.
Syntax explained
doveadm- Invokes the principal tool or configuration operation for “Initialize one test mailbox and recalculate quota”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}- Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
|- Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
Values stay on this page and are never sent or saved.
sudo doveadm mailbox create -u {{testAddress}} INBOX; sudo doveadm quota recalc -u {{testAddress}}; sudo find {{mailRoot}}/{{domain}}/{{user}} -maxdepth 2 -printf '%m %u:%g %p\n' | headMailbox tree is owned by vmail and quota state initializes.
Checkpoint: Checkpoint: Initialize one test mailbox and recalculate quota
Continue whenMailbox tree is owned by vmail and quota state initializes. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when doveadm reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Initialize one test mailbox and recalculate quota” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v doveadm 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
verification
Test login, delivery, quota warning, and hard limit
Deliver safe fixtures below and above limits, inspect SMTP/LMTP result, quota get output, warning event, and ensure over-quota mail is deferred or rejected per policy.
Why this step matters
Test login, delivery, quota warning, and hard limit is a separate checkpoint because it establishes one auditable part of host mailbox identities independent of unix users with deterministic storage and enforceable limits. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.
What to understand
Deliver safe fixtures below and above limits, inspect SMTP/LMTP result, quota get output, warning event, and ensure over-quota mail is deferred or rejected per policy. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.
Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.
Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.
System changes
- This step may affect the files, packages, identities, services, or runtime policy named in “Test login, delivery, quota warning, and hard limit”. The scope must remain limited to the selected application and supported host.
Syntax explained
doveadm- Invokes the principal tool or configuration operation for “Test login, delivery, quota warning, and hard limit”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}- Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Values stay on this page and are never sent or saved.
sudo doveadm auth test {{testAddress}} '{{protectedSecret}}'; sudo doveadm quota get -u {{testAddress}}; sudo doveadm save -u {{testAddress}} INBOX < {{safeMessage}}Valid login and delivery work; configured warning and hard limit trigger predictably.
Checkpoint: Checkpoint: Test login, delivery, quota warning, and hard limit
Continue whenValid login and delivery work; configured warning and hard limit trigger predictably. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.
Stop whenStop before the next step when doveadm reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.
If this step fails
The command for “Test login, delivery, quota warning, and hard limit” fails, produces no useful evidence, or the expected service/configuration state is absent.
Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.
command -v doveadm 2>/dev/null || truesystemctl --failed --no-pager 2>/dev/null || truejournalctl -p warning -n 50 --no-pager 2>/dev/null || true
ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.
Security notes
- Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.
Alternatives
- When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.
Stop conditions
- Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
Finish line
Verification checklist
sudo doveadm user {{testAddress}} && sudo doveadm auth test {{testAddress}} '{{protectedSecret}}'The address resolves to the intended vmail path and authenticates.sudo doveadm quota get -u {{testAddress}}Storage and message usage plus configured limits are reported.Recovery guidance
Common problems and safe checks
A message remains queued or the remote server returns a temporary 4xx response.
Likely causeDNS/MX resolution, routing, network reachability, TLS negotiation, remote greylisting/rate limits, reputation or recipient policy prevents delivery.
exim -bp 2>/dev/null || postqueue -pdig +short MX example.netjournalctl -u exim4 -u postfix --since '-30 min' --no-pager
ResolutionInspect one message's recorded diagnostic and route first, fix the evidenced dependency, then retry only that message; do not force an undiagnosed bulk queue.
SMTP accepts a recipient, but the mailbox is absent, unreadable or never visible over IMAP.
Likely causeRecipient maps, LMTP/LDA route, virtual UID/GID, Maildir path, quota, Dovecot namespace or filesystem permissions disagree.
doveconf -ndoveadm user user@example.comdoveadm mailbox list -u user@example.com
ResolutionTrace the exact address through recipient validation, delivery socket and resolved mailbox path; correct the narrow mapping/ownership mismatch before accepting more mail.
Authentication or TLS fails despite apparently correct credentials and certificate files.
Likely causeThe listener uses another configuration, hostname/SAN does not match, chain/key permissions are wrong, authentication is attempted without TLS, or the identity backend maps another username.
openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com </dev/nullopenssl s_client -connect mail.example.com:993 -servername mail.example.com </dev/nulljournalctl -u dovecot -u postfix -u exim4 -p warning -n 100 --no-pager
ResolutionVerify the advertised hostname, chain, listener and mapped user independently; never disable certificate verification or enable plaintext authentication to bypass the failure.
Reference
Frequently asked questions
Why is one successful test email insufficient?
It may bypass the actual external DNS, authentication, recipient, DKIM, queue retry or IMAP path. Test each boundary and preserve protocol/header evidence.
Can TLS be tested by checking that encryption is present?
No. Verify the chain and hostname and ensure authentication is unavailable before STARTTLS; encryption to an unverified endpoint is not server authentication.
Should a stuck queue be forced immediately?
No. Read one message's diagnostic and fix the dependency first. Bulk retries can amplify rate limits, duplicates or reputation damage.
Recovery
Rollback
Restore prior passdb/userdb and quota configuration while retaining all mailbox data.
- Restore /etc/dovecot, validate, and restart before accepting new delivery.
- Disable quota enforcement only after documenting capacity risk; do not delete quota metadata blindly.
- Never remove the vmail identity or mail root during configuration rollback.
Evidence