Files @ 08bc7c6ea086
Branch filter:

Location: majic-ansible-roles/roles/backup_server/molecule/default/tests/test_parameters_optional.py - annotation

branko
MAR-239: Updated documentation, dropping references to Debian 11 Bullseye where appropriate.
ef201fa5ec5f
ef201fa5ec5f
770551dc8c6f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
d62b3adec462
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
d752715bb533
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
d752715bb533
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
5ae7541e88d1
ef201fa5ec5f
ef201fa5ec5f
770551dc8c6f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
770551dc8c6f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
770551dc8c6f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
770551dc8c6f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
770551dc8c6f
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
ef201fa5ec5f
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
2c24e973d44a
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 ( 192.168.56.1 192.168.56.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")
@pytest.mark.parametrize('key_algorithm', [
    'rsa-sha2-512',
    'ssh-ed25519',
    'ecdsa-sha2-nistp256',
])
def test_backup_ssh_service_key_fingerprints(host, key_algorithm):
    """
    Tests fingerprints of backup SSH server in order to ensure correct keys are
    in use.
    """

    # 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://")

    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_algorithm, remote_ip))
    assert login_attempt.rc == 1
    assert "This service allows sftp connections only." in login_attempt.stdout