Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c801ef40b4 | ||
|
|
125cb27de8 | ||
|
|
e45b89c582 | ||
|
|
4a8dab7b01 | ||
|
|
fa47178ed1 | ||
|
|
4629b58a7e |
@@ -11,14 +11,11 @@ The folder holding the script must be owned by *root* and have *600* permissions
|
||||
|
||||
```sh
|
||||
cd /root/
|
||||
git clone http://gitlab-ap.factory.tools/scripts-collections/aws-user-create.git users
|
||||
git clone <UrlToGitRepository> users
|
||||
chown root. users
|
||||
chgrp 600 users
|
||||
```
|
||||
|
||||
Alternate download:
|
||||
`git clone https://git.tequila.jp/ScriptsCollections/AwsUserCreate.git users`
|
||||
|
||||
## Folders
|
||||
|
||||
Inside the base folder there are
|
||||
@@ -269,7 +266,7 @@ If not set it defaults to allow, if a user_list.txt file with this user exist it
|
||||
|
||||
There are two scripts that can be user to check if and when the user has logged in the last time.
|
||||
|
||||
Because of users who do not open shells (for example sftp users) we cannot rely on lastlog, so a script called `collect_login_data.sh` exists that parses the systemd logind info or /var/log/secure for user authentication data.
|
||||
Because of users who do not open shells (for example sftp users) we cannot rely on lslogins, so a script called `collect_login_data.sh` exists that parses the systemd logind info or /var/log/secure for user authentication data.
|
||||
|
||||
Data is stored in `auth-log/user_auth.log` folder as `user;last login date`
|
||||
|
||||
@@ -281,7 +278,7 @@ This script should be run every day via crontab as root:
|
||||
|
||||
The script `check_last_login.sh` will go through the ssh allow groups (sshallow/sshforward) users and flag out those that have not logged in, in the last 60 days and recommend to lock them. The script will also check for user accounts that never logged in and where created in the last 30 days and recomment to lock them too.
|
||||
|
||||
This script will first check the `auth-log/user_auth.log` file, then lastlog output and finally check for creation time in passwd file or home director for when the user was created.
|
||||
This script will first check the `auth-log/user_auth.log` file, then lslogins output and finally check for creation time in passwd file or home director for when the user was created.
|
||||
|
||||
Currently only information is printed out and no action is done itself.
|
||||
|
||||
|
||||
@@ -88,6 +88,24 @@ if [ -f "${BASE_FOLDER}${IGNORE_USER_FILE}" ]; then
|
||||
echo "Reading ${IGNORE_USER_FILE}";
|
||||
fi;
|
||||
|
||||
LOG="${BASE_FOLDER}/../log/user_management.log";
|
||||
function write_log()
|
||||
{
|
||||
text="${1}";
|
||||
do_echo="${2}";
|
||||
log_prefix="";
|
||||
# log prefix for testing
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
log_prefix="[TEST] ";
|
||||
fi;
|
||||
# write log not in info run
|
||||
echo "[$(date +"%F %T")] [$0] ${log_prefix}${text}" >> "${LOG}";
|
||||
if [ "${do_echo}" = "1" ]; then
|
||||
echo "${text}";
|
||||
fi;
|
||||
}
|
||||
write_log "START SCRIPT RUN";
|
||||
|
||||
# loop over passwd file
|
||||
# if not in no action then check if .ssh/authorized_keys file exists
|
||||
cut -d ":" -f 1,6 /etc/passwd |
|
||||
@@ -97,14 +115,17 @@ while read -r user_home; do
|
||||
# skip admin usernames
|
||||
if [[ " ${NO_ACTION[*]} " =~ [[:space:]]${username}[[:space:]] ]]; then
|
||||
printf "${PRINTF_INFO}" "NO ACT" "!" "${username}" "user in NO ACTION list";
|
||||
write_log "[NO ACT] ${username} in NO ACTION list";
|
||||
continue;
|
||||
fi;
|
||||
if [[ " ${SKIP_USERS[*]} " =~ [[:space:]]${username}[[:space:]] ]]; then
|
||||
printf "${PRINTF_INFO}" "SKIP" "*" "${username}" "skip forced via command line";
|
||||
write_log "[SKIP] ${username} skip forced via command line";
|
||||
continue;
|
||||
fi;
|
||||
if [[ " ${IGNORE_USER[*]} " =~ [[:space:]]${username}[[:space:]] ]]; then
|
||||
printf "${PRINTF_INFO}" "SKIP" "**" "${username}" "skip from ignore config file";
|
||||
write_log "[SKIP] ${username} skip from ignore config file";
|
||||
continue;
|
||||
fi;
|
||||
home_folder=$(echo "${user_home}" | cut -d ":" -f 2);
|
||||
@@ -113,8 +134,10 @@ while read -r user_home; do
|
||||
# but do we have an auth folder, if yes -> exist skip
|
||||
if [ -f "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}" ]; then
|
||||
printf "${PRINTF_INFO}" "DONE" "." "${username}" "already moved";
|
||||
write_log "[DONE] ${username} already moved";
|
||||
else
|
||||
printf "${PRINTF_INFO}" "IGNORE" "?" "${username}" "no authorized_keys file";
|
||||
write_log "[IGNORE] ${username} no authorized_keys file";
|
||||
fi;
|
||||
continue;
|
||||
fi;
|
||||
@@ -124,6 +147,7 @@ while read -r user_home; do
|
||||
ssh_key_diff=$(diff -u "${home_folder}/.ssh/authorized_keys" "${SSH_MASTER_AUTHORIZED_FILE}");
|
||||
if [ -n "${ssh_key_diff}" ]; then
|
||||
printf "${PRINTF_INFO}" "ABORT" "!!!" "${username}" "authorized key is not matching the master key file";
|
||||
write_log "[ABORT] ${username} authorized key is not matching the master key file";
|
||||
exit;
|
||||
fi;
|
||||
fi;
|
||||
@@ -132,6 +156,7 @@ while read -r user_home; do
|
||||
ssh_key_diff=$(diff -u "${home_folder}/.ssh/authorized_keys" "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}");
|
||||
if [ -z "${ssh_key_diff}" ]; then
|
||||
printf "${PRINTF_INFO}" "REMOVE" "-" "${username}" ".ssh/authorized_keys";
|
||||
write_log "[REMOVE] ${username} .ssh/authorized_keys";
|
||||
if [ ${master_user} -eq 0 ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
rm "${home_folder}/.ssh/authorized_keys";
|
||||
@@ -139,15 +164,17 @@ while read -r user_home; do
|
||||
echo "$> rm \"${home_folder}/.ssh/authorized_keys\"";
|
||||
fi;
|
||||
else
|
||||
echo "[!] No delete for master user, must be done manually";
|
||||
write_log "[!] No delete for master user, must be done manually" "1";
|
||||
fi;
|
||||
continue;
|
||||
fi;
|
||||
# No update, alert
|
||||
printf "${PRINTF_INFO}" "DIFF" "???" "${username}" "Different authorized keys in home dir, SKIPPED";
|
||||
write_log "[DIFF] ${username} Different authorized keys in home dir, SKIPPED";
|
||||
continue;
|
||||
fi;
|
||||
printf "${PRINTF_INFO}" "MOVE" ">" "${username}" "Move SSH Key to central location";
|
||||
write_log "[MOVE] ${username} Move SSH Key to central location";
|
||||
# move public keys over
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
cat "${home_folder}/.ssh/authorized_keys" > "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}";
|
||||
@@ -159,13 +186,14 @@ while read -r user_home; do
|
||||
ssh_key_diff=$(diff -u "${home_folder}/.ssh/authorized_keys" "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}");
|
||||
if [ -n "${ssh_key_diff}" ]; then
|
||||
printf "${PRINTF_INFO}" "ERROR" "!!!" "${username}" "Move problem ${ssh_key_diff}";
|
||||
write_log "[ERROR] ${username} Move problem ${ssh_key_diff}";
|
||||
break;
|
||||
fi;
|
||||
# remove home .ssh/authorized_keys (do not remove folder)
|
||||
if [ ${master_user} -eq 0 ]; then
|
||||
rm "${home_folder}/.ssh/authorized_keys";
|
||||
else
|
||||
echo "=> No delete for master user, must be done manually";
|
||||
write_log "=> No delete for master user, must be done manually" "1";
|
||||
fi;
|
||||
else
|
||||
echo "[START] ====>";
|
||||
|
||||
@@ -44,6 +44,11 @@ if [ -z "$(command -v jq)" ]; then
|
||||
echo "Missing jq application, aborting";
|
||||
error=1;
|
||||
fi;
|
||||
# use lslogins instead of last log
|
||||
if [ -z "$(command -v lslogins)" ]; then
|
||||
echo "Missing lslogins application, aborting";
|
||||
error=1;
|
||||
fi;
|
||||
if [ $error -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
@@ -76,7 +81,7 @@ account_id=$(echo "${instance_data}" | jq .accountId)
|
||||
region=$(echo "${instance_data}" | jq .region)
|
||||
|
||||
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}");
|
||||
echo "[START] =============>";
|
||||
echo "AWS ID : ${account_id}";
|
||||
@@ -111,6 +116,10 @@ for ssh_group in "${ssh_groups[@]}"; do
|
||||
fi;
|
||||
fi;
|
||||
while read -r username; do
|
||||
# skip empty, if group exists but has no users
|
||||
if [ "${username}" = "" ]; then
|
||||
continue;
|
||||
fi;
|
||||
# check that user exists in passwd
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
out_string="[!] User $username does not exists in /etc/passwd file";
|
||||
@@ -183,10 +192,18 @@ for ssh_group in "${ssh_groups[@]}"; do
|
||||
|
||||
# below only works if the user logged in, a lot of them are just file upload
|
||||
# users. Use the collect script from systemd-logind or /var/log/secure
|
||||
# Username Port From Latest
|
||||
# user pts/35 10.110.160.230 Wed Nov 2 09:40:35 +0900 2022
|
||||
last_login_string=$(lastlog -u "${username}" | sed 1d);
|
||||
search="Never logged in";
|
||||
# for the rest use lslogin, returns ":" separted list, not set is never logged in
|
||||
# LAST LOGIN :FAILED LOGIN
|
||||
# 2025-09-12T09:56:22+09:00:
|
||||
last_login_string=$(
|
||||
lslogins \
|
||||
-c --noheadings --notruncate \
|
||||
--time-format=iso \
|
||||
-o LAST-LOGIN,FAILED-LOGIN \
|
||||
-l "${username}"
|
||||
);
|
||||
last_login_date=$(echo "${last_login_string}" | cut -d ":" -f 1);
|
||||
# search="Never logged in";
|
||||
never_logged_in="false";
|
||||
found="";
|
||||
login_source="";
|
||||
@@ -223,12 +240,10 @@ for ssh_group in "${ssh_groups[@]}"; do
|
||||
login_source="ssh";
|
||||
# rewrite to Y-M-D, aka
|
||||
last_login_date="${last_login_date_string}"
|
||||
elif [ -n "${last_login_string##*"$search"*}" ]; then
|
||||
elif [ -n "${last_login_date}" ]; then
|
||||
# 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}
|
||||
# awk '{for(i=4;i<=NF;++i)printf $i FS}'
|
||||
last_login_date=$(echo "${last_login_string}" | awk '{for(i=4;i<=NF;++i)printf $i FS}' | date +"%s" -f -);
|
||||
# date -d "Wed Nov 2 09:40:35 +0900 2022" +%s
|
||||
# we get an ISO DATE with timezone
|
||||
last_login_date=$(echo "${last_login_string}" | date +"%s" -f -);
|
||||
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";
|
||||
@@ -241,7 +256,7 @@ for ssh_group in "${ssh_groups[@]}"; do
|
||||
out_string="OK [lastlog, ${last_login} days ago]";
|
||||
fi;
|
||||
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}" | date +"%F %T" -f -)
|
||||
elif [ -n "${user_create_date}" ]; then
|
||||
if [ "${account_age}" -gt ${max_age_create} ]; then
|
||||
out_string="[!] Never logged in: account created ${account_age} days ago";
|
||||
|
||||
@@ -176,6 +176,12 @@ if [ "$(whoami)" != "root" ]; then
|
||||
fi;
|
||||
fi;
|
||||
|
||||
# do not allow test and info at the same
|
||||
if [ ${TEST} -eq 1 ] && [ ${INFO} -eq 1 ]; then
|
||||
echo "Cannot have --test and --info option at the same time";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
# exit if not -g parameter set
|
||||
if [ $GO -eq 0 ]; then
|
||||
echo "Script has to be run with -g option for actual user creation.";
|
||||
@@ -187,20 +193,51 @@ if [ $error -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
|
||||
LOG="${BASE_FOLDER}/../log/user_management.log";
|
||||
function write_log()
|
||||
{
|
||||
text="${1}";
|
||||
do_echo="${2}";
|
||||
log_prefix="";
|
||||
# log prefix for testing
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
log_prefix="[TEST] ";
|
||||
fi;
|
||||
# write log not in info run
|
||||
if [ ${INFO} -eq 0 ]; then
|
||||
echo "[$(date +"%F %T")] [$0] ${log_prefix}${text}" >> "${LOG}";
|
||||
fi;
|
||||
if [ "${do_echo}" = "1" ]; then
|
||||
echo "${text}";
|
||||
fi;
|
||||
}
|
||||
write_log "START SCRIPT RUN";
|
||||
|
||||
# used for test run only
|
||||
overall_run_error=0;
|
||||
|
||||
# MARK: LOOP START
|
||||
# create users
|
||||
while read -r i; do
|
||||
# run error for one row
|
||||
run_error=0;
|
||||
# skip rows start with # (comment)
|
||||
if [[ "${i}" =~ ^\# ]]; then
|
||||
continue;
|
||||
fi;
|
||||
|
||||
# log create inly on not info
|
||||
if [ ${INFO} -eq 0 ]; then
|
||||
write_log "[CREATE] ROW: $i";
|
||||
fi;
|
||||
|
||||
# MARK: VALUES CHECK
|
||||
# POS 2: make lower case, remove spaces
|
||||
username=$(echo "${i}" | cut -d ";" -f 2 | tr "[:upper:]" "[:lower:]" | tr -d ' ');
|
||||
# check username is alphanumeric with .
|
||||
if ! [[ "${username}" =~ ^[a-z0-9]+([.a-z0-9_-]+[a-z0-9])?$ ]]; then
|
||||
echo "User name can only be a-z 0-9 - _ . and cannot start or end with - . or _: ${username}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
run_error=1;
|
||||
write_log "[ERROR] User name can only be a-z 0-9 - _ . and cannot start or end with - . or _: ${username}" "1";
|
||||
fi;
|
||||
# POS 3: groups
|
||||
_group=$(echo "${i}" | cut -d ";" -f 3 | tr "[:upper:]" "[:lower:]" | tr -d ' ');
|
||||
@@ -223,14 +260,12 @@ while read -r i; do
|
||||
ssh_access_type=$(echo "${i}" | cut -d ";" -f 4 | cut -d "|" -f 1 | tr "[:upper:]" "[:lower:]" | tr -d ' ');
|
||||
# if not allow or forward, set to access
|
||||
if [ "${ssh_access_type}" != "allow" ] && [ "${ssh_access_type}" != "forward" ]; then
|
||||
echo "[!!] Not valid ssh access type ${ssh_access_type}, set to allow";
|
||||
ssh_access_type="allow";
|
||||
run_error=1;
|
||||
write_log "[ERROR] Not valid ssh access type ${ssh_access_type}" "1";
|
||||
fi;
|
||||
if [ $ssh_forward_ok -eq 0 ] && [ "${ssh_access_type}" = "forward" ]; then
|
||||
echo "[!!!] sshforward group does not exsts, cannot set user ${username}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
write_log "[ERROR] sshforward group does not exsts, cannot set user ${username}" "1";
|
||||
run_error=1;
|
||||
fi;
|
||||
ssh_group="ssh${ssh_access_type}";
|
||||
# sshallow group is always added
|
||||
@@ -259,24 +294,35 @@ while read -r i; do
|
||||
fi;
|
||||
# user & group not set
|
||||
if [ -z "${username}" ] || [ -z "${_group}" ]; then
|
||||
echo "[!!!!!] Missing user or group entry for ${username}/${_group}";
|
||||
echo "[*** ABORT RUN ***]"
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
run_error=1;
|
||||
write_log "[ERROR] Missing user or group entry for ${username}/${_group}" "1";
|
||||
else
|
||||
group_error=0;
|
||||
# check group names valid
|
||||
for create_group in ${_group//,/ }; do
|
||||
if ! [[ "${create_group}" =~ ^[a-z0-9]+([a-z0-9_-]+[a-z0-9])?$ ]]; then
|
||||
echo "Group name can only be a-z 0-9 - _ and cannot start or end with - or _: ${create_group}";
|
||||
write_log "[ERROR] Group name can only be a-z 0-9 - _ and cannot start or end with - or _: ${create_group}" "1";
|
||||
group_error=1;
|
||||
fi;
|
||||
done;
|
||||
if [ $group_error -eq 1 ] && [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
if [ $group_error -eq 1 ]; then
|
||||
run_error=1;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
# error & test -> break
|
||||
if [ ${run_error} -eq 1 ]; then
|
||||
overall_run_error=1;
|
||||
write_log "[*** ABORT RUN ***]" "1";
|
||||
# end if not test and not info
|
||||
if [ ${TEST} -eq 0 ] && [ ${INFO} -eq 0 ]; then
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
# MARK: SSH NAMES SET
|
||||
# SSH file name part without folder
|
||||
ssh_keygen_id="${hostname}${separator}${group}${separator}${username}${separator}${ssh_keytype}.pem";
|
||||
# the full file including folder name
|
||||
@@ -286,20 +332,21 @@ while read -r i; do
|
||||
# check existing pub file
|
||||
ssh_keyfile_check_pub="${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}${ssh_keygen_id}.pub";
|
||||
|
||||
# MARK: INFO
|
||||
if [ ${INFO} -eq 1 ]; then
|
||||
info_string="User: '${username}:${group}(${sub_group});${ssh_group}', SSH: ${ssh_keygen_id}";
|
||||
# test if pub file exists or not, test if user exists
|
||||
echo -n "User: '${username}:${group}(${sub_group});${ssh_group}', SSH: ${ssh_keygen_id}";
|
||||
if getent passwd "${username}" > /dev/null 2>&1; then
|
||||
echo -n ", User exists";
|
||||
info_string="${info_string}, User exists";
|
||||
fi;
|
||||
if [ -f "${ssh_keyfile_check_pub}" ]; then
|
||||
echo -n ", SSH Pub key OK";
|
||||
info_string="${info_string}, SSH Pub key OK";
|
||||
fi;
|
||||
# line break
|
||||
echo "";
|
||||
echo "${info_string}";
|
||||
continue;
|
||||
fi;
|
||||
|
||||
# MARK: CREATE
|
||||
# add group for each entry in _group
|
||||
for create_group in ${_group//,/ }; do
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
@@ -311,9 +358,9 @@ while read -r i; do
|
||||
# check if user is not already created
|
||||
# if getent passwd ${username} > /dev/null 2>&1; then
|
||||
if id "${username}" &>/dev/null; then
|
||||
echo "-- Skip '${username}:${group}(${sub_group})'";
|
||||
write_log "-- Skip '${username}:${group}(${sub_group})'" "1";
|
||||
else
|
||||
echo "++ Create '${username}:${group}(${sub_group})'";
|
||||
write_log "++ Create '${username}:${group}(${sub_group})'" "1";
|
||||
params=(
|
||||
"-c" "$(date +"%F")" "-s" "${user_login_shell}"
|
||||
"-g" "${group}" "-G" "$(IFS=, ; echo "${sub_group_opt[*]}")"
|
||||
@@ -349,7 +396,7 @@ while read -r i; do
|
||||
password=${_password};
|
||||
fi;
|
||||
# create SSH key
|
||||
echo " > Create ssh key-pair '${ssh_keyfile}'";
|
||||
write_log " > Create ssh key-pair: ${ssh_keyfile}" "1";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
ssh-keygen \
|
||||
-t "${ssh_keytype}" \
|
||||
@@ -366,16 +413,17 @@ while read -r i; do
|
||||
fi;
|
||||
if [ -n "${found}" ]; then
|
||||
skip_ssh=1;
|
||||
echo "-- Skip SSH Key creation: ${ssh_keygen_id}.pub";
|
||||
write_log "-- Skip SSH Key creation: ${ssh_keygen_id}.pub" "1";
|
||||
else
|
||||
# override previously set with stored one
|
||||
ssh_keyfile_pub=${ssh_keyfile_check_pub};
|
||||
echo " < Use existing public ssh key '${ssh_keygen_id}.pub'";
|
||||
write_log " < Use existing public ssh key: ${ssh_keygen_id}.pub" "1";
|
||||
# Password already set notification
|
||||
fi;
|
||||
password="[ALREADY SET]";
|
||||
fi;
|
||||
if [ ${skip_ssh} -eq 0 ]; then
|
||||
# MARK: SSH CREATE
|
||||
# write login info to output file
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
create_output_file="${ROOT_FOLDER}${output_file}";
|
||||
@@ -444,6 +492,8 @@ done <<< "$(cat "${ROOT_FOLDER}${input_file}")";
|
||||
if [ ${INFO} -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# MARK: ZIP FILE CREATE
|
||||
# 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
|
||||
@@ -488,4 +538,9 @@ else
|
||||
echo "$> rm ${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}*";
|
||||
fi;
|
||||
|
||||
# MARK: TEST ERROR INFO
|
||||
if [ ${TEST} -eq 1 ] && [ ${overall_run_error} -eq 1 ]; then
|
||||
echo "[ERROR] Some errors occoured during the run, they will prohibit the live run of this script";
|
||||
fi;
|
||||
|
||||
# __END__
|
||||
|
||||
@@ -60,20 +60,16 @@ backup_folder="${BASE_FOLDER}../backup/";
|
||||
input_file='user_list.txt';
|
||||
user_list_file="${root_folder}${input_file}";
|
||||
# log file
|
||||
LOG="${BASE_FOLDER}/../log/delete_user."$(date +"%F_%H%m%S");
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
LOG="${LOG}.log";
|
||||
else
|
||||
LOG="${LOG}.test.log";
|
||||
fi;
|
||||
HISTORY="${BASE_FOLDER}/../log/delete_user.log";
|
||||
# ignore users (root and admin users)
|
||||
ignore_users=('root' 'ec2-user' 'ubuntu' 'admin');
|
||||
# detect ssh authorized_keys setting
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER='';
|
||||
SSH_AUTHORIZED_FILE='';
|
||||
for cf in $(grep "^AuthorizedKeysFile" /etc/ssh/sshd_config | grep "%u"); do
|
||||
if [ -n "$(echo "${cf}" | grep "%u")" ]; then
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER=$(echo "${cf}" | sed -e 's/%u//');
|
||||
# shellcheck disable=SC2013
|
||||
for cf in $(grep "^AuthorizedKeysFile" "/etc/ssh/sshd_config" | grep "%u"); do
|
||||
if echo "$cf" | grep -q "%u"; then
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER="${cf/%%u//}";
|
||||
if [ ! -d "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ]; then
|
||||
echo "ssh central authorized_file folder could not be found: ${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}";
|
||||
exit;
|
||||
@@ -86,17 +82,39 @@ if [ ! -f "${user_list_file}" ]; then
|
||||
exit;
|
||||
fi;
|
||||
|
||||
LOG="${BASE_FOLDER}/../log/user_management.log";
|
||||
function write_log()
|
||||
{
|
||||
text="${1}";
|
||||
do_echo="${2}";
|
||||
log_prefix="";
|
||||
# log prefix for testing
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
log_prefix="[TEST] ";
|
||||
fi;
|
||||
# write log not in info run
|
||||
echo "[$(date +"%F %T")] [$0] ${log_prefix}${text}" >> "${LOG}";
|
||||
if [ "${do_echo}" = "1" ]; then
|
||||
echo "${text}";
|
||||
fi;
|
||||
}
|
||||
write_log "START SCRIPT RUN";
|
||||
|
||||
# used for test run only
|
||||
overall_run_error=0;
|
||||
|
||||
# $1 ... $n
|
||||
for username in "$@"; do
|
||||
error=0;
|
||||
# skip if there is an option hidden
|
||||
# shellcheck disable=SC2154
|
||||
if [[ ${_arg:0:1} = "-" ]]; then
|
||||
continue;
|
||||
fi;
|
||||
# skip ignore users, note that if a user is not in the sshallow list anyway
|
||||
# we skip them too, this is just in case check
|
||||
if [[ " ${ignore_users[*]} " =~ [[:space:]]${username}[[:space:]] ]]; then
|
||||
echo "[!] User ${username} is in the ignore user list";
|
||||
write_log "[!] User ${username} is in the ignore user list" "1";
|
||||
continue;
|
||||
fi;
|
||||
|
||||
@@ -104,31 +122,33 @@ for username in "$@"; do
|
||||
# if missing in or another do not continue
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
# not in passwd
|
||||
echo "[!!!] User ${username} does not exist in /etc/passwd";
|
||||
write_log "[ERRPR] User ${username} does not exist in /etc/passwd" "1";
|
||||
error=1;
|
||||
fi;
|
||||
user_list_entry=$(grep "${username}" "${user_list_file}");
|
||||
if [ -z "${user_list_entry}" ]; then
|
||||
echo "[!!!] User ${username} does not exist in user_list.txt file";
|
||||
write_log "[ERROR] User ${username} does not exist in user_list.txt file" "1";
|
||||
error=1;
|
||||
elif [[ "${user_list_entry}" =~ ^#DELETED ]]; then
|
||||
echo "[!!!] User ${username} is flagged as deleted in user_list.txt file";
|
||||
write_log "[ERROR] User ${username} is flagged as deleted in user_list.txt file" "1";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
if [ $error -eq 1 ]; then
|
||||
overall_run_error=1;
|
||||
write_log "[*** ABORT RUN ***]" "1";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
echo "=> Delete: ${username}";
|
||||
write_log "=> Delete: ${username}" "1";
|
||||
# ssh authorized file
|
||||
SSH_AUTHORIZED_FILE="${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}${username}";
|
||||
|
||||
# make backup from /home
|
||||
if [ ${BACKUP} -eq 1 ]; then
|
||||
home_folder=$(getent passwd ${username} | cut -d ":" -f 6);
|
||||
home_folder=$(getent passwd "${username}" | cut -d ":" -f 6);
|
||||
backup_file="${backup_folder}${host}${separator}${username}.${timestamp}.tar.bz2";
|
||||
files_list="${home_folder}";
|
||||
if [ -f "${SSH_AUTHORIZED_FILE}" ]; then
|
||||
@@ -136,7 +156,7 @@ for username in "$@"; do
|
||||
fi;
|
||||
echo "[0] Backup ${files_list} to ${backup_file}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
tar cfjp "${backup_file}" ${file_list};
|
||||
tar cfjp "${backup_file}" "${files_list}";
|
||||
else
|
||||
echo "$> tar cfjp \"${backup_file}\" ${files_list};";
|
||||
fi;
|
||||
@@ -144,9 +164,13 @@ for username in "$@"; do
|
||||
|
||||
echo "[1] Remove user + home dir";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
userdel -r ${username}
|
||||
# remove all secondary group entries first before we delete the user
|
||||
# there might be cases where they are left
|
||||
usermod -G "" "${username}";
|
||||
userdel -r "${username}";
|
||||
else
|
||||
echo "$> userdel -r ${username}";
|
||||
echo "$> usermod -G \"\" \"${username}\"";
|
||||
echo "$> userdel -r \"${username}\"";
|
||||
fi;
|
||||
|
||||
# remove ssh files in pub
|
||||
@@ -162,7 +186,7 @@ for username in "$@"; do
|
||||
fi;
|
||||
else
|
||||
# Not critical error
|
||||
echo "[?] Cannot find ${SSH_AUTHORIZED_FILE}";
|
||||
write_log "[?] Cannot find ${SSH_AUTHORIZED_FILE}" "1";
|
||||
fi;
|
||||
|
||||
# Update user_list.txt file and add # for the line
|
||||
@@ -172,11 +196,17 @@ for username in "$@"; do
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
sed -i -e "s/^\([A-Za-z0-9]\{1,\};${username};\)/#DELETED-${delete_date}:\1/" "${user_list_file}";
|
||||
else
|
||||
# shellcheck disable=SC2028
|
||||
echo "$> sed -i -e \"s/^\([A-Za-z0-9]\{1,\};${username};\)/#DELETED-${delete_date}:\1/\" \"${user_list_file}\";";
|
||||
fi;
|
||||
|
||||
echo $(date +"%F %T")";${host};${username}" >> "${LOG}";
|
||||
echo "$(date +"%F %T");${host};${username};${TEST}" >> "${HISTORY}";
|
||||
|
||||
done;
|
||||
|
||||
# MARK: TEST ERROR INFO
|
||||
if [ ${TEST} -eq 1 ] && [ ${overall_run_error} -eq 1 ]; then
|
||||
echo "[ERROR] Some errors occoured during the run, they will prohibit the live run of this script";
|
||||
fi;
|
||||
|
||||
# __END__
|
||||
|
||||
@@ -46,27 +46,50 @@ ssh_allow_group="sshallow";
|
||||
ssh_forward_group="sshforward";
|
||||
user_group_tpl="gpasswd -d %s %s\ngpasswd -a %s %s\n";
|
||||
|
||||
# base folder for all data
|
||||
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
||||
LOG="${BASE_FOLDER}/../log/user_management.log";
|
||||
function write_log()
|
||||
{
|
||||
text="${1}";
|
||||
do_echo="${2}";
|
||||
log_prefix="";
|
||||
# log prefix
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
log_prefix="TEST";
|
||||
fi;
|
||||
if [ -n "${log_prefix}" ]; then
|
||||
log_prefix="[${log_prefix}] ";
|
||||
fi;
|
||||
echo "[$(date +"%F %T")] [$0] ${log_prefix}${text}" >> "${LOG}";
|
||||
if [ "${do_echo}" = "1" ]; then
|
||||
echo "${text}";
|
||||
fi;
|
||||
}
|
||||
write_log "START SCRIPT RUN";
|
||||
|
||||
echo "--------------------->"
|
||||
# $1 ... $n
|
||||
for username in "$@"; do
|
||||
# skip if there is an option hidden
|
||||
# shellcheck disable=SC2154
|
||||
if [[ ${_arg:0:1} = "-" ]]; then
|
||||
continue;
|
||||
fi;
|
||||
# skip ignore users, note that if a user is not in the sshallow list anyway
|
||||
# we skip them too, this is just in case check
|
||||
if [[ " ${ignore_users[*]} " =~ [[:space:]]${username}[[:space:]] ]]; then
|
||||
echo "[!] User ${username} is in the ignore user list";
|
||||
write_log "[ERROR] User ${username} is in the ignore user list" "1";
|
||||
continue;
|
||||
fi;
|
||||
# check that user exists in passwd
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
echo "[!] User ${username} does not exists in /etc/passwd file";
|
||||
write_log "[ERROR] User ${username} does not exists in /etc/passwd file" "1";
|
||||
continue;
|
||||
fi;
|
||||
# if not check if in reject list
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_reject_group}"; then
|
||||
echo "[.] User ${username} already in the ${ssh_reject_group} list";
|
||||
write_log "[.] User ${username} already in the ${ssh_reject_group} list";
|
||||
continue;
|
||||
fi;
|
||||
# check if user is in sshallow/forward list
|
||||
@@ -77,14 +100,14 @@ for username in "$@"; do
|
||||
# if user is in ssh allow group and ALSO in ssh forward group -> bad
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_forward_group}"; then
|
||||
if [ -n "${ssh_remove_group}" ]; then
|
||||
echo "[!!!! ERROR !!!!] User ${username} exists in both ${ssh_allow_group} and ${ssh_forward_group} group which should not be allowed. Remove user from one group and run script again.";
|
||||
write_log "[!!!! ERROR !!!!] User ${username} exists in both ${ssh_allow_group} and ${ssh_forward_group} group which should not be allowed. Remove user from one group and run script again." "1";
|
||||
break;
|
||||
fi;
|
||||
ssh_remove_group="${ssh_forward_group}";
|
||||
fi;
|
||||
if [ -n "${ssh_remove_group}" ]; then
|
||||
# remove user from ssh group and add to reject groups
|
||||
echo "[*] User ${username} will be removed from ${ssh_remove_group}";
|
||||
write_log "[*] User ${username} will be removed from ${ssh_remove_group}" "1";
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
# shellcheck disable=SC2059
|
||||
printf "${user_group_tpl}" "${username}" "${ssh_remove_group}" "${username}" "${ssh_reject_group}";
|
||||
@@ -94,7 +117,7 @@ for username in "$@"; do
|
||||
fi;
|
||||
else
|
||||
# skip not ssh user
|
||||
echo "[?] User ${username} not in any ssh allow/foward groups";
|
||||
write_log "[?] User ${username} not in any ssh allow/foward groups" "1";
|
||||
fi;
|
||||
done;
|
||||
|
||||
|
||||
@@ -58,13 +58,6 @@ input_file='user_list.txt';
|
||||
user_list_file="${ROOT_FOLDER}${input_file}";
|
||||
default_ssh_keytype='ed25519';
|
||||
ssh_keytype='';
|
||||
# log file
|
||||
LOG="${BASE_FOLDER}/../log/rename_user."$(date +"%F_%H%m%S");
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
LOG="${LOG}.log";
|
||||
else
|
||||
LOG="${LOG}.test.log";
|
||||
fi;
|
||||
# ignore users (root and admin users)
|
||||
ignore_users=('root' 'ec2-user' 'ubuntu' 'admin');
|
||||
# detect ssh authorized_keys setting
|
||||
@@ -144,6 +137,27 @@ if [ $error -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# log file
|
||||
LOG="${BASE_FOLDER}/../log/user_management.log";
|
||||
function write_log()
|
||||
{
|
||||
text="${1}";
|
||||
do_echo="${2}";
|
||||
log_prefix="";
|
||||
# log prefix
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
log_prefix="TEST";
|
||||
fi;
|
||||
if [ -n "${log_prefix}" ]; then
|
||||
log_prefix="[${log_prefix}] ";
|
||||
fi;
|
||||
echo "[$(date +"%F %T")] [$0] ${log_prefix}${text}" >> "${LOG}";
|
||||
if [ "${do_echo}" = "1" ]; then
|
||||
echo "${text}";
|
||||
fi;
|
||||
}
|
||||
write_log "START SCRIPT RUN";
|
||||
|
||||
# parse user list entry for group/hostname/ssh type key to build ssh key list
|
||||
|
||||
# POS 3: groups
|
||||
@@ -164,7 +178,7 @@ else
|
||||
ssh_keytype=${default_ssh_keytype};
|
||||
fi;
|
||||
|
||||
echo "* Rename ${OLD_USERNAME} to ${NEW_USERNAME}";
|
||||
write_log "* Rename ${OLD_USERNAME} to ${NEW_USERNAME}" "1";
|
||||
|
||||
old_home_dir=$(getent passwd "${OLD_USERNAME}" | cut -d: -f6);
|
||||
new_home_dir=$(echo "${old_home_dir}" | sed -e "s/\/${OLD_USERNAME}$/\/${NEW_USERNAME}/");
|
||||
@@ -202,7 +216,7 @@ NEW_SSH_AUTHORIZED_FILE="${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}${NEW_USERNAME}";
|
||||
|
||||
if [ -f "${OLD_SSH_AUTHORIZED_FILE}" ]; then
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "rename to ${NEW_SSH_AUTHORIZED_FILE}";
|
||||
write_log "rename to ${NEW_SSH_AUTHORIZED_FILE}" "1";
|
||||
chattr -i "${OLD_SSH_AUTHORIZED_FILE}";
|
||||
mv "${OLD_SSH_AUTHORIZED_FILE}" "${NEW_SSH_AUTHORIZED_FILE}";
|
||||
chattr +i "${NEW_SSH_AUTHORIZED_FILE}";
|
||||
@@ -212,7 +226,7 @@ if [ -f "${OLD_SSH_AUTHORIZED_FILE}" ]; then
|
||||
echo "$> chattr +i \"${NEW_SSH_AUTHORIZED_FILE}\";";
|
||||
fi;
|
||||
else
|
||||
echo "[?] ${OLD_SSH_AUTHORIZED_FILE} is missing";
|
||||
write_log "[?] ${OLD_SSH_AUTHORIZED_FILE} is missing" "1";
|
||||
fi;
|
||||
|
||||
# rename keygen public file
|
||||
@@ -221,13 +235,13 @@ NEW_ssh_keygen_pub="${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}${hostname}${s
|
||||
|
||||
if [ -f "${OLD_ssh_keygen_pub}" ]; then
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "rename to ${NEW_ssh_keygen_pub}";
|
||||
write_log "rename to ${NEW_ssh_keygen_pub}" "1";
|
||||
mv "${OLD_ssh_keygen_pub}" "${NEW_ssh_keygen_pub}";
|
||||
else
|
||||
echo "$> mv \"${OLD_ssh_keygen_pub}\" \"${NEW_ssh_keygen_pub}\";";
|
||||
fi;
|
||||
else
|
||||
echo "[?] ${OLD_ssh_keygen_pub} is missing";
|
||||
write_log "[?] ${OLD_ssh_keygen_pub} is missing" "1";
|
||||
fi;
|
||||
|
||||
# rename entry in user list txt file
|
||||
|
||||
@@ -61,31 +61,52 @@ ssh_allow_group="sshallow";
|
||||
ssh_forward_group="sshforward";
|
||||
user_group_tpl="gpasswd -d %s %s\ngpasswd -a %s %s\n";
|
||||
|
||||
LOG="${BASE_FOLDER}/../log/user_management.log";
|
||||
function write_log()
|
||||
{
|
||||
text="${1}";
|
||||
do_echo="${2}";
|
||||
log_prefix="";
|
||||
# log prefix
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
log_prefix="TEST";
|
||||
fi;
|
||||
if [ -n "${log_prefix}" ]; then
|
||||
log_prefix="[${log_prefix}] ";
|
||||
fi;
|
||||
echo "[$(date +"%F %T")] [$0] ${log_prefix}${text}" >> "${LOG}";
|
||||
if [ "${do_echo}" = "1" ]; then
|
||||
echo "${text}";
|
||||
fi;
|
||||
}
|
||||
write_log "START SCRIPT RUN";
|
||||
|
||||
echo "--------------------->"
|
||||
# $1 ... $n
|
||||
for username in "$@"; do
|
||||
# skip if there is an option hidden
|
||||
# shellcheck disable=SC2154
|
||||
if [[ ${_arg:0:1} = "-" ]]; then
|
||||
continue;
|
||||
fi;
|
||||
# skip ignore users, note that if a user is not in the sshallow list anyway
|
||||
# we skip them too, this is just in case check
|
||||
if [[ " ${ignore_users[*]} " =~ [[:space:]]${username}[[:space:]] ]]; then
|
||||
echo "[!] User ${username} is in the ignore user list";
|
||||
write_log "[ERROR] User ${username} is in the ignore user list" "1";
|
||||
continue;
|
||||
fi;
|
||||
# check that user exists in passwd
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
echo "[!] User ${username} does not exists in /etc/passwd file";
|
||||
write_log "[ERROR] User ${username} does not exists in /etc/passwd file" "1";
|
||||
continue;
|
||||
fi;
|
||||
# check if already in OK groups
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_allow_group}"; then
|
||||
echo "[.] User ${username} already in the ${ssh_allow_group} list";
|
||||
write_log "[.] User ${username} already in the ${ssh_allow_group} list" "1";
|
||||
continue;
|
||||
fi;
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_forward_group}"; then
|
||||
echo "[.] User ${username} already in the ${ssh_forward_group} list";
|
||||
write_log "[.] User ${username} already in the ${ssh_forward_group} list" "1";
|
||||
continue;
|
||||
fi;
|
||||
# try to find user in user_list.txt and get the allow/forward flag from there,
|
||||
@@ -103,7 +124,7 @@ for username in "$@"; do
|
||||
# check if user is in reject group remove
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_reject_group}"; then
|
||||
# remove user from ssh group and add to reject groups
|
||||
echo "[*] User ${username} will be added to ${ssh_add_group}";
|
||||
write_log "[*] User ${username} will be added to ${ssh_add_group}" "1";
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
# shellcheck disable=SC2059
|
||||
printf "${user_group_tpl}" "${username}" "${ssh_reject_group}" "${username}" "${ssh_add_group}";
|
||||
@@ -113,7 +134,7 @@ for username in "$@"; do
|
||||
fi;
|
||||
else
|
||||
# skip not ssh user
|
||||
echo "[?] User ${username} not in the ssh reject group";
|
||||
write_log "[?] User ${username} not in the ssh reject group" "1";
|
||||
fi;
|
||||
done;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user