diff --git a/roles/mail_server/molecule/default/group_vars/smtp-server-refusing-tls.yml b/roles/mail_server/molecule/default/group_vars/smtp-server-refusing-tls.yml new file mode 100644 index 0000000000000000000000000000000000000000..b60391c233c22fd5ea3b7b2d4e39caabbd86a567 --- /dev/null +++ b/roles/mail_server/molecule/default/group_vars/smtp-server-refusing-tls.yml @@ -0,0 +1,4 @@ +--- + +smtpd_tls_security_level: "none" +extra_mydestination: "smtp-server-refusing-tls" diff --git a/roles/mail_server/molecule/default/group_vars/smtp-server-requiring-tls.yml b/roles/mail_server/molecule/default/group_vars/smtp-server-requiring-tls.yml new file mode 100644 index 0000000000000000000000000000000000000000..84783a6228238d48c06628707a43343acb247752 --- /dev/null +++ b/roles/mail_server/molecule/default/group_vars/smtp-server-requiring-tls.yml @@ -0,0 +1,4 @@ +--- + +smtpd_tls_security_level: "encrypt" +extra_mydestination: "smtp-server-requiring-tls" diff --git a/roles/mail_server/molecule/default/molecule.yml b/roles/mail_server/molecule/default/molecule.yml index 1367899784937cd530a7c7522c103343fc66db70..5e35f624f714a827dc09ec3ba99ff0dafcf21474 100644 --- a/roles/mail_server/molecule/default/molecule.yml +++ b/roles/mail_server/molecule/default/molecule.yml @@ -29,6 +29,7 @@ platforms: - client - client-relay-allowed - stretch + - smtp-server-requiring-tls box: debian/contrib-stretch64 memory: 256 cpus: 1 @@ -43,6 +44,7 @@ platforms: - client - client-relay-forbidden - stretch + - smtp-server-refusing-tls box: debian/contrib-stretch64 memory: 256 cpus: 1 diff --git a/roles/mail_server/molecule/default/prepare.yml b/roles/mail_server/molecule/default/prepare.yml index 4ee505cd304c0f302931511173b77ebd13b228f6..011685d4206f4dc5163cde258b41cc42ec4d6a20 100644 --- a/roles/mail_server/molecule/default/prepare.yml +++ b/roles/mail_server/molecule/default/prepare.yml @@ -81,8 +81,8 @@ state: present with_dict: 10.31.127.10: "ldap-server backup-server" - 10.31.127.22: "client1" - 10.31.127.23: "client2" + 10.31.127.22: "client1 smtp-server-requiring-tls" + 10.31.127.23: "client2 smtp-server-refusing-tls" 10.31.127.32: "parameters-mandatory parameters-mandatory-stretch64" 10.31.127.33: "parameters-optional parameters-optional-stretch64" @@ -138,11 +138,46 @@ notify: - Update CA certificate cache + - name: Install and configure Postfix for testing mail sending from managed servers + block: + + - name: Install Postfix + apt: + name: postfix + state: present + + - name: Purge Exim + apt: + name: "exim4*" + state: absent + purge: true + + - name: Configure Postfix + template: + src: "helper_smtp_main.cf.j2" + dest: "/etc/postfix/main.cf" + owner: root + group: root + mode: 0644 + notify: + - Restart Postfix + + - name: Enable Postfix service + service: + name: postfix + state: started + enabled: true + handlers: - name: Update CA certificate cache command: /usr/sbin/update-ca-certificates --fresh + - name: Restart Postfix + service: + name: postfix + state: restarted + - hosts: ldap-server become: true roles: diff --git a/roles/mail_server/molecule/default/templates/helper_smtp_main.cf.j2 b/roles/mail_server/molecule/default/templates/helper_smtp_main.cf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..edcfeaa76d07c22915852df263400ffc98d03a2c --- /dev/null +++ b/roles/mail_server/molecule/default/templates/helper_smtp_main.cf.j2 @@ -0,0 +1,48 @@ +# See /usr/share/postfix/main.cf.dist for a commented, more complete version + + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname + +smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) +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 + +readme_directory = no + +# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on +# fresh installs. +compatibility_level = 2 + + + +# TLS parameters +smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem +smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key +smtpd_use_tls=yes +smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache +smtpd_tls_security_level = {{ smtpd_tls_security_level }} +smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache + +# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for +# information on enabling SSL in the smtp client. + +smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination +myhostname = contrib-buster.localdomain +alias_maps = hash:/etc/aliases +alias_database = hash:/etc/aliases +myorigin = /etc/mailname +mydestination = $myhostname, localhost.localdomain, localhost, {{ extra_mydestination }} +relayhost = +mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 +mailbox_size_limit = 0 +recipient_delimiter = + +inet_interfaces = all +inet_protocols = all diff --git a/roles/mail_server/molecule/default/tests/test_default.py b/roles/mail_server/molecule/default/tests/test_default.py index 3d78fac856373848b8efa7c35d263aad923bca4b..a5b326464d00b337affc86214325e78c8ff31802 100644 --- a/roles/mail_server/molecule/default/tests/test_default.py +++ b/roles/mail_server/molecule/default/tests/test_default.py @@ -506,3 +506,59 @@ def test_postfix_local_delivery(host): pattern = r"postfix/local\[\d+\]: %s: to=, relay=local,.*, status=sent \(delivered to mailbox\)" % queue_id match_result = re.search(pattern, mail_log.content_string) assert match_result is not None, queue_id + + +def test_postfix_sends_mails_without_tls_when_unavailable(host): + """ + Tests if Postfix sends out mails even if STARTTLS is not available + on remote server. + """ + + # Verify that the remote host refuses to accept mails over TLS first. + send = host.run('swaks --tls --suppress-data --to root@smtp-server-refusing-tls --server smtp-server-refusing-tls') + assert send.rc == 29 + assert "Host did not advertise STARTTLS" in send.stderr + + message_id = str(uuid.uuid4()) + send = host.run('swaks --header %s --suppress-data --to root@smtp-server-refusing-tls --server localhost', "Message-Id: <%s>" % message_id) + assert send.rc == 0 + + with host.sudo(): + mail_log = host.file('/var/log/mail.log') + + pattern = r"postfix/cleanup\[\d+\]: (?P[^:]+): message-id=<%s>" % message_id + match_result = re.search(pattern, mail_log.content_string) + assert match_result is not None + + queue_id = match_result.group('queue_id') + pattern = r"postfix/smtp\[\d+\]: %s: to=, relay=smtp-server-refusing-tls.*, status=sent" % queue_id + match_result = re.search(pattern, mail_log.content_string) + assert match_result is not None, queue_id + + +def test_postfix_sends_mails_over_tls_when_available(host): + """ + Tests if Postfix sends out mails using STARTTLS if available on + remote server (oportunistic encryption). + """ + + # Verify that the remote host refuses to accept mails without TLS first. + send = host.run('swaks --suppress-data --to root@smtp-server-requiring-tls --server smtp-server-requiring-tls') + assert send.rc == 23 + assert "Must issue a STARTTLS command first" in send.stdout + + message_id = str(uuid.uuid4()) + send = host.run('swaks --tls --header %s --suppress-data --to root@smtp-server-requiring-tls --server localhost', "Message-Id: <%s>" % message_id) + assert send.rc == 0 + + with host.sudo(): + mail_log = host.file('/var/log/mail.log') + + pattern = r"postfix/cleanup\[\d+\]: (?P[^:]+): message-id=<%s>" % message_id + match_result = re.search(pattern, mail_log.content_string) + assert match_result is not None + + queue_id = match_result.group('queue_id') + pattern = r"postfix/smtp\[\d+\]: %s: to=, relay=smtp-server-requiring-tls.*, status=sent" % queue_id + match_result = re.search(pattern, mail_log.content_string) + assert match_result is not None, queue_id diff --git a/roles/mail_server/templates/main.cf.j2 b/roles/mail_server/templates/main.cf.j2 index abbfb2621eb144bfe165cdae3ae6d790940909b0..57f2fe092d0c7d9f73bf62f9234e845d331f9f13 100644 --- a/roles/mail_server/templates/main.cf.j2 +++ b/roles/mail_server/templates/main.cf.j2 @@ -70,6 +70,7 @@ smtpd_tls_dh512_param_file = /etc/ssl/private/{{ inventory_hostname }}_smtp.dh.p smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache +smtp_tls_security_level = may # Allow relaying only from trusted networks. Do not relay mails for # domains for which the mail server is not responsible.