Files @ 17cf34f73ca6
Branch filter:

Location: majic-ansible-roles/roles/mail_server/tests/test_mandatory.py

branko
MAR-28: Implemented additional tests for mail_server role:

- Deploy a number of tools on clients in order to test SMTP, IMAP, and Sieve
services.
- Added one more user to LDAP directory for testing group restrictions.
- Deploy CA certificate on all testing machines for TLS validation purposes.
- Use different custom-configured cipher for mail server ciphers.
- Fixed invalid postmaster address for parameters-optional host.
- Deploy configuration files for use with Imap-CLI on client test machines.
- Updated testing of SMTP server to include checks for users that do not belong
to mail group.
- Extended some SMTP-related tests to cover both test servers.
- Some small fixes in SMTP-related tests for expected output from commands.
- Implemented tests covering Dovecot (IMAP + Sieve) functionality.
- Implemented tests for running/enabled services.
- Implemented tests for ClamAV.
- Implemented tests for firewall and connectivity.
- Implemented tests for Postfix TLS configuration.
- TODO: Tests for Sieve TLS configuration have not been written yet due to
limitation of available tools.
import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    '.molecule/ansible_inventory').get_hosts('parameters-mandatory')


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

    with Sudo():

        tls_file = File('/etc/ssl/private/parameters-mandatory_smtp.key')
        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-mandatory_smtp.key", "r").read().rstrip()

        tls_file = File('/etc/ssl/certs/parameters-mandatory_smtp.pem')
        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-mandatory_smtp.pem", "r").read().rstrip()

        tls_file = File('/etc/ssl/private/parameters-mandatory_imap.key')
        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-mandatory_imap.key", "r").read().rstrip()

        tls_file = File('/etc/ssl/certs/parameters-mandatory_imap.pem')
        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-mandatory_imap.pem", "r").read().rstrip()


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

    config = File('/etc/check_certificate/parameters-mandatory_smtp.conf')
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content == "/etc/ssl/certs/parameters-mandatory_smtp.pem"

    config = File('/etc/check_certificate/parameters-mandatory_imap.conf')
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content == "/etc/ssl/certs/parameters-mandatory_imap.pem"


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

    mailname = File('/etc/mailname')

    assert mailname.content == "parameters-mandatory"


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

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

    assert "myhostname = parameters-mandatory" in config_lines
    assert "mydestination = parameters-mandatory, parameters-mandatory, localhost.localdomain, localhost" in config_lines
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" in config_lines
    assert "smtpd_tls_cert_file = /etc/ssl/certs/parameters-mandatory_smtp.pem" in config_lines
    assert "smtpd_tls_key_file = /etc/ssl/private/parameters-mandatory_smtp.key" in config_lines
    assert "reject_rbl" not in config_lines


def test_dovecot_mailbox_directories(File, Sudo):
    """
    Tests if mailbox directories are created correctly.
    """

    with Sudo():

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

            directory = File(directory_path)

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


def test_mail_owner(Group, User):
    """
    Tests creation of mail owner group and user.
    """

    group = Group("vmail")
    assert group.exists
    assert group.gid == 1002

    user = User("vmail")
    assert user.exists
    assert user.uid == 1002
    assert user.home == "/var/vmail"
    assert user.group == "vmail"
    assert user.groups == ["vmail"]


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

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

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

    # Test TLS protocol versions.
    starttls_old_tls_versions_disabled = Command("echo 'a0001 LOGOUT' | openssl s_client -quiet -starttls imap -no_tls1_2 -connect parameters-mandatory:143")
    assert starttls_old_tls_versions_disabled.rc != 0
    assert "write:errno=104" in starttls_old_tls_versions_disabled.stderr

    tls_old_tls_versions_disabled = Command("echo 'a0001 LOGOUT' | openssl s_client -quiet -no_tls1_2 -connect parameters-mandatory:993")
    assert tls_old_tls_versions_disabled.rc != 0
    assert "write:errno=104" in tls_old_tls_versions_disabled.stderr

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

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

    # Test weaker TLS cipher are disabled.
    starttls_cipher = Command("echo 'a0001 LOGOUT' | openssl s_client -starttls imap -cipher ECDHE-RSA-AES128-SHA -connect parameters-mandatory:143")
    assert starttls_cipher.rc != 0
    assert "ECDHE-RSA-AES128-SHA" not in starttls_cipher.stdout

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


def test_dovecot_postmaster(Command, Sudo):
    """
    Tests if Dovecot postmaster has been correctly configured.
    """

    with Sudo():

        config = Command("doveadm config")
        assert config.rc == 0
        assert "  postmaster_address = postmaster@" in config.stdout


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

    with Sudo():

        config = Command("doveadm config")

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


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

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

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

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

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

    starttls = Command("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -connect parameters-mandatory:587")
    assert starttls.rc != 0
    assert 'write:errno=104' in starttls.stderr

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

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

    # Test ciphers for submission port (weak ciphers not available).
    starttls_cipher = Command("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-mandatory:587")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

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


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

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