diff --git a/SOURCES/ci-Fix-home-permissions-modified-by-ssh-module-SC-338-9.patch b/SOURCES/ci-Fix-home-permissions-modified-by-ssh-module-SC-338-9.patch new file mode 100644 index 0000000..4e0aeff --- /dev/null +++ b/SOURCES/ci-Fix-home-permissions-modified-by-ssh-module-SC-338-9.patch @@ -0,0 +1,262 @@ +From 5bfe2ee2b063d87e6fd255d6c5e63123aa3f6de0 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Sat, 21 Aug 2021 13:55:53 +0200 +Subject: [PATCH] Fix home permissions modified by ssh module (SC-338) (#984) + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 9: Fix home permissions modified by ssh module +RH-Commit: [1/1] ab55db88aa1bf2f77acaca5e76ffabbab72b1fb2 (eesposit/cloud-init-centos-) +RH-Bugzilla: 1995843 +RH-Acked-by: Mohamed Gamal Morsy +RH-Acked-by: Eduardo Otubo + +TESTED: By me and QA +BREW: 39178085 + +Fix home permissions modified by ssh module (SC-338) (#984) + +commit 7d3f5d750f6111c2716143364ea33486df67c927 +Author: James Falcon +Date: Fri Aug 20 17:09:49 2021 -0500 + + Fix home permissions modified by ssh module (SC-338) (#984) + + Fix home permissions modified by ssh module + + In #956, we updated the file and directory permissions for keys not in + the user's home directory. We also unintentionally modified the + permissions within the home directory as well. These should not change, + and this commit changes that back. + + LP: #1940233 + +Signed-off-by: Emanuele Giuseppe Esposito +--- + cloudinit/ssh_util.py | 35 ++++- + .../modules/test_ssh_keysfile.py | 132 +++++++++++++++--- + 2 files changed, 146 insertions(+), 21 deletions(-) + +diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py +index b8a3c8f7..9ccadf09 100644 +--- a/cloudinit/ssh_util.py ++++ b/cloudinit/ssh_util.py +@@ -321,23 +321,48 @@ def check_create_path(username, filename, strictmodes): + home_folder = os.path.dirname(user_pwent.pw_dir) + for directory in directories: + parent_folder += "/" + directory +- if home_folder.startswith(parent_folder): ++ ++ # security check, disallow symlinks in the AuthorizedKeysFile path. ++ if os.path.islink(parent_folder): ++ LOG.debug( ++ "Invalid directory. Symlink exists in path: %s", ++ parent_folder) ++ return False ++ ++ if os.path.isfile(parent_folder): ++ LOG.debug( ++ "Invalid directory. File exists in path: %s", ++ parent_folder) ++ return False ++ ++ if (home_folder.startswith(parent_folder) or ++ parent_folder == user_pwent.pw_dir): + continue + +- if not os.path.isdir(parent_folder): ++ if not os.path.exists(parent_folder): + # directory does not exist, and permission so far are good: + # create the directory, and make it accessible by everyone + # but owned by root, as it might be used by many users. + with util.SeLinuxGuard(parent_folder): +- os.makedirs(parent_folder, mode=0o755, exist_ok=True) +- util.chownbyid(parent_folder, root_pwent.pw_uid, +- root_pwent.pw_gid) ++ mode = 0o755 ++ uid = root_pwent.pw_uid ++ gid = root_pwent.pw_gid ++ if parent_folder.startswith(user_pwent.pw_dir): ++ mode = 0o700 ++ uid = user_pwent.pw_uid ++ gid = user_pwent.pw_gid ++ os.makedirs(parent_folder, mode=mode, exist_ok=True) ++ util.chownbyid(parent_folder, uid, gid) + + permissions = check_permissions(username, parent_folder, + filename, False, strictmodes) + if not permissions: + return False + ++ if os.path.islink(filename) or os.path.isdir(filename): ++ LOG.debug("%s is not a file!", filename) ++ return False ++ + # check the file + if not os.path.exists(filename): + # if file does not exist: we need to create it, since the +diff --git a/tests/integration_tests/modules/test_ssh_keysfile.py b/tests/integration_tests/modules/test_ssh_keysfile.py +index f82d7649..3159feb9 100644 +--- a/tests/integration_tests/modules/test_ssh_keysfile.py ++++ b/tests/integration_tests/modules/test_ssh_keysfile.py +@@ -10,10 +10,10 @@ 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 = """\ ++_USERDATA = """\ + #cloud-config + bootcmd: +- - sed -i 's;#AuthorizedKeysFile.*;AuthorizedKeysFile /etc/ssh/authorized_keys %h/.ssh/authorized_keys2;' /etc/ssh/sshd_config ++ - {bootcmd} + ssh_authorized_keys: + - {default} + users: +@@ -24,27 +24,17 @@ users: + - name: test_user2 + ssh_authorized_keys: + - {user2} +-""".format( # noqa: E501 ++""".format( ++ bootcmd='{bootcmd}', + 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), +- ] +- ++def common_verify(client, expected_keys): + for user, filename, keys in expected_keys: ++ # Ensure key is in the key file + contents = client.read_from_file(filename) + if user in ['ubuntu', 'root']: + # Our personal public key gets added by pycloudlib +@@ -83,3 +73,113 @@ def test_authorized_keys(client: IntegrationInstance): + look_for_keys=False, + allow_agent=False, + ) ++ ++ # Ensure we haven't messed with any /home permissions ++ # See LP: #1940233 ++ home_dir = '/home/{}'.format(user) ++ home_perms = '755' ++ if user == 'root': ++ home_dir = '/root' ++ home_perms = '700' ++ assert '{} {}'.format(user, home_perms) == client.execute( ++ 'stat -c "%U %a" {}'.format(home_dir) ++ ) ++ if client.execute("test -d {}/.ssh".format(home_dir)).ok: ++ assert '{} 700'.format(user) == client.execute( ++ 'stat -c "%U %a" {}/.ssh'.format(home_dir) ++ ) ++ assert '{} 600'.format(user) == client.execute( ++ 'stat -c "%U %a" {}'.format(filename) ++ ) ++ ++ # Also ensure ssh-keygen works as expected ++ client.execute('mkdir {}/.ssh'.format(home_dir)) ++ assert client.execute( ++ "ssh-keygen -b 2048 -t rsa -f {}/.ssh/id_rsa -q -N ''".format( ++ home_dir) ++ ).ok ++ assert client.execute('test -f {}/.ssh/id_rsa'.format(home_dir)) ++ assert client.execute('test -f {}/.ssh/id_rsa.pub'.format(home_dir)) ++ ++ assert 'root 755' == client.execute('stat -c "%U %a" /home') ++ ++ ++DEFAULT_KEYS_USERDATA = _USERDATA.format(bootcmd='""') ++ ++ ++@pytest.mark.ubuntu ++@pytest.mark.user_data(DEFAULT_KEYS_USERDATA) ++def test_authorized_keys_default(client: IntegrationInstance): ++ expected_keys = [ ++ ('test_user1', '/home/test_user1/.ssh/authorized_keys', ++ TEST_USER1_KEYS), ++ ('test_user2', '/home/test_user2/.ssh/authorized_keys', ++ TEST_USER2_KEYS), ++ ('ubuntu', '/home/ubuntu/.ssh/authorized_keys', ++ TEST_DEFAULT_KEYS), ++ ('root', '/root/.ssh/authorized_keys', TEST_DEFAULT_KEYS), ++ ] ++ common_verify(client, expected_keys) ++ ++ ++AUTHORIZED_KEYS2_USERDATA = _USERDATA.format(bootcmd=( ++ "sed -i 's;#AuthorizedKeysFile.*;AuthorizedKeysFile " ++ "/etc/ssh/authorized_keys %h/.ssh/authorized_keys2;' " ++ "/etc/ssh/sshd_config")) ++ ++ ++@pytest.mark.ubuntu ++@pytest.mark.user_data(AUTHORIZED_KEYS2_USERDATA) ++def test_authorized_keys2(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), ++ ] ++ common_verify(client, expected_keys) ++ ++ ++NESTED_KEYS_USERDATA = _USERDATA.format(bootcmd=( ++ "sed -i 's;#AuthorizedKeysFile.*;AuthorizedKeysFile " ++ "/etc/ssh/authorized_keys %h/foo/bar/ssh/keys;' " ++ "/etc/ssh/sshd_config")) ++ ++ ++@pytest.mark.ubuntu ++@pytest.mark.user_data(NESTED_KEYS_USERDATA) ++def test_nested_keys(client: IntegrationInstance): ++ expected_keys = [ ++ ('test_user1', '/home/test_user1/foo/bar/ssh/keys', ++ TEST_USER1_KEYS), ++ ('test_user2', '/home/test_user2/foo/bar/ssh/keys', ++ TEST_USER2_KEYS), ++ ('ubuntu', '/home/ubuntu/foo/bar/ssh/keys', ++ TEST_DEFAULT_KEYS), ++ ('root', '/root/foo/bar/ssh/keys', TEST_DEFAULT_KEYS), ++ ] ++ common_verify(client, expected_keys) ++ ++ ++EXTERNAL_KEYS_USERDATA = _USERDATA.format(bootcmd=( ++ "sed -i 's;#AuthorizedKeysFile.*;AuthorizedKeysFile " ++ "/etc/ssh/authorized_keys /etc/ssh/authorized_keys/%u/keys;' " ++ "/etc/ssh/sshd_config")) ++ ++ ++@pytest.mark.ubuntu ++@pytest.mark.user_data(EXTERNAL_KEYS_USERDATA) ++def test_external_keys(client: IntegrationInstance): ++ expected_keys = [ ++ ('test_user1', '/etc/ssh/authorized_keys/test_user1/keys', ++ TEST_USER1_KEYS), ++ ('test_user2', '/etc/ssh/authorized_keys/test_user2/keys', ++ TEST_USER2_KEYS), ++ ('ubuntu', '/etc/ssh/authorized_keys/ubuntu/keys', ++ TEST_DEFAULT_KEYS), ++ ('root', '/etc/ssh/authorized_keys/root/keys', TEST_DEFAULT_KEYS), ++ ] ++ common_verify(client, expected_keys) +-- +2.27.0 + diff --git a/SOURCES/ci-Inhibit-sshd-keygen-.service-if-cloud-init-is-active.patch b/SOURCES/ci-Inhibit-sshd-keygen-.service-if-cloud-init-is-active.patch new file mode 100644 index 0000000..7535bda --- /dev/null +++ b/SOURCES/ci-Inhibit-sshd-keygen-.service-if-cloud-init-is-active.patch @@ -0,0 +1,104 @@ +From e6412be62079bbec5d67d178711ea42f21cafab8 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Tue, 12 Oct 2021 16:35:00 +0200 +Subject: [PATCH 1/2] Inhibit sshd-keygen@.service if cloud-init is active + (#1028) + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 11: Add drop-in to prevent race with sshd-keygen service +RH-Commit: [1/2] 77ba3f167e71c43847aa5b38e1833d84568ed5a7 (eesposit/cloud-init-centos-) +RH-Bugzilla: 2002492 +RH-Acked-by: Eduardo Otubo +RH-Acked-by: Mohamed Gamal Morsy + +TESTED: by me and QA +BREW: 40286693 + +commit 02c71f097bca455a0f87d3e0a2af4d04b1cbd727 +Author: Ryan Harper +Date: Tue Oct 12 09:31:36 2021 -0500 + + Inhibit sshd-keygen@.service if cloud-init is active (#1028) + + In some cloud-init enabled images the sshd-keygen@.service + may race with cloud-init and prevent ssh host keys from being + generated or generating host keys twice slowing boot and consuming + additional entropy during boot. This drop-in unit adds a condition to + the sshd-keygen@.service which prevents running if cloud-init is active. + +Signed-off-by: Emanuele Giuseppe Esposito + +Conflicts: minor conflict in setup.py (line 253), where we still use +"/usr/lib/" instead of LIB +--- + packages/redhat/cloud-init.spec.in | 1 + + packages/suse/cloud-init.spec.in | 1 + + setup.py | 5 ++++- + systemd/disable-sshd-keygen-if-cloud-init-active.conf | 8 ++++++++ + 4 files changed, 14 insertions(+), 1 deletion(-) + create mode 100644 systemd/disable-sshd-keygen-if-cloud-init-active.conf + +diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in +index 16138012..1491822b 100644 +--- a/packages/redhat/cloud-init.spec.in ++++ b/packages/redhat/cloud-init.spec.in +@@ -175,6 +175,7 @@ fi + + %if "%{init_system}" == "systemd" + /usr/lib/systemd/system-generators/cloud-init-generator ++%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf + %{_unitdir}/cloud-* + %else + %attr(0755, root, root) %{_initddir}/cloud-config +diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in +index 004b875f..da8107b4 100644 +--- a/packages/suse/cloud-init.spec.in ++++ b/packages/suse/cloud-init.spec.in +@@ -126,6 +126,7 @@ version_pys=$(cd "%{buildroot}" && find . -name version.py -type f) + + %{_sysconfdir}/dhcp/dhclient-exit-hooks.d/hook-dhclient + %{_sysconfdir}/NetworkManager/dispatcher.d/hook-network-manager ++%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf + + # Python code is here... + %{python_sitelib}/* +diff --git a/setup.py b/setup.py +index d5cd01a4..ec03fa27 100755 +--- a/setup.py ++++ b/setup.py +@@ -38,6 +38,7 @@ def is_generator(p): + def pkg_config_read(library, var): + fallbacks = { + 'systemd': { ++ 'systemdsystemconfdir': '/etc/systemd/system', + 'systemdsystemunitdir': '/lib/systemd/system', + 'systemdsystemgeneratordir': '/lib/systemd/system-generators', + } +@@ -249,7 +250,9 @@ if not platform.system().endswith('BSD'): + data_files.extend([ + (ETC + '/NetworkManager/dispatcher.d/', + ['tools/hook-network-manager']), +- ('/usr/lib/udev/rules.d', [f for f in glob('udev/*.rules')]) ++ ('/usr/lib/udev/rules.d', [f for f in glob('udev/*.rules')]), ++ (ETC + '/systemd/system/sshd-keygen@.service.d/', ++ ['systemd/disable-sshd-keygen-if-cloud-init-active.conf']), + ]) + # Use a subclass for install that handles + # adding on the right init system configuration files +diff --git a/systemd/disable-sshd-keygen-if-cloud-init-active.conf b/systemd/disable-sshd-keygen-if-cloud-init-active.conf +new file mode 100644 +index 00000000..71e35876 +--- /dev/null ++++ b/systemd/disable-sshd-keygen-if-cloud-init-active.conf +@@ -0,0 +1,8 @@ ++# In some cloud-init enabled images the sshd-keygen template service may race ++# with cloud-init during boot causing issues with host key generation. This ++# drop-in config adds a condition to sshd-keygen@.service if it exists and ++# prevents the sshd-keygen units from running *if* cloud-init is going to run. ++# ++[Unit] ++ConditionPathExists=!/run/systemd/generator.early/multi-user.target.wants/cloud-init.target ++EOF +-- +2.27.0 + diff --git a/SOURCES/ci-cc_ssh.py-fix-private-key-group-owner-and-permission.patch b/SOURCES/ci-cc_ssh.py-fix-private-key-group-owner-and-permission.patch new file mode 100644 index 0000000..35884b0 --- /dev/null +++ b/SOURCES/ci-cc_ssh.py-fix-private-key-group-owner-and-permission.patch @@ -0,0 +1,97 @@ +From 2a6b3b5afb20a7856ad81b3ec3da621571c3bec3 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Wed, 20 Oct 2021 10:41:36 +0200 +Subject: [PATCH] cc_ssh.py: fix private key group owner and permissions + (#1070) + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 12: cc_ssh.py: fix private key group owner and permissions (#1070) +RH-Commit: [1/1] b2dc9cfd18ac0a8e1e22a37b1585d22dbde11536 (eesposit/cloud-init-centos-) +RH-Bugzilla: 2015974 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Mohamed Gamal Morsy + +commit ee296ced9c0a61b1484d850b807c601bcd670ec1 +Author: Emanuele Giuseppe Esposito +Date: Tue Oct 19 21:32:10 2021 +0200 + + cc_ssh.py: fix private key group owner and permissions (#1070) + + When default host keys are created by sshd-keygen (/etc/ssh/ssh_host_*_key) + in RHEL/CentOS/Fedora, openssh it performs the following: + + // create new keys + if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then + exit 1 + fi + + // sanitize permissions + /usr/bin/chgrp ssh_keys $KEY + /usr/bin/chmod 640 $KEY + /usr/bin/chmod 644 $KEY.pub + Note that the group ssh_keys exists only in RHEL/CentOS/Fedora. + + Now that we disable sshd-keygen to allow only cloud-init to create + them, we miss the "sanitize permissions" part, where we set the group + owner as ssh_keys and the private key mode to 640. + + According to https://bugzilla.redhat.com/show_bug.cgi?id=2013644#c8, failing + to set group ownership and permissions like openssh does makes the RHEL openscap + tool generate an error. + + Signed-off-by: Emanuele Giuseppe Esposito eesposit@redhat.com + + RHBZ: 2013644 + +Signed-off-by: Emanuele Giuseppe Esposito +--- + cloudinit/config/cc_ssh.py | 7 +++++++ + cloudinit/util.py | 14 ++++++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/cloudinit/config/cc_ssh.py b/cloudinit/config/cc_ssh.py +index 05a16dbc..4e986c55 100755 +--- a/cloudinit/config/cc_ssh.py ++++ b/cloudinit/config/cc_ssh.py +@@ -240,6 +240,13 @@ def handle(_name, cfg, cloud, log, _args): + try: + out, err = subp.subp(cmd, capture=True, env=lang_c) + sys.stdout.write(util.decode_binary(out)) ++ ++ gid = util.get_group_id("ssh_keys") ++ if gid != -1: ++ # perform same "sanitize permissions" as sshd-keygen ++ os.chown(keyfile, -1, gid) ++ os.chmod(keyfile, 0o640) ++ os.chmod(keyfile + ".pub", 0o644) + except subp.ProcessExecutionError as e: + err = util.decode_binary(e.stderr).lower() + if (e.exit_code == 1 and +diff --git a/cloudinit/util.py b/cloudinit/util.py +index 343976ad..fe37ae89 100644 +--- a/cloudinit/util.py ++++ b/cloudinit/util.py +@@ -1831,6 +1831,20 @@ def chmod(path, mode): + os.chmod(path, real_mode) + + ++def get_group_id(grp_name: str) -> int: ++ """ ++ Returns the group id of a group name, or -1 if no group exists ++ ++ @param grp_name: the name of the group ++ """ ++ gid = -1 ++ try: ++ gid = grp.getgrnam(grp_name).gr_gid ++ except KeyError: ++ LOG.debug("Group %s is not a valid group name", grp_name) ++ return gid ++ ++ + def get_permissions(path: str) -> int: + """ + Returns the octal permissions of the file/folder pointed by the path, +-- +2.27.0 + diff --git a/SOURCES/ci-remove-unnecessary-EOF-string-in-disable-sshd-keygen.patch b/SOURCES/ci-remove-unnecessary-EOF-string-in-disable-sshd-keygen.patch new file mode 100644 index 0000000..7ee219d --- /dev/null +++ b/SOURCES/ci-remove-unnecessary-EOF-string-in-disable-sshd-keygen.patch @@ -0,0 +1,45 @@ +From ec9c280ad24900ad078a0f371fa8b4f5f407ee90 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Tue, 26 Oct 2021 21:52:45 +0200 +Subject: [PATCH] remove unnecessary EOF string in + disable-sshd-keygen-if-cloud-init-active.conf (#1075) + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 13: remove unnecessary EOF string in disable-sshd-keygen-if-cloud-init-active.conf (#1075) +RH-Commit: [1/1] 4c01a4bb86a73df3212bb4cf0388b2df707eddc4 (eesposit/cloud-init-centos-) +RH-Bugzilla: 2016305 +RH-Acked-by: Eduardo Otubo +RH-Acked-by: Mohamed Gamal Morsy + +commit a8380a125d40ff0ae88f2ba25a518346f2063a1a +Author: Emanuele Giuseppe Esposito +Date: Tue Oct 26 16:15:47 2021 +0200 + + remove unnecessary EOF string in disable-sshd-keygen-if-cloud-init-active.conf (#1075) + + Running 'systemd-analyze verify cloud-init-local.service' + triggers the following warning: + + disable-sshhd-keygen-if-cloud-init-active.conf:8: Missing '=', ignoring line. + + The string "EOF" is probably a typo, so remove it. + + Signed-off-by: Emanuele Giuseppe Esposito + +Signed-off-by: Emanuele Giuseppe Esposito +--- + systemd/disable-sshd-keygen-if-cloud-init-active.conf | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/systemd/disable-sshd-keygen-if-cloud-init-active.conf b/systemd/disable-sshd-keygen-if-cloud-init-active.conf +index 71e35876..1a5d7a5a 100644 +--- a/systemd/disable-sshd-keygen-if-cloud-init-active.conf ++++ b/systemd/disable-sshd-keygen-if-cloud-init-active.conf +@@ -5,4 +5,3 @@ + # + [Unit] + ConditionPathExists=!/run/systemd/generator.early/multi-user.target.wants/cloud-init.target +-EOF +-- +2.27.0 + diff --git a/SOURCES/ci-ssh_utils.py-ignore-when-sshd_config-options-are-not.patch b/SOURCES/ci-ssh_utils.py-ignore-when-sshd_config-options-are-not.patch new file mode 100644 index 0000000..1fe2bc1 --- /dev/null +++ b/SOURCES/ci-ssh_utils.py-ignore-when-sshd_config-options-are-not.patch @@ -0,0 +1,86 @@ +From ce346f6057377c7bb9b89703fb8855ccf4947a61 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Wed, 8 Sep 2021 16:08:12 +0200 +Subject: [PATCH] ssh_utils.py: ignore when sshd_config options are not + key/value pairs + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 10: ssh_utils.py: ignore when sshd_config options are not key/value pairs +RH-Commit: [1/1] 546081571e8b6b1415aae1a04660137070532fae (eesposit/cloud-init-centos-) +RH-Bugzilla: 2002302 +RH-Acked-by: Eduardo Otubo +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Mohamed Gamal Morsy + +TESTED: by me +BREW: 39622506 + +commit 2ce857248162957a785af61c135ca8433fdbbcde +Author: Emanuele Giuseppe Esposito +Date: Wed Sep 8 02:08:36 2021 +0200 + + ssh_utils.py: ignore when sshd_config options are not key/value pairs (#1007) + + As specified in #LP 1845552, + In cloudinit/ssh_util.py, in parse_ssh_config_lines(), we attempt to + parse each line of sshd_config. This function expects each line to + be one of the following forms: + + \# comment + key value + key=value + + However, options like DenyGroups and DenyUsers are specified to + *optionally* accepts values in sshd_config. + Cloud-init should comply to this and skip the option if a value + is not provided. + + Signed-off-by: Emanuele Giuseppe Esposito + +Signed-off-by: Emanuele Giuseppe Esposito +--- + cloudinit/ssh_util.py | 8 +++++++- + tests/unittests/test_sshutil.py | 8 ++++++++ + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py +index 9ccadf09..33679dcc 100644 +--- a/cloudinit/ssh_util.py ++++ b/cloudinit/ssh_util.py +@@ -484,7 +484,13 @@ def parse_ssh_config_lines(lines): + try: + key, val = line.split(None, 1) + except ValueError: +- key, val = line.split('=', 1) ++ try: ++ key, val = line.split('=', 1) ++ except ValueError: ++ LOG.debug( ++ "sshd_config: option \"%s\" has no key/value pair," ++ " skipping it", line) ++ continue + ret.append(SshdConfigLine(line, key, val)) + return ret + +diff --git a/tests/unittests/test_sshutil.py b/tests/unittests/test_sshutil.py +index a66788bf..08e20050 100644 +--- a/tests/unittests/test_sshutil.py ++++ b/tests/unittests/test_sshutil.py +@@ -525,6 +525,14 @@ class TestUpdateSshConfigLines(test_helpers.CiTestCase): + self.assertEqual([self.pwauth], result) + self.check_line(lines[-1], self.pwauth, "no") + ++ def test_option_without_value(self): ++ """Implementation only accepts key-value pairs.""" ++ extended_exlines = self.exlines.copy() ++ denyusers_opt = "DenyUsers" ++ extended_exlines.append(denyusers_opt) ++ lines = ssh_util.parse_ssh_config_lines(list(extended_exlines)) ++ self.assertNotIn(denyusers_opt, str(lines)) ++ + def test_single_option_updated(self): + """A single update should have change made and line updated.""" + opt, val = ("UsePAM", "no") +-- +2.27.0 + diff --git a/SPECS/cloud-init.spec b/SPECS/cloud-init.spec index fd76b0e..01deac3 100644 --- a/SPECS/cloud-init.spec +++ b/SPECS/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init Version: 21.1 -Release: 7%{?dist} +Release: 12%{?dist} Summary: Cloud instance init scripts License: ASL 2.0 or GPLv3 URL: http://launchpad.net/cloud-init @@ -20,6 +20,16 @@ Patch6: ci-write-passwords-only-to-serial-console-lock-down-clo.patch Patch7: ci-ssh-util-allow-cloudinit-to-merge-all-ssh-keys-into-.patch # For bz#1979099 - [cloud-init]Customize ssh AuthorizedKeysFile causes login failure[RHEL-9.0] Patch8: ci-Stop-copying-ssh-system-keys-and-check-folder-permis.patch +# For bz#1995843 - [cloudinit] Fix home permissions modified by ssh module +Patch9: ci-Fix-home-permissions-modified-by-ssh-module-SC-338-9.patch +# For bz#2002302 - cloud-init fails with ValueError: need more than 1 value to unpack[rhel-9] +Patch10: ci-ssh_utils.py-ignore-when-sshd_config-options-are-not.patch +# For bz#2002492 - util.py[WARNING]: Failed generating key type rsa to file /etc/ssh/ssh_host_rsa_key +Patch11: ci-Inhibit-sshd-keygen-.service-if-cloud-init-is-active.patch +# For bz#2015974 - cloud-init fails to set host key permissions correctly +Patch12: ci-cc_ssh.py-fix-private-key-group-owner-and-permission.patch +# For bz#2016305 - disable-sshd-keygen-if-cloud-init-active.conf:8: Missing '=', ignoring line +Patch13: ci-remove-unnecessary-EOF-string-in-disable-sshd-keygen.patch # Source-git patches @@ -211,12 +221,38 @@ fi %{_bindir}/cloud-id %{_libexecdir}/%{name}/ds-identify %{_systemdgeneratordir}/cloud-init-generator - +%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf %dir %{_sysconfdir}/rsyslog.d %config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf %changelog +* Mon Nov 01 2021 Miroslav Rezanina - 21.1-12 +- ci-remove-unnecessary-EOF-string-in-disable-sshd-keygen.patch [bz#2016305] +- Resolves: bz#2016305 + (disable-sshd-keygen-if-cloud-init-active.conf:8: Missing '=', ignoring line) + +* Tue Oct 26 2021 Miroslav Rezanina - 21.1-11 +- ci-cc_ssh.py-fix-private-key-group-owner-and-permission.patch [bz#2015974] +- Resolves: bz#2015974 + (cloud-init fails to set host key permissions correctly) + +* Mon Oct 18 2021 Miroslav Rezanina - 21.1-10 +- ci-Inhibit-sshd-keygen-.service-if-cloud-init-is-active.patch [bz#2002492] +- ci-add-the-drop-in-also-in-the-files-section-of-cloud-i.patch [bz#2002492] +- Resolves: bz#2002492 + (util.py[WARNING]: Failed generating key type rsa to file /etc/ssh/ssh_host_rsa_key) + +* Fri Sep 10 2021 Miroslav Rezanina - 21.1-9 +- ci-ssh_utils.py-ignore-when-sshd_config-options-are-not.patch [bz#2002302] +- Resolves: bz#2002302 + (cloud-init fails with ValueError: need more than 1 value to unpack[rhel-9]) + +* Fri Sep 03 2021 Miroslav Rezanina - 21.1-8 +- ci-Fix-home-permissions-modified-by-ssh-module-SC-338-9.patch [bz#1995843] +- Resolves: bz#1995843 + ([cloudinit] Fix home permissions modified by ssh module) + * Mon Aug 16 2021 Miroslav Rezanina - 21.1-7 - ci-Stop-copying-ssh-system-keys-and-check-folder-permis.patch [bz#1979099] - ci-Report-full-specific-version-with-cloud-init-version.patch [bz#1971002]