Files
@ c063f27000b9
Branch filter:
Location: majic-ansible-roles/roles/backup_server/molecule/default/tests/test_parameters_optional.py
c063f27000b9
9.7 KiB
text/x-python
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).
- 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).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-optional')
def test_backup_client_users_and_groups(host):
"""
Tests if the system groups and users for backup clients have been set-up
correctly.
"""
with host.sudo():
client1_group = host.group('bak-client1_backup')
assert client1_group.exists
assert client1_group.gid < 1000
client1_user = host.user('bak-client1_backup')
assert client1_user.exists
assert client1_user.group == 'bak-client1_backup'
assert sorted(client1_user.groups) == sorted(['bak-client1_backup', 'backup'])
assert client1_user.home == '/srv/backups/client1.backup'
assert client1_user.uid < 1000
assert client1_user.password == '!'
client2_group = host.group('bak-client2-backup')
assert client2_group.exists
assert client2_group.gid == 5001
client2_user = host.user('bak-client2-backup')
assert client2_user.exists
assert client2_user.group == 'bak-client2-backup'
assert sorted(client2_user.groups) == sorted(['bak-client2-backup', 'backup'])
assert client2_user.home == '/srv/backups/client2-backup'
assert client2_user.uid == 5001
assert client2_user.password == '!'
def test_backup_client_home_directories(host):
"""
Tests if the home directory structure has been set-up correctly for the
backup client system user.
"""
with host.sudo():
client1_user = host.user('bak-client1_backup')
client1_user_home = host.file(client1_user.home)
assert client1_user_home.is_directory
assert client1_user_home.user == 'root'
assert client1_user_home.group == 'bak-client1_backup'
assert client1_user_home.mode == 0o750
client1_user_duplicity = host.file(os.path.join(client1_user.home, 'duplicity'))
assert client1_user_duplicity.is_directory
assert client1_user_duplicity.user == 'bak-client1_backup'
assert client1_user_duplicity.group == 'bak-client1_backup'
assert client1_user_duplicity.mode == 0o770
client1_user_ssh = host.file(os.path.join(client1_user.home, '.ssh'))
assert client1_user_ssh.is_directory
assert client1_user_ssh.user == 'root'
assert client1_user_ssh.group == 'root'
assert client1_user_ssh.mode == 0o751
# This verifies /etc/skel was not used for setting-up home.
assert not host.file(os.path.join(client1_user.home, '.bashrc')).exists
client2_user = host.user('bak-client2-backup')
client2_user_home = host.file(client2_user.home)
assert client2_user_home.is_directory
assert client2_user_home.user == 'root'
assert client2_user_home.group == 'bak-client2-backup'
assert client2_user_home.mode == 0o750
client2_user_duplicity = host.file(os.path.join(client2_user.home, 'duplicity'))
assert client2_user_duplicity.is_directory
assert client2_user_duplicity.user == 'bak-client2-backup'
assert client2_user_duplicity.group == 'bak-client2-backup'
assert client2_user_duplicity.mode == 0o770
client2_user_ssh = host.file(os.path.join(client2_user.home, '.ssh'))
assert client2_user_ssh.is_directory
assert client2_user_ssh.user == 'root'
assert client2_user_ssh.group == 'root'
assert client2_user_ssh.mode == 0o751
# This verifies /etc/skel was not used for setting-up home.
assert not host.file(os.path.join(client2_user.home, '.bashrc')).exists
def test_backup_client_authorized_keys(host):
"""
Tests if the authorized keys for backup client system user have been set-up
correctly.
"""
with host.sudo():
client1_user = host.user('bak-client1_backup')
client1_user_authorized_keys = host.file(os.path.join(client1_user.home, '.ssh', 'authorized_keys'))
assert client1_user_authorized_keys.is_file
assert client1_user_authorized_keys.user == 'root'
assert client1_user_authorized_keys.group == 'bak-client1_backup'
assert client1_user_authorized_keys.mode == 0o640
assert client1_user_authorized_keys.content_string == open('tests/data/ssh/client1.pub', 'r').read()
client2_user = host.user('bak-client2-backup')
client2_user_authorized_keys = host.file(os.path.join(client2_user.home, '.ssh', 'authorized_keys'))
assert client2_user_authorized_keys.is_file
assert client2_user_authorized_keys.user == 'root'
assert client2_user_authorized_keys.group == 'bak-client2-backup'
assert client2_user_authorized_keys.mode == 0o640
assert client2_user_authorized_keys.content_string == open('tests/data/ssh/client2.pub', 'r').read()
def test_firewall_configuration(host):
"""
Tests if the firewall configuration file has been deployed correctly.
"""
with host.sudo():
firewall_config = host.file('/etc/ferm/conf.d/40-backup.conf')
assert firewall_config.is_file
assert firewall_config.user == 'root'
assert firewall_config.group == 'root'
assert firewall_config.mode == 0o640
assert 'saddr ( 10.31.127.1 10.31.127.3) @subchain "backup_in" {' in firewall_config.content_string
@pytest.mark.usefixtures("prepare_ssh_client_private_key_permissions")
def test_regular_ssh_server_inaccessible(host):
"""
Tests if the default SSH server is inaccessible for the backup client system
users.
"""
# Extract first non-IPv6 IP. Crude test, but it should work.
remote_ip = next(a for a in host.interface("eth1").addresses if ":" not in a)
local = host.get_host("local://")
# Test connectivity towards regular ssh (should fail).
login_attempt = local.run("ssh "
"-o PasswordAuthentication=no "
"-o StrictHostKeyChecking=no "
"-o UserKnownHostsFile=/dev/null "
"-i tests/data/ssh/client1 "
"bak-client1_backup@%s "
"/bin/echo sshtest" % remote_ip)
assert login_attempt.rc != 0
assert "bad permissions" not in login_attempt.stderr # Avoid passing test due to client private key having wrong permissions.
assert "Permission denied (publickey)" in login_attempt.stderr
login_attempt = local.run("ssh "
"-o PasswordAuthentication=no "
"-o StrictHostKeyChecking=no "
"-o UserKnownHostsFile=/dev/null "
"-i tests/data/ssh/client2 "
"bak-client2-backup@%s "
"/bin/echo sshtest" % remote_ip)
assert login_attempt.rc != 0
assert "bad permissions" not in login_attempt.stderr # Avoid passing test due to client private key having wrong permissions.
assert "Permission denied (publickey)" in login_attempt.stderr
@pytest.mark.usefixtures("prepare_ssh_client_private_key_permissions")
def test_backup_ssh_service_connectivity(host):
"""
Tests if SFTP (only) is availavble to system users used by backup clients.
"""
# Extract first non-IPv6 IP. Crude test, but it should work.
remote_ip = next(a for a in host.interface("eth1").addresses if ":" not in a)
local = host.get_host("local://")
# Test connectivity towards dedicated ssh (should be allowed, but only for sftp).
login_attempt = local.run("ssh -p 2222 "
"-o PasswordAuthentication=no "
"-o StrictHostKeyChecking=no "
"-o UserKnownHostsFile=/dev/null "
"-i tests/data/ssh/client1 "
"bak-client1_backup@%s /bin/echo sshtest" % remote_ip)
assert login_attempt.rc == 1
assert "This service allows sftp connections only." in login_attempt.stdout
# Test connectivity towards dedicated ssh (should be allowed, but only for sftp).
login_attempt = local.run("ssh -p 2222 "
"-o PasswordAuthentication=no "
"-o StrictHostKeyChecking=no "
"-o UserKnownHostsFile=/dev/null "
"-i tests/data/ssh/client2 "
"bak-client2-backup@%s /bin/echo sshtest" % remote_ip)
assert login_attempt.rc == 1
assert "This service allows sftp connections only." in login_attempt.stdout
@pytest.mark.usefixtures("prepare_ssh_client_private_key_permissions")
def test_backup_ssh_service_key_fingerprints(host):
"""
Tests fingerprints of backup SSH server in order to ensure correct keys are
in use.
"""
key_types = ['ssh-rsa', 'ssh-ed25519', 'ecdsa-sha2-nistp256']
# Extract first non-IPv6 IP. Crude test, but it should work.
remote_ip = next(a for a in host.interface("eth1").addresses if ":" not in a)
local = host.get_host("local://")
for key_type in key_types:
login_attempt = local.run("ssh -p 2222 "
"-o PasswordAuthentication=no "
"-o StrictHostKeyChecking=yes "
"-o UserKnownHostsFile=tests/data/ssh/known_hosts "
"-i tests/data/ssh/client1 "
"-o HostKeyAlgorithms=%s "
"bak-client1_backup@%s /bin/echo sshtest" % (key_type, remote_ip))
assert login_attempt.rc == 1
assert "This service allows sftp connections only." in login_attempt.stdout
|