Compare commits

...

9 Commits

Author SHA1 Message Date
Clemens Schwaighofer
ca4616c5ee Text fix for error strings in last login check 2024-09-06 14:36:09 +09:00
Clemens Schwaighofer
251b0bf981 SSH login last date check was wrong 2024-09-06 14:34:38 +09:00
Clemens Schwaighofer
6daccfe57c Check last login update with more days info
if WARN then write WARN instead of OK.
Add day numbers if OK

Some minor shellscript updates
2024-09-06 14:25:28 +09:00
Clemens Schwaighofer
935d6a84c9 Add login shell type select (bash login or no login), fix ssh base groups
no ssh allow/forward/reject base group was set if an optional sub group was set

Add possibility to chose no login when setting the ssh access type to "...|no_login"
2024-09-06 10:44:31 +09:00
Clemens Schwaighofer
83f84abd46 Fix skip naming for zip/move creation 2024-09-04 14:04:25 +09:00
Clemens Schwaighofer
090d6f9cec Download zip file message only if there is a file to download 2024-09-04 13:44:47 +09:00
Clemens Schwaighofer
5659cc010f Update zip file/clean up skip with skip information 2024-09-04 13:43:24 +09:00
Clemens Schwaighofer
0bd40cdd73 Create user: skip zip creation run if there are no PEM files
Avoid "file not found" zip file creation and remove if there are no
PEM files created, eg if we have a pre defined pub file
2024-09-04 13:21:36 +09:00
Clemens Schwaighofer
5bf30a8b2f Add shellcheckrc 2024-09-03 12:47:52 +09:00
4 changed files with 72 additions and 38 deletions

2
.shellcheckrc Normal file
View File

@@ -0,0 +1,2 @@
shell=bash
external-sources=true

View File

@@ -4,7 +4,7 @@
# if user login >30days, remoe user from sshallow group and write log # if user login >30days, remoe user from sshallow group and write log
# base folder # base folder
BASE_FOLDER=$(dirname $(readlink -f $0))"/"; BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
# which groups holds the ssh allowed login users (outside of admin users) # which groups holds the ssh allowed login users (outside of admin users)
ssh_groups=('sshforward' 'sshallow' 'sshreject'); ssh_groups=('sshforward' 'sshallow' 'sshreject');
ssh_reject_group='sshreject'; ssh_reject_group='sshreject';
@@ -68,7 +68,7 @@ esac;
# collect info via: curl http://169.254.169.254/latest/meta-data/ # collect info via: curl http://169.254.169.254/latest/meta-data/
instance_data=$( instance_data=$(
TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") &&
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document
) )
instance_id=$(echo "${instance_data}" | jq .instanceId) instance_id=$(echo "${instance_data}" | jq .instanceId)
@@ -76,14 +76,14 @@ account_id=$(echo "${instance_data}" | jq .accountId)
region=$(echo "${instance_data}" | jq .region) region=$(echo "${instance_data}" | jq .region)
if [ "${OUTPUT_TARGET}" = "text" ]; then if [ "${OUTPUT_TARGET}" = "text" ]; then
LOG="${LOG}/check_ssh_user."$(date +"%F_%H%m%S")".log"; LOG="${LOG}/check_ssh_user.$(date +"%F_%H%m%S").log";
exec &> >(tee -a "${LOG}"); exec &> >(tee -a "${LOG}");
echo "[START] =============>"; echo "[START] =============>";
echo "AWS ID : ${account_id}"; echo "AWS ID : ${account_id}";
echo "Region : ${region}"; echo "Region : ${region}";
echo "Instance ID : ${instance_id}"; echo "Instance ID : ${instance_id}";
echo "Hostname : "$(hostname); echo "Hostname : $(hostname)";
echo "Run date : "$(date +"%F %T"); echo "Run date : $(date +"%F %T")";
echo "Max age last login : ${max_age_login} days"; echo "Max age last login : ${max_age_login} days";
echo "Warn age last login: ${warn_age_login} days"; echo "Warn age last login: ${warn_age_login} days";
echo "Max age no login : ${max_age_create} days"; echo "Max age no login : ${max_age_create} days";
@@ -197,7 +197,7 @@ for ssh_group in ${ssh_groups[@]}; do
found=$(grep "${username};" "${AUTH_LOG}"); found=$(grep "${username};" "${AUTH_LOG}");
fi; fi;
# always pre work account dates if they exist, but output only if text # always pre work account dates if they exist, but output only if text
if [ ! -z "${user_create_date_string}" ]; then if [ -n "${user_create_date_string}" ]; then
user_create_date=$(echo "${user_create_date_string}" | date +"%s" -f -); user_create_date=$(echo "${user_create_date_string}" | date +"%s" -f -);
# if all empty, we continue with only check if user has last login date # if all empty, we continue with only check if user has last login date
# else get days since creation # else get days since creation
@@ -205,24 +205,24 @@ for ssh_group in ${ssh_groups[@]}; do
account_age=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${user_create_date} ${day}"); account_age=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${user_create_date} ${day}");
user_create_date_out=$(echo "${user_create_date_string}" | date +"%F" -f -); user_create_date_out=$(echo "${user_create_date_string}" | date +"%F" -f -);
fi; fi;
if [ ! -z "${found}" ]; then if [ -n "${found}" ]; then
last_login_date_string=$(grep "${username};" "${AUTH_LOG}" | cut -d ";" -f 2); last_login_date_string=$(grep "${username};" "${AUTH_LOG}" | cut -d ";" -f 2);
last_login_date=$(echo "${last_login_date}" | date +"%s" -f -); last_login_date=$(echo "${last_login_date_string}" | date +"%s" -f -);
last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}"); last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}");
if [ ${last_login} -gt ${max_age_login} ]; then if [ ${last_login} -gt ${max_age_login} ]; then
out_string="[!] last ssh log in ${last_login} days ago"; out_string="[!] Last ssh log in ${last_login} days ago";
if [ "${ssh_group}" != "${ssh_reject_group}" ]; then if [ "${ssh_group}" != "${ssh_reject_group}" ]; then
lock_user=1; lock_user=1;
fi; fi;
elif [ ${last_login} -gt ${warn_age_login} ]; then elif [ ${last_login} -gt ${warn_age_login} ]; then
out_string="OK [last ssh login ${last_login} days ago]"; out_string="WARN [last ssh login ${last_login} days ago]";
else else
out_string="OK [ssh]"; out_string="OK [ssh, ${last_login} days ago]";
fi; fi;
login_source="ssh"; login_source="ssh";
# rewrite to Y-M-D, aka # rewrite to Y-M-D, aka
last_login_date="${last_login_date_string}" last_login_date="${last_login_date_string}"
elif [ ! -z "${last_login_string##*$search*}" ]; then elif [ -n "${last_login_string##*$search*}" ]; then
# if we have "** Never logged in**" the user never logged in # if we have "** Never logged in**" the user never logged in
# find \w{3} \w{3} [\s\d]{2} \d{2}:\d{2}:\d{2} \+\d{4} \d{4} # find \w{3} \w{3} [\s\d]{2} \d{2}:\d{2}:\d{2} \+\d{4} \d{4}
# awk '{for(i=4;i<=NF;++i)printf $i FS}' # awk '{for(i=4;i<=NF;++i)printf $i FS}'
@@ -230,25 +230,25 @@ for ssh_group in ${ssh_groups[@]}; do
# date -d "Wed Nov 2 09:40:35 +0900 2022" +%s # date -d "Wed Nov 2 09:40:35 +0900 2022" +%s
last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}"); last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}");
if [ ${last_login} -gt ${max_age_login} ]; then if [ ${last_login} -gt ${max_age_login} ]; then
out_string="[!] last terminal log in ${last_login} days ago"; out_string="[!] Last terminal log in ${last_login} days ago";
if [ "${ssh_group}" != "${ssh_reject_group}" ]; then if [ "${ssh_group}" != "${ssh_reject_group}" ]; then
lock_user=1; lock_user=1;
fi; fi;
elif [ ${last_login} -gt ${warn_age_login} ]; then elif [ ${last_login} -gt ${warn_age_login} ]; then
out_string="OK [last terminal login ${last_login} days ago]"; out_string="WARN [last terminal login ${last_login} days ago]";
else else
out_string="OK [lastlog]"; out_string="OK [lastlog, ${last_login} days ago]";
fi; fi;
login_source="lastlog"; login_source="lastlog";
last_login_date=$(echo "${last_login_string}" | awk '{for(i=4;i<=NF;++i)printf $i FS}' | date +"%F %T" -f -) last_login_date=$(echo "${last_login_string}" | awk '{for(i=4;i<=NF;++i)printf $i FS}' | date +"%F %T" -f -)
elif [ ! -z "${user_create_date}" ]; then elif [ -n "${user_create_date}" ]; then
if [ ${account_age} -gt ${max_age_create} ]; then if [ ${account_age} -gt ${max_age_create} ]; then
out_string="[!] Never logged in: account created ${account_age} days ago"; out_string="[!] Never logged in: account created ${account_age} days ago";
if [ "${ssh_group}" != "${ssh_reject_group}" ]; then if [ "${ssh_group}" != "${ssh_reject_group}" ]; then
lock_user=1; lock_user=1;
fi; fi;
else else
out_string="OK [Never logged in]"; out_string="OK [Never logged in, created ${account_age} days ago]";
fi; fi;
never_logged_in="true"; never_logged_in="true";
else else
@@ -295,13 +295,13 @@ for ssh_group in ${ssh_groups[@]}; do
done; done;
done; done;
if [ "${OUTPUT_TARGET}" = "text" ]; then if [ "${OUTPUT_TARGET}" = "text" ]; then
if [ ! -z "${lock_accounts}" ]; then if [ -n "${lock_accounts}" ]; then
echo "--------------------->" echo "--------------------->"
echo "% Run script below to move users to reject ssh group"; echo "% Run script below to move users to reject ssh group";
echo ""; echo "";
echo "bin/lock_user.sh ${lock_accounts}"; echo "bin/lock_user.sh ${lock_accounts}";
fi; fi;
if [ ! -z "${unlock_accounts}" ]; then if [ -n "${unlock_accounts}" ]; then
echo "--------------------->" echo "--------------------->"
echo "% Run script below to move users to allow or forward ssh group"; echo "% Run script below to move users to allow or forward ssh group";
echo ""; echo "";

View File

@@ -2,13 +2,14 @@
# * input file # * input file
# user_list.txt # user_list.txt
# <ignored id>;<user name>;<group>[,sub group,sub group];<ssh access type>;[override password];[override hostname];[override ssh key type] # <ignored id>;<user name>;<group>[,sub group,sub group];<ssh access type>|<no login flag>;[override password];[override hostname];[override ssh key type]
# lines with # are skipped # lines with # are skipped
# already created users are skipped # already created users are skipped
# Mandatory: <ignored id>;<user name>;<group>;<ssh access type> # Mandatory: <ignored id>;<user name>;<group>;<ssh access type>
# <ssh access type> can be # <ssh access type> can be
# allow (full login access) # allow (full login access)
# forward (forward/jump host only) # forward (forward/jump host only)
# if in this column with pipe (|) the flag "no_login" is set then the default shell will change to "/sbin/nologin"
# * output file # * output file
# <date>;<target connect host name>;<hostname>;<username>;<password>;<ssh access type> # <date>;<target connect host name>;<hostname>;<username>;<password>;<ssh access type>
# If already existing PEM key is used then <password> is [ALREADY SET] # If already existing PEM key is used then <password> is [ALREADY SET]
@@ -111,6 +112,10 @@ ssh_keytype='';
# sshallow or sshforward # sshallow or sshforward
ssh_group=''; ssh_group='';
ssh_forward_ok=0; ssh_forward_ok=0;
# login shells
login_shell="/bin/bash";
no_login_shell="/sbin/nologin";
user_login_shell="";
# detect ssh authorized_keys setting # detect ssh authorized_keys setting
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER=''; SSH_CENTRAL_AUTHORIZED_FILE_FOLDER='';
SSH_AUTHORIZED_FILE=''; SSH_AUTHORIZED_FILE='';
@@ -202,8 +207,21 @@ while read i; do
_group=$(echo "${i}" | cut -d ";" -f 3 | tr A-Z a-z | tr -d ' '); _group=$(echo "${i}" | cut -d ";" -f 3 | tr A-Z a-z | tr -d ' ');
group=$(echo "${_group}" | cut -d "," -f 1); group=$(echo "${_group}" | cut -d "," -f 1);
sub_group=""; sub_group="";
# POS 4: ssh access type # POS 4: ssh access type and no login flag
ssh_access_type=$(echo "${i}" | cut -d ";" -f 4 | tr A-Z a-z | tr -d ' '); # no login flag
no_login_flag="";
# if there is a pipe, check, else ignore
if echo "${i}" | cut -d ";" -f 4 | grep -q "|"; then
no_login_flag=$(echo "${i}" | cut -d ";" -f 4 | cut -d "|" -f 2);
fi;
# anything set in no login shell flag, we set no login shell
if [ -n "${no_login_flag}" ]; then
user_login_shell="${no_login_shell}";
else
user_login_shell="${login_shell}";
fi;
# ssh access type
ssh_access_type=$(echo "${i}" | cut -d ";" -f 4 | cut -d "|" -f 1 | tr A-Z a-z | tr -d ' ');
# if not allow or forward, set to access # if not allow or forward, set to access
if [ "${ssh_access_type}" != "allow" ] && [ "${ssh_access_type}" != "forward" ]; then if [ "${ssh_access_type}" != "allow" ] && [ "${ssh_access_type}" != "forward" ]; then
echo "[!!] Not valid ssh access type ${ssh_access_type}, set to allow"; echo "[!!] Not valid ssh access type ${ssh_access_type}, set to allow";
@@ -221,7 +239,7 @@ while read i; do
# check if "," inside and extract sub groups # check if "," inside and extract sub groups
if [ -z "${_group##*,*}" ]; then if [ -z "${_group##*,*}" ]; then
sub_group=$(echo "${_group}" | cut -d "," -f 2-); sub_group=$(echo "${_group}" | cut -d "," -f 2-);
sub_group_opt=" -G ${sub_group}"; sub_group_opt=" -G ${ssh_group},${sub_group}";
fi; fi;
# POS 5: do we have a password preset # POS 5: do we have a password preset
_password=$(echo "${i}" | cut -d ";" -f 5); _password=$(echo "${i}" | cut -d ";" -f 5);
@@ -299,9 +317,9 @@ while read i; do
echo "++ Create '${username}:${group}(${sub_group})'"; echo "++ Create '${username}:${group}(${sub_group})'";
if [ ${TEST} -eq 0 ]; then if [ ${TEST} -eq 0 ]; then
# comment is user create time # comment is user create time
useradd -c `date +"%F"` -s /bin/bash -g ${group}${sub_group_opt} -d "${HOME_FOLDER}${username}" -m ${username}; useradd -c `date +"%F"` -s "${user_login_shell}" -g ${group}${sub_group_opt} -d "${HOME_FOLDER}${username}" -m ${username};
else else
echo "$> useradd -c `date +"%F"` -s /bin/bash -g ${group}${sub_group_opt} -d "${HOME_FOLDER}${username}" -m ${username}"; echo "$> useradd -c `date +"%F"` -s "${user_login_shell}" -g ${group}${sub_group_opt} -d "${HOME_FOLDER}${username}" -m ${username}";
fi; fi;
fi; fi;
# set the auth file # set the auth file
@@ -421,14 +439,24 @@ done;
if [ ${INFO} -eq 1 ]; then if [ ${INFO} -eq 1 ]; then
exit; exit;
fi; fi;
# check if there are any files in the SSH_KEYGEN_FOLDER, else skip zip file creation and file move
has_pem_files=0;
if (shopt -s nullglob dotglob; f=("${SSH_KEYGEN_FOLDER}"*".pem"*); ((${#f[@]}))); then
has_pem_files=1;
fi;
# zip everything and remove data in ssh key folder, delete output file with passwords # zip everything and remove data in ssh key folder, delete output file with passwords
if [ ${TEST} -eq 0 ]; then if [ ${TEST} -eq 0 ]; then
if [ "${has_pem_files}" -eq 1 ]; then
zip -r \ zip -r \
"${ROOT_FOLDER}${output_zip_folder}${output_zip}" \ "${ROOT_FOLDER}${output_zip_folder}${output_zip}" \
"${input_file}" \ "${input_file}" \
"${output_file}" \ "${output_file}" \
"${SSH_KEYGEN_FOLDER}" \ "${SSH_KEYGEN_FOLDER}" \
-x\*.gitignore; -x\*.gitignore;
echo "Download: ${ROOT_FOLDER}${output_zip_folder}${output_zip}";
else
echo "Skip ZIP file creation, no pem files";
fi;
else else
echo "zip -r \\" echo "zip -r \\"
echo "${ROOT_FOLDER}${output_zip_folder}${output_zip} \\" echo "${ROOT_FOLDER}${output_zip_folder}${output_zip} \\"
@@ -436,15 +464,19 @@ else
echo "${output_file} \\" echo "${output_file} \\"
echo "${SSH_KEYGEN_FOLDER} \\" echo "${SSH_KEYGEN_FOLDER} \\"
echo "-x\*.gitignore;" echo "-x\*.gitignore;"
echo "Download: ${ROOT_FOLDER}${output_zip_folder}${output_zip}";
fi; fi;
echo "Download: ${ROOT_FOLDER}${output_zip_folder}${output_zip}";
# cleam up user log file and ssh keys # cleam up user log file and ssh keys
if [ ${TEST} -eq 0 ]; then if [ ${TEST} -eq 0 ]; then
if [ "${has_pem_files}" -eq 1 ]; then
# move pub to created folders # move pub to created folders
mv "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}"*.pub "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}"; mv "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}"*.pub "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}";
# delete the rest # delete the rest
rm "${ROOT_FOLDER}${output_file}"; rm "${ROOT_FOLDER}${output_file}";
rm "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}"*; rm "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}"*;
else
echo "Skip pub file move and cleanup, no pem files";
fi;
else else
echo "$> mv ${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}*.pub ${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB};"; echo "$> mv ${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}*.pub ${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB};";
echo "$> rm ${ROOT_FOLDER}${output_file}"; echo "$> rm ${ROOT_FOLDER}${output_file}";

View File

@@ -1 +1 @@
#user_id;user_name;group,subgroup;ssh access type;override password;override hostname;override ssh type #user_id;user_name;group,subgroup;ssh access type|no login flag;override password;override hostname;override ssh type