Changeset - c063f27000b9
[Not reviewed]
0 4 3
Branko Majic (branko) - 3 years ago 2020-12-22 17:27:47
branko@majic.rs
MAR-175: Mail server should be opportunistic in using TLS when delivering mail to remove servers:

- Previously the mail server would only deliver mails over plaintext.
- Deploy a simple SMTP server on both client1/client2
machines. Servers are set-up to require/refuse the STARTTLS over
SMTP.
- Added tests for checking if STARTTLS is used when available for mail
delivery.
- Fixed the wrong configurtion (making sure the TLS security level is
properly set for Postfix).
7 files changed with 152 insertions and 2 deletions:
0 comments (0 inline, 0 general)
roles/mail_server/molecule/default/group_vars/smtp-server-refusing-tls.yml
Show inline comments
 
new file 100644
 
---
 

	
 
smtpd_tls_security_level: "none"
 
extra_mydestination: "smtp-server-refusing-tls"
roles/mail_server/molecule/default/group_vars/smtp-server-requiring-tls.yml
Show inline comments
 
new file 100644
 
---
 

	
 
smtpd_tls_security_level: "encrypt"
 
extra_mydestination: "smtp-server-requiring-tls"
roles/mail_server/molecule/default/molecule.yml
Show inline comments
 
@@ -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
roles/mail_server/molecule/default/prepare.yml
Show inline comments
 
@@ -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:
roles/mail_server/molecule/default/templates/helper_smtp_main.cf.j2
Show inline comments
 
new file 100644
 
# 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
roles/mail_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -506,3 +506,59 @@ def test_postfix_local_delivery(host):
 
        pattern = r"postfix/local\[\d+\]: %s: to=<localuser@localhost>, 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<queue_id>[^:]+): 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=<root@smtp-server-refusing-tls>, 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<queue_id>[^:]+): 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=<root@smtp-server-requiring-tls>, 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
roles/mail_server/templates/main.cf.j2
Show inline comments
 
@@ -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.
0 comments (0 inline, 0 general)