Clean up admin ssh rotate scripts

This commit is contained in:
Clemens Schwaighofer
2024-08-30 09:46:59 +09:00
parent 043a16f397
commit 07108e5764
5 changed files with 82 additions and 58 deletions

View File

@@ -7,31 +7,27 @@ BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
# config folder
CONFIG_BASE="${BASE_FOLDER}../config/";
# previous public key
SSH_PUBLIC_KEYS_PREVIOUS="${BASE_FOLDER}../ssh-public-keys/previous/";
SSH_PUBLIC_KEYS_PREVIOUS="${BASE_FOLDER}../ssh-public-keys/admin-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;
GO=0;
HOST_ONLY="";
USER_ONLY="";
#
while getopts ":h:u:nfg" opt; do
while getopts ":h:u:ng" opt; do
case "${opt}" in
h|hostname)
h) # hostname
HOST_ONLY="${OPTARG}";
;;
u|username)
u) # username
USER_ONLY="${OPTARG}";
;;
n|dry-run)
n) # dry-run
DRY_RUN=1;
;;
f|force)
FORCE=1;
;;
g|go)
g) # go
GO=1;
;;
\?)
@@ -53,9 +49,20 @@ if [ ! -d "${SSH_PUBLIC_KEYS_PREVIOUS}" ]; then
fi
# load config
if [ -f "${CONFIG_BASE}settings.ini" ]; then
source <(grep = "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
if [ ! -f "${CONFIG_BASE}settings.ini" ]; then
echo "Missing 'settings.ini' file in ${CONFIG_BASE}";
exit;
fi
# shellcheck source=../config/settings.ini
source <(grep "=" "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
if [ -z "${key_age}" ]; then
echo "A minimnum key age in days must be set in the settings";
exit;
fi
if [ -z "${server_list}" ]; then
echo "No server list is defined in the settings";
exit;
fi;
# we must have "server_list" set and file must be in config folder
if [ ! -f "${CONFIG_BASE}${server_list}" ]; then
echo "Cannot find ${server_list} file in the config folder";
@@ -113,26 +120,26 @@ uninstall_ssh_key() {
}
# find last public in remote server and remove it
for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
if [[ "${i}" =~ ^\# ]]; then
while read -r line; do
if [[ "${line}" =~ ^\# ]]; 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
if [ -n "${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
if [ -n "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then
continue;
fi
# flags: (not used at the moment)
flags=$(echo "${line}" | cut -d "," -f 3);
# auth key settings (in front of auth key)
settings=$(echo "${line}" | cut -d "," -f 4);
# settings=$(echo "${line}" | cut -d "," -f 4);
# ssh key names
SSH_KEY_PUB_FILE="${hostname}_${username}.pem.pub";
@@ -145,7 +152,7 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
echo "[-] Remove previous key for: ${username}@${hostname} with flags '${flags}'";
# find in master key and $admin user
if [[ ${ADMIN_USERS[@]} =~ $username ]]; then
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
@@ -158,6 +165,6 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
echo "rm \"${SSH_PUBLIC_KEYS_PREVIOUS}${SSH_KEY_PUB_FILE}\";";
fi;
echo "[=] ............... DONE";
done
done <<<"$(sed 1d "${CONFIG_BASE}${server_list}")";
# __END__

View File

@@ -11,8 +11,8 @@ LAST_ROTATE="${BASE_FOLDER}../last-rotate/";
# ssh-keys temp holder
SSH_PRIVATE_KEYS="${BASE_FOLDER}../ssh-keys/";
# ssh public keys from current and last
SSH_PUBLIC_KEYS_PREVIOUS="${BASE_FOLDER}../ssh-public-keys/previous/";
SSH_PUBLIC_KEYS_CURRENT="${BASE_FOLDER}../ssh-public-keys/current/";
SSH_PUBLIC_KEYS_PREVIOUS="${BASE_FOLDER}../ssh-public-keys/admin-previous/";
SSH_PUBLIC_KEYS_CURRENT="${BASE_FOLDER}../ssh-public-keys/admin-current/";
# list of admin user names, if username does not match this only update the user entry
ADMIN_USERS=(admin ubuntu ec2-user)
@@ -23,24 +23,24 @@ GO=0;
HOST_ONLY="";
USER_ONLY="";
#
while getopts ":h:u:nfg" opt; do
while getopts ":h:u:nfcg" opt; do
case "${opt}" in
h|hostname)
h) # hostname
HOST_ONLY="${OPTARG}";
;;
u|username)
u) # username
USER_ONLY="${OPTARG}";
;;
n|dry-run)
n) # dry-run
DRY_RUN=1;
;;
f|force)
f) # force
FORCE=1;
;;
c|force-create)
c) # force-create
FORCE_CREATE=1
;;
g|go)
g) # go
GO=1;
;;
\?)
@@ -71,13 +71,20 @@ if [ ! -d "${SSH_PUBLIC_KEYS_PREVIOUS}" ]; then
fi
# load config
if [ -f "${CONFIG_BASE}settings.ini" ]; then
source <(grep = "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
fi
if [ -z "${key_age}" ]; then
echo "A minimnum key age in days must be set";
if [ ! -f "${CONFIG_BASE}settings.ini" ]; then
echo "Missing 'settings.ini' file in ${CONFIG_BASE}";
exit;
fi
# shellcheck source=../config/settings.ini
source <(grep "=" "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
if [ -z "${key_age}" ]; then
echo "A minimnum key age in days must be set in the settings";
exit;
fi
if [ -z "${server_list}" ]; then
echo "No server list is defined in the settings";
exit;
fi;
# we must have "server_list" set and file must be in config folder
if [ ! -f "${CONFIG_BASE}${server_list}" ]; then
echo "Cannot find ${server_list} file in the config folder";
@@ -141,7 +148,7 @@ add_ssh_key() {
pub_key=$(cat "${PUB_KEY_FILE}");
# if we have auth key settings, prefix them to the pub key
# Note that the check key "pub_key" ignores any prefixes, but we add with settings prefix
if [ ! -z "${AUTH_KEY_SETTINGS}" ]; then
if [ -n "${AUTH_KEY_SETTINGS}" ]; then
pub_key_write="${AUTH_KEY_SETTINGS} ${pub_key}";
else
pub_key_write="${pub_key}";
@@ -182,20 +189,20 @@ install_ssh_key() {
fi
}
for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
if [[ "${i}" =~ ^\# ]]; then
while read -r line; do
if [[ "${line}" =~ ^\# ]]; 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
if [ -n "${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
if [ -n "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then
continue;
fi
# check if force or if last rotaet in valid range
@@ -203,9 +210,9 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
# holds unix timestamp, if now - this timestamp is < key_age => skip
last_rotate=$(cat "${LAST_ROTATE}${hostname}_${username}.last-rotate");
current_timestamp=$(date +%s)
age=$(( ($current_timestamp - $last_rotate) ))
age=$(( current_timestamp - last_rotate ))
days_left=$(( (age)/(3600*24) ))
if [ $days_left -le $key_age ]; then
if [ $days_left -le "$key_age" ]; then
echo "[!] Last rotate for ${username}@${hostname} was ${days_left} days ago, minimum is ${key_age}";
echo "[_] ............... SKIP";
continue;
@@ -285,7 +292,7 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
echo "[~] Deploy current key for: ${username}@${hostname} with flags '${flags}': ${SSH_KEY_PUB_FILE}";
fi
# deploy public key to server
if [[ ${ADMIN_USERS[@]} =~ $username ]]; then
if [[ ${ADMIN_USERS[*]} =~ $username ]]; then
# - master admin file
install_ssh_key "${hostname}" "${username}" "${SSH_PUBLIC_KEYS_CURRENT}${SSH_KEY_PUB_FILE}" "/etc/ssh/authorized_keys--master" "${auth_key_settings}";
fi
@@ -320,11 +327,11 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
fi
# post roate write timestamp into rotate file
if [ ${DRY_RUN} -eq 0 ]; then
echo $(date +%s) > "${LAST_ROTATE}${hostname}_${username}.last-rotate";
"$(date +%s)" > "${LAST_ROTATE}${hostname}_${username}.last-rotate";
else
echo "\"echo $(date +%s) > \"${LAST_ROTATE}${hostname}_${username}.last-rotate\";";
echo "\"$(date +%s) > \"${LAST_ROTATE}${hostname}_${username}.last-rotate\";";
fi
echo "[=] ............... DONE";
done
done <<<"$(sed 1d "${CONFIG_BASE}${server_list}")";
# __END__

View File

@@ -10,12 +10,12 @@ LAST_ROTATE="${BASE_FOLDER}../last-rotate/";
HOST_ONLY="";
USER_ONLY="";
while getopts ":h:u:nfg" opt; do
while getopts ":h:u:" opt; do
case "${opt}" in
h|hostname)
h) # hostname
HOST_ONLY="${OPTARG}";
;;
u|username)
u) # username
USER_ONLY="${OPTARG}";
;;
\?)
@@ -29,9 +29,20 @@ while getopts ":h:u:nfg" opt; do
done
# load config
if [ -f "${CONFIG_BASE}settings.ini" ]; then
source <(grep = "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
if [ ! -f "${CONFIG_BASE}settings.ini" ]; then
echo "Missing 'settings.ini' file in ${CONFIG_BASE}";
exit;
fi
# shellcheck source=../config/settings.ini
source <(grep "=" "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
if [ -z "${key_age}" ]; then
echo "A minimnum key age in days must be set in the settings";
exit;
fi
if [ -z "${server_list}" ]; then
echo "No server list is defined in the settings";
exit;
fi;
# we must have "server_list" set and file must be in config folder
if [ ! -f "${CONFIG_BASE}${server_list}" ]; then
echo "Cannot find ${server_list} file in the config folder";
@@ -50,20 +61,20 @@ TEST_STRING="TEST";
ERROR=0;
WARNING=0;
for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
if [[ "${i}" =~ ^\# ]]; then
while read -r line; do
if [[ "${line}" =~ ^\# ]]; 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
if [ -n "${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
if [ -n "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then
continue;
fi
@@ -81,7 +92,7 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
rotate_date="";
if [ -f "${LAST_ROTATE}${hostname}_${username}.last-rotate" ]; then
# load last rotate timestamp and get YYYY-MM-DD
rotate_date=$(${datecmd} -d @$(cat "${LAST_ROTATE}${hostname}_${username}.last-rotate") +%F);
rotate_date=$(${datecmd} -d @"$(cat "${LAST_ROTATE}${hostname}_${username}.last-rotate")" +%F);
fi
# check for diff in username / hostname
warning_string=""
@@ -90,13 +101,13 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
fi
# check for creation date diff
if [ "${rotate_date}" != "${current_date}" ]; then
if [ ! -z "${warning_string}" ]; then
if [ -n "${warning_string}" ]; then
warning_string="${warning_string}, ";
fi
warning_string="${warning_string}${rotate_date} != ${current_date}";
fi
# print out warning or ok
if [ ! -z "${warning_string}" ]; then
if [ -n "${warning_string}" ]; then
echo "[WARNING] ${warning_string}";
WARNING=1;
else
@@ -107,8 +118,7 @@ for line in `cat "${CONFIG_BASE}${server_list}" | sed 1d`; do
echo "[!] FAILURE: ${response}";
ERROR=1;
fi
done
done <<<"$(sed 1d "${CONFIG_BASE}${server_list}")";
if [ ${WARNING} -eq 1 ]; then
echo "A warning has been found by either username/hostname string in the PEM key not matching to call username/hostname or the rotate date differs to the creation date from the PEM public key";