Browse Source

mailserver: add VERP marking of outgoing an unmarking of incoming mails

master
iburadempa 3 months ago
parent
commit
b0bc240ee5

+ 3
- 0
mail_system.yml View File

@@ -27,9 +27,12 @@
27 27
 #     overwrite_config: no
28 28
 #     reject_sender_login_mismatch: yes
29 29
 #     mynetworks: "10.0.0.0/24 [2a01:XXXX:XXXX:XXXX::]/64"
30
+#     verp_marker: rstxyz
30 31
 #   dovecot:
31 32
 #     auth_default_realm: mymaindomain.org
32 33
 #
34
+# Take care thate the verp_marker only contains [a-z0-9]+ (NO UPPER CASE LETTERS!).
35
+#
33 36
 # (Use ansible-vault encrypt_string zo encrypt the password.)
34 37
 #
35 38
 # TODOs after running this playbook:

+ 27
- 0
mail_system/tasks/database.yml View File

@@ -131,3 +131,30 @@
131 131
     table: shared_folders_anyone
132 132
     columns: from_user
133 133
     idxname: shared_folders__from
134
+
135
+- name: database table mail_from
136
+  postgresql_table:
137
+    login_host: "{{ mailserver.postgresql.host }}"
138
+    port: "{{ mailserver.postgresql.port }}"
139
+    login_user: "{{ mailserver.postgresql.username }}"
140
+    login_password: "{{ mailserver.postgresql.password }}"
141
+    db: "{{ mailserver.postgresql.dbname }}"
142
+    ssl_mode: disable
143
+    name: mail_from
144
+    columns:
145
+    - id bigserial primary key
146
+    - t timestamp default now()
147
+    - original varchar(250) not null
148
+    - rewritten varchar(250) not null
149
+
150
+- name: database index mail_from__rewritten
151
+  postgresql_idx:
152
+    login_host: "{{ mailserver.postgresql.host }}"
153
+    port: "{{ mailserver.postgresql.port }}"
154
+    login_user: "{{ mailserver.postgresql.username }}"
155
+    login_password: "{{ mailserver.postgresql.password }}"
156
+    db: "{{ mailserver.postgresql.dbname }}"
157
+    ssl_mode: disable
158
+    table: mail_from
159
+    columns: rewritten
160
+    idxname: mail_from__rewritten

+ 2
- 0
mail_system/tasks/postfix.yml View File

@@ -72,6 +72,8 @@
72 72
     - relay_domains.cf
73 73
     - relay_recipient_maps.cf
74 74
     - transport_maps.cf
75
+    - sender_canonical_maps.cf
76
+    - recipient_canonical_maps.cf
75 77
 
76 78
 - name: restart postfix
77 79
   systemd:

+ 10
- 0
mail_system/templates/postfix/main.cf View File

@@ -95,6 +95,16 @@ smtpd_relay_restrictions =
95 95
 # rspamd
96 96
 
97 97
 
98
+# VERP marking
99
+# Envelope sender addresses matching mydomains are marked.
100
+# The marker is removed from envelope recipient addresses.
101
+canonical_classes = envelope_sender, envelope_recipient
102
+sender_canonical_classes = envelope_sender
103
+sender_canonical_maps = pgsql:/etc/postfix/sender_canonical_maps.cf
104
+recipient_canonical_classes = envelope_recipient
105
+recipient_canonical_maps = pgsql:/etc/postfix/recipient_canonical_maps.cf
106
+
107
+
98 108
 # useful for log analysis
99 109
 enable_long_queue_ids = yes
100 110
 

+ 10
- 0
mail_system/templates/postfix/recipient_canonical_maps.cf View File

@@ -0,0 +1,10 @@
1
+# THIS FILE IS CONTROLLED BY ANSIBLE - DO NOT CHANGE IN DEPLOYMENT!
2
+
3
+
4
+# man pgsql_table
5
+
6
+user = {{ mailserver.postgresql.username }}
7
+password = {{ mailserver.postgresql.password }}
8
+dbname = {{ mailserver.postgresql.dbname }}
9
+hosts = {{ mailserver.postgresql.host }}
10
+query = select regexp_replace('%s', '\+(.*){{ mailserver.postfix.verp_marker }}-\d+@', '+\1@')

+ 21
- 0
mail_system/templates/postfix/sender_canonical_maps.cf View File

@@ -0,0 +1,21 @@
1
+# THIS FILE IS CONTROLLED BY ANSIBLE - DO NOT CHANGE IN DEPLOYMENT!
2
+
3
+
4
+# man pgsql_table
5
+
6
+user = {{ mailserver.postgresql.username }}
7
+password = {{ mailserver.postgresql.password }}
8
+dbname = {{ mailserver.postgresql.dbname }}
9
+hosts = {{ mailserver.postgresql.host }}
10
+query = insert into mail_from (id, original, rewritten)
11
+  values (nextval('mail_from_id_seq'), '%s',
12
+    case
13
+    when regexp_replace('%s', '.*@([^@]+)$', '\1') in (select name from domains)
14
+    then case
15
+         when '%s'~*'{{ mailserver.postfix.verp_marker }}-\d+@'
16
+         then '%s'
17
+         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')
18
+         end
19
+    else '%s'
20
+    end
21
+  ) on conflict (rewritten) do nothing returning rewritten

Loading…
Cancel
Save