First stage for ssh key rotate and remove scripts
This commit is contained in:
124
bin/remove-old-ssh-keys.sh
Normal file → Executable file
124
bin/remove-old-ssh-keys.sh
Normal file → Executable file
@@ -6,6 +6,44 @@ BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
||||
CONFIG_BASE="${BASE_FOLDER}../config/";
|
||||
# previous public key
|
||||
SSH_PUBLIC_KEYS_PREVIOUS="${BASE_FOLDER}../ssh-public-keys/previous/";
|
||||
# list of admin user names, if username does not match this only update the user entry
|
||||
ADMIN_USERS=(admin ubuntu ec2-user)
|
||||
|
||||
DRY_RUN=0;
|
||||
FORCE=0;
|
||||
HOST_ONLY="";
|
||||
USER_ONLY="";
|
||||
#
|
||||
while getopts ":h:u:nf" opt; do
|
||||
case "${opt}" in
|
||||
h|hostname)
|
||||
HOST_ONLY="${OPTARG}";
|
||||
;;
|
||||
u|username)
|
||||
USER_ONLY="${OPTARG}";
|
||||
;;
|
||||
n|dry-run)
|
||||
DRY_RUN=1;
|
||||
;;
|
||||
f|force)
|
||||
FORCE=1;
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "-h override single host name";
|
||||
echo "-u override user name for a host";
|
||||
echo "-f force key change";
|
||||
echo "-n dry run";
|
||||
echo ""
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -d "${SSH_PUBLIC_KEYS_PREVIOUS}" ]; then
|
||||
echo "Missing ssh public keys previous folder: ${SSH_PUBLIC_KEYS_PREVIOUS}";
|
||||
exit;
|
||||
fi
|
||||
|
||||
# load config
|
||||
if [ -f "${CONFIG_BASE}settings.ini" ]; then
|
||||
@@ -17,13 +55,91 @@ if [ ! -f "${CONFIG_BASE}${server_list}" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
# default ssh command
|
||||
SSH="ssh -a -x";
|
||||
|
||||
remove_ssh_key() {
|
||||
AUTH_KEY_FILE="${1}";
|
||||
PUB_KEY_FILE="${2}";
|
||||
RMV_CHATTR_I="chattr -i"
|
||||
ADD_CHATTR_I="chattr +i"
|
||||
RMV_CHMOD_UW="chmod u-w"
|
||||
ADD_CHMOD_UW="chmod u+w"
|
||||
pub_key=$(cat "${PUB_KEY_FILE}");
|
||||
# we need to escape for sed
|
||||
pub_key_escaped=$(printf '%s\n' "$pub_key" | sed -e 's/[]\/$*.^[]/\\&/g');
|
||||
# the -z `tail ...` checks for a trailing newline. The echo adds one if was missing (from ssh-copy-id)
|
||||
UNINSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
|
||||
if [ -f "${AUTH_KEY_FILE}" ] && grep "${pub_key}" "${AUTH_KEY_FILE}" >> /dev/null; then
|
||||
${RMV_CHATTR_I} "${AUTH_KEY_FILE}";
|
||||
${ADD_CHMOD_UW} "${AUTH_KEY_FILE}";
|
||||
sed -i "/${pub_key_escaped}/d" "${AUTH_KEY_FILE}";
|
||||
${RMV_CHMOD_UW} "${AUTH_KEY_FILE}";
|
||||
${ADD_CHATTR_I} "${AUTH_KEY_FILE}";
|
||||
fi;
|
||||
EOF
|
||||
);
|
||||
# to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
|
||||
printf "exec sudo sh -c '%s'" "${UNINSTALLKEYS_SH}"
|
||||
}
|
||||
|
||||
uninstall_ssh_key() {
|
||||
HOSTNAME="${1}";
|
||||
USERNAME="${2}";
|
||||
PUB_KEY_FILE="${3}";
|
||||
AUTH_KEY_FILE="${4}";
|
||||
echo "[.] Remove from auth file: ${AUTH_KEY_FILE}";
|
||||
if [ ${DRY_RUN} -eq 0 ]; then
|
||||
# find the pub key in the file and remove this line only
|
||||
${SSH} "${USERNAME}"@"${HOSTNAME}" "$(remove_ssh_key "${AUTH_KEY_FILE}" "${PUB_KEY_FILE}")"
|
||||
else
|
||||
echo "${SSH} \"${USERNAME}\"@\"${HOSTNAME}\" \"\$(remove_ssh_key \"${AUTH_KEY_FILE}\" \"${PUB_KEY_FILE}\")\"";
|
||||
fi
|
||||
}
|
||||
|
||||
# find last public in remote server and remove it
|
||||
for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
|
||||
hostname=$(echo "${line}" | cut -d "," -f 1)
|
||||
# flags are current "M" for multi key, has other users public key in too
|
||||
flags=$(echo "${line}" | cut -d "," -f 2)
|
||||
echo "Remove previous key for: ${hostname}";
|
||||
if [[ "${i}" =~ ^\# ]]; then
|
||||
continue;
|
||||
fi
|
||||
# hostname is on pos 1
|
||||
hostname=$(echo "${line}" | cut -d "," -f 1);
|
||||
# if hostname opt set and not matching skip
|
||||
if [ ! -z "${HOST_ONLY}" ] && [ "${HOST_ONLY}" != "${hostname}" ]; then
|
||||
continue;
|
||||
fi
|
||||
# login user name
|
||||
username=$(echo "${line}" | cut -d "," -f 2);
|
||||
# if username opt set and not matching skip
|
||||
if [ ! -z "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then
|
||||
continue;
|
||||
fi
|
||||
# flags: (not used at the moment)
|
||||
flags=$(echo "${line}" | cut -d "," -f 3);
|
||||
# ssh key names
|
||||
SSH_KEY_PUB_FILE="${hostname}_${username}.pem.pub";
|
||||
|
||||
# previous public key does not exist, skip
|
||||
if [ ! -f "${SSH_PUBLIC_KEYS_PREVIOUS}${SSH_KEY_PUB_FILE}" ]; then
|
||||
echo "[!] Missing previous public key file ${SSH_KEY_PUB_FILE} for ${username}@${hostname}";
|
||||
continue;
|
||||
fi
|
||||
|
||||
echo "[-] Remove previous key for: ${username}@${hostname} with flags '${flags}'";
|
||||
# find in master key and $admin user
|
||||
if [[ ${ADMIN_USERS[@]} =~ $username ]]; then
|
||||
# find in "/etc/ssh/authorized_keys--master";
|
||||
uninstall_ssh_key "${hostname}" "${username}" "${SSH_PUBLIC_KEYS_PREVIOUS}${SSH_KEY_PUB_FILE}" "/etc/ssh/authorized_keys--master";
|
||||
fi
|
||||
uninstall_ssh_key "${hostname}" "${username}" "${SSH_PUBLIC_KEYS_PREVIOUS}${SSH_KEY_PUB_FILE}" "/etc/ssh/authorized_keys/${username}"
|
||||
# remove old key
|
||||
echo "[-] Remove previous public key: ${SSH_KEY_PUB_FILE}";
|
||||
if [ ${DRY_RUN} -eq 0 ]; then
|
||||
rm "${SSH_PUBLIC_KEYS_PREVIOUS}${SSH_KEY_PUB_FILE}";
|
||||
else
|
||||
echo "rm \"${SSH_PUBLIC_KEYS_PREVIOUS}${SSH_KEY_PUB_FILE}\";";
|
||||
fi;
|
||||
echo "[=] ............... DONE";
|
||||
done
|
||||
|
||||
# __END__
|
||||
|
||||
Reference in New Issue
Block a user