diff options
author | Emanuele Giuseppe Esposito <eesposit@redhat.com> | 2021-07-12 20:21:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-12 12:21:02 -0600 |
commit | 9b52405c6f0de5e00d5ee9c1d13540425d8f6bf5 (patch) | |
tree | f931bfaa3757d0a1ee83ef88845bc8bd79e4a8ea /tests/integration_tests/modules | |
parent | 108611aee26e09bec683e6cf1b8e03bec9362de9 (diff) | |
download | vyos-cloud-init-9b52405c6f0de5e00d5ee9c1d13540425d8f6bf5.tar.gz vyos-cloud-init-9b52405c6f0de5e00d5ee9c1d13540425d8f6bf5.zip |
ssh-util: allow cloudinit to merge all ssh keys into a custom user file, defined in AuthorizedKeysFile (#937)
This patch aims to fix LP1911680, by analyzing the files provided
in sshd_config and merge all keys into an user-specific file. Also
introduces additional tests to cover this specific case.
The file is picked by analyzing the path given in AuthorizedKeysFile.
If it points inside the current user folder (path is /home/user/*), it
means it is an user-specific file, so we can copy all user-keys there.
If it contains a %u or %h, it means that there will be a specific
authorized_keys file for each user, so we can copy all user-keys there.
If no path points to an user-specific file, for example when only
/etc/ssh/authorized_keys is given, default to ~/.ssh/authorized_keys.
Note that if there are more than a single user-specific file, the last
one will be picked.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Co-authored-by: James Falcon <therealfalcon@gmail.com>
LP: #1911680
RHBZ:1862967
Diffstat (limited to 'tests/integration_tests/modules')
-rw-r--r-- | tests/integration_tests/modules/test_ssh_keysfile.py | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/tests/integration_tests/modules/test_ssh_keysfile.py b/tests/integration_tests/modules/test_ssh_keysfile.py new file mode 100644 index 00000000..f82d7649 --- /dev/null +++ b/tests/integration_tests/modules/test_ssh_keysfile.py @@ -0,0 +1,85 @@ +import paramiko +import pytest +from io import StringIO +from paramiko.ssh_exception import SSHException + +from tests.integration_tests.instances import IntegrationInstance +from tests.integration_tests.util import get_test_rsa_keypair + +TEST_USER1_KEYS = get_test_rsa_keypair('test1') +TEST_USER2_KEYS = get_test_rsa_keypair('test2') +TEST_DEFAULT_KEYS = get_test_rsa_keypair('test3') + +USERDATA = """\ +#cloud-config +bootcmd: + - sed -i 's;#AuthorizedKeysFile.*;AuthorizedKeysFile /etc/ssh/authorized_keys %h/.ssh/authorized_keys2;' /etc/ssh/sshd_config +ssh_authorized_keys: + - {default} +users: +- default +- name: test_user1 + ssh_authorized_keys: + - {user1} +- name: test_user2 + ssh_authorized_keys: + - {user2} +""".format( # noqa: E501 + default=TEST_DEFAULT_KEYS.public_key, + user1=TEST_USER1_KEYS.public_key, + user2=TEST_USER2_KEYS.public_key, +) + + +@pytest.mark.ubuntu +@pytest.mark.user_data(USERDATA) +def test_authorized_keys(client: IntegrationInstance): + expected_keys = [ + ('test_user1', '/home/test_user1/.ssh/authorized_keys2', + TEST_USER1_KEYS), + ('test_user2', '/home/test_user2/.ssh/authorized_keys2', + TEST_USER2_KEYS), + ('ubuntu', '/home/ubuntu/.ssh/authorized_keys2', + TEST_DEFAULT_KEYS), + ('root', '/root/.ssh/authorized_keys2', TEST_DEFAULT_KEYS), + ] + + for user, filename, keys in expected_keys: + contents = client.read_from_file(filename) + if user in ['ubuntu', 'root']: + # Our personal public key gets added by pycloudlib + lines = contents.split('\n') + assert len(lines) == 2 + assert keys.public_key.strip() in contents + else: + assert contents.strip() == keys.public_key.strip() + + # Ensure we can actually connect + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + paramiko_key = paramiko.RSAKey.from_private_key(StringIO( + keys.private_key)) + + # Will fail with AuthenticationException if + # we cannot connect + ssh.connect( + client.instance.ip, + username=user, + pkey=paramiko_key, + look_for_keys=False, + allow_agent=False, + ) + + # Ensure other uses can't connect using our key + other_users = [u[0] for u in expected_keys if u[2] != keys] + for other_user in other_users: + with pytest.raises(SSHException): + print('trying to connect as {} with key from {}'.format( + other_user, user)) + ssh.connect( + client.instance.ip, + username=other_user, + pkey=paramiko_key, + look_for_keys=False, + allow_agent=False, + ) |