Files @ 4c0b2aa9cb69
Branch filter:

Location: majic-ansible-roles/roles/mail_server/molecule/default/tests/test_optional.py

branko
MAR-152: Drop support for Debian 8 Jessie from the mail_server role.
import os
import re
import time
import uuid

import testinfra.utils.ansible_runner


testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-optional')


def test_smtp_tls_files(host):
    """
    Tests if SMTP TLS private key has been deployed correctly.
    """

    hostname = host.run('hostname').stdout.strip()

    with host.sudo():

        tls_file = host.file('/etc/ssl/private/%s_smtp.key' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o640
        assert tls_file.content == open("tests/data/x509/parameters-optional_smtp.key.pem", "r").read().rstrip()

        tls_file = host.file('/etc/ssl/certs/%s_smtp.pem' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o644
        assert tls_file.content == open("tests/data/x509/parameters-optional_smtp.cert.pem", "r").read().rstrip()

        tls_file = host.file('/etc/ssl/private/%s_imap.key' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o640
        assert tls_file.content == open("tests/data/x509/parameters-optional_imap.key.pem", "r").read().rstrip()

        tls_file = host.file('/etc/ssl/certs/%s_imap.pem' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o644
        assert tls_file.content == open("tests/data/x509/parameters-optional_imap.cert.pem", "r").read().rstrip()


def test_certificate_validity_check_configuration(host):
    """
    Tests if certificate validity check configuration file has been deployed
    correctly.
    """

    hostname = host.run('hostname').stdout.strip()

    config = host.file('/etc/check_certificate/%s_smtp.conf' % hostname)
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content == "/etc/ssl/certs/%s_smtp.pem" % hostname

    config = host.file('/etc/check_certificate/%s_imap.conf' % hostname)
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content == "/etc/ssl/certs/%s_imap.pem" % hostname


def test_mailname_file_content(host):
    """
    Tests the system mail name file content.
    """

    mailname = host.file('/etc/mailname')
    hostname = host.run('hostname').stdout.strip()

    assert mailname.content == hostname


def test_postfix_main_cf_file_content(host):
    """
    Tests if the Postfix main configuration file content is correct.
    """

    allow_relay_from_ip = "10.31.127.22"

    hostname = host.run('hostname').stdout.strip()

    config = host.file('/etc/postfix/main.cf')
    config_lines = config.content.split("\n")

    assert "myhostname = %s" % hostname in config_lines
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 %s" % allow_relay_from_ip in config_lines
    assert "smtpd_tls_cert_file = /etc/ssl/certs/%s_smtp.pem" % hostname in config_lines
    assert "smtpd_tls_key_file = /etc/ssl/private/%s_smtp.key" % hostname in config_lines
    assert "  reject_rbl bl.spamcop.net" in config_lines
    assert "  reject_rbl zen.spamhaus.org" in config_lines
    assert "smtp_host_lookup = dns, native" in config_lines


def test_local_aliases(host):
    """
    Tests if local aliases are configured correctly.
    """

    message_id = str(uuid.uuid4())

    send = host.run('swaks --header %s --suppress-data --to root@localhost', "Message-Id: <%s>" % message_id)
    time.sleep(1)
    assert send.rc == 0

    with host.sudo():
        mail_log = host.file('/var/log/mail.log')
        pattern = r"dovecot: lda\(john.doe@domain1\): msgid=<%s>: saved mail to INBOX" % message_id
        assert re.search(pattern, mail_log.content) is not None


def test_dovecot_mailbox_directories(host):
    """
    Tests if mailbox directories are created correctly.
    """

    # Deliver two mails in order to make sure the directory structure is
    # created.
    send = host.run('swaks --suppress-data --to john.doe@domain1 --server localhost')
    assert send.rc == 0
    send = host.run('swaks --suppress-data --to jane.doe@domain2 --server localhost')
    assert send.rc == 0

    with host.sudo():

        for directory_path in ["/var/virtmail/domain1",
                               "/var/virtmail/domain1/john.doe",
                               "/var/virtmail/domain1/john.doe/Maildir",
                               "/var/virtmail/domain2",
                               "/var/virtmail/domain2/jane.doe",
                               "/var/virtmail/domain2/jane.doe/Maildir"]:

            directory = host.file(directory_path)

            assert directory.is_directory
            assert directory.user == "virtmail"
            assert directory.group == "virtmail"
            assert directory.mode == 0o700


def test_mail_owner(host):
    """
    Tests creation of mail owner group and user.
    """

    group = host.group("virtmail")
    assert group.exists
    assert group.gid == 5000

    user = host.user("virtmail")
    assert user.exists
    assert user.uid == 5000
    assert user.home == "/var/virtmail"
    assert user.group == "virtmail"
    assert user.groups == ["virtmail"]


def test_imap_tls_configuration(host):
    """
    Tests TLS configuration for IMAP in Dovecot.
    """

    # Test plain connectivity first.
    starttls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -starttls imap -connect parameters-optional:143')
    assert starttls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    tls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -connect parameters-optional:993')
    assert tls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    # Test TLS protocol versions.
    starttls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -starttls imap -no_tls1_2 -connect parameters-optional:143')
    assert starttls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    tls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -no_tls1_2 -connect parameters-optional:993')
    assert tls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    starttls = host.run("echo 'a0001 LOGOUT' | openssl s_client -quiet -starttls imap -no_tls1_1 -no_tls1_2 -connect parameters-optional:143")
    assert starttls.rc != 0
    assert 'SSL alert number 70' in starttls.stderr

    tls = host.run("echo 'a0001 LOGOUT' | openssl s_client -quiet -no_tls1_1 -no_tls1_2 -connect parameters-optional:993")
    assert tls.rc != 0
    assert 'SSL alert number 70' in tls.stderr

    # Test at least one strong TLS cipher.
    starttls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -starttls imap -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:143")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

    tls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:993")
    assert tls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in tls_cipher.stdout

    # Test weaker TLS cipher that was explicitly configured
    starttls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -starttls imap -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:143")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in starttls_cipher.stdout

    tls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:993")
    assert tls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in tls_cipher.stdout


def test_dovecot_postmaster(host):
    """
    Tests if Dovecot postmaster has been correctly configured.
    """

    with host.sudo():

        config = host.run("doveadm config")

        assert config.rc == 0
        assert "  postmaster_address = webmaster@parameters-optional" in config.stdout


def test_imap_max_user_connections_per_ip(host):
    """
    Tests if Dovecot per-user connection limit has been set-up correctly.
    """

    with host.sudo():

        config = host.run("doveadm config")

        assert config.rc == 0
        assert "  mail_max_userip_connections = 2" in config.stdout


def test_postfix_tls_configuration(host):
    """
    Tests TLS configuration for SMTP in Postfix.
    """

    # Test TLS protocol versions for default port (all should be enabled).
    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1 -no_tls1_1 -connect parameters-optional:25")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -connect parameters-optional:25")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -no_tls1_1 -connect parameters-optional:25")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    # Test TLS protocol versions for submission port (only TLS 1.1 and TLS 1.2 should be enabled).
    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -connect parameters-optional:587")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -connect parameters-optional:587")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_1 -no_tls1_2 -connect parameters-optional:587")
    assert starttls.rc != 0
    assert 'SSL alert number 70' in starttls.stderr

    # Test ciphers for default port (less restrictive).
    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:25")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:25")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in starttls_cipher.stdout

    # Test ciphers for submission port (at least one weak cipher was configured).
    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:587")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:587")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in starttls_cipher.stdout


def test_sieve_tls_configuration(host):
    """
    Tests TLS configuration for SIEVE in Dovecot
    """

    # @TODO: Currently not possible to test since openssl s_client does not
    # support STARTTLS for Sieve.
    pass