From ee87e05f53bf4801a8043b61a71da2190de2522b Mon Sep 17 00:00:00 2001 From: John Hensley Date: Tue, 4 May 2021 11:18:22 -0400 Subject: [PATCH] Use actual hostname in Postfix configuration The legacy "ossec.server" value of the Postfix myhostname setting does not match our current recommended mon server hostname ("mon"), so prevents correct rewriting of the from address when sending to the SMTP relay. This changes the "postfix_hostname" Ansible variable to use the value of "monitor_hostname". The "postfix_from_address" still uses "ossec_from_address" if configured, but now defaults to sasl_username@sasl_domain if sasl_domain is supplied, enabling another chance for a valid rewrite of ossec@mon. If neither ossec_from_address nor sasl_domain is specified, postfix_from_address will be empty, and in that case the playbook will now remove an existing /etc/postfix/generic database. --- .../roles/postfix/defaults/main.yml | 8 +-- .../roles/postfix/tasks/install_postfix.yml | 15 +++++- .../securedrop-ossec-server/DEBIAN/postinst | 52 ++++++++++++++++++- molecule/testinfra/mon/test_postfix.py | 18 ++++--- molecule/testinfra/vars/mon-staging.yml | 7 ++- molecule/testinfra/vars/qubes-staging.yml | 7 ++- molecule/testinfra/vars/staging.yml | 7 ++- 7 files changed, 97 insertions(+), 17 deletions(-) diff --git a/install_files/ansible-base/roles/postfix/defaults/main.yml b/install_files/ansible-base/roles/postfix/defaults/main.yml index d190597b27..1e829dcf93 100644 --- a/install_files/ansible-base/roles/postfix/defaults/main.yml +++ b/install_files/ansible-base/roles/postfix/defaults/main.yml @@ -1,8 +1,10 @@ --- # Email address listed in the FROM line when sending OSSEc email alerts. # Some mail servers require that this match the account that authenticated -# to send mail. Using the `ossec_from_address` for backwards-compatibility. -postfix_from_address: "{{ ossec_from_address|default('') }}" +# to send mail. Using the `ossec_from_address` for +# backwards-compatibility. +sasl_id: "{% if sasl_domain %}{{ sasl_username }}@{{ sasl_domain }}{% endif %}" +postfix_from_address: "{{ ossec_from_address|default(sasl_id) }}" # Apt dependencies for the ossec server package postfix_dependencies: @@ -11,7 +13,7 @@ postfix_dependencies: - mailutils # Configuration info for procmail and postfix -postfix_hostname: ossec.server +postfix_hostname: "{{ monitor_hostname }}" # Whether to enable Postfix for sending mail. Required in prod, # but unnecessary in staging contexts, where SASL authentication diff --git a/install_files/ansible-base/roles/postfix/tasks/install_postfix.yml b/install_files/ansible-base/roles/postfix/tasks/install_postfix.yml index 213b10f304..8d9a3044ed 100644 --- a/install_files/ansible-base/roles/postfix/tasks/install_postfix.yml +++ b/install_files/ansible-base/roles/postfix/tasks/install_postfix.yml @@ -15,15 +15,26 @@ tags: - postfix -- name: Create mapping for outbound address. +- name: Create outbound mapping for postfix_from_address in /etc/postfix/generic. copy: - content: "ossec@{{ postfix_hostname }} {{ postfix_from_address }}" + content: "ossec@{{ postfix_hostname }} {{ postfix_from_address }}\n" dest: /etc/postfix/generic notify: update generic_maps when: postfix_from_address != "" tags: - postfix +- name: Remove /etc/postfix/generic database because postfix_from_address is empty. + file: + state: absent + dest: "{{ item }}" + with_items: + - /etc/postfix/generic + - /etc/postfix/generic.db + when: postfix_from_address == "" + tags: + - postfix + - name: Configure SASL password for SMTP relay. template: src: sasl_passwd diff --git a/install_files/securedrop-ossec-server/DEBIAN/postinst b/install_files/securedrop-ossec-server/DEBIAN/postinst index 05a7805fa5..54e20dc3f6 100755 --- a/install_files/securedrop-ossec-server/DEBIAN/postinst +++ b/install_files/securedrop-ossec-server/DEBIAN/postinst @@ -16,11 +16,59 @@ set -x # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package +configure_postfix_myhostname() { + if [ -f /etc/postfix/main.cf ] + then + sed -i -E "s/^myhostname\\s*=\\s*ossec.server.*$/myhostname = $(hostname -f)/" /etc/postfix/main.cf + fi +} + +configure_postfix_generics() { + if [ -f /etc/postfix/main.cf ] + then + python3 - <localhost<\/smtp_server>/127.0.0.1<\/smtp_server>/g" /var/ossec/etc/ossec.conf diff --git a/molecule/testinfra/mon/test_postfix.py b/molecule/testinfra/mon/test_postfix.py index 4b1b0d78ee..578ad02ed0 100644 --- a/molecule/testinfra/mon/test_postfix.py +++ b/molecule/testinfra/mon/test_postfix.py @@ -29,14 +29,18 @@ def test_postfix_headers(host, header): def test_postfix_generic_maps(host): """ - Regression test to check that generic Postfix maps are not configured - by default. As of #1565 Admins can opt-in to overriding the FROM address - used for sending OSSEC alerts, but by default we're preserving the old - `ossec@ossec.server` behavior, to avoid breaking email for previously - existing instances. + Check configuration of Postfix generic map when sasl_domain is set + and ossec_from_address is not specified. """ - assert not host.file("/etc/postfix/generic").exists - assert not host.file("/etc/postfix/main.cf").contains("^smtp_generic_maps") + assert host.file("/etc/postfix/generic").exists + assert host.file("/etc/postfix/generic").contains( + "^ossec@{} {}@{}".format( + securedrop_test_vars.monitor_hostname, + securedrop_test_vars.sasl_username, + securedrop_test_vars.sasl_domain, + ) + ) + assert host.file("/etc/postfix/main.cf").contains("^smtp_generic_maps") assert host.file("/etc/postfix/main.cf").contains( "^smtpd_recipient_restrictions = reject_unauth_destination") diff --git a/molecule/testinfra/vars/mon-staging.yml b/molecule/testinfra/vars/mon-staging.yml index 1a6b3f6db5..9630e75e4b 100644 --- a/molecule/testinfra/vars/mon-staging.yml +++ b/molecule/testinfra/vars/mon-staging.yml @@ -13,9 +13,14 @@ tor_services: authenticated: yes # value will automatically be coerced to boolean client: admin -# Disable Postfix in staging, since we don't have valid credentials. +# Postfix is disabled in staging. postfix_enabled: False +# But it does get configured. +sasl_username: "test" +sasl_domain: "ossec.test" +sasl_password: "password123" + # Log events for OSSEC alerts we suppress log_events_without_ossec_alerts: # Check that using an overloaded guard does not produce an OSSEC alert diff --git a/molecule/testinfra/vars/qubes-staging.yml b/molecule/testinfra/vars/qubes-staging.yml index 83d7f1feee..aa7c2e96b1 100644 --- a/molecule/testinfra/vars/qubes-staging.yml +++ b/molecule/testinfra/vars/qubes-staging.yml @@ -74,9 +74,14 @@ allowed_apache_logfiles: - /var/log/apache2/other_vhosts_access.log - /var/log/apache2/source-error.log -# Disable Postfix in staging, since we don't have valid credentials. +# Postfix is disabled in staging. postfix_enabled: False +# But it does get configured. +sasl_username: "test" +sasl_domain: "ossec.test" +sasl_password: "password123" + # Log events for OSSEC alerts we suppress log_events_without_ossec_alerts: # Check that using an overloaded guard does not produce an OSSEC alert diff --git a/molecule/testinfra/vars/staging.yml b/molecule/testinfra/vars/staging.yml index 533b7033a5..081d0fa640 100644 --- a/molecule/testinfra/vars/staging.yml +++ b/molecule/testinfra/vars/staging.yml @@ -74,9 +74,14 @@ allowed_apache_logfiles: - /var/log/apache2/other_vhosts_access.log - /var/log/apache2/source-error.log -# Disable Postfix in staging, since we don't have valid credentials. +# Postfix is disabled in staging. postfix_enabled: False +# But it does get configured. +sasl_username: "test" +sasl_domain: "ossec.test" +sasl_password: "password123" + # Log events for OSSEC alerts we suppress log_events_without_ossec_alerts: # Check that using an overloaded guard does not produce an OSSEC alert