import os import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-*') def test_installed_software(host): """ Tests if the required packages have been installed. """ assert host.package('duplicity').is_installed assert host.package('duply').is_installed def test_backup_directory(host): """ Tests if the backup directory has been set-up correctly. """ with host.sudo(): backup_directory = host.file('/srv/backups') assert backup_directory.is_directory assert backup_directory.user == 'root' assert backup_directory.group == 'root' assert backup_directory.mode == 0o751 def test_regular_ssh_server_configuration(host): """ Tests if the default SSH server has been configured correctly (to prevent access to it via backup users). """ with host.sudo(): assert "DenyGroups backup" in host.file('/etc/ssh/sshd_config').content_string def test_backup_ssh_server_configuration_directory(host): """ Tests if the backup SSH server configuration directory has been created correctly. """ with host.sudo(): backup_ssh_server_directory = host.file('/etc/ssh-backup') assert backup_ssh_server_directory.is_directory assert backup_ssh_server_directory.user == 'root' assert backup_ssh_server_directory.group == 'root' assert backup_ssh_server_directory.mode == 0o700 def test_backup_ssh_server_service_configuration(host): """ Tests if the backup SSH server service configuration file has been set-up correctly. """ config_file = host.file('/etc/default/ssh-backup') assert config_file.is_file assert config_file.user == 'root' assert config_file.group == 'root' assert config_file.mode == 0o644 assert 'SSHD_OPTS="-f /etc/ssh-backup/sshd_config"' in config_file.content_string def test_backup_ssh_server_configuration(host): """ Tests if the backup SSH server configuration file has been set-up correctly. """ with host.sudo(): config_file = host.file('/etc/ssh-backup/sshd_config') assert config_file.is_file assert config_file.user == 'root' assert config_file.group == 'root' assert config_file.mode == 0o600 assert "AllowGroups backup" in config_file.content_string assert "ChrootDirectory %h" in config_file.content_string assert "ForceCommand internal-sftp" in config_file.content_string assert "Subsystem sftp internal-sftp" in config_file.content_string assert "PasswordAuthentication no" in config_file.content_string assert "PubkeyAuthentication yes" in config_file.content_string assert "PermitRootLogin no" in config_file.content_string assert "HostKey /etc/ssh-backup/ssh_host_rsa_key" in config_file.content_string assert "HostKey /etc/ssh-backup/ssh_host_ecdsa_key" in config_file.content_string assert "HostKey /etc/ssh-backup/ssh_host_ed25519_key" in config_file.content_string def test_backup_ssh_server_keys(host): """ Tests if the backup SSH server private keys have been deployed correctly. """ with host.sudo(): rsa = host.file('/etc/ssh-backup/ssh_host_rsa_key') assert rsa.is_file assert rsa.user == 'root' assert rsa.group == 'root' assert rsa.mode == 0o600 assert rsa.content_string == open('tests/data/ssh/server_rsa', 'r').read() ed25519 = host.file('/etc/ssh-backup/ssh_host_ed25519_key') assert ed25519.is_file assert ed25519.user == 'root' assert ed25519.group == 'root' assert ed25519.mode == 0o600 assert ed25519.content_string == open('tests/data/ssh/server_ed25519', 'r').read() ecdsa = host.file('/etc/ssh-backup/ssh_host_ecdsa_key') assert ecdsa.is_file assert ecdsa.user == 'root' assert ecdsa.group == 'root' assert ecdsa.mode == 0o600 assert ecdsa.content_string == open('tests/data/ssh/server_ecdsa', 'r').read() def test_backup_ssh_server_systemd_service(host): """ Tests if the backup SSH server systemd service file has been deployed correctly. """ service_file = host.file('/etc/systemd/system/ssh-backup.service') assert service_file.is_file assert service_file.user == 'root' assert service_file.group == 'root' assert service_file.mode == 0o644 assert "EnvironmentFile=-/etc/default/ssh-backup" in service_file.content_string def test_backup_ssh_server_service(host): """ Tests if the backup SSH server service is running and listening on correct port. """ with host.sudo(): service = host.service('ssh-backup') assert service.is_running assert service.is_enabled assert host.socket('tcp://0.0.0.0:2222').is_listening def test_backup_ssh_server_login_mechanisms(host): """ Tests available SSH login mechanisms (should be just public key). """ # Try to login with no preferred authentication types to the # server. # @TODO: The /bin/false is used because the ssh command listed # below will return error code 255. On the other hand, # Testinfra itself treats exit code 255 as special case for # detecting when the ssh connection to managed machine # fails. It might be a good idea to try to reach out to # Testinfra maintainer about this or update this test to # use Paramiko in some way. login_attempt = host.run("ssh -v -o PreferredAuthentications=none -o NoHostAuthenticationForLocalhost=yes localhost || /bin/false") assert login_attempt.rc == 1 assert "debug1: Authentications that can continue: publickey" in login_attempt.stderr.split("\r\n")