From ffe8bf61adb9ca181702e9a8a53b4252afce554c Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 00:59:52 -0400 Subject: [PATCH 01/29] Configure Postfix --- .../real-postfix/files/postfix/blocked_users | 28 ++++++++++++ .../postfix/mailbox-command-maps-ldap.cf | 6 +++ .../files/postfix/mailbox_command_maps | 1 + .../real-postfix/files/postfix/mailq_users | 2 + .../roles/real-postfix/files/postfix/main.cf | 45 +++++++++++++++++++ .../roles/real-postfix/files/postfix/virtual | 0 .../postfix/virtual-alias-domains-ldap.cf | 21 +++++++++ .../virtual-alias-maps-ldap-reserved.cf | 7 +++ .../files/postfix/virtual-alias-maps-ldap.cf | 22 +++++++++ ansible/roles/real-postfix/handlers/main.yml | 2 + ansible/roles/real-postfix/tasks/main.yml | 13 ++++++ .../real-postfix/templates/root-procmailrc.j2 | 4 ++ 12 files changed, 151 insertions(+) create mode 100644 ansible/roles/real-postfix/files/postfix/blocked_users create mode 100644 ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf create mode 100644 ansible/roles/real-postfix/files/postfix/mailbox_command_maps create mode 100644 ansible/roles/real-postfix/files/postfix/mailq_users create mode 100644 ansible/roles/real-postfix/files/postfix/main.cf create mode 100644 ansible/roles/real-postfix/files/postfix/virtual create mode 100644 ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf create mode 100644 ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf create mode 100644 ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf create mode 100644 ansible/roles/real-postfix/handlers/main.yml create mode 100644 ansible/roles/real-postfix/tasks/main.yml create mode 100644 ansible/roles/real-postfix/templates/root-procmailrc.j2 diff --git a/ansible/roles/real-postfix/files/postfix/blocked_users b/ansible/roles/real-postfix/files/postfix/blocked_users new file mode 100644 index 00000000..62b3d0c5 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/blocked_users @@ -0,0 +1,28 @@ +raskar +maoting +bsu +delian +buechley +cssa +mitlti +paxters +crhie +baker-foundation +11.309j +kgsa +jains +unfolding +4.332 +asme +alisono +laublab +eltahirgroup +early-warning +blackhistory +seek +braintrust +newmanlab +game +lebanon +crpg +scioly diff --git a/ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf b/ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf new file mode 100644 index 00000000..6cc9dc02 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf @@ -0,0 +1,6 @@ +server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +search_base = ou=People,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=posixAccount)(uid=%s)) +result_attribute = scriptsMailboxCommand +bind = no +version = 3 diff --git a/ansible/roles/real-postfix/files/postfix/mailbox_command_maps b/ansible/roles/real-postfix/files/postfix/mailbox_command_maps new file mode 100644 index 00000000..8f1753b9 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/mailbox_command_maps @@ -0,0 +1 @@ +root /usr/bin/procmail /etc/scripts/root-procmailrc diff --git a/ansible/roles/real-postfix/files/postfix/mailq_users b/ansible/roles/real-postfix/files/postfix/mailq_users new file mode 100644 index 00000000..fd7f838d --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/mailq_users @@ -0,0 +1,2 @@ +nrpe +munin diff --git a/ansible/roles/real-postfix/files/postfix/main.cf b/ansible/roles/real-postfix/files/postfix/main.cf new file mode 100644 index 00000000..e679cfd6 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/main.cf @@ -0,0 +1,45 @@ +#biff = no + +# appending .domain is the MUA's job. +#append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +alias_maps = hash:/etc/aliases +alias_database = hash:/etc/aliases +myorigin = scripts.mit.edu +mydestination = scripts.mit.edu, scripts, $myhostname, scripts-test.mit.edu, scripts-test, localhost +relayhost = +mynetworks_style = host +mailbox_command_maps = + texthash:/etc/postfix/mailbox_command_maps, + ldap:/etc/postfix/mailbox-command-maps-ldap.cf +mailbox_size_limit = 0 +message_size_limit = 41943040 +recipient_delimiter = + +inet_interfaces = $myhostname, scripts.mit.edu, scripts-vhosts.mit.edu +readme_directory = /usr/share/doc/postfix/README_FILES +sample_directory = /usr/share/doc/postfix/samples +sendmail_path = /usr/sbin/sendmail +html_directory = no +setgid_group = postdrop +command_directory = /usr/sbin +manpage_directory = /usr/share/man +daemon_directory = /usr/libexec/postfix +newaliases_path = /usr/bin/newaliases +mailq_path = /usr/bin/mailq +queue_directory = /var/spool/postfix +mail_owner = postfix +virtual_alias_domains = !scripts.mit.edu, !scripts, !$myhostname, !scripts-test.mit.edu, !scripts-test, !localhost, scripts-vhosts.mit.edu, ldap:/etc/postfix/virtual-alias-domains-ldap.cf +virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf +data_directory = /var/lib/postfix +authorized_flush_users = fail +authorized_mailq_users = /etc/postfix/mailq_users +authorized_submit_users = !/etc/postfix/blocked_users, static:all +non_smtpd_milters = unix:/run/spamass-milter/postfix/sock +# "all" is the default, but if we do not specify it, Fedora's packaging +# will add the wrong value here. +inet_protocols = all +# note: as of 21 Oct 2015, our IPv6 addresses do not have rDNS and are rejected by Gmail +smtp_address_preference = ipv4 diff --git a/ansible/roles/real-postfix/files/postfix/virtual b/ansible/roles/real-postfix/files/postfix/virtual new file mode 100644 index 00000000..e69de29b diff --git a/ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf b/ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf new file mode 100644 index 00000000..ca211045 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf @@ -0,0 +1,21 @@ +# Find any vhost with a name or alias matching the domain of the e-mail +# address. We're queried with only the domain portion to determine whether +# we accept mail at all for a given domain. If we have no matching vhost +# and return no records, Postfix will reject mail with a "Relay access denied" +# error, unless the domain is configured in $mydestination. We don't match +# the scripts.mit.edu vhost here because otherwise it'll be treated as a +# virtual alias domain and once we resolve an address to a scripts account, +# we'll end up resolving the locker@scripts.mit.edu address to go to the +# owners of the scripts.mit.edu vhost. The value we return (if we return +# anything at all) is supposedly arbitrary. We choose to return the same +# value we were queried with (the domain whose mail we host). Protocol +# version 3 is necessary to use ldapi. + +server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%s)(scriptsVhostAlias=%s))(!(scriptsVhostName=scripts.mit.edu))) +result_attribute = scriptsVhostName +result_format = %S +bind = no +version = 3 + diff --git a/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf b/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf new file mode 100644 index 00000000..f93fa6ca --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf @@ -0,0 +1,7 @@ +server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(scriptsReservedMail=%u)) +result_attribute = scriptsVhostName +result_format = %U +bind = no +version = 3 diff --git a/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf b/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf new file mode 100644 index 00000000..56c5973d --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf @@ -0,0 +1,22 @@ +# Find any vhost with a name or alias matching the domain of the +# e-mail address. We're queried with an entire e-mail address, but +# are only interested in checking whether the domain portion +# corresponds to a vhost; we'll simply deliver any mail for the vhost +# to its owner, appending the original lefthand side of the address as +# an extension. %d extracts only the domain. We don't match the +# scripts.mit.edu vhost here because we don't want to first resolve an +# arbitrary address to a scripts account, and then end up sending +# their mail to the owners of the scripts.mit.edu vhost. The uid +# attribute, generated by the CoS template +# cn=vhostOwnerCoS,ou=VirtualHosts,dc=scripts,dc=mit,dc=edu, is the +# name of the locker that owns the vhost. Protocol version 3 is +# necessary to use ldapi. + +server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))) +result_attribute = uid +result_format = %s+%U +bind = no +version = 3 + diff --git a/ansible/roles/real-postfix/handlers/main.yml b/ansible/roles/real-postfix/handlers/main.yml new file mode 100644 index 00000000..92e6bc6b --- /dev/null +++ b/ansible/roles/real-postfix/handlers/main.yml @@ -0,0 +1,2 @@ +- name: reload postfix + service: name=postfix state=reloaded diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml new file mode 100644 index 00000000..e27415ec --- /dev/null +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- name: Install postfix + dnf: name=postfix state=present +- name: Install postfix configuration files + copy: + src: postfix/ + dest: /etc/postfix/ + notify: reload postfix +- name: Install root's procmailrc + template: + src: root-procmailrc.j2 + dest: /etc/scripts/root-procmailrc +# TODO: Move blocked users from /etc/aliases into LDAP as scriptsMailboxCommand: /bin/false diff --git a/ansible/roles/real-postfix/templates/root-procmailrc.j2 b/ansible/roles/real-postfix/templates/root-procmailrc.j2 new file mode 100644 index 00000000..a3b222be --- /dev/null +++ b/ansible/roles/real-postfix/templates/root-procmailrc.j2 @@ -0,0 +1,4 @@ +:0 +! {% for maintainer in maintainers|rejectattr('root_mail', 'none') -%} +{{ maintainer.root_mail|default(maintainer.username + '@mit.edu') }}{{ '' if loop.last else ', ' }} +{%- endfor %} \ No newline at end of file From de4437ed3339ef11133b63f206858222774c1cff Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 01:40:30 -0400 Subject: [PATCH 02/29] Make /etc/scripts --- ansible/roles/real-postfix/tasks/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index e27415ec..62c115aa 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -6,6 +6,10 @@ src: postfix/ dest: /etc/postfix/ notify: reload postfix +- name: Ensure /etc/scripts exists + file: + path: /etc/scripts/ + state: directory - name: Install root's procmailrc template: src: root-procmailrc.j2 From 0c88576d61d25c025894b0d5dd99117e1a8f39b4 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 01:52:12 -0400 Subject: [PATCH 03/29] Enable postfix --- ansible/roles/real-postfix/tasks/main.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 62c115aa..528d013c 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -14,4 +14,9 @@ template: src: root-procmailrc.j2 dest: /etc/scripts/root-procmailrc +- name: Enable postfix + service: + name: postfix + enabled: yes + state: started # TODO: Move blocked users from /etc/aliases into LDAP as scriptsMailboxCommand: /bin/false From 579ff3ccaca9a1a2fe524d39575675f3740ec36e Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 02:11:24 -0400 Subject: [PATCH 04/29] Only accept mail on some VIPs --- ansible/roles/real-postfix/tasks/main.yml | 4 ++++ .../{files/postfix/main.cf => templates/main.cf.j2} | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) rename ansible/roles/real-postfix/{files/postfix/main.cf => templates/main.cf.j2} (93%) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 528d013c..e66b5895 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -6,6 +6,10 @@ src: postfix/ dest: /etc/postfix/ notify: reload postfix +- name: Install main.cf + template: + src: main.cf.j2 + dest: /etc/postfix/main.cf - name: Ensure /etc/scripts exists file: path: /etc/scripts/ diff --git a/ansible/roles/real-postfix/files/postfix/main.cf b/ansible/roles/real-postfix/templates/main.cf.j2 similarity index 93% rename from ansible/roles/real-postfix/files/postfix/main.cf rename to ansible/roles/real-postfix/templates/main.cf.j2 index e679cfd6..7f941506 100644 --- a/ansible/roles/real-postfix/files/postfix/main.cf +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -18,7 +18,8 @@ mailbox_command_maps = mailbox_size_limit = 0 message_size_limit = 41943040 recipient_delimiter = + -inet_interfaces = $myhostname, scripts.mit.edu, scripts-vhosts.mit.edu +inet_interfaces = $myhostname{% for vip in vips %}{% if vip.mail | default(False) %}, {{ vip.host }}{% endif %}{% endfor %} + readme_directory = /usr/share/doc/postfix/README_FILES sample_directory = /usr/share/doc/postfix/samples sendmail_path = /usr/sbin/sendmail From cda3e5ba2e11e7befa44316fe3c0a70b1ef0874c Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 03:14:21 -0400 Subject: [PATCH 05/29] Install Postfix LDAP plugin --- ansible/roles/real-postfix/tasks/main.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index e66b5895..3ad048ef 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -1,6 +1,12 @@ --- - name: Install postfix - dnf: name=postfix state=present + dnf: + name: "{{ item }}" + state: present + with_items: + - postfix + - postfix-ldap + notify: reload postfix - name: Install postfix configuration files copy: src: postfix/ @@ -10,6 +16,7 @@ template: src: main.cf.j2 dest: /etc/postfix/main.cf + notify: reload postfix - name: Ensure /etc/scripts exists file: path: /etc/scripts/ From 7368b54a4f952e5343acb5224111f8bed9617274 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 03:16:44 -0400 Subject: [PATCH 06/29] Use non-deprecated way to specify multiple packages --- ansible/roles/real-postfix/tasks/main.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 3ad048ef..a19a2fa8 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -1,11 +1,10 @@ --- - name: Install postfix dnf: - name: "{{ item }}" + name: + - postfix + - postfix-ldap state: present - with_items: - - postfix - - postfix-ldap notify: reload postfix - name: Install postfix configuration files copy: From f0f5272acdd0bba1e2c632c8d05b53e9cacd8c61 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 03:21:03 -0400 Subject: [PATCH 07/29] Specify now-required smtpd_relay_restrictions --- ansible/roles/real-postfix/templates/main.cf.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index 7f941506..108dd5d4 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -44,3 +44,4 @@ non_smtpd_milters = unix:/run/spamass-milter/postfix/sock inet_protocols = all # note: as of 21 Oct 2015, our IPv6 addresses do not have rDNS and are rejected by Gmail smtp_address_preference = ipv4 +smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination From f35bd7f4c3e4f335c8c2150050d854d4470654d2 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 22:53:47 -0400 Subject: [PATCH 08/29] Configure Postfix with variable LDAP server --- ansible/roles/real-postfix/tasks/main.yml | 9 +++++++++ .../postfix/mailbox-command-maps-ldap.cf.j2} | 2 +- .../postfix/virtual-alias-domains-ldap.cf.j2} | 2 +- .../postfix/virtual-alias-maps-ldap-reserved.cf.j2} | 2 +- .../postfix/virtual-alias-maps-ldap.cf.j2} | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) rename ansible/roles/real-postfix/{files/postfix/mailbox-command-maps-ldap.cf => templates/postfix/mailbox-command-maps-ldap.cf.j2} (73%) rename ansible/roles/real-postfix/{files/postfix/virtual-alias-domains-ldap.cf => templates/postfix/virtual-alias-domains-ldap.cf.j2} (94%) rename ansible/roles/real-postfix/{files/postfix/virtual-alias-maps-ldap-reserved.cf => templates/postfix/virtual-alias-maps-ldap-reserved.cf.j2} (82%) rename ansible/roles/real-postfix/{files/postfix/virtual-alias-maps-ldap.cf => templates/postfix/virtual-alias-maps-ldap.cf.j2} (94%) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index a19a2fa8..397afd0f 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -11,6 +11,15 @@ src: postfix/ dest: /etc/postfix/ notify: reload postfix +- name: Install postfix LDAP configuration + template: + src: "postfix/{{ item }}.j2" + dest: /etc/postfix/{{ item }} + loop: + - mailbox-command-maps-ldap.cf + - virtual-alias-domains-ldap.cf + - virtual-alias-maps-ldap-reserved.cf + - virtual-alias-maps-ldap.cf - name: Install main.cf template: src: main.cf.j2 diff --git a/ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf b/ansible/roles/real-postfix/templates/postfix/mailbox-command-maps-ldap.cf.j2 similarity index 73% rename from ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf rename to ansible/roles/real-postfix/templates/postfix/mailbox-command-maps-ldap.cf.j2 index 6cc9dc02..a83ad2dc 100644 --- a/ansible/roles/real-postfix/files/postfix/mailbox-command-maps-ldap.cf +++ b/ansible/roles/real-postfix/templates/postfix/mailbox-command-maps-ldap.cf.j2 @@ -1,4 +1,4 @@ -server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +server_host = {{ ldap_server }} search_base = ou=People,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=posixAccount)(uid=%s)) result_attribute = scriptsMailboxCommand diff --git a/ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf b/ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 similarity index 94% rename from ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf rename to ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 index ca211045..8763f574 100644 --- a/ansible/roles/real-postfix/files/postfix/virtual-alias-domains-ldap.cf +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 @@ -11,7 +11,7 @@ # value we were queried with (the domain whose mail we host). Protocol # version 3 is necessary to use ldapi. -server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%s)(scriptsVhostAlias=%s))(!(scriptsVhostName=scripts.mit.edu))) result_attribute = scriptsVhostName diff --git a/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap-reserved.cf.j2 similarity index 82% rename from ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf rename to ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap-reserved.cf.j2 index f93fa6ca..995d018e 100644 --- a/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap-reserved.cf +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap-reserved.cf.j2 @@ -1,4 +1,4 @@ -server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(scriptsReservedMail=%u)) result_attribute = scriptsVhostName diff --git a/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 similarity index 94% rename from ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf rename to ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 index 56c5973d..a7681b46 100644 --- a/ansible/roles/real-postfix/files/postfix/virtual-alias-maps-ldap.cf +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 @@ -12,7 +12,7 @@ # name of the locker that owns the vhost. Protocol version 3 is # necessary to use ldapi. -server_host = ldapi://%2fvar%2frun%2fslapd-scripts.socket/ +server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))) result_attribute = uid From 05f84731da623bbf98f1b5d9ee9365e434e2e3ca Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 23 May 2019 23:00:01 -0400 Subject: [PATCH 09/29] Reload postfix when config changes --- ansible/roles/real-postfix/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 397afd0f..0f0fbaaf 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -20,6 +20,7 @@ - virtual-alias-domains-ldap.cf - virtual-alias-maps-ldap-reserved.cf - virtual-alias-maps-ldap.cf + notify: reload postfix - name: Install main.cf template: src: main.cf.j2 From 003949f53849d439afbfc660163b0be0c16ae736 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 25 May 2019 15:46:41 -0400 Subject: [PATCH 10/29] Install procmail --- ansible/roles/real-postfix/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 0f0fbaaf..81eb9c3c 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -4,6 +4,7 @@ name: - postfix - postfix-ldap + - procmail state: present notify: reload postfix - name: Install postfix configuration files From 53968ae1657ed1b57c0f1d9bc26cce7ca42e6881 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Tue, 28 May 2019 21:30:55 -0400 Subject: [PATCH 11/29] Install scripts's version of /etc/aliases --- ansible/roles/real-postfix/files/aliases | 170 +++++++++++++++++++ ansible/roles/real-postfix/handlers/main.yml | 2 + ansible/roles/real-postfix/tasks/main.yml | 5 + 3 files changed, 177 insertions(+) create mode 100644 ansible/roles/real-postfix/files/aliases diff --git a/ansible/roles/real-postfix/files/aliases b/ansible/roles/real-postfix/files/aliases new file mode 100644 index 00000000..5f007621 --- /dev/null +++ b/ansible/roles/real-postfix/files/aliases @@ -0,0 +1,170 @@ +# +# Aliases in this file will NOT be expanded in the header from +# Mail, but WILL be visible over networks or from /bin/mail. +# +# >>>>>>>>>> The program "newaliases" must be run after +# >> NOTE >> this file is updated for any changes to +# >>>>>>>>>> show through to sendmail. +# + +# Basic system aliases -- these MUST be present. +mailer-daemon: postmaster +postmaster: root + +# General redirections for pseudo accounts. +bin: root +daemon: root +adm: root +lp: root +sync: root +shutdown: root +halt: root +mail: root +news: root +uucp: root +operator: root +games: root +gopher: root +ftp: root +nobody: root +radiusd: root +nut: root +dbus: root +vcsa: root +canna: root +wnn: root +rpm: root +nscd: root +pcap: root +apache: root +webalizer: root +dovecot: root +fax: root +quagga: root +radvd: root +pvm: root +amandabackup: root +privoxy: root +ident: root +named: root +xfs: root +gdm: root +mailnull: root +postgres: root +sshd: root +smmsp: root +postfix: root +netdump: root +ldap: root +squid: root +ntp: root +mysql: root +desktop: root +rpcuser: root +rpc: root +nfsnobody: root + +ingres: root +system: root +toor: root +manager: root +dumper: root +abuse: root + +newsadm: news +newsadmin: news +usenet: news +ftpadm: ftp +ftpadmin: ftp +ftp-adm: ftp +ftp-admin: ftp +www: webmaster +webmaster: root +noc: root +security: root +hostmaster: root + + +# trap decode to catch security attacks +decode: root + +# Person who should get root's mail +# root: (moved to /etc/scripts/root-procmailrc so this mail gets spam filtered) + +scripts: root +signup: root +afsagent: root +logview: root +scripts-build: root + +# People who are abusing or otherwise causing problems with the mail system +# Put "/dev/null" as the target of their alias +# srimano: has a phpBB generating a lot of backscatter +srimano: /dev/null +# dbriggs: phpBB: added 2011-06-25, see mail to -root 2011-03-27, 2011-06-03 +dbriggs: /dev/null +# ro21531: spam to rosmosis.net: added 2011-06-25, see mail to -root 2011-06-03 +ro21531: /dev/null +# buechley: not responsive to mail sent by -root on 2013-05-14, added 2013-07-04 +buechley: /dev/null +# cssa: spam, added 2014-02-01 +cssa: /dev/null +# mitlti: added 2014-07-26, causing way too much queued mail and not +# yet responded to mail by -root +mitlti: /dev/null +# paxters: so much spam, added 2014-09-09 +paxters: /dev/null +# crhie: why all the same, added 2014-10-05 +crhie: /dev/null +# baker-foundation: spam, spam, and more spam. Added 2014-11-21 +baker-foundation: /dev/null +# 11.309j: still all spammy, despite contact on 2014-11-09. Added 2014-12-01 +11.309j: /dev/null +# kgsa: repeat unhappiness. Added 2014-12-01 +kgsa: /dev/null +# jains: compromised account sourcing spam. Added 2014-12-13 +jains: /dev/null +# unfolding: compromised account sourcing spam. Added 2014-12-13 +unfolding: /dev/null +# 4.332: compromised account sourcing spam. Added 2014-12-13 +4.332: /dev/null +# asme: compromised account sourcing spam. Added 2014-12-13 +asme: /dev/null +# alisono: compromised account sourcing spam. Added 2014-12-13 +alisono: /dev/null +# laublab: compromised account sourcing spam. Added 2014-12-24 +laublab: /dev/null +# eltahirgroup: compromised account sourcing spam. Added 2015-07-07 +eltahirgroup: /dev/null +# strategic: backscatter. Added 2015-10-09 +strategic: /dev/null +# je18337: cron spam. Added 2015-10-09 +je18337: /dev/null +# gsc: backscatter. Added 2015-10-09 +gsc: /dev/null +# rwf: backscatter. Added 2015-10-09 +rwf: /dev/null +# saxelab: spam. Added 2015-10-09 +saxelab: /dev/null +# qeg: spam. Added 2015-10-09 +qeg: /dev/null +# blackhistory: backscatter. Added 2016-09-03 +blackhistory: /dev/null +# tdc: mail loop on procmailrc. Added 2016-09-11 +tdc: /dev/null +# seek: spam. Added 2016-10-09. +seek: /dev/null +# braintrust: spam. Added 2016-10-20. +braintrust: /dev/null +# newmanlab: spam. Added 2016-12-04. +newmanlab: /dev/null +# game: spam. Added 2017-01-23 +game: /dev/null +# lebanon: spam. Added 2017-01-23 +lebanon: /dev/null +# crpg: spam. Added 2017-01-23 +crpg: /dev/null +# scioly: spam. Added 2017-02-23 +scioly: /dev/null +# xavid: mail loop. Added 2017-03-06 +xavid: /dev/null diff --git a/ansible/roles/real-postfix/handlers/main.yml b/ansible/roles/real-postfix/handlers/main.yml index 92e6bc6b..a5643e7d 100644 --- a/ansible/roles/real-postfix/handlers/main.yml +++ b/ansible/roles/real-postfix/handlers/main.yml @@ -1,2 +1,4 @@ - name: reload postfix service: name=postfix state=reloaded +- name: newaliases + command: newaliases diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 81eb9c3c..fb272a8b 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -35,6 +35,11 @@ template: src: root-procmailrc.j2 dest: /etc/scripts/root-procmailrc +- name: Install aliases + copy: + dest: /etc/aliases + src: aliases + notify: newaliases - name: Enable postfix service: name: postfix From e4eedf1e0266664cb560da20b0a2eb8524091747 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Tue, 28 May 2019 22:23:12 -0400 Subject: [PATCH 12/29] Delay postfix startup until network is online --- ansible/roles/real-postfix/tasks/main.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index fb272a8b..f6b27859 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -7,6 +7,13 @@ - procmail state: present notify: reload postfix +- name: Delay postfix startup until network is online + copy: + dest: /etc/systemd/system/postfix.service.d/scripts-postfix-network-online.conf + content: | + [Unit] + Wants=network-online.target + After=network-online.target - name: Install postfix configuration files copy: src: postfix/ From 39ec12c5a29ccefbbb3f3c85185653fd146b2845 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Tue, 28 May 2019 22:33:01 -0400 Subject: [PATCH 13/29] Create postfix unit override directory --- ansible/roles/real-postfix/tasks/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index f6b27859..97215668 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -7,6 +7,10 @@ - procmail state: present notify: reload postfix +- name: Create /etc/systemd/system/postfix.service.d/ + file: + path: /etc/systemd/system/postfix.service.d/ + state: directory - name: Delay postfix startup until network is online copy: dest: /etc/systemd/system/postfix.service.d/scripts-postfix-network-online.conf From fa652009caee8bec7a7509ae1db0191aadd0908e Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Wed, 29 May 2019 10:56:02 -0400 Subject: [PATCH 14/29] Install and run Spamassassin --- ansible/roles/real-postfix/tasks/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 97215668..9ec7f701 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -5,6 +5,7 @@ - postfix - postfix-ldap - procmail + - spamass-milter state: present notify: reload postfix - name: Create /etc/systemd/system/postfix.service.d/ @@ -53,7 +54,10 @@ notify: newaliases - name: Enable postfix service: - name: postfix + name: "{{ item }}" enabled: yes state: started + loop: + - spamass-milter + - postfix # TODO: Move blocked users from /etc/aliases into LDAP as scriptsMailboxCommand: /bin/false From c2a11ac1ceee90a56baa1f45820004c1b85283b6 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Wed, 29 May 2019 12:18:13 -0400 Subject: [PATCH 15/29] Configure spamass-milter --- ansible/roles/real-postfix/handlers/main.yml | 2 ++ ansible/roles/real-postfix/tasks/main.yml | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ansible/roles/real-postfix/handlers/main.yml b/ansible/roles/real-postfix/handlers/main.yml index a5643e7d..4c0671e9 100644 --- a/ansible/roles/real-postfix/handlers/main.yml +++ b/ansible/roles/real-postfix/handlers/main.yml @@ -2,3 +2,5 @@ service: name=postfix state=reloaded - name: newaliases command: newaliases +- name: restart spamass-milter + service: name=spamass-milter state=restarted diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 9ec7f701..b27c3452 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -5,7 +5,7 @@ - postfix - postfix-ldap - procmail - - spamass-milter + - spamass-milter-postfix state: present notify: reload postfix - name: Create /etc/systemd/system/postfix.service.d/ @@ -52,6 +52,13 @@ dest: /etc/aliases src: aliases notify: newaliases +- name: Configure spamass-milter + ini_file: + path: /etc/sysconfig/spamass-milter + option: EXTRA_FLAGS + value: '"-m -r -1 -- --socket=/run/spamd.socket"' + no_extra_spaces: yes + notify: restart spamass-milter - name: Enable postfix service: name: "{{ item }}" From a055fa1e6ccd6cbd84c0812ff5b0720aedb96c26 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Wed, 29 May 2019 12:36:56 -0400 Subject: [PATCH 16/29] Configure spamassassin --- ansible/roles/real-postfix/handlers/main.yml | 2 ++ ansible/roles/real-postfix/tasks/main.yml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/ansible/roles/real-postfix/handlers/main.yml b/ansible/roles/real-postfix/handlers/main.yml index 4c0671e9..459c98a1 100644 --- a/ansible/roles/real-postfix/handlers/main.yml +++ b/ansible/roles/real-postfix/handlers/main.yml @@ -2,5 +2,7 @@ service: name=postfix state=reloaded - name: newaliases command: newaliases +- name: restart spamassassin + service: name=spamassassin state=restarted - name: restart spamass-milter service: name=spamass-milter state=restarted diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index b27c3452..4b495c4e 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -59,6 +59,13 @@ value: '"-m -r -1 -- --socket=/run/spamd.socket"' no_extra_spaces: yes notify: restart spamass-milter +- name: Configure spamassassin + ini_file: + path: /etc/sysconfig/spamassassin + option: SPAMDOPTIONS + value: '"--username=sa-milt --groupname=sa-milt --nouser-config --socketpath=/run/spamd.socket --socketowner=sa-milt --socketgroup=sa-milt --socketmode=0600"' + no_extra_spaces: yes + notify: restart spamassassin - name: Enable postfix service: name: "{{ item }}" From fa72caa8fa32ae001985c08cd4913399feaad2fa Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Wed, 29 May 2019 12:39:50 -0400 Subject: [PATCH 17/29] Section null must be specified explicitly --- ansible/roles/real-postfix/tasks/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 4b495c4e..af012c25 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -55,6 +55,7 @@ - name: Configure spamass-milter ini_file: path: /etc/sysconfig/spamass-milter + section: null option: EXTRA_FLAGS value: '"-m -r -1 -- --socket=/run/spamd.socket"' no_extra_spaces: yes @@ -62,6 +63,7 @@ - name: Configure spamassassin ini_file: path: /etc/sysconfig/spamassassin + section: null option: SPAMDOPTIONS value: '"--username=sa-milt --groupname=sa-milt --nouser-config --socketpath=/run/spamd.socket --socketowner=sa-milt --socketgroup=sa-milt --socketmode=0600"' no_extra_spaces: yes From 6c720563ae85e75e199a9ba9830343c52596959a Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Mon, 24 Jun 2019 01:57:31 -0400 Subject: [PATCH 18/29] Install prune-mailq --- ansible/roles/real-postfix/files/prune-mailq | 184 +++++++++++++++++++ ansible/roles/real-postfix/tasks/main.yml | 5 + 2 files changed, 189 insertions(+) create mode 100755 ansible/roles/real-postfix/files/prune-mailq diff --git a/ansible/roles/real-postfix/files/prune-mailq b/ansible/roles/real-postfix/files/prune-mailq new file mode 100755 index 00000000..00c0537a --- /dev/null +++ b/ansible/roles/real-postfix/files/prune-mailq @@ -0,0 +1,184 @@ +#!/bin/sh + +set -eu +shopt -s failglob + +usage="Usage: + $0 list-from + $0 list-fullname + $0 list-to + $0 show-rand [from regex|to regex] + $0 email lockers... + $0 purge-fullname fullnames... + $0 purge-from lockers... + $0 purge-from-re regexes... + $0 purge-to lockers... + $0 purge-to-re regexes..." + +usage() { + echo "$usage" >&2; + exit 1 +} + +clean_locker() { + echo "${1%%@scripts.mit.edu}" +} + +canonicalize_address() { + if [[ "$1" == *@* ]]; then + echo "$1" + else + echo "$1@scripts.mit.edu" + fi +} + +list_fullname() { + echo "Top twenty sender fullnames by number of queued messages:" + mailq | grep -v '^ *(\|^-' | awk 'BEGIN { RS = "" } { print $1 }' | tr -d '*!' | xargs postcat -q -e | sed -n 's/sender_fullname: //p' | sort | uniq -c | sort -n | tail -n 20 +} + +list_from() { + echo "Top twenty sending addresses by number of queued messages:" + mailq | grep -v '^ *(\|^-' | awk 'BEGIN { RS = "" } { print $7 }' | sort | uniq -c | sort -n | tail -n 20 +} + +list_to() { + echo "Top twenty recipients by number of queued messages:" + mailq | grep -v '^ *(\|^-' | awk 'BEGIN { RS = "" } { print $8 }' | sort | uniq -c | sort -n | tail -n 20 +} + +show_rand() { + if [[ $# -eq 0 ]]; then + files=$(printf '%s\n' /var/spool/postfix/deferred/?/* | shuf -n 3) + elif [[ $# -eq 2 ]]; then + match=$2 + case "$1" in + from) dir=7;; + to) dir=8;; + *) usage;; + esac + msgids=$(mailq | grep -v '^ *(\|^-' | awk "BEGIN { RS = \"\" } (\$$dir ~ /$match/) { print \$1 }" | shuf -n 3) + files=$(for msgid in $msgids; do echo /var/spool/postfix/deferred/${msgid:0:1}/$msgid; done) + else + usage + fi + for file in $files; do + echo ">>>> $file"; + postcat "$file" + echo; + done +} + +tmpl_email() { + sender=${SSH_GSSAPI_NAME%%/*} + if [[ $# -eq 0 ]]; then + echo "Please specify a locker to generate template for." >&2 + exit 1 + fi + for locker in "$@"; do + locker=$(clean_locker "$locker") + echo "fs la /mit/$locker/" + fs la "/mit/$locker" + echo + cat <<-EOF +The scripts.mit.edu servers currently have a large number of email messages destined for the *$locker* account that are not being handled by your account and are being queued. Sufficiently large numbers of queued messages can cause stability issues for the servers, so we would like you to ensure that your account can handle all messages it receives by two weeks from now. + +You will be able to process the incoming messages if you sign up for the mail scripts service (http://scripts.mit.edu/mail/). You're welcome to simply forward all incoming mail to another address (the default is to forward it to the mit.edu address of the user who signs up); otherwise, you can configure mail scripts to process the incoming messages in some suitable fashion. + +Frequently, large numbers of queued messages are a sign that some wiki, blog, forum, or other site has been spammed. If this is the case, you should apply some appropriate spam-blocking mechanism. + +If you have any questions, feel free to contact us. + +Thanks, +scripts.mit.edu team +scripts@mit.edu --- semi-private +scripts-root@mit.edu --- service maintainers only +EOF + echo;echo + done +} + +purge_fullname() { + if [[ $# -eq 0 ]]; then + echo "Please specify a fullname to purge emails from" >&2 + exit 1 + fi + for locker in "$@"; do + mailq | grep -v '^ *(\|^-' | awk 'BEGIN { RS = "" } { print $1 }' | tr -d '*!' | xargs postcat -q -e | awk "BEGIN { RS = \"*** ENVELOPE RECORDS \" } /\\nsender_fullname: $locker\\n/ { sub(\".*/\", \"\", \$1); print \$1 }" | postsuper -d - + echo + done +} + +purge_from() { + if [[ $# -eq 0 ]]; then + echo "Please specify an address to purge emails from" >&2 + exit 1 + fi + for address in "$@"; do + address=$(canonicalize_address "$address") + echo "$address..." + mailq | grep -v '^ *(\|^-' | awk "BEGIN { RS = \"\" } (\$7 == \"$address\") { print \$1 }" | tr -d '*!' | postsuper -d - + echo + done +} + +purge_from_re() { + if [[ $# -eq 0 ]]; then + echo "Please specify a regex to purge emails from" >&2 + exit 1 + fi + for re in "$@"; do + echo "$re" + mailq | tail -n +2 | grep -v '^ *(' | awk "BEGIN { RS = \"\" } (\$7 ~ \"$re\") { print \$1 }" | tr -d '*!' | postsuper -d - + echo + done +} + +purge_to() { + if [[ $# -eq 0 ]]; then + echo "Please specify a locker to purge emails to" >&2 + exit 1 + fi + for locker in "$@"; do + address=$(canonicalize_address "$locker") + echo "$address..." + mailq | grep -v '^ *(\|^-' | awk "BEGIN { RS = \"\" } (\$8 == \"$address\" && \$9 == \"\") { print \$1 }" | tr -d '*!' | postsuper -d - + echo + done +} + +purge_to_re() { + if [[ $# -eq 0 ]]; then + echo "Please specify a regex to purge emails to" >&2 + exit 1 + fi + for re in "$@"; do + echo "$re" + mailq | tail -n +2 | grep -v '^ *(' | awk "BEGIN { RS = \"\" } (\$8 ~ \"$re\" && \$9 == \"\") { print \$1 }" | tr -d '*!' | postsuper -d - + echo + done +} + +op=${1:-} + +# We want to go ahead and show the usage message if there are no args, so +# don't let the shift fail and end the script because of "set -e" +shift || : + +case "$op" in + list-from) list_from;; + list-fullname) list_fullname;; + list-to) list_to;; + show-rand) show_rand "$@";; + email) tmpl_email "$@";; + purge-fullname) purge_fullname "$@";; + purge-from) purge_from "$@";; + purge-from-re) purge_from_re "$@";; + purge-to) purge_to "$@";; + purge-to-re) purge_to_re "$@";; + *) + usage + ;; +esac + +# vim: set sts=4 sw=4 et: diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index af012c25..2f54de8c 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -47,6 +47,11 @@ template: src: root-procmailrc.j2 dest: /etc/scripts/root-procmailrc +- name: Install prune-mailq + copy: + dest: /etc/scripts/prune-mailq + src: prune-mailq + mode: preserve - name: Install aliases copy: dest: /etc/aliases From e17d0e5e2b04c3b1568ee9f241c5d2fba6afb109 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 20 Jul 2019 03:31:01 -0400 Subject: [PATCH 19/29] Generate postfix virtual_alias_domains from vips --- ansible/roles/real-postfix/templates/main.cf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index 108dd5d4..f68e647b 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -32,7 +32,7 @@ newaliases_path = /usr/bin/newaliases mailq_path = /usr/bin/mailq queue_directory = /var/spool/postfix mail_owner = postfix -virtual_alias_domains = !scripts.mit.edu, !scripts, !$myhostname, !scripts-test.mit.edu, !scripts-test, !localhost, scripts-vhosts.mit.edu, ldap:/etc/postfix/virtual-alias-domains-ldap.cf +virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endfor %}!$myhostname, !localhost, ldap:/etc/postfix/virtual-alias-domains-ldap.cf virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf data_directory = /var/lib/postfix authorized_flush_users = fail From f532d2318c194a2ce72b7c1fadcbc86dba7c3816 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Thu, 5 Sep 2019 04:18:14 -0400 Subject: [PATCH 20/29] Incoming mail blocks are now in LDAP --- ansible/roles/real-postfix/files/aliases | 78 +++-------------------- ansible/roles/real-postfix/tasks/main.yml | 2 +- 2 files changed, 9 insertions(+), 71 deletions(-) diff --git a/ansible/roles/real-postfix/files/aliases b/ansible/roles/real-postfix/files/aliases index 5f007621..c7ea1edb 100644 --- a/ansible/roles/real-postfix/files/aliases +++ b/ansible/roles/real-postfix/files/aliases @@ -98,73 +98,11 @@ logview: root scripts-build: root # People who are abusing or otherwise causing problems with the mail system -# Put "/dev/null" as the target of their alias -# srimano: has a phpBB generating a lot of backscatter -srimano: /dev/null -# dbriggs: phpBB: added 2011-06-25, see mail to -root 2011-03-27, 2011-06-03 -dbriggs: /dev/null -# ro21531: spam to rosmosis.net: added 2011-06-25, see mail to -root 2011-06-03 -ro21531: /dev/null -# buechley: not responsive to mail sent by -root on 2013-05-14, added 2013-07-04 -buechley: /dev/null -# cssa: spam, added 2014-02-01 -cssa: /dev/null -# mitlti: added 2014-07-26, causing way too much queued mail and not -# yet responded to mail by -root -mitlti: /dev/null -# paxters: so much spam, added 2014-09-09 -paxters: /dev/null -# crhie: why all the same, added 2014-10-05 -crhie: /dev/null -# baker-foundation: spam, spam, and more spam. Added 2014-11-21 -baker-foundation: /dev/null -# 11.309j: still all spammy, despite contact on 2014-11-09. Added 2014-12-01 -11.309j: /dev/null -# kgsa: repeat unhappiness. Added 2014-12-01 -kgsa: /dev/null -# jains: compromised account sourcing spam. Added 2014-12-13 -jains: /dev/null -# unfolding: compromised account sourcing spam. Added 2014-12-13 -unfolding: /dev/null -# 4.332: compromised account sourcing spam. Added 2014-12-13 -4.332: /dev/null -# asme: compromised account sourcing spam. Added 2014-12-13 -asme: /dev/null -# alisono: compromised account sourcing spam. Added 2014-12-13 -alisono: /dev/null -# laublab: compromised account sourcing spam. Added 2014-12-24 -laublab: /dev/null -# eltahirgroup: compromised account sourcing spam. Added 2015-07-07 -eltahirgroup: /dev/null -# strategic: backscatter. Added 2015-10-09 -strategic: /dev/null -# je18337: cron spam. Added 2015-10-09 -je18337: /dev/null -# gsc: backscatter. Added 2015-10-09 -gsc: /dev/null -# rwf: backscatter. Added 2015-10-09 -rwf: /dev/null -# saxelab: spam. Added 2015-10-09 -saxelab: /dev/null -# qeg: spam. Added 2015-10-09 -qeg: /dev/null -# blackhistory: backscatter. Added 2016-09-03 -blackhistory: /dev/null -# tdc: mail loop on procmailrc. Added 2016-09-11 -tdc: /dev/null -# seek: spam. Added 2016-10-09. -seek: /dev/null -# braintrust: spam. Added 2016-10-20. -braintrust: /dev/null -# newmanlab: spam. Added 2016-12-04. -newmanlab: /dev/null -# game: spam. Added 2017-01-23 -game: /dev/null -# lebanon: spam. Added 2017-01-23 -lebanon: /dev/null -# crpg: spam. Added 2017-01-23 -crpg: /dev/null -# scioly: spam. Added 2017-02-23 -scioly: /dev/null -# xavid: mail loop. Added 2017-03-06 -xavid: /dev/null +# MOVED TO LDAP +# cat < Date: Thu, 5 Sep 2019 04:42:39 -0400 Subject: [PATCH 21/29] authorized_submit_users is now in LDAP --- .../real-postfix/files/postfix/blocked_users | 28 ------------------- ansible/roles/real-postfix/tasks/main.yml | 2 +- .../roles/real-postfix/templates/main.cf.j2 | 2 +- .../authorized-submit-users-ldap.cf.j2 | 7 +++++ 4 files changed, 9 insertions(+), 30 deletions(-) delete mode 100644 ansible/roles/real-postfix/files/postfix/blocked_users create mode 100644 ansible/roles/real-postfix/templates/postfix/authorized-submit-users-ldap.cf.j2 diff --git a/ansible/roles/real-postfix/files/postfix/blocked_users b/ansible/roles/real-postfix/files/postfix/blocked_users deleted file mode 100644 index 62b3d0c5..00000000 --- a/ansible/roles/real-postfix/files/postfix/blocked_users +++ /dev/null @@ -1,28 +0,0 @@ -raskar -maoting -bsu -delian -buechley -cssa -mitlti -paxters -crhie -baker-foundation -11.309j -kgsa -jains -unfolding -4.332 -asme -alisono -laublab -eltahirgroup -early-warning -blackhistory -seek -braintrust -newmanlab -game -lebanon -crpg -scioly diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index b2f651f3..8d496136 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -29,6 +29,7 @@ src: "postfix/{{ item }}.j2" dest: /etc/postfix/{{ item }} loop: + - authorized-submit-users-ldap.cf - mailbox-command-maps-ldap.cf - virtual-alias-domains-ldap.cf - virtual-alias-maps-ldap-reserved.cf @@ -81,4 +82,3 @@ loop: - spamass-milter - postfix -# TODO: Move blocked_users into LDAP and configure an authorized_submit_users map diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index f68e647b..c3d242e0 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -37,7 +37,7 @@ virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap data_directory = /var/lib/postfix authorized_flush_users = fail authorized_mailq_users = /etc/postfix/mailq_users -authorized_submit_users = !/etc/postfix/blocked_users, static:all +authorized_submit_users = !ldap:/etc/postfix/authorized-submit-users-ldap.cf, static:all non_smtpd_milters = unix:/run/spamass-milter/postfix/sock # "all" is the default, but if we do not specify it, Fedora's packaging # will add the wrong value here. diff --git a/ansible/roles/real-postfix/templates/postfix/authorized-submit-users-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/authorized-submit-users-ldap.cf.j2 new file mode 100644 index 00000000..18a12ab2 --- /dev/null +++ b/ansible/roles/real-postfix/templates/postfix/authorized-submit-users-ldap.cf.j2 @@ -0,0 +1,7 @@ +# N.B. If this /does/ match, the user is /blocked/. +server_host = {{ ldap_server }} +search_base = ou=People,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=posixAccount)(uid=%s)(scriptsBlockMailSubmit=TRUE)) +result_attribute = uid +bind = no +version = 3 From f7053d532b14d8e72fb14781d72a442bb83de783 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Fri, 20 Dec 2019 02:57:46 -0500 Subject: [PATCH 22/29] Install a bunch of packages from F20 on F30 --- ansible/roles/real-postfix/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 8d496136..2e9b03f1 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -6,6 +6,7 @@ - postfix-ldap - procmail - spamass-milter-postfix + - postfix-perl-scripts state: present notify: reload postfix - name: Create /etc/systemd/system/postfix.service.d/ From a7b99f9ec90c271c5e334f15ce1114b2112ac408 Mon Sep 17 00:00:00 2001 From: James Koppel Date: Sat, 1 Feb 2020 00:13:52 -0500 Subject: [PATCH 23/29] Updating Postfix conf to forward messages to other server if current server is not in the user's IPv4 pool --- .../roles/real-postfix/templates/main.cf.j2 | 1 + .../postfix/transport-maps-ldap.cf.j2 | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index c3d242e0..f94ad7f3 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -34,6 +34,7 @@ queue_directory = /var/spool/postfix mail_owner = postfix virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endfor %}!$myhostname, !localhost, ldap:/etc/postfix/virtual-alias-domains-ldap.cf virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf +transport_maps = ldap:/etc/postfix/transport-maps-ldap.cf data_directory = /var/lib/postfix authorized_flush_users = fail authorized_mailq_users = /etc/postfix/mailq_users diff --git a/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 new file mode 100644 index 00000000..a2e3841f --- /dev/null +++ b/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 @@ -0,0 +1,21 @@ +# Find any vhost with a name or alias matching the domain of the +# e-mail address. We're queried with an entire e-mail address, but +# are only interested in checking whether the domain portion +# corresponds to a vhost; we'll simply deliver any mail for the vhost +# to its owner, appending the original lefthand side of the address as +# an extension. %d extracts only the domain. We don't match the +# scripts.mit.edu vhost here because we don't want to first resolve an +# arbitrary address to a scripts account, and then end up sending +# their mail to the owners of the scripts.mit.edu vhost. The uid +# attribute, generated by the CoS template +# cn=vhostOwnerCoS,ou=VirtualHosts,dc=scripts,dc=mit,dc=edu, is the +# name of the locker that owns the vhost. Protocol version 3 is +# necessary to use ldapi. + +server_host = {{ ldap_server }} +search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(!(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %}))) +result_attribute = scriptsVhostPoolIPv4 +result_format = smtp:%s +bind = no +version = 3 From ca1cf4836113f46f6ec74eb9c685d9c1ef732c36 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 1 Feb 2020 00:13:24 -0500 Subject: [PATCH 24/29] Only bind the VIPs for the current codename --- ansible/roles/real-postfix/templates/main.cf.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index f94ad7f3..afb5c8f7 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -18,7 +18,7 @@ mailbox_command_maps = mailbox_size_limit = 0 message_size_limit = 41943040 recipient_delimiter = + -inet_interfaces = $myhostname{% for vip in vips %}{% if vip.mail | default(False) %}, {{ vip.host }}{% endif %}{% endfor %} +inet_interfaces = $myhostname{% for vip in vips %}{% if vip.mail | default(False) and (vip.codename|default(ansible_lsb.codename) == ansible_lsb.codename) %}, {{ vip.host }}{% endif %}{% endfor %} readme_directory = /usr/share/doc/postfix/README_FILES sample_directory = /usr/share/doc/postfix/samples @@ -32,7 +32,7 @@ newaliases_path = /usr/bin/newaliases mailq_path = /usr/bin/mailq queue_directory = /var/spool/postfix mail_owner = postfix -virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endfor %}!$myhostname, !localhost, ldap:/etc/postfix/virtual-alias-domains-ldap.cf +virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}{% if (vip.codename|default(ansible_lsb.codename) == ansible_lsb.codename) %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endif %}{% endfor %}!$myhostname, !localhost, ldap:/etc/postfix/virtual-alias-domains-ldap.cf virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf transport_maps = ldap:/etc/postfix/transport-maps-ldap.cf data_directory = /var/lib/postfix From 492fbb0370b86a7d1999cf46fbb6b5d5e7208f14 Mon Sep 17 00:00:00 2001 From: James Koppel Date: Sat, 1 Feb 2020 00:42:17 -0500 Subject: [PATCH 25/29] Adding transport-maps-ldap.cf to template list --- ansible/roles/real-postfix/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 2e9b03f1..4983e461 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -32,6 +32,7 @@ loop: - authorized-submit-users-ldap.cf - mailbox-command-maps-ldap.cf + - transport-maps-ldap.cf - virtual-alias-domains-ldap.cf - virtual-alias-maps-ldap-reserved.cf - virtual-alias-maps-ldap.cf From 89eb8018fb3ee61d564bf5586640e0600c8f2c57 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 1 Feb 2020 02:16:18 -0500 Subject: [PATCH 26/29] Disable virtual_alias_maps for vhosts on another pool. Otherwise the rewrite -> @scripts.mit.edu happens before transport_maps. --- .../templates/postfix/virtual-alias-maps-ldap.cf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 index a7681b46..13404737 100644 --- a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 @@ -14,7 +14,7 @@ server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu -query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))) +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %})) result_attribute = uid result_format = %s+%U bind = no From 17af44294194c5ad74257dce8b1206afb7687ad1 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 1 Feb 2020 02:59:47 -0500 Subject: [PATCH 27/29] Make other pools into relay domains --- .../roles/real-postfix/templates/main.cf.j2 | 3 ++- .../postfix/transport-maps-ldap.cf.j2 | 18 ++++-------------- .../postfix/virtual-alias-domains-ldap.cf.j2 | 2 +- .../postfix/virtual-alias-maps-ldap.cf.j2 | 2 +- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index afb5c8f7..4d3ab5f8 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -34,7 +34,8 @@ queue_directory = /var/spool/postfix mail_owner = postfix virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}{% if (vip.codename|default(ansible_lsb.codename) == ansible_lsb.codename) %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endif %}{% endfor %}!$myhostname, !localhost, ldap:/etc/postfix/virtual-alias-domains-ldap.cf virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf -transport_maps = ldap:/etc/postfix/transport-maps-ldap.cf +relay_domains = ldap:/etc/postfix/transport-maps-ldap.cf +transport_maps = $relay_domains data_directory = /var/lib/postfix authorized_flush_users = fail authorized_mailq_users = /etc/postfix/mailq_users diff --git a/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 index a2e3841f..834b6abe 100644 --- a/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 @@ -1,21 +1,11 @@ -# Find any vhost with a name or alias matching the domain of the -# e-mail address. We're queried with an entire e-mail address, but -# are only interested in checking whether the domain portion -# corresponds to a vhost; we'll simply deliver any mail for the vhost -# to its owner, appending the original lefthand side of the address as -# an extension. %d extracts only the domain. We don't match the -# scripts.mit.edu vhost here because we don't want to first resolve an -# arbitrary address to a scripts account, and then end up sending -# their mail to the owners of the scripts.mit.edu vhost. The uid -# attribute, generated by the CoS template -# cn=vhostOwnerCoS,ou=VirtualHosts,dc=scripts,dc=mit,dc=edu, is the -# name of the locker that owns the vhost. Protocol version 3 is -# necessary to use ldapi. +# Check if the vhost is served from another pool; if so, we relay to +# that pool's IP. This is also used as a relay_domains map to tell +# Postfix it's a relay domain. server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(!(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %}))) result_attribute = scriptsVhostPoolIPv4 -result_format = smtp:%s +result_format = relay:%s bind = no version = 3 diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 index 8763f574..507ee7dd 100644 --- a/ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-domains-ldap.cf.j2 @@ -13,7 +13,7 @@ server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu -query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%s)(scriptsVhostAlias=%s))(!(scriptsVhostName=scripts.mit.edu))) +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%s)(scriptsVhostAlias=%s))(!(scriptsVhostName=scripts.mit.edu))(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %})) result_attribute = scriptsVhostName result_format = %S bind = no diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 index 13404737..a7681b46 100644 --- a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 @@ -14,7 +14,7 @@ server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu -query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %})) +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))) result_attribute = uid result_format = %s+%U bind = no From 6d28907910cb38e0df7c7080d542fbc6e562e0e0 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 1 Feb 2020 03:17:18 -0500 Subject: [PATCH 28/29] cleanup checks virtual_alias_maps before both relay_domains and transport_maps, so we need to avoid returning virtual aliases --- .../templates/postfix/virtual-alias-maps-ldap.cf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 index a7681b46..13404737 100644 --- a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 @@ -14,7 +14,7 @@ server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu -query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))) +query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %})) result_attribute = uid result_format = %s+%U bind = no From 8af2d418383381239adfc9a6875130159357b8b2 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Wed, 5 Feb 2020 01:04:16 -0500 Subject: [PATCH 29/29] Route mail for user@scripts.mit.edu based on user.scripts.mit.edu's pool --- .../roles/real-postfix/files/postfix/force_pool | 6 ++++++ .../files/postfix/generic-strip-pool | 5 +++++ .../files/postfix/pass-scripts.mit.edu | 3 +++ .../files/postfix/pass-scripts.mit.edu-suffix | 3 +++ ansible/roles/real-postfix/tasks/main.yml | 5 ++++- ansible/roles/real-postfix/templates/main.cf.j2 | 17 ++++++++++++----- .../postfix/virtual-alias-maps-ldap.cf.j2 | 2 +- ...f.j2 => virtual-alias-maps-relay-ldap.cf.j2} | 2 +- .../virtual-alias-maps-relay-user-ldap.cf.j2 | 10 ++++++++++ ...tual-alias-maps-relay-user-suffix-ldap.cf.j2 | 11 +++++++++++ 10 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 ansible/roles/real-postfix/files/postfix/force_pool create mode 100644 ansible/roles/real-postfix/files/postfix/generic-strip-pool create mode 100644 ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu create mode 100644 ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu-suffix rename ansible/roles/real-postfix/templates/postfix/{transport-maps-ldap.cf.j2 => virtual-alias-maps-relay-ldap.cf.j2} (95%) create mode 100644 ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-ldap.cf.j2 create mode 100644 ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-suffix-ldap.cf.j2 diff --git a/ansible/roles/real-postfix/files/postfix/force_pool b/ansible/roles/real-postfix/files/postfix/force_pool new file mode 100644 index 00000000..7665cd21 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/force_pool @@ -0,0 +1,6 @@ +# To force a vhost or user to one pool or the other, uncomment one of +# the below: +#/(.*)@vhost\.mit\.edu/ $1!vhost.mit.edu@[18.4.86.22] +#/user(\+.*)?@scripts\.mit\.edu/ user$1!scripts.mit.edu@[18.4.86.22] +#/(.*)@vhost\.mit\.edu/ user+$1@localhost +#/user(\+.*)?@scripts\.mit\.edu/ user$1@localhost diff --git a/ansible/roles/real-postfix/files/postfix/generic-strip-pool b/ansible/roles/real-postfix/files/postfix/generic-strip-pool new file mode 100644 index 00000000..6fbdcc9b --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/generic-strip-pool @@ -0,0 +1,5 @@ +# Rewrite foo!bar.com@[18.4.86.200] to foo@bar.com +# This happens after transport selection, so the message is still +# delivered to 18.4.86.200 + +/(.*)!(.*)@\[[0-9.]+\]/ $1@$2 diff --git a/ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu b/ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu new file mode 100644 index 00000000..21f31896 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu @@ -0,0 +1,3 @@ +# Match @scripts.mit.edu addresses (but don't change them) +# This is chained with an LDAP lookup using pipemap +/(.*)@scripts\.mit\.edu/ $1@scripts.mit.edu diff --git a/ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu-suffix b/ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu-suffix new file mode 100644 index 00000000..4ebed2c4 --- /dev/null +++ b/ansible/roles/real-postfix/files/postfix/pass-scripts.mit.edu-suffix @@ -0,0 +1,3 @@ +# Match quentin+foo@scripts.mit.edu and rewrite to quentin@+foo +# This allows the chained LDAP lookup to resolve quentin.scripts.mit.edu with %u +/([^+]+)([^@]*)@scripts\.mit\.edu/ $1@$2 \ No newline at end of file diff --git a/ansible/roles/real-postfix/tasks/main.yml b/ansible/roles/real-postfix/tasks/main.yml index 4983e461..777345d8 100644 --- a/ansible/roles/real-postfix/tasks/main.yml +++ b/ansible/roles/real-postfix/tasks/main.yml @@ -4,6 +4,7 @@ name: - postfix - postfix-ldap + - postfix-pcre - procmail - spamass-milter-postfix - postfix-perl-scripts @@ -32,10 +33,12 @@ loop: - authorized-submit-users-ldap.cf - mailbox-command-maps-ldap.cf - - transport-maps-ldap.cf - virtual-alias-domains-ldap.cf - virtual-alias-maps-ldap-reserved.cf - virtual-alias-maps-ldap.cf + - virtual-alias-maps-relay-ldap.cf + - virtual-alias-maps-relay-user-ldap.cf + - virtual-alias-maps-relay-user-suffix-ldap.cf notify: reload postfix - name: Install main.cf template: diff --git a/ansible/roles/real-postfix/templates/main.cf.j2 b/ansible/roles/real-postfix/templates/main.cf.j2 index 4d3ab5f8..b2fa74a9 100644 --- a/ansible/roles/real-postfix/templates/main.cf.j2 +++ b/ansible/roles/real-postfix/templates/main.cf.j2 @@ -1,7 +1,7 @@ #biff = no # appending .domain is the MUA's job. -#append_dot_mydomain = no +append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h @@ -32,10 +32,17 @@ newaliases_path = /usr/bin/newaliases mailq_path = /usr/bin/mailq queue_directory = /var/spool/postfix mail_owner = postfix -virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}{% if (vip.codename|default(ansible_lsb.codename) == ansible_lsb.codename) %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endif %}{% endfor %}!$myhostname, !localhost, ldap:/etc/postfix/virtual-alias-domains-ldap.cf -virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf -relay_domains = ldap:/etc/postfix/transport-maps-ldap.cf -transport_maps = $relay_domains +# virtual-alias-maps-ldap-reserved.cf redirects {abuse,webmaster,etc.}@ -> root +# For domains on this pool, virtual-alias-maps-ldap.cf does foo@bar.com -> user+foo@localhost +# For domains on another pool, virtual-alias-maps-relay-ldap.cf does foo@bar.com -> foo!bar.com@[18.4.86.22] +# For users on another pool, pass-scripts.mit.edu matches *@scripts.mit.edu and virtual-alias-maps-relay-user-ldap.cf does foo@scripts.mit.edu -> foo!scripts.mit.edu@[18.4.86.22] +# pass-scripts.mit.edu-suffix and virtual-alias-maps-relay-user-suffix-ldap.cf do the same for foo+bar@scripts.mit.edu +# Native routing does foo@scripts.mit.edu -> foo +# smtp_generic_map rewrites foo!scripts.mit.edu@[18.4.86.22] -> foo@scripts.mit.edu after the transport is selected +# To override, put something in /etc/postfix/force_pool +virtual_alias_domains = {% for vip in vips | rejectattr('type', 'defined') %}{% if (vip.codename|default(ansible_lsb.codename) == ansible_lsb.codename) %}!{{ vip.host }}, !{{ vip.host | replace('.mit.edu', '') }}, {% endif %}{% endfor %}!$myhostname, !localhost, pcre:/etc/postfix/force_pool, ldap:/etc/postfix/virtual-alias-domains-ldap.cf +virtual_alias_maps = ldap:/etc/postfix/virtual-alias-maps-ldap-reserved.cf, ldap:/etc/postfix/virtual-alias-maps-ldap.cf, ldap:/etc/postfix/virtual-alias-maps-relay-ldap.cf, pipemap:{pcre:/etc/postfix/pass-scripts.mit.edu,ldap:/etc/postfix/virtual-alias-maps-relay-user-ldap.cf}, pipemap:{pcre:/etc/postfix/pass-scripts.mit.edu-suffix,ldap:/etc/postfix/virtual-alias-maps-relay-user-suffix-ldap.cf} +smtp_generic_maps = pcre:/etc/postfix/generic-strip-pool data_directory = /var/lib/postfix authorized_flush_users = fail authorized_mailq_users = /etc/postfix/mailq_users diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 index 13404737..c333df92 100644 --- a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-ldap.cf.j2 @@ -16,7 +16,7 @@ server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %})) result_attribute = uid -result_format = %s+%U +result_format = %s+%U@localhost bind = no version = 3 diff --git a/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-ldap.cf.j2 similarity index 95% rename from ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 rename to ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-ldap.cf.j2 index 834b6abe..408f72db 100644 --- a/ansible/roles/real-postfix/templates/postfix/transport-maps-ldap.cf.j2 +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-ldap.cf.j2 @@ -6,6 +6,6 @@ server_host = {{ ldap_server }} search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu query_filter = (&(objectClass=scriptsVhost)(|(scriptsVhostName=%d)(scriptsVhostAlias=%d))(!(scriptsVhostName=scripts.mit.edu))(!(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %}))) result_attribute = scriptsVhostPoolIPv4 -result_format = relay:%s +result_format = %U!%D@[%s] bind = no version = 3 diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-ldap.cf.j2 new file mode 100644 index 00000000..2c7c90b4 --- /dev/null +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-ldap.cf.j2 @@ -0,0 +1,10 @@ +# Check if the user's vhost is served from another pool; if so, we +# relay to that pool's IP. + +server_host = {{ ldap_server }} +search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=scriptsVhost)(scriptsVhostName=%u.scripts.mit.edu)(!(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %}))) +result_attribute = scriptsVhostPoolIPv4 +result_format = %U!scripts.mit.edu@[%s] +bind = no +version = 3 diff --git a/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-suffix-ldap.cf.j2 b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-suffix-ldap.cf.j2 new file mode 100644 index 00000000..eb9df9c5 --- /dev/null +++ b/ansible/roles/real-postfix/templates/postfix/virtual-alias-maps-relay-user-suffix-ldap.cf.j2 @@ -0,0 +1,11 @@ +# Check if the user's vhost is served from another pool; if so, we +# relay to that pool's IP. This lookup handles user@+suffix as the +# input (transformed by pass-scripts.mit.edu-suffix). + +server_host = {{ ldap_server }} +search_base = ou=VirtualHosts,dc=scripts,dc=mit,dc=edu +query_filter = (&(objectClass=scriptsVhost)(scriptsVhostName=%u.scripts.mit.edu)(!(|{% for ip in ansible_all_ipv4_addresses %}(scriptsVhostPoolIPv4={{ip}}){% endfor %}))) +result_attribute = scriptsVhostPoolIPv4 +result_format = %U%D!scripts.mit.edu@[%s] +bind = no +version = 3 \ No newline at end of file