|
# Remove SSH keys from user's configuration (typically ~user/.ssh/authorized_keys)
|
|
#
|
|
# By Alex Tkachenko <alex.sysadm@gmail.com>
|
|
#
|
|
bundle agent rudder_disable_ssh_keys
|
|
{
|
|
vars:
|
|
|
|
any::
|
|
"technique_name" string => "SSH keys removal";
|
|
"component_name" string => "SSH key";
|
|
|
|
"config_basename" string => "&SSH_DISABLE_KEY_CONFIG_BASENAME&";
|
|
|
|
&SSH_DISABLE_KEY_TAG:{tag |"sshkey_disable_tag[&i&]" string => "&tag&";
|
|
}&
|
|
&SSH_DISABLE_KEY_USERNAME:{username |"sshkey_disable_name[&i&]" string => "&username&";
|
|
}&
|
|
&SSH_DISABLE_KEY_KEYSPEC:{keyspec |"sshkey_disable_key[&i&]" string => "&keyspec&";
|
|
}&
|
|
&TRACKINGKEY:{uuid |"sshkey_disable_uuid[&i&]" string => "&uuid&";
|
|
}&
|
|
|
|
"sshkey_disable_index"
|
|
slist => getindices("sshkey_disable_name");
|
|
"sshkey_class_prefix[${sshkey_disable_index}]"
|
|
string => canonify("${sshkey_disable_tag[${sshkey_disable_index}]}_${sshkey_disable_uuid[${sshkey_disable_index}]}");
|
|
"userdata_${sshkey_disable_index}"
|
|
string => execresult("/usr/bin/getent passwd ${sshkey_disable_name[${sshkey_disable_index}]}", "noshell");
|
|
"no_${sshkey_disable_index}"
|
|
int => parsestringarray("userarray_${sshkey_disable_index}", "${userdata_${sshkey_disable_index}}", "", ":", "1000", "200000" );
|
|
"homedir[${sshkey_disable_index}]"
|
|
string => "${userarray_${sshkey_disable_index}[${sshkey_disable_name[${sshkey_disable_index}]}][5]}";
|
|
|
|
classes:
|
|
|
|
any::
|
|
"begin_evaluation"
|
|
expression => isvariable("sshkey_disable_index");
|
|
|
|
begin_evaluation::
|
|
"user_${sshkey_disable_index}_exists"
|
|
expression => userexists("${sshkey_disable_name[${sshkey_disable_index}]}");
|
|
|
|
"cfgfile_${sshkey_disable_index}_exists"
|
|
ifvarclass => canonify("user_${sshkey_disable_index}_exists"),
|
|
expression => fileexists("${homedir[${sshkey_disable_index}]}/.ssh/${config_basename}");
|
|
|
|
|
|
files:
|
|
|
|
"${homedir[${sshkey_disable_index}]}/.ssh/${config_basename}"
|
|
comment => "Remove key from ${config_basename}",
|
|
edit_line => remove_ssh_key("${sshkey_disable_key[${sshkey_disable_index}]}"),
|
|
ifvarclass => "cfgfile_${sshkey_disable_index}_exists",
|
|
classes => rudder_common_classes("${sshkey_class_prefix[${sshkey_disable_index}]}");
|
|
|
|
methods:
|
|
|
|
"No User Exist Report"
|
|
ifvarclass => "!user_${sshkey_disable_index}_exists",
|
|
usebundle => rudder_common_report(
|
|
"${technique_name}", "result_success",
|
|
"${sshkey_disable_uuid[${sshkey_disable_index}]}", "${component_name}", "${sshkey_disable_tag[${sshkey_disable_index}]}", "The user ${sshkey_disable_name[${sshkey_disable_index}]} does NOT exist on this machine...skipping this check"
|
|
);
|
|
"No ${config_basename} File Exist Report"
|
|
ifvarclass => "user_${sshkey_disable_index}_exists.!cfgfile_${sshkey_disable_index}_exists",
|
|
usebundle => rudder_common_report(
|
|
"${technique_name}", "result_success",
|
|
"${sshkey_disable_uuid[${sshkey_disable_index}]}", "${component_name}", "${sshkey_disable_tag[${sshkey_disable_index}]}", "The user ${sshkey_disable_name[${sshkey_disable_index}]} does NOT have ${config_basename} file on this machine...skipping this check"
|
|
);
|
|
|
|
# Removal Key Reports - rudder_common_reports_generic is not used as the messaging is reversed
|
|
"Report key not found"
|
|
usebundle => rudder_common_report(
|
|
"${technique_name}", "result_success", "${sshkey_disable_uuid[${sshkey_disable_index}]}", "${component_name}", "${sshkey_disable_tag[${sshkey_disable_index}]}",
|
|
"SSH key \"${sshkey_disable_tag[${sshkey_disable_index}]}\" was not found in user ${sshkey_disable_name[${sshkey_disable_index}]} ${config_basename} file"),
|
|
ifvarclass => "${sshkey_class_prefix[${sshkey_disable_index}]}_kept.!${sshkey_class_prefix[${sshkey_disable_index}]}_repaired.!${sshkey_class_prefix[${sshkey_disable_index}]}_error";
|
|
|
|
"Report key removed"
|
|
usebundle => rudder_common_report(
|
|
"${technique_name}", "result_repaired", "${sshkey_disable_uuid[${sshkey_disable_index}]}", "${component_name}", "${sshkey_disable_tag[${sshkey_disable_index}]}",
|
|
"SSH key \"${sshkey_disable_tag[${sshkey_disable_index}]}\" for user ${sshkey_disable_name[${sshkey_disable_index}]} was removed"),
|
|
ifvarclass => "${sshkey_class_prefix[${sshkey_disable_index}]}_repaired.!${sshkey_class_prefix[${sshkey_disable_index}]}_error";
|
|
|
|
"Report removal failure"
|
|
usebundle => rudder_common_report(
|
|
"${technique_name}", "result_error", "${sshkey_disable_uuid[${sshkey_disable_index}]}", "${component_name}", "${sshkey_disable_tag[${sshkey_disable_index}]}",
|
|
"SSH key \"${sshkey_disable_tag[${sshkey_disable_index}]}\" for user ${sshkey_disable_name[${sshkey_disable_index}]} could not be removed"),
|
|
ifvarclass => "${sshkey_class_prefix[${sshkey_disable_index}]}_error";
|
|
}
|
|
|
|
# Remove ssh key from the file. The key is matched by the key value
|
|
# (i.e. comments, options in the keyspec are ignored).
|
|
bundle edit_line remove_ssh_key(keyspec)
|
|
{
|
|
vars:
|
|
key_parsed::
|
|
"ckey" string => canonify($(keybits[3]));
|
|
"ekey" string => escape($(keybits[3]));
|
|
|
|
classes:
|
|
"key_parsed"
|
|
# If the key hash happens to exceed 1000 chars $keybits[3] is going to be undefined because
|
|
# of some weird cfengine bugs, probably this one: https://cfengine.com/dev/issues/1258
|
|
# Therefore we limit the regex to extract as much of the hash as possible to make it unique enough
|
|
# without exceeding 1000 charachter limit.
|
|
# The hashes of that length apparently correspond to DSS 2048 bits keys, generated i.e. on rhel 4,
|
|
# with openssh v3.9p1-redhat. I believe that since openssh v4 DSS bitlengh is limited to 1024,
|
|
# as required by FIPS.
|
|
expression => regextract("(.*\s+)?(ssh-rsa|ssh-dss)\s+(\S{1,1000})\S*=(\s+.+)?\Z", "$(keyspec)", "keybits" );
|
|
|
|
delete_lines:
|
|
".*\s$(ekey)\s?.*"
|
|
ifvarclass => "key_parsed";
|
|
}
|