import re import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( '.molecule/ansible_inventory.yml').get_hosts('parameters-optional') def test_smtp_tls_files(host): """ Tests if SMTP TLS private key has been deployed correctly. """ with host.sudo(): tls_file = host.file('/etc/ssl/private/parameters-optional-jessie64_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-optional_smtp.key.pem", "r").read().rstrip() tls_file = host.file('/etc/ssl/certs/parameters-optional-jessie64_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-optional_smtp.cert.pem", "r").read().rstrip() tls_file = host.file('/etc/ssl/private/parameters-optional-jessie64_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-optional_imap.key.pem", "r").read().rstrip() tls_file = host.file('/etc/ssl/certs/parameters-optional-jessie64_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-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. """ config = host.file('/etc/check_certificate/parameters-optional-jessie64_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-optional-jessie64_smtp.pem" config = host.file('/etc/check_certificate/parameters-optional-jessie64_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-optional-jessie64_imap.pem" def test_mailname_file_content(host): """ Tests the system mail name file content. """ mailname = host.file('/etc/mailname') assert mailname.content == "parameters-optional-jessie64" def test_postfix_main_cf_file_content(host): """ Tests if the Postfix main configuration file content is correct. """ config = host.file('/etc/postfix/main.cf') config_lines = config.content.split("\n") assert "myhostname = parameters-optional-jessie64" in config_lines assert "mydestination = parameters-optional-jessie64, parameters-optional-jessie64, localhost.localdomain, localhost" in config_lines assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.31.127.20" in config_lines assert "smtpd_tls_cert_file = /etc/ssl/certs/parameters-optional-jessie64_smtp.pem" in config_lines assert "smtpd_tls_key_file = /etc/ssl/private/parameters-optional-jessie64_smtp.key" 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. """ send = host.run('swaks --suppress-data --to root@localhost') assert send.rc == 0 message_id = re.search('Ok: queued as (.*)', send.stdout).group(1) with host.sudo(): mail_log = host.file('/var/log/mail.log') pattern = "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 "write:errno=104" 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 "write:errno=104" 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 'write:errno=104' 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