From b0bc240ee5a05bf73a47bab5df3ee54d71f1031f Mon Sep 17 00:00:00 2001 From: iburadempa Date: Fri, 11 Oct 2019 18:14:38 +0200 Subject: [PATCH] mailserver: add VERP marking of outgoing an unmarking of incoming mails --- mail_system.yml | 3 +++ mail_system/tasks/database.yml | 27 +++++++++++++++++++ mail_system/tasks/postfix.yml | 2 ++ mail_system/templates/postfix/main.cf | 10 +++++++ .../postfix/recipient_canonical_maps.cf | 10 +++++++ .../postfix/sender_canonical_maps.cf | 21 +++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 mail_system/templates/postfix/recipient_canonical_maps.cf create mode 100644 mail_system/templates/postfix/sender_canonical_maps.cf diff --git a/mail_system.yml b/mail_system.yml index 3d51a18..70e3adc 100644 --- a/mail_system.yml +++ b/mail_system.yml @@ -27,9 +27,12 @@ # overwrite_config: no # reject_sender_login_mismatch: yes # mynetworks: "10.0.0.0/24 [2a01:XXXX:XXXX:XXXX::]/64" +# verp_marker: rstxyz # dovecot: # auth_default_realm: mymaindomain.org # +# Take care thate the verp_marker only contains [a-z0-9]+ (NO UPPER CASE LETTERS!). +# # (Use ansible-vault encrypt_string zo encrypt the password.) # # TODOs after running this playbook: diff --git a/mail_system/tasks/database.yml b/mail_system/tasks/database.yml index 031c1a3..bdc516d 100644 --- a/mail_system/tasks/database.yml +++ b/mail_system/tasks/database.yml @@ -131,3 +131,30 @@ table: shared_folders_anyone columns: from_user idxname: shared_folders__from + +- name: database table mail_from + postgresql_table: + login_host: "{{ mailserver.postgresql.host }}" + port: "{{ mailserver.postgresql.port }}" + login_user: "{{ mailserver.postgresql.username }}" + login_password: "{{ mailserver.postgresql.password }}" + db: "{{ mailserver.postgresql.dbname }}" + ssl_mode: disable + name: mail_from + columns: + - id bigserial primary key + - t timestamp default now() + - original varchar(250) not null + - rewritten varchar(250) not null + +- name: database index mail_from__rewritten + postgresql_idx: + login_host: "{{ mailserver.postgresql.host }}" + port: "{{ mailserver.postgresql.port }}" + login_user: "{{ mailserver.postgresql.username }}" + login_password: "{{ mailserver.postgresql.password }}" + db: "{{ mailserver.postgresql.dbname }}" + ssl_mode: disable + table: mail_from + columns: rewritten + idxname: mail_from__rewritten diff --git a/mail_system/tasks/postfix.yml b/mail_system/tasks/postfix.yml index 72a9724..88fa152 100644 --- a/mail_system/tasks/postfix.yml +++ b/mail_system/tasks/postfix.yml @@ -72,6 +72,8 @@ - relay_domains.cf - relay_recipient_maps.cf - transport_maps.cf + - sender_canonical_maps.cf + - recipient_canonical_maps.cf - name: restart postfix systemd: diff --git a/mail_system/templates/postfix/main.cf b/mail_system/templates/postfix/main.cf index 75a2762..50d157e 100644 --- a/mail_system/templates/postfix/main.cf +++ b/mail_system/templates/postfix/main.cf @@ -95,6 +95,16 @@ smtpd_relay_restrictions = # rspamd +# VERP marking +# Envelope sender addresses matching mydomains are marked. +# The marker is removed from envelope recipient addresses. +canonical_classes = envelope_sender, envelope_recipient +sender_canonical_classes = envelope_sender +sender_canonical_maps = pgsql:/etc/postfix/sender_canonical_maps.cf +recipient_canonical_classes = envelope_recipient +recipient_canonical_maps = pgsql:/etc/postfix/recipient_canonical_maps.cf + + # useful for log analysis enable_long_queue_ids = yes diff --git a/mail_system/templates/postfix/recipient_canonical_maps.cf b/mail_system/templates/postfix/recipient_canonical_maps.cf new file mode 100644 index 0000000..13cf5a6 --- /dev/null +++ b/mail_system/templates/postfix/recipient_canonical_maps.cf @@ -0,0 +1,10 @@ +# THIS FILE IS CONTROLLED BY ANSIBLE - DO NOT CHANGE IN DEPLOYMENT! + + +# man pgsql_table + +user = {{ mailserver.postgresql.username }} +password = {{ mailserver.postgresql.password }} +dbname = {{ mailserver.postgresql.dbname }} +hosts = {{ mailserver.postgresql.host }} +query = select regexp_replace('%s', '\+(.*){{ mailserver.postfix.verp_marker }}-\d+@', '+\1@') diff --git a/mail_system/templates/postfix/sender_canonical_maps.cf b/mail_system/templates/postfix/sender_canonical_maps.cf new file mode 100644 index 0000000..f02fc9e --- /dev/null +++ b/mail_system/templates/postfix/sender_canonical_maps.cf @@ -0,0 +1,21 @@ +# THIS FILE IS CONTROLLED BY ANSIBLE - DO NOT CHANGE IN DEPLOYMENT! + + +# man pgsql_table + +user = {{ mailserver.postgresql.username }} +password = {{ mailserver.postgresql.password }} +dbname = {{ mailserver.postgresql.dbname }} +hosts = {{ mailserver.postgresql.host }} +query = insert into mail_from (id, original, rewritten) + values (nextval('mail_from_id_seq'), '%s', + case + when regexp_replace('%s', '.*@([^@]+)$', '\1') in (select name from domains) + then case + when '%s'~*'{{ mailserver.postfix.verp_marker }}-\d+@' + then '%s' + else regexp_replace('%s', '^(.*)@[^@]+$', '\1') || case when '%s'~'\+' then '{{ mailserver.postfix.verp_marker }}-' else '+{{ mailserver.postfix.verp_marker }}-' end || lastval()::text || '@' || regexp_replace('%s', '.*@([^@]+)$', '\1') + end + else '%s' + end + ) on conflict (rewritten) do nothing returning rewritten