Initial commit

This commit is contained in:
Julian Rother 2025-01-14 16:16:36 +01:00
commit a7c269731d
Signed by: julian
GPG key ID: C19B924C0CD13341
6 changed files with 97 additions and 0 deletions

16
README.md Normal file
View file

@ -0,0 +1,16 @@
# MUA-facing IMAP and SMTP (submission) proxy with Dovecot
Forwards IMAP and SMTP (submission) connections from MUAs to different backend servers based on the mail domain.
```yaml
dovecot_proxy:
domain_proxies:
example.com:
backend_host: myoldmailsetup.net
mymaildomain.org:
backend_host: mynewmailsetup.org
```
This proxies users with `@example.com` email addresses to myoldmailsetup.net and users with `@mymaildomain.org` email addresses to mynewmailsetup.org.
Make sure to setup ssl certificates (see defaults for `ssl_cert` and `ssl_key`).

10
defaults/main.yml Normal file
View file

@ -0,0 +1,10 @@
dovecot_proxy:
debug_log_enabled: false # Logs passwords and more to /var/log/dovecot.debug.log
ssl_cert: "/etc/ssl/{{ inventory_hostname }}.chain.crt"
ssl_key: "/etc/ssl/private/{{ inventory_hostname }}.key"
auth_mechanisms: plain login
imaps_enabled: true
submission_enabled: true
submissions_enabled: false # Only works if submission_enabled is true!
domain_proxies: {}

4
handlers/main.yml Normal file
View file

@ -0,0 +1,4 @@
- name: Reload dovecot
ansible.builtin.systemd_service:
name: dovecot
state: reloaded

25
tasks/main.yml Normal file
View file

@ -0,0 +1,25 @@
- name: Install dovecot
ansible.builtin.apt:
pkg:
- dovecot-common
- dovecot-imapd
- dovecot-submissiond
- name: Copy dovecot config
ansible.builtin.template:
src: dovecot.conf.j2
dest: /etc/dovecot/dovecot.conf
owner: root
group: root
mode: 0644
notify: Reload dovecot
- name: Copy dovecot proxy configs
ansible.builtin.template:
src: proxy-sql.conf.j2
dest: "/etc/dovecot/proxy-domain-{{ item.key }}-sql.conf"
owner: root
group: root
mode: 0644
loop: "{{ dovecot_proxy.domain_proxies|dict2items }}"
notify: Reload dovecot

38
templates/dovecot.conf.j2 Normal file
View file

@ -0,0 +1,38 @@
{% if dovecot_proxy.debug_log_enabled %}
auth_verbose = yes
auth_debug = yes
auth_debug_passwords = yes
mail_debug = yes
debug_log_path = /var/log/dovecot.debug.log
{% endif %}
auth_mechanisms = {{ dovecot_proxy.auth_mechanisms }}
protocols = {% if dovecot_proxy.imaps_enabled %}imap {% endif %}{% if dovecot_proxy.submission_enabled %}submission{% endif %}
{% if dovecot_proxy.submissions_enabled %}
service submission-login {
inet_listener submissions {
port = 465
ssl = yes
}
}
{% endif %}
ssl = required
ssl_ca = </etc/ssl/certs/ca-certificates.crt
ssl_require_crl = no
ssl_cert = <{{ dovecot_proxy.ssl_cert }}
ssl_key = <{{ dovecot_proxy.ssl_key }}
ssl_dh = </etc/ssl/dh-4096.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl_prefer_server_ciphers = yes
{% for domain in dovecot_proxy.domain_proxies %}
passdb {
driver = sql
args = /etc/dovecot/proxy-domain-{{ domain }}-sql.conf
}
{% endfor%}

View file

@ -0,0 +1,4 @@
# Effectively static passdb but with sql for flexibility
driver = sqlite
connect = ::memory::
password_query = SELECT NULL AS password, 'Y' AS nopassword, 'Y' AS proxy, '{{ item.value.backend_host }}' AS host, CASE WHEN '%s' = 'imap' THEN 993 ELSE 587 END AS port, CASE WHEN '%s' = 'imap' THEN 'Y' ELSE NULL END as ssl, CASE WHEN '%s' = 'imap' THEN NULL ELSE 'Y' END as starttls WHERE '%d' = '{{ item.key }}'