Compare commits

..

10 Commits

Author SHA1 Message Date
Clemens Schwaighofer
694f04313c Add Account, Region and Instance info for each report
So we can easy match up user reports to other information we collect
2023-12-22 11:54:34 +09:00
Clemens Schwaighofer
50e28c7cfd Check that fallback last access file exists 2023-12-21 16:43:57 +09:00
Clemens Schwaighofer
65b7a6ad43 Fix date check for account created date
Use regex to check instead of empty string.
A comment could be set instead of a date
2023-12-21 16:39:05 +09:00
Clemens Schwaighofer
244461d466 sshforward group typo in lock and unlock users 2023-12-21 16:11:31 +09:00
Clemens Schwaighofer
66213dfd65 Text fixes for check last login 2023-12-21 16:06:53 +09:00
Clemens Schwaighofer
39da44b546 Wrong unlock account var used for unlock users 2023-12-21 16:01:35 +09:00
Clemens Schwaighofer
d4bb06e3e1 Fix lock user flow to only lock if the user is not in the reject group 2023-12-21 15:58:28 +09:00
Clemens Schwaighofer
cc647de495 Readme update 2023-12-21 15:14:57 +09:00
Clemens Schwaighofer
68b450baaf Add warning message for logins 2023-12-21 13:46:58 +09:00
Clemens Schwaighofer
8452a1b8c0 Fix pre check for ssh login checks 2023-12-21 13:35:50 +09:00
4 changed files with 74 additions and 34 deletions

View File

@@ -297,13 +297,8 @@ some.host,name_b,staff,sshallow,2021-11-15,767,2023-12-20 22:18:36,1,ssh,false,O
"SubGroups": [
"sudo",
"users",
"ikea",
"harley",
"aeon",
"primaham",
"nisshin",
"nissan",
"pfizer"
"group_a",
"group_b",
],
"AccountCreatedDate": "2021-11-15",
"AccountAge": "767",

View File

@@ -12,6 +12,7 @@ ssh_reject_group='sshreject';
now=$(date +"%s");
# max age for last login or account create without login
max_age_login=90;
warn_age_login=80;
max_age_create=30;
# one day in seconds
day=86400;
@@ -34,6 +35,14 @@ if [ ! -d "${LOG}" ]; then
echo "log folder ${LOG} not found";
exit;
fi;
if [ -z $(command -v curl) ]; then
echo "Missing curl application, aborting";
error=1;
fi;
if [ -z $(command -v jq) ]; then
echo "Missing jq application, aborting";
error=1;
fi;
# option 1 in list
case "${1,,}" in
text)
@@ -44,35 +53,50 @@ case "${1,,}" in
echo "{";
;;
csv)
CSV_LINE="%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n";
OUTPUT_TARGET="csv";
echo "Hostname,Username,Main Group,SSH Group,Account Created Date,Account Age,Last Login Date,Last Login Age,Never Logged In,Login Source,Status";
echo "Account ID,Region,Instance ID,Hostname,Username,Main Group,SSH Group,Account Created Date,Account Age,Last Login Date,Last Login Age,Never Logged In,Login Source,Status";
;;
*)
OUTPUT_TARGET="text";
;;
esac;
if [ "${OUTPUT_TARGET}" == "text" ]; then
# collect info via: curl http://instance-data/latest/meta-data/
instance_id=$(curl -s http://instance-data/latest/meta-data/instance-id)
account_id=$(curl -s http://instance-data/latest/meta-data/identity-credentials/ec2/info/ | jq -r .AccountId)
region=$(curl -s http://instance-data/latest/meta-data/placement/region)
if [ "${OUTPUT_TARGET}" = "text" ]; then
LOG="${LOG}/check_ssh_user."$(date +"%F_%H%m%S")".log";
exec &> >(tee -a "${LOG}");
echo "[START] =============>";
echo "Hostname : "$(hostname);
echo "Run date : "$(date +"%F %T");
echo "Max age last login: ${max_age_login} days";
echo "Max age no login : ${max_age_create} days";
elif [ "${OUTPUT_TARGET}" == "json" ]; then
echo "AWS ID : ${account_id}";
echo "Region : ${region}";
echo "Instance ID : ${instance_id}";
echo "Hostname : "$(hostname);
echo "Run date : "$(date +"%F %T");
echo "Max age last login : ${max_age_login} days";
echo "Warn age last login: ${warn_age_login} days";
echo "Max age no login : ${max_age_create} days";
elif [ "${OUTPUT_TARGET}" = "json" ]; then
echo '"Info": {'
echo '"AccountId": "'${account_id}'",';
echo '"Region": "'${region}'",';
echo '"InstanceId": "'${instance_id}'",';
echo '"Hostname": "'$(hostname)'",';
echo '"Date": "'$(date +"%F %T")'",';
echo '"MaxAgeLogin": '${max_age_login}',';
echo '"WarnAgeLogin": '${warn_age_login}',';
echo '"MaxAgeCreate": '${max_age_create}'';
echo '},'
echo '"Users": ['
fi;
for ssh_group in ${ssh_groups[@]}; do
if [ "${OUTPUT_TARGET}" == "text" ]; then
if [ "${OUTPUT_TARGET}" = "text" ]; then
echo "--------------------->"
if [ "${ssh_group}" == "${ssh_reject_group}" ]; then
if [ "${ssh_group}" = "${ssh_reject_group}" ]; then
echo "Showing current SSH Reject users:";
unlock_flag=1
else
@@ -103,13 +127,13 @@ for ssh_group in ${ssh_groups[@]}; do
echo "}";
;;
csv)
printf "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" "$(hostname)" "${username}" "" "${ssh_group}" "" "" "" "" "true" "${out_string}"
printf "${CSV_LINE}" "${account_id}" "${region}" "${instance_id}" "$(hostname)" "${username}" "" "${ssh_group}" "" "" "" "" "true" "${out_string}"
;;
esac;
continue;
fi;
# for json output, we need , between outputs
if [ "${OUTPUT_TARGET}" == "json" ] && [ $first_run -eq 0 ]; then
if [ "${OUTPUT_TARGET}" = "json" ] && [ $first_run -eq 0 ]; then
echo ",";
fi;
first_run=0;
@@ -128,14 +152,25 @@ for ssh_group in ${ssh_groups[@]}; do
# check user create time, if we have set it in comment
user_create_date_string=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 5);
# if empty try last password set time
if [ -z "${user_create_date_string}" ]; then
if ! [[ "${user_create_date_string}" =~ ^\d{4}-\d{2}-\{2} ]]; then
# user L 11/09/2020 0 99999 7 -1
user_create_date_string=$(passwd -S ${username} | cut -d " " -f 3);
fi;
# last try is user home .bash_logout
if [ -z "${user_create_date_string}" ]; then
home_dir=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 6)"/.bash_logout";
user_create_date_string=$(stat -c %Z "${home_dir}");
if ! [[ "${user_create_date_string}" =~ ^\d{4}-\d{2}-\{2} ]]; then
# try logout or bash history
home_dir_bl=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 6)"/.bash_logout";
home_dir_bh=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 6)"/.bash_history";
# check that this file exists
if [ -f "${home_dir_bl}" ]; then
user_create_date_string=$(stat -c %Z "${home_dir_bl}");
elif [ -f "${home_dir_bh}" ]; then
user_create_date_string=$(stat -c %Z "${home_dir_bh}");
fi;
fi;
# still no date -> set empty
if ! [[ "${user_create_date_string}" =~ ^\d{4}-\d{2}-\{2} ]]; then
user_create_date_string="";
fi;
# below only works if the user logged in, a lot of them are just file upload
@@ -169,7 +204,11 @@ for ssh_group in ${ssh_groups[@]}; do
last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}");
if [ ${last_login} -gt ${max_age_login} ]; then
out_string="[!] last ssh log in ${last_login} days ago";
lock_user=1;
if [ "${ssh_group}" != "${ssh_reject_group}" ]; then
lock_user=1;
fi;
elif [ ${last_login} -gt ${warn_age_login} ]; then
out_string="OK [last ssh login ${last_login} days ago]";
else
out_string="OK [ssh]";
fi;
@@ -185,7 +224,11 @@ for ssh_group in ${ssh_groups[@]}; do
last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}");
if [ ${last_login} -gt ${max_age_login} ]; then
out_string="[!] last terminal log in ${last_login} days ago";
lock_user=1;
if [ "${ssh_group}" != "${ssh_reject_group}" ]; then
lock_user=1;
fi;
elif [ ${last_login} -gt ${warn_age_login} ]; then
out_string="OK [last terminal login ${last_login} days ago]";
else
out_string="OK [lastlog]";
fi;
@@ -194,7 +237,9 @@ for ssh_group in ${ssh_groups[@]}; do
elif [ ! -z "${user_create_date}" ]; then
if [ ${account_age} -gt ${max_age_create} ]; then
out_string="[!] Never logged in: account created ${account_age} days ago";
lock_user=1;
if [ "${ssh_group}" != "${ssh_reject_group}" ]; then
lock_user=1;
fi;
else
out_string="OK [Never logged in]";
fi;
@@ -204,7 +249,7 @@ for ssh_group in ${ssh_groups[@]}; do
never_logged_in="true";
fi;
# build delete output
if [ ${lock_user} = 1 ]; then
if [ ${lock_user} -eq 1 ]; then
lock_accounts="${lock_accounts} ${username}"
fi;
case "${OUTPUT_TARGET}" in
@@ -215,7 +260,7 @@ for ssh_group in ${ssh_groups[@]}; do
sub_groups_string="["
sub_group_first=1
for s_group in $sub_groups; do
if [ "${sub_group_first}" == 0 ]; then
if [ "${sub_group_first}" = 0 ]; then
sub_groups_string="${sub_groups_string},";
fi;
sub_groups_string="${sub_groups_string}\"${s_group}\"";
@@ -237,12 +282,12 @@ for ssh_group in ${ssh_groups[@]}; do
echo "}";
;;
csv)
printf "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" "$(hostname)" "${username}" "${main_group}" "${ssh_group}" "${user_create_date_out}" "${account_age}" "${last_login_date}" "${last_login}" "${never_logged_in}" "${login_source}" "${out_string}"
printf "${CSV_LINE}" "${account_id}" "${region}" "${instance_id}" "$(hostname)" "${username}" "${main_group}" "${ssh_group}" "${user_create_date_out}" "${account_age}" "${last_login_date}" "${last_login}" "${never_logged_in}" "${login_source}" "${out_string}"
;;
esac;
done;
done;
if [ "${OUTPUT_TARGET}" == "text" ]; then
if [ "${OUTPUT_TARGET}" = "text" ]; then
if [ ! -z "${lock_accounts}" ]; then
echo "--------------------->"
echo "% Run script below to move users to reject ssh group";
@@ -254,13 +299,13 @@ if [ "${OUTPUT_TARGET}" == "text" ]; then
echo "% Run script below to move users to allow or forward ssh group";
echo "";
echo "For ALLOW:"
echo "bin/unlock_user.sh -s allow ${lock_accounts}";
echo "bin/unlock_user.sh -s allow ${unlock_accounts}";
echo "";
echo "For FORWARDONLY:"
echo "bin/unlock_user.sh -s forward ${lock_accounts}";
echo "bin/unlock_user.sh -s forward ${unlock_accounts}";
fi;
echo "[END] ===============>"
elif [ "${OUTPUT_TARGET}" == "json" ]; then
elif [ "${OUTPUT_TARGET}" = "json" ]; then
# users
echo "]";
# overall

View File

@@ -39,7 +39,7 @@ if [ -z $(cat /etc/group | grep "${ssh_reject_group}:") ]; then
exit;
fi;
ssh_allow_group="sshallow";
ssh_forward_group="sshfoward";
ssh_forward_group="sshforward";
user_group_tpl="gpasswd -d %s %s\ngpasswd -a %s %s\n";
echo "--------------------->"

View File

@@ -53,7 +53,7 @@ if [ -z $(cat /etc/group | grep "${ssh_reject_group}:") ]; then
exit;
fi;
ssh_allow_group="sshallow";
ssh_forward_group="sshfoward";
ssh_forward_group="sshforward";
user_group_tpl="gpasswd -d %s %s\ngpasswd -a %s %s\n";
echo "--------------------->"