From f76e0a31ae5b517b69a3afab0cd082daec74cddc Mon Sep 17 00:00:00 2001 From: Luciano Giacchetta Date: Wed, 11 Feb 2026 14:49:22 -0300 Subject: [PATCH] feat(postfix): implement virtual mailbox configuration for Dovecot LMTP Updates the Postfix configuration to correctly handle virtual domains when Dovecot LMTP is enabled, moving away from local system delivery settings. - Removes `postfix_mail_domain` from `postfix_mydestination` to prevent conflicts with virtual domain handling. - Updates `main.cf` to set `virtual_transport`, `virtual_mailbox_domains`, and `virtual_mailbox_maps` instead of `mailbox_transport`. - Adds a new template `virtual_mailbox_maps.j2` to authorize specific users defined in `dovecot_users`. - Adds tasks to generate the virtual mailbox map file and run `postmap` upon changes. --- defaults/main.yml | 7 ++++--- tasks/main.yml | 23 +++++++++++++++++++++++ templates/main.cf.j2 | 9 ++++----- templates/virtual_mailbox_maps.j2 | 8 ++++++++ 4 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 templates/virtual_mailbox_maps.j2 diff --git a/defaults/main.yml b/defaults/main.yml index cbcb9bc..472860f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -18,9 +18,10 @@ postfix_mail_domain: "{{ ansible_domain | default('internal.local') }}" # The Fully Qualified Domain Name of the mail server. postfix_myhostname: "mail.{{ postfix_mail_domain }}" -# Comma-separated list of domains this server accepts mail for. -# It's critical that this includes the server's own hostname and mail domain. -postfix_mydestination: "$myhostname, localhost.{{ postfix_mail_domain }}, localhost, {{ postfix_mail_domain }}" +# Comma-separated list of domains this server accepts mail for locally. +# When using Dovecot with LMTP (virtual mailboxes), the mail domain is handled +# separately via virtual_mailbox_domains, so it should NOT be included here. +postfix_mydestination: "$myhostname, localhost.{{ postfix_mail_domain }}, localhost" # The list of "trusted" remote SMTP clients that have more privileges than "strangers". postfix_mynetworks: "127.0.0.0/8 [::1]/128" diff --git a/tasks/main.yml b/tasks/main.yml index 91cfcd0..441b1ba 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -54,6 +54,29 @@ - postfix_config - postfix_smarthost +- name: "POSTFIX | Configure virtual mailbox maps" + when: dovecot_enabled | default(false) and dovecot_postfix_lmtp_enable | default(false) + ansible.builtin.template: + src: virtual_mailbox_maps.j2 + dest: /etc/postfix/virtual_mailbox_maps + owner: root + group: root + mode: '0644' + notify: Restart Postfix + tags: + - postfix_config + - dovecot_config + +- name: "POSTFIX | Create hash map for virtual mailbox maps" + when: dovecot_enabled | default(false) and dovecot_postfix_lmtp_enable | default(false) + ansible.builtin.command: + cmd: postmap hash:/etc/postfix/virtual_mailbox_maps + changed_when: true + notify: Restart Postfix + tags: + - postfix_config + - dovecot_config + - name: "DOVECOT | Install Dovecot packages" when: dovecot_enabled | default(false) ansible.builtin.apt: diff --git a/templates/main.cf.j2 b/templates/main.cf.j2 index df24ecf..04bce3d 100644 --- a/templates/main.cf.j2 +++ b/templates/main.cf.j2 @@ -51,9 +51,6 @@ alias_database = hash:/etc/aliases # Dovecot Integration {% if dovecot_enabled | default(false) %} -# Use Maildir format -home_mailbox = Maildir/ - {% if dovecot_postfix_sasl_enable | default(false) %} # SASL Authentication via Dovecot smtpd_sasl_type = dovecot @@ -62,7 +59,9 @@ smtpd_sasl_auth_enable = yes {% endif %} {% if dovecot_postfix_lmtp_enable | default(false) %} -# Delivery via LMTP -mailbox_transport = lmtp:unix:private/dovecot-lmtp +# Virtual mailbox configuration for Dovecot users +virtual_mailbox_domains = {{ postfix_mail_domain }} +virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox_maps +virtual_transport = lmtp:unix:private/dovecot-lmtp {% endif %} {% endif %} diff --git a/templates/virtual_mailbox_maps.j2 b/templates/virtual_mailbox_maps.j2 new file mode 100644 index 0000000..50fdbf6 --- /dev/null +++ b/templates/virtual_mailbox_maps.j2 @@ -0,0 +1,8 @@ +# Virtual mailbox maps for Postfix +# Ansible managed: {{ ansible_managed }} +# Format: user@domain OK +{% if dovecot_users is defined and dovecot_users | length > 0 %} +{% for user in dovecot_users %} +{{ user.name }}@{{ postfix_mail_domain }} OK +{% endfor %} +{% endif %}