diff --git a/.zuul.yaml b/.zuul.yaml index 163f0b93e7..921bdccefb 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -447,6 +447,26 @@ - playbooks/group_vars/letsencrypt.yaml - playbooks/roles/letsencrypt.* +- job: + name: system-config-run-lists + parent: system-config-run + description: | + Run the playbook for a list server. + nodeset: + nodes: + - name: bridge.openstack.org + label: ubuntu-bionic + - name: lists.openstack.org + label: ubuntu-xenial + files: + - .zuul.yaml + - modules/openstack_project/manifests/lists.pp + - playbooks/host_vars/lists.openstack.org.yaml + - roles/exim + vars: + run_playbooks: + - playbooks/remote_puppet_else.yaml + - job: name: system-config-run-nodepool parent: system-config-run @@ -674,6 +694,7 @@ voting: false - system-config-run-dns - system-config-run-eavesdrop + - system-config-run-lists - system-config-run-nodepool - system-config-run-mirror - system-config-run-docker-registry @@ -700,6 +721,7 @@ - system-config-run-base - system-config-run-dns - system-config-run-eavesdrop + - system-config-run-lists - system-config-run-nodepool - system-config-run-mirror - system-config-run-docker-registry diff --git a/playbooks/host_vars/lists.openstack.org.yaml b/playbooks/host_vars/lists.openstack.org.yaml index 7d0a95d2ae..8f9111f0b9 100644 --- a/playbooks/host_vars/lists.openstack.org.yaml +++ b/playbooks/host_vars/lists.openstack.org.yaml @@ -1,5 +1,6 @@ mm_domains: 'lists.openstack.org:lists.zuul-ci.org:lists.airshipit.org:lists.starlingx.io:lists.opendev.org' exim_local_domains: "@:{{ mm_domains }}" +exim_enable_spf: true exim_aliases: root: "{{ ','.join(listadmins|default([])) }}" interop-wg: openstack-discuss diff --git a/roles/exim/defaults/main.yaml b/roles/exim/defaults/main.yaml index 103e319931..37c5d36b5c 100644 --- a/roles/exim/defaults/main.yaml +++ b/roles/exim/defaults/main.yaml @@ -25,3 +25,4 @@ exim_routers: - system_aliases: '{{ exim_system_aliases_router }}' - localuser: '{{ exim_localuser_router }}' exim_transports: [] +exim_enable_spf: false diff --git a/roles/exim/tasks/Debian.yaml b/roles/exim/tasks/Debian.yaml new file mode 100644 index 0000000000..4309d0535d --- /dev/null +++ b/roles/exim/tasks/Debian.yaml @@ -0,0 +1,10 @@ +- name: Install Exim + package: + state: present + name: '{{ package }}' + +- name: Install SPF tools + when: exim_enable_spf + package: + state: present + name: spf-tools-perl diff --git a/roles/exim/templates/exim4.conf.j2 b/roles/exim/templates/exim4.conf.j2 index 5c3b2dceb2..55d2d5a480 100644 --- a/roles/exim/templates/exim4.conf.j2 +++ b/roles/exim/templates/exim4.conf.j2 @@ -488,6 +488,51 @@ acl_check_rcpt: # require verify = csa ############################################################################# + # Use spfquery to perform a pair of SPF checks (for details, see + # http://www.openspf.org/) + # + # This is quite costly in terms of DNS lookups (~6 lookups per mail). Do not + # enable if that's an issue. Also note that if you enable this, you must + # install "spf-tools-perl" which provides the spfquery command. + # Missing spf-tools-perl will trigger the "Unexpected error in + # SPF check" warning. + {% if exim_enable_spf %} + deny + message = [SPF] $sender_host_address is not allowed to send mail from \ + ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}. \ + Please see \ + http://www.openspf.org/Why?scope=${if def:sender_address_domain \ + {mfrom}{helo}};identity=${if def:sender_address_domain \ + {$sender_address}{$sender_helo_name}};ip=$sender_host_address + log_message = SPF check failed. + condition = ${run{/usr/bin/spfquery.mail-spf-perl --ip \ + ${quote:$sender_host_address} --identity \ + ${if def:sender_address_domain \ + {--scope mfrom --identity ${quote:$sender_address}}\ + {--scope helo --identity ${quote:$sender_helo_name}}}}\ + {no}{${if eq {$runrc}{1}{yes}{no}}}} + + defer + message = Temporary DNS error while checking SPF record. Try again later. + condition = ${if eq {$runrc}{5}{yes}{no}} + + warn + condition = ${if <={$runrc}{6}{yes}{no}} + add_header = Received-SPF: ${if eq {$runrc}{0}{pass}\ + {${if eq {$runrc}{2}{softfail}\ + {${if eq {$runrc}{3}{neutral}\ + {${if eq {$runrc}{4}{permerror}\ + {${if eq {$runrc}{6}{none}{error}}}}}}}}}\ + } client-ip=$sender_host_address; \ + ${if def:sender_address_domain \ + {envelope-from=${sender_address}; }{}}\ + helo=$sender_helo_name + + warn + log_message = Unexpected error in SPF check. + condition = ${if >{$runrc}{6}{yes}{no}} + {% endif %} + # At this point, the address has passed all the checks that have been # configured, so we accept it unconditionally.