diff --git a/README.md b/README.md index 64bdf02..ea7b4ba 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,10 @@ It includes a helper script to create new email aliases. You can create an alias ```shell alias addmail='ssh root@host create-email-alias' ``` -Usage: `addmail newservice` creates an alias to receive mail at newservice@example.com + +Usage: `addmail newservice` creates an alias to receive mail at `newservice@example.com` + +I go one step further and add an alias on my local machine: `alias addmail="ssh root@mail.example.com create-email-alias"` ## Requirements @@ -30,6 +33,18 @@ postfix_smtpd_tls_key_file: "" postfix_smtpd_tls_dh1024_param_file: "" ``` +To operate multiple domains from a single server, add additional domains to the `virtual_domains` list: + +```yaml +postfix_virtual_domains: + - name: example.org + cert: /var/acme/certificates/mail.example.org.crt + key: /var/acme/certificates/mail.example.org.key + - name: example.net + cert: /var/acme/certificates/mail.example.net.crt + key: /var/acme/certificates/mail.example.net.key +``` + See the [default variables](defaults/main.yml). ## Example Playbook @@ -70,9 +85,11 @@ systemctl status opendkim dovecot postfix journalctl -fu postfix@- journalctl -fu dovecot ``` + ## Misc There are some interesting mta implementations that may replace or compliment parts of this stack in the future: + * [simple-nixos-mailserver](https://gitlab.com/simple-nixos-mailserver/nixos-mailserver) * [maddy](https://github.com/foxcpp/maddy) (go) * [jmap](https://github.com/stalwartlabs/jmap-server), [vsmtp](https://github.com/viridIT/vSMTP) (rust) diff --git a/defaults/main.yml b/defaults/main.yml index ecd038d..a77162d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,5 +1,6 @@ --- postfix_domain: "" +postfix_virtual_domains: [] postfix_virtual_mailbox_base: /var/disposable-mail postfix_smtpd_banner: "$myhostname ESMTP $mail_name ({{ postfix_domain }})" diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index d5db3b4..b0b0b72 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -16,7 +16,7 @@ 3. Configure credentials for the "hello" virtual inbox on the server. Use your favorite password manager to generate a passphrase and then run this to configure it: ```shell - sudo echo hello:$(doveadm pw -s BLF-CRYPT):$(id -u maildir):$(id -g maildir) >> /etc/dovecot/imap.passwd + sudo echo hello@example.com:$(doveadm pw -s BLF-CRYPT):$(id -u maildir):$(id -g maildir) >> /etc/dovecot/imap.passwd ``` Also, if you use `doas` rather than `sudo`, you need to permit your ansible_user to become opendkim in your `/etc/doas.conf`: diff --git a/handlers/main.yml b/handlers/main.yml index 3b78f8f..8f8b556 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -14,6 +14,11 @@ - name: reload postfix service: name=postfix@- state=reload +- name: new virtual domains + ansible.builtin.command: + chdir: /etc/postfix + cmd: postmap virtual_domains + - name: new virtual mailboxes ansible.builtin.command: chdir: /etc/postfix diff --git a/tasks/postfix.yml b/tasks/postfix.yml index 44c654d..9b7af0e 100644 --- a/tasks/postfix.yml +++ b/tasks/postfix.yml @@ -57,19 +57,16 @@ dest: /etc/postfix/main.cf - name: Configure virtual mailboxes - ansible.builtin.lineinfile: - path: /etc/postfix/vmailbox - regexp: '^main@{{ postfix_domain }}\s+main/' - line: 'main@{{ postfix_domain }} main/' - create: true + ansible.builtin.template: + src: vmailbox.j2 + dest: /etc/postfix/vmailbox notify: new virtual mailboxes -- name: Postmap the virtual addresses - ansible.builtin.lineinfile: - path: /etc/postfix/vmailbox - regexp: '^main@{{ postfix_domain }}\s+main/' - line: 'main@{{ postfix_domain }} main/' - notify: new virtual aliases +- name: Configure virtual domains + ansible.builtin.template: + src: virtual_domains.j2 + dest: /etc/postfix/virtual_domains + notify: new virtual domains - name: Flush handlers ansible.builtin.meta: flush_handlers diff --git a/templates/dovecot.conf.j2 b/templates/dovecot.conf.j2 index f89bbbf..4190eec 100644 --- a/templates/dovecot.conf.j2 +++ b/templates/dovecot.conf.j2 @@ -21,7 +21,7 @@ service imap-login { # doveadm pw -s BLF-CRYPT passdb { driver = passwd-file - args = username_format=%n scheme=blf-crypt {{ dovecot_passwd_file }} + args = username_format=%u scheme=blf-crypt {{ dovecot_passwd_file }} auth_verbose=yes } @@ -30,7 +30,7 @@ passdb { userdb { driver = passwd-file - args = username_format=%n {{ dovecot_passwd_file }} + args = username_format=%u {{ dovecot_passwd_file }} default_fields = uid={{ postfix_maildir_user }} gid={{ postfix_maildir_user }} # override_fields = @@ -50,6 +50,16 @@ ssl_key=<{{ postfix_smtpd_tls_key_file }} ssl_dh=<{{ postfix_smtpd_tls_dh1024_param_file }} #verbose_ssl=yes +{% if postfix_virtual_domains|length > 0 %} +{% for domain in postfix_virtual_domains %} +# SNI configuration for {{ domain.name }} +local_name {{ domain.name }} { + ssl_cert = <{{ domain.cert }} + ssl_key = <{{ domain.key }} +} +{% endfor %} +{% endif %} + # SASL service auth { unix_listener /var/spool/postfix/private/auth { @@ -62,8 +72,8 @@ service auth { # https://doc.dovecot.org/configuration_manual/home_directories_for_virtual_users/#ways-to-set-up-home-directory # https://doc.dovecot.org/admin_manual/filesystem_permission/ -mail_location = maildir:{{ postfix_virtual_mailbox_base }}/{{ postfix_domain }}/%n -mail_home=/srv/mail/%Lu +mail_location = maildir:{{ postfix_virtual_mailbox_base }}/%d/%n +mail_home=/srv/mail/%d/%Lu # https://doc.dovecot.org/admin_manual/logging/#dovecot-logging #mail_debug=yes diff --git a/templates/main.cf.j2 b/templates/main.cf.j2 index e9568ec..1d454b2 100644 --- a/templates/main.cf.j2 +++ b/templates/main.cf.j2 @@ -12,8 +12,8 @@ mydomain = {{ postfix_domain }} # https://www.postfix.org/VIRTUAL_README.html#virtual_mailbox # https://doc.dovecot.org/configuration_manual/home_directories_for_virtual_users/#ways-to-set-up-home-directory -virtual_mailbox_domains = $mydomain -virtual_mailbox_base = {{ postfix_virtual_mailbox_base }}/{{ postfix_domain }} +virtual_mailbox_domains = hash:/etc/postfix/virtual_domains +virtual_mailbox_base = {{ postfix_virtual_mailbox_base }} virtual_mailbox_maps = {{ postfix_default_database_type }}:{{ postfix_virtual_mailbox_maps }} virtual_mailbox_limit = 0 # User: {{ postfix_maildir_user }} diff --git a/templates/virtual_domains.j2 b/templates/virtual_domains.j2 new file mode 100644 index 0000000..c3b87cf --- /dev/null +++ b/templates/virtual_domains.j2 @@ -0,0 +1,8 @@ +{% if postfix_virtual_domains|length > 0 %} +{{ postfix_domain }} OK +{% for domain in postfix_virtual_domains %} +{{ domain.name }} OK +{% endfor %} +{% else %} +{{ postfix_domain }} OK +{% endif %} \ No newline at end of file diff --git a/templates/vmailbox.j2 b/templates/vmailbox.j2 new file mode 100644 index 0000000..191a7c8 --- /dev/null +++ b/templates/vmailbox.j2 @@ -0,0 +1,8 @@ +{% if postfix_virtual_domains|length > 0 %} +main@{{ postfix_domain }} {{ postfix_domain }}/main/ +{% for domain in postfix_virtual_domains %} +main@{{ domain.name }} {{ domain.name }}/main/ +{% endfor %} +{% else %} +main@{{ postfix_domain }} {{ postfix_domain }}/main/ +{% endif %} \ No newline at end of file