#!/usr/bin/env bash # Test connections BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/"; # config folder CONFIG_BASE="${BASE_FOLDER}../config/"; # timestamps of last rotate per user/host LAST_ROTATE="${BASE_FOLDER}../last-rotate/"; HOST_ONLY=""; USER_ONLY=""; while getopts ":h:u:" opt; do case "${opt}" in h) # hostname HOST_ONLY="${OPTARG}"; ;; u) # username USER_ONLY="${OPTARG}"; ;; \?) echo -e "\n Option does not exist: ${OPTARG}\n"; echo "-h override single host name"; echo "-u override user name for a host"; echo "" exit 1; ;; esac done # load config if [ ! -f "${CONFIG_BASE}settings.ini" ]; then echo "Missing 'settings.ini' file in ${CONFIG_BASE}"; exit; fi # shellcheck source=../config/settings.ini # shellcheck disable=SC1094 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"; exit; fi SSH="ssh -a -x -n"; # date command datecmd="date"; if date --version 2>&1 | grep -qi "date: illegal option"; then # if this is macOS date, see if gdate exists and use this one type gdate >/dev/null || error "macOS date does not support -d and no GNU date installed"; datecmd="gdate"; fi TEST_STRING="TEST"; ERROR=0; WARNING=0; 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 [ -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 [ -n "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then continue; fi echo -n "[:] Test connection to: ${username}@${hostname}: "; response=$(${SSH} -S none "${username}"@"${hostname}" echo "${TEST_STRING}"); if [ "${response}" = "${TEST_STRING}" ]; then # get the SSH key with "${username}"@"${hostname}": YYYY-MM-DD to confirm the correct one is set current_ssh_key=$( ${SSH} -S none "${username}"@"${hostname}" grep "${username}@${hostname}: " /etc/ssh/authorized_keys--master | cut -d " " -f 3,4 ); # extract username@hostname and create date current_user_hostname=$(echo "${current_ssh_key}" | cut -d ":" -f 1); current_date=$(echo "${current_ssh_key}" | cut -d ":" -f 2); current_date=${current_date//[[:blank:]]/}; 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); fi # check for diff in username / hostname warning_string="" if [ "${current_user_hostname}" != "${username}@${hostname}" ]; then warning_string="User/Hostname does not match: ${current_user_hostname}"; fi # check for creation date diff if [ "${rotate_date}" != "${current_date}" ]; 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 [ -n "${warning_string}" ]; then echo "[WARNING] ${warning_string}"; WARNING=1; else echo "[OK]"; fi else echo "" echo "[!] FAILURE: ${response}"; ERROR=1; fi 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"; fi if [ ${ERROR} -eq 1 ]; then echo "An error has been found. Some connection did not success, investigate and fix before removing old ssh keys"; fi # __END__