Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70212da3cb | ||
|
|
168cf9db15 | ||
|
|
92ef3f0f2e | ||
|
|
f181ee74e3 | ||
|
|
93224e3768 | ||
|
|
571ddcc717 | ||
|
|
eb194c2f1c | ||
|
|
a1af63de39 | ||
|
|
b5854f93c4 | ||
|
|
5735cf2ffb | ||
|
|
081bb1cc4c | ||
|
|
e02822f06d | ||
|
|
2956998762 | ||
|
|
46dc2be34d | ||
|
|
43ef147de6 | ||
|
|
fa7e7fbe86 | ||
|
|
fa3c4e0c6e | ||
|
|
ebf0eaf412 | ||
|
|
190b12b288 | ||
|
|
3a42c521f6 | ||
|
|
61a8bca3d7 | ||
|
|
a0e7347033 | ||
|
|
c58b0ea7a4 | ||
|
|
fb00036ab9 | ||
|
|
8808b94413 | ||
|
|
1fbc6c8125 | ||
|
|
87d53cdb13 | ||
|
|
716a0c2bfb | ||
|
|
365b52efe5 | ||
|
|
b10cb62612 | ||
|
|
1f4e295e9f |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,3 @@
|
||||
user_list.txt
|
||||
user_password*.txt
|
||||
user_password*.txt*
|
||||
*.zip
|
||||
|
||||
89
Readme.md
89
Readme.md
@@ -11,22 +11,27 @@ The folder holding the script must be owned by *root* and have *600* permissions
|
||||
|
||||
```sh
|
||||
cd /root/
|
||||
git clone https://git.tequila.jp/ScriptsCollections/AwsUserCreate.git users
|
||||
git clone http://gitlab-ap.factory.tools/scripts-collections/aws-user-create.git users
|
||||
chown root. users
|
||||
chgrp 600 users
|
||||
```
|
||||
|
||||
Alternate download: `git clone http://gitlab-ap.factory.tools/scripts-collections/aws-user-create.git users`
|
||||
Alternate download:
|
||||
`git clone https://git.tequila.jp/ScriptsCollections/AwsUserCreate.git users`
|
||||
|
||||
## Folders
|
||||
|
||||
Inside the base folder there are
|
||||
|
||||
* ssh-keygen for temporary holding the PEM/PUB files
|
||||
* zip file which holds the created user list, password and PEM/PUB files
|
||||
- ssh-keygen for temporary holding the PEM/PUB files
|
||||
- zip file which holds the created user list, password and PEM/PUB files
|
||||
|
||||
## Options
|
||||
|
||||
### -g (go)
|
||||
|
||||
If not set, the script will not run.
|
||||
|
||||
### -t (test)
|
||||
|
||||
Run in test mode. This will *NOT* create any groups or users. Nor will it create any ssh key files.
|
||||
@@ -42,14 +47,15 @@ In the `/root/users/` folder there needs to be a file called '*user_list.txt*'
|
||||
|
||||
This is a CSV type file with the following layout
|
||||
|
||||
ID | Username | Group | Optional Password | Override host name | Override ssh key type
|
||||
-|-|-|-|-|-
|
||||
ID | Username | Group and Sub Group | SSH Access Type | Optional Password | Override host name | Override ssh key type
|
||||
-|-|-|-|-|-|-
|
||||
|
||||
The ID, Username and Group column must be filled.
|
||||
For sub groups add them with a *,* The first group is the master group
|
||||
If the password column is filled, the string from here will be used as the PEM Key password.
|
||||
If a override hostname is set it will be used instead of `hostname`
|
||||
If the ssh key type is set, it will override the default *ed25519* type. This is not recommended. Only *rsa* is allowed. This is for setting up backwards compatible lists.
|
||||
1: The ID, Username and Group column must be filled.
|
||||
2: For sub groups add them with a *,* The first group is the master group
|
||||
3: SSH Access type as: allow/forward. allow is default
|
||||
4: If the password column is filled, the string from here will be used as the PEM Key password.
|
||||
5: If a override hostname is set it will be used instead of `hostname`
|
||||
6: If the ssh key type is set, it will override the default *ed25519* type. Only *rsa* is allowed. This is for setting up backwards compatible lists. Change is not recommended
|
||||
|
||||
The ID can be any string in any form.
|
||||
It can also be left empty. It is not used at the moment
|
||||
@@ -59,10 +65,11 @@ The file can hold comments. The first character in the line must be a *#*
|
||||
Example file
|
||||
|
||||
```csv
|
||||
user1;some.name;group-a;;hostname
|
||||
user2;othername;group-a;;
|
||||
#user_id;user_name;group,subgroup;ssh access type;override password;override hostname;override ssh type
|
||||
user1;some.name;group-a;allow;;hostname;
|
||||
user2;othername;group-a;allow;;;
|
||||
# I am a comment
|
||||
;username;groupC;setpassword;
|
||||
;username;groupC;allow;setpassword;;
|
||||
...
|
||||
```
|
||||
|
||||
@@ -131,7 +138,7 @@ If the public pem file is already provided the output will be a bit different
|
||||
|
||||
```txt
|
||||
++ Create 'some.name:group-a'
|
||||
< Use existing public ssh key '/root/users/ssh-keygen/hostname#group-a#some.name#ed25519.pem.pub'
|
||||
< Use existing public ssh key '/root/users/ssh-keygen-created-pub/hostname#group-a#some.name#ed25519.pem.pub'
|
||||
> Create .ssh folder
|
||||
> Add public into authorized_keys
|
||||
> Secure folder .ssh and authorized_keys file
|
||||
@@ -187,9 +194,9 @@ The SSH PEM key password can be reset or changed with
|
||||
|
||||
To remove the password use this `-N ""`
|
||||
|
||||
**NOTE**
|
||||
If the command is used like this it will be stored in the history file.
|
||||
For scurity reason it is recommended to not give the -P and -N options when changing the password.
|
||||
> [!notice]
|
||||
> If the command is used like this it will be stored in the history file.
|
||||
> For scurity reason it is recommended to not give the -P and -N options when changing the password
|
||||
|
||||
### Missing PUB key
|
||||
|
||||
@@ -197,7 +204,32 @@ The public key part can be extracted from the SSH PEM key with
|
||||
|
||||
`$> ssh-keygen -y -f [PEM].pem > [PEM].pem.pub`
|
||||
|
||||
*[PEM]* is the placeholder for the filename
|
||||
`[PEM]` is the placeholder for the filename
|
||||
|
||||
## Lock and unlock uses
|
||||
|
||||
If a user should be stopped from logging in via ssh the user needs to be removed from the sshallow or sshforward groups. Note that the sshforward group only exists on jump hosts and can normally be ignored.
|
||||
|
||||
Default 100% ignored users are 'root', 'ec2-user', 'admin', 'ubuntu'
|
||||
|
||||
### Lock users
|
||||
|
||||
`bin/lock_users.sh -t <user 1> <user 2> ...`
|
||||
|
||||
The `-t` flag is for test run.
|
||||
|
||||
If the user is not in the sshallow or sshreject group the change will be skipped.
|
||||
Locked users will be moved to the sshreject group
|
||||
|
||||
### Unlock users
|
||||
|
||||
If a user exists in the sshreject group the user can be unlocked
|
||||
|
||||
`bin/unlock_uses.sh -t -s <allow|forward> <user 1> <user 2> ...`
|
||||
|
||||
Like the lock user script it will only work on users in the sshreject group. But here the target allow / forward group must be selected.
|
||||
|
||||
If not set it defaults to allow, if a user_list.txt file with this user exist it will try to extract this data if the `-s` option is not set
|
||||
|
||||
## Last login check scripts
|
||||
|
||||
@@ -224,3 +256,22 @@ The script can be put into the crontab and run once a month, it prints to STDOUT
|
||||
```crontab
|
||||
0 2 1 * * root /root/users/bin/check_last_login.sh | mail -s "User Account check: $(hostname)"
|
||||
```
|
||||
|
||||
## Delete users
|
||||
|
||||
`bin/delete_user.sh -t -b <user 1> <user 2> ...`
|
||||
|
||||
Deletes one or more users
|
||||
|
||||
- `-t` test, no action done
|
||||
- `-b` do not create a backup
|
||||
|
||||
Unless `-b` is set the home folder and public key in /etc/ssh will be backed up.
|
||||
Flags user with #DELETED-YYYYMMDD_HHmmss:id;... in the user_list.txt file
|
||||
|
||||
## Rename user
|
||||
|
||||
`bin/rename_user.sh -t -o <current user name> -n <new user name>`
|
||||
|
||||
Renames a user including the home directory, public key files and any other connected data.
|
||||
Also updates the user_list.txt
|
||||
|
||||
2
backup/.gitignore
vendored
Normal file
2
backup/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
181
bin/authorized_key_location_change.sh
Executable file
181
bin/authorized_key_location_change.sh
Executable file
@@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# check if we need to move the users authorized keys to the central location
|
||||
|
||||
TEST=1;
|
||||
LIST=0;
|
||||
SKIP_USERS=();
|
||||
while getopts ":gls:" opt; do
|
||||
case "${opt}" in
|
||||
g|go)
|
||||
# default we test
|
||||
TEST=0;
|
||||
;;
|
||||
s|skip)
|
||||
SKIP_USERS+=("${OPTARG}");
|
||||
;;
|
||||
l|list)
|
||||
LIST=1;
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "Use -g for go (run) and -s <user> for users to skip";
|
||||
exit 1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
|
||||
# check if authorized keys is actually enabled
|
||||
# detect ssh authorized_keys setting
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER='';
|
||||
SSH_MASTER_AUTHORIZED_FILE='';
|
||||
SSH_AUTHORIZED_FILE='';
|
||||
for cf in $(grep "^AuthorizedKeysFile" /etc/ssh/sshd_config | grep "%u"); do
|
||||
if [ ! -z $(echo "${cf}" | grep "%u") ]; then
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER=$(echo "${cf}" | sed -e 's/%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;
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
if [ -z "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ]; then
|
||||
echo "No central authorized_keys file detected, no change check needed";
|
||||
exit;
|
||||
fi;
|
||||
for cf in $(grep "^AuthorizedKeysFile" /etc/ssh/sshd_config | grep -- "--master"); do
|
||||
if [ ! -z $(echo "${cf}" | grep -- "--master") ]; then
|
||||
SSH_MASTER_AUTHORIZED_FILE="${cf}";
|
||||
if [ ! -f "${SSH_MASTER_AUTHORIZED_FILE}" ]; then
|
||||
echo "ssh master authorized_file could not be found: ${SSH_MASTER_AUTHORIZED_FILE}"l
|
||||
exit;
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
if [ -z "${SSH_MASTER_AUTHORIZED_FILE}" ]; then
|
||||
echo "No master authorized_key file detected, no change check needed";
|
||||
exit;
|
||||
fi;
|
||||
echo "SSH Master Authorized Key file: ${SSH_MASTER_AUTHORIZED_FILE}";
|
||||
echo "SSH Authorized Keys file folder: ${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}";
|
||||
|
||||
if [ ${LIST} -eq 1 ]; then
|
||||
ls -l "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}";
|
||||
lsattr "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# base folder
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
# output printf
|
||||
PRINTF_INFO="%-8s [%3s]: %-25s: %s\n";
|
||||
# list of user accounts we will never touch
|
||||
NO_ACTION=(root);
|
||||
# move, but must check that master is set
|
||||
# master key is the first in the authorized keys list for the below users
|
||||
MASTER_KEY=(admin ec2-user ubuntu);
|
||||
# skip user file
|
||||
IGNORE_USER_FILE="../config/authorized_key_location_change.ignore"
|
||||
# list of users to skip from file
|
||||
IGNORE_USER=();
|
||||
|
||||
if [ -f "${BASE_FOLDER}${IGNORE_USER_FILE}" ]; then
|
||||
readarray -t IGNORE_USER < "${BASE_FOLDER}${IGNORE_USER_FILE}";
|
||||
echo "Reading ${IGNORE_USER_FILE}";
|
||||
fi;
|
||||
|
||||
# loop over passwd file
|
||||
# if not in no action then check if .ssh/authorized_keys file exists
|
||||
cat /etc/passwd | cut -d ":" -f 1,6 |
|
||||
while read user_home; do
|
||||
username=$(echo "${user_home}" | cut -d ":" -f 1);
|
||||
master_user=0;
|
||||
# skip admin usernames
|
||||
if [[ " ${NO_ACTION[*]} " =~ " ${username} " ]]; then
|
||||
printf "${PRINTF_INFO}" "NO ACT" "!" "${username}" "user in NO ACTION list";
|
||||
continue;
|
||||
fi;
|
||||
if [[ " ${SKIP_USERS[*]} " =~ " ${username} " ]]; then
|
||||
printf "${PRINTF_INFO}" "SKIP" "*" "${username}" "skip forced via command line";
|
||||
continue;
|
||||
fi;
|
||||
if [[ " ${IGNORE_USER[*]} " =~ " ${username} " ]]; then
|
||||
printf "${PRINTF_INFO}" "SKIP" "**" "${username}" "skip from ignore config file";
|
||||
continue;
|
||||
fi;
|
||||
home_folder=$(echo "${user_home}" | cut -d ":" -f 2);
|
||||
# skip no .ssh/authorized_ekys
|
||||
if [ ! -f "${home_folder}/.ssh/authorized_keys" ]; then
|
||||
# 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";
|
||||
else
|
||||
printf "${PRINTF_INFO}" "IGNORE" "?" "${username}" "no authorized_keys file";
|
||||
fi;
|
||||
continue;
|
||||
fi;
|
||||
# check those keys are in the master key list
|
||||
if [[ " ${MASTER_KEY[*]} " =~ " ${username} " ]]; then
|
||||
master_user=1;
|
||||
ssh_key_diff=$(diff -u "${home_folder}/.ssh/authorized_keys" "${SSH_MASTER_AUTHORIZED_FILE}");
|
||||
if [ ! -z "${ssh_key_diff}" ]; then
|
||||
printf "${PRINTF_INFO}" "ABORT" "!!!" "${username}" "authorized key is not matching the master key file";
|
||||
exit;
|
||||
fi;
|
||||
fi;
|
||||
# check if this user public key(s) exist in AuthorizedKeysFile target
|
||||
if [ -f "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}" ]; then
|
||||
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";
|
||||
if [ ${master_user} -eq 0 ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
rm "${home_folder}/.ssh/authorized_keys";
|
||||
else
|
||||
echo "$> rm \"${home_folder}/.ssh/authorized_keys\"";
|
||||
fi;
|
||||
else
|
||||
echo "[!] No delete for master user, must be done manually";
|
||||
fi;
|
||||
continue;
|
||||
fi;
|
||||
# No update, alert
|
||||
printf "${PRINTF_INFO}" "DIFF" "???" "${username}" "Different authorized keys in home dir, SKIPPED";
|
||||
continue;
|
||||
fi;
|
||||
printf "${PRINTF_INFO}" "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}";
|
||||
# secure new folder: chown/chmod/chattr
|
||||
chown ${username} "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}";
|
||||
chmod 400 "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}";
|
||||
chattr +i "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}";
|
||||
# confirm
|
||||
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}" "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";
|
||||
fi;
|
||||
else
|
||||
echo "[START] ====>";
|
||||
echo "$> cat \"${home_folder}/.ssh/authorized_keys\" > \"${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}\"";
|
||||
echo "$> chown ${username} \"${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}\"";
|
||||
echo "$> chmod 400 \"${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}\"";
|
||||
echo "$> chattr +i \"${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}/${username}\"";
|
||||
if [ ${master_user} -eq 0 ]; then
|
||||
echo "$> rm \"${home_folder}/.ssh/authorized_keys\"";
|
||||
else
|
||||
echo "[!] No delete for master user, must be done manually";
|
||||
fi;
|
||||
echo "[END ] ====>";
|
||||
fi;
|
||||
done;
|
||||
|
||||
# __END__
|
||||
@@ -16,8 +16,7 @@ max_age_create=30;
|
||||
# one day in seconds
|
||||
day=86400;
|
||||
# delete account strings
|
||||
delete_accounts="";
|
||||
user_group_tpl="gpasswd -d %s %s;gpasswd -a %s %s;";
|
||||
lock_accounts="";
|
||||
# log base folder
|
||||
LOG="${BASE_FOLDER}/../log";
|
||||
# auth log file user;date from collect_login_data script
|
||||
@@ -41,21 +40,26 @@ echo "Max age no login : ${max_age_create} days";
|
||||
for ssh_group in ${ssh_groups[@]}; do
|
||||
echo "--------------------->"
|
||||
echo "Checking Group : ${ssh_group}";
|
||||
for user in $(cat /etc/group|grep "${ssh_group}:" | cut -d ":" -f 4 | sed -e 's/,/ /g'); do
|
||||
for username in $(cat /etc/group|grep "${ssh_group}:" | cut -d ":" -f 4 | sed -e 's/,/ /g'); do
|
||||
# check that user exists in passwd
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
echo "[!] User $username does not exists in /etc/passwd file";
|
||||
continue;
|
||||
fi;
|
||||
account_age=0;
|
||||
delete_user=0;
|
||||
lock_user=0;
|
||||
out_string="";
|
||||
#echo "* Checking user ${user}";
|
||||
#echo "* Checking user ${username}";
|
||||
# check user create time, if we have set it in comment
|
||||
user_create_date=$(cat /etc/passwd | grep "${user}:" | cut -d ":" -f 5);
|
||||
user_create_date=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 5);
|
||||
# if empty try last password set time
|
||||
if [ -z "${user_create_date}" ]; then
|
||||
# user L 11/09/2020 0 99999 7 -1
|
||||
user_create_date=$(passwd -S ${user} | cut -d " " -f 3);
|
||||
user_create_date=$(passwd -S ${username} | cut -d " " -f 3);
|
||||
fi;
|
||||
# last try is user home .bash_logout
|
||||
if [ -z "${user_create_date}" ]; then
|
||||
home_dir=$(cat /etc/passwd | grep "${user}:" | cut -d ":" -f 6)"/.bash_logout";
|
||||
home_dir=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 6)"/.bash_logout";
|
||||
user_create_date=$(stat -c %Z "${home_dir}");
|
||||
fi;
|
||||
|
||||
@@ -63,19 +67,19 @@ echo "Checking Group : ${ssh_group}";
|
||||
# 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 ${user} | sed 1d);
|
||||
last_login_string=$(lastlog -u ${username} | sed 1d);
|
||||
search="Never logged in";
|
||||
found="";
|
||||
# problem with running rep check in if
|
||||
if [ -f "${AUTH_LOG}" ]; then
|
||||
found=$(grep "${user};" "${AUTH_LOG}");
|
||||
found=$(grep "${username};" "${AUTH_LOG}");
|
||||
fi;
|
||||
if [ ! -z "${found}" ]; then
|
||||
last_login_date=$(grep "${user};" "${AUTH_LOG}" | cut -d ";" -f 2 | date +"%s" -f -);
|
||||
last_login_date=$(grep "${username};" "${AUTH_LOG}" | cut -d ";" -f 2 | 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 ssh log in ${last_login} days ago";
|
||||
delete_user=1;
|
||||
lock_user=1;
|
||||
else
|
||||
out_string="OK [ssh]";
|
||||
fi;
|
||||
@@ -88,7 +92,7 @@ echo "Checking Group : ${ssh_group}";
|
||||
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";
|
||||
delete_user=1;
|
||||
lock_user=1;
|
||||
else
|
||||
out_string="OK [lastlog]";
|
||||
fi;
|
||||
@@ -100,7 +104,7 @@ echo "Checking Group : ${ssh_group}";
|
||||
account_age=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${user_create_date} ${day}");
|
||||
if [ ${account_age} -gt ${max_age_create} ]; then
|
||||
out_string="[!] Never logged in, account created ${account_age} days ago";
|
||||
delete_user=1;
|
||||
lock_user=1;
|
||||
else
|
||||
out_string="OK [first login]";
|
||||
fi;
|
||||
@@ -108,10 +112,10 @@ echo "Checking Group : ${ssh_group}";
|
||||
out_string="[!!!] Never logged in and we have no create date";
|
||||
fi;
|
||||
# build delete output
|
||||
if [ ${delete_user} = 1 ]; then
|
||||
delete_accounts="${delete_accounts}"$(printf "${user_group_tpl}" "${user}" "${ssh_group}" "${user}" "${ssh_reject_group}")$'\n';
|
||||
if [ ${lock_user} = 1 ]; then
|
||||
lock_accounts="${lock_accounts} ${username}"
|
||||
fi;
|
||||
printf "* Checking user %-20s: %s\n" "${user}" "${out_string}";
|
||||
printf "* Checking user %-20s: %s\n" "${username}" "${out_string}";
|
||||
done;
|
||||
done;
|
||||
echo "--------------------->"
|
||||
@@ -119,11 +123,11 @@ echo "Showing current SSH Reject users:"
|
||||
for user in $(cat /etc/group|grep "${ssh_reject_group}:" | cut -d ":" -f 4 | sed -e 's/,/ /g'); do
|
||||
echo "${user}";
|
||||
done;
|
||||
if [ ! -z "${delete_accounts}" ]; then
|
||||
if [ ! -z "${lock_accounts}" ]; then
|
||||
echo "--------------------->"
|
||||
echo "% Run list below to move users to reject ssh group";
|
||||
echo "% Run script below to move users to reject ssh group";
|
||||
echo "";
|
||||
echo "${delete_accounts}";
|
||||
echo "bin/lock_user.sh ${lock_accounts}";
|
||||
fi;
|
||||
echo "[END] ===============>"
|
||||
|
||||
|
||||
@@ -61,7 +61,8 @@ function parseLog()
|
||||
if [ "${logger}" = "systemd" ]; then
|
||||
# 2022-11-18T20:04:08+0900
|
||||
auth_date=$(echo "${line}" | cut -d " " -f 1);
|
||||
auth_user=$(echo "${line}" | cut -d "]" -f 2 | cut -d " " -f 7 | cut -d "." -f 1);
|
||||
# Note, instead of cut with dot, remove last dot in line
|
||||
auth_user=$(echo "${line}" | cut -d "]" -f 2 | cut -d " " -f 7 | sed -e "s/\.$//");
|
||||
else
|
||||
auth_date=$(echo "${line}" | cut -c 1-6)" ${start_year} "$(echo "${line}" | cut -c 8-15);
|
||||
auth_user=$(echo "${line}" | cut -d ")" -f 2 | cut -d " " -f 6 | cut -d "(" -f 1);
|
||||
|
||||
@@ -25,68 +25,131 @@
|
||||
# They pem pub key must follow the set rules above
|
||||
|
||||
# SET TO 1 to TEST [will not create user/group/folder]
|
||||
TEST=0; # no creation except ssh keys
|
||||
TEST=0; # no actions will be run
|
||||
INFO=0; # no creation of anything, just print info strings
|
||||
while getopts ":ti" opt; do
|
||||
GO=0; # without this flag the script will exit with an info box
|
||||
while getopts ":gtih:" opt; do
|
||||
case "${opt}" in
|
||||
g|go)
|
||||
GO=1;
|
||||
;;
|
||||
t|test)
|
||||
TEST=1;
|
||||
;;
|
||||
i|info)
|
||||
INFO=1;
|
||||
;;
|
||||
h|home)
|
||||
HOME_LOCATION="${OPTARG}";
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "Use -t for test and -i for info";
|
||||
echo "Use -g for actually creation run";
|
||||
echo "Override default /home/ folder location with -h <base>";
|
||||
exit 1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
error=0;
|
||||
# hostname for output file only
|
||||
host=$(hostname);
|
||||
timestamp=$(date +%Y%m%d-%H%M%S)
|
||||
# character to set getween info blocks
|
||||
separator="#";
|
||||
# base folder for all data
|
||||
root_folder=$(pwd)'/';
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
# home folder is always thome
|
||||
HOME_BASE="/home/";
|
||||
# config location
|
||||
CONFIG_BASE="${BASE_FOLDER}../config/";
|
||||
# check config folder for .env file with HOME_LOCATION
|
||||
# only use if HOME_LOCATION not yet set
|
||||
if [ -z "${HOME_LOCATION}" ] && [ -f "${CONFIG_BASE}create_user.cfg" ]; then
|
||||
source <(grep = ${CONFIG_BASE}create_user.cfg | sed 's/ *= */=/g')
|
||||
fi;
|
||||
|
||||
if [ ! -z "${HOME_LOCATION}" ]; then
|
||||
# must start with / as it has to be from root
|
||||
if [ "${HOME_LOCATION##/*}" ]; then
|
||||
echo "Home location folder must start with a slash (/): ${HOME_LOCATION}";
|
||||
error=1;
|
||||
fi;
|
||||
# must be valid folder
|
||||
if [ ! -d "${HOME_LOCATION}" ]; then
|
||||
echo "Folder for home location does not exists: ${HOME_LOCATION}";
|
||||
error=1;
|
||||
fi;
|
||||
fi;
|
||||
# the new location for home, if override is set will be created in this folder
|
||||
HOME_FOLDER="${HOME_LOCATION}${HOME_BASE}"
|
||||
if [ ! -d "${HOME_FOLDER}" ]; then
|
||||
echo "Home folder location not found: ${HOME_FOLDER}";
|
||||
error=1;
|
||||
fi;
|
||||
# home dir error abort
|
||||
if [ $error -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
ROOT_FOLDER="${BASE_FOLDER}../";
|
||||
input_file='user_list.txt';
|
||||
output_file="user_password.${timestamp}.txt";
|
||||
output_zip_folder='zip/';
|
||||
output_zip="users.${timestamp}.zip"
|
||||
ssh_keygen_folder='ssh-keygen/';
|
||||
ssh_keygen_folder_created_pub='ssh-keygen-created-pub/';
|
||||
ssh_keytype='ed25519';
|
||||
SSH_KEYGEN_FOLDER='ssh-keygen/';
|
||||
SSH_KEYGEN_FOLDER_CREATED_PUB='ssh-keygen-created-pub/';
|
||||
# set default key tpye
|
||||
default_ssh_keytype='ed25519';
|
||||
ssh_keytype='';
|
||||
# sshallow or sshforward
|
||||
ssh_group='';
|
||||
ssh_forward_ok=0;
|
||||
# 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 [ ! -z $(echo "${cf}" | grep "%u") ]; then
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER=$(echo "${cf}" | sed -e 's/%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;
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
|
||||
# check if ssh key folder exists
|
||||
if [ ! -d "${root_folder}${ssh_keygen_folder}" ]; then
|
||||
mkdir "${root_folder}${ssh_keygen_folder}";
|
||||
if [ ! -d "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}" ]; then
|
||||
mkdir "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}";
|
||||
fi;
|
||||
# check if zip folder is missing
|
||||
if [ ! -d "${root_folder}${output_zip_folder}" ]; then
|
||||
mkdir "${root_folder}${output_zip_folder}";
|
||||
if [ ! -d "${ROOT_FOLDER}${output_zip_folder}" ]; then
|
||||
mkdir "${ROOT_FOLDER}${output_zip_folder}";
|
||||
fi;
|
||||
# check if password generate software is installed
|
||||
# if [ ! command -v pwgen &> /dev/null ]; then
|
||||
if [ -z $(command -v pwgen) ]; then
|
||||
echo "Missing pwgen application, aborting";
|
||||
exit;
|
||||
error=1;
|
||||
fi;
|
||||
# check for zip
|
||||
# if [ ! command -v zip &> /dev/null ]; then
|
||||
if [ -z $(command -v zip) ]; then
|
||||
echo "Missing zip application, aborting";
|
||||
exit;
|
||||
error=1;
|
||||
fi;
|
||||
# check if sshallow or sshfoward group exists
|
||||
if [ -z $(cat /etc/group | grep "sshallow:") ]; then
|
||||
echo "Missing ssh access group: sshallow";
|
||||
exit;
|
||||
error=1;
|
||||
fi;
|
||||
# flag if we can set ssh forward
|
||||
if [ ! -z $(cat /etc/group | grep "sshforward:") ]; then
|
||||
ssh_forward_ok=1;
|
||||
fi;
|
||||
# check if user list file exists
|
||||
if [ ! -f "${root_folder}${input_file}" ]; then
|
||||
echo "Missing ${root_folder}${input_file}";
|
||||
exit;
|
||||
if [ ! -f "${ROOT_FOLDER}${input_file}" ]; then
|
||||
echo "Missing ${ROOT_FOLDER}${input_file}";
|
||||
error=1;
|
||||
fi;
|
||||
# make sure my own folder is owned by root and 600 (except for testing)
|
||||
if [ $(stat -c %a .) != "600" ]; then
|
||||
@@ -95,23 +158,44 @@ fi;
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ] && [ ${INFO} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
exit;
|
||||
error=1;
|
||||
else
|
||||
echo "!!!! Script must be run as root user !!!!";
|
||||
fi;
|
||||
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.";
|
||||
echo "It is recommended to run -t for testing prior to user creation.";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
if [ $error -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# create users
|
||||
cat "${root_folder}${input_file}" |
|
||||
cat "${ROOT_FOLDER}${input_file}" |
|
||||
while read i; do
|
||||
# skip rows start with # (comment)
|
||||
if [[ "${i}" =~ ^\# ]]; then
|
||||
continue;
|
||||
fi;
|
||||
# make lower case, remove spaces
|
||||
user=$(echo "${i}" | cut -d ";" -f 2 | tr A-Z a-z | tr -d ' ');
|
||||
# POS 2: make lower case, remove spaces
|
||||
username=$(echo "${i}" | cut -d ";" -f 2 | tr A-Z a-z | 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;
|
||||
fi;
|
||||
# POS 3: groups
|
||||
_group=$(echo "${i}" | cut -d ";" -f 3 | tr A-Z a-z | tr -d ' ');
|
||||
group=$(echo "${_group}" | cut -d "," -f 1);
|
||||
sub_group="";
|
||||
# POS 4: ssh access type
|
||||
ssh_access_type=$(echo "${i}" | cut -d ";" -f 4 | tr A-Z a-z | tr -d ' ');
|
||||
# if not allow or forward, set to access
|
||||
if [ "${ssh_access_type}" != "allow" ] && [ "${ssh_access_type}" != "forward" ]; then
|
||||
@@ -119,8 +203,10 @@ while read i; do
|
||||
ssh_access_type="allow";
|
||||
fi;
|
||||
if [ $ssh_forward_ok -eq 0 ] && [ "${ssh_access_type}" = "forward" ]; then
|
||||
echo "[!!!] sshforward group does not exsts, cannot set user ${user}";
|
||||
break;
|
||||
echo "[!!!] sshforward group does not exsts, cannot set user ${username}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
fi;
|
||||
ssh_group="ssh${ssh_access_type}";
|
||||
# sshallow group is always added
|
||||
@@ -130,39 +216,56 @@ while read i; do
|
||||
sub_group=$(echo "${_group}" | cut -d "," -f 2-);
|
||||
sub_group_opt=" -G ${sub_group}";
|
||||
fi;
|
||||
# override host name, lowercase and spaces removed
|
||||
_hostname=$(echo "${i}" | cut -d ";" -f 5 | tr A-Z a-z | tr -d ' ');
|
||||
# POS 5: do we have a password preset
|
||||
_password=$(echo "${i}" | cut -d ";" -f 5);
|
||||
# POS 6: override host name, lowercase and spaces removed
|
||||
_hostname=$(echo "${i}" | cut -d ";" -f 6 | tr A-Z a-z | tr -d ' ');
|
||||
if [ -z "${_hostname}" ]; then
|
||||
hostname=${host};
|
||||
else
|
||||
hostname=${_hostname};
|
||||
fi;
|
||||
# do we have a password preset
|
||||
_password=$(echo "${i}" | cut -d ";" -f 4);
|
||||
_ssh_keytype=$(echo "${i}" | cut -d ";" -f 6 | tr A-Z a-z | tr -d ' ');
|
||||
# POS 7: ssh keytype override
|
||||
_ssh_keytype=$(echo "${i}" | cut -d ";" -f 7 | tr A-Z a-z | tr -d ' ');
|
||||
if [ "${_ssh_keytype}" = "rsa" ]; then
|
||||
ssh_keytype="${_ssh_keytype}";
|
||||
#echo "[!!] BACKWARDS COMPATIBLE RSA TYPE SELECTION [!!]";
|
||||
else
|
||||
ssh_keytype=${default_ssh_keytype};
|
||||
fi;
|
||||
# user & group not set
|
||||
if [ -z "${user}" ] || [ -z "${_group}" ]; then
|
||||
echo "[!!!!!] Missing user or group entry for ${user}/${_group}";
|
||||
if [ -z "${username}" ] || [ -z "${_group}" ]; then
|
||||
echo "[!!!!!] Missing user or group entry for ${username}/${_group}";
|
||||
echo "[*** ABORT RUN ***]"
|
||||
break;
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
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}";
|
||||
group_error=1;
|
||||
fi;
|
||||
done;
|
||||
if [ $group_error -eq 1 ] && [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
fi;
|
||||
# SSH file name part without folder
|
||||
ssh_keygen_id="${hostname}${separator}${group}${separator}${user}${separator}${ssh_keytype}.pem";
|
||||
ssh_keygen_id="${hostname}${separator}${group}${separator}${username}${separator}${ssh_keytype}.pem";
|
||||
# the full file including folder name
|
||||
ssh_keyfile="${root_folder}${ssh_keygen_folder}${ssh_keygen_id}";
|
||||
ssh_keyfile="${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}${ssh_keygen_id}";
|
||||
# publ file if new
|
||||
ssh_keyfile_pub="${ssh_keyfile}.pub";
|
||||
# check existing pub file
|
||||
ssh_keyfile_check_pub="${root_folder}${ssh_keygen_folder_created_pub}${ssh_keygen_id}.pub";
|
||||
ssh_keyfile_check_pub="${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}${ssh_keygen_id}.pub";
|
||||
|
||||
if [ ${INFO} -eq 1 ]; then
|
||||
# test if pub file exists or not, test if user exists
|
||||
echo -n "User: '${user}:${group}(${sub_group});${ssh_group}', SSH: ${ssh_keygen_id}";
|
||||
if getent passwd ${user} > /dev/null 2>&1; then
|
||||
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";
|
||||
fi;
|
||||
if [ -f "${ssh_keyfile_check_pub}" ]; then
|
||||
@@ -182,24 +285,31 @@ while read i; do
|
||||
fi;
|
||||
done;
|
||||
# check if user is not already created
|
||||
if getent passwd ${user} > /dev/null 2>&1; then
|
||||
echo "-- Skip '${user}:${group}(${sub_group})'";
|
||||
# if getent passwd ${username} > /dev/null 2>&1; then
|
||||
if id "${username}" &>/dev/null; then
|
||||
echo "-- Skip '${username}:${group}(${sub_group})'";
|
||||
else
|
||||
echo "++ Create '${user}:${group}(${sub_group})'";
|
||||
echo "++ Create '${username}:${group}(${sub_group})'";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
# comment is user create time
|
||||
useradd -c `date +"%F"` -s /bin/bash -g ${group}${sub_group_opt} -m ${user};
|
||||
useradd -c `date +"%F"` -s /bin/bash -g ${group}${sub_group_opt} -d "${HOME_FOLDER}${username}" -m ${username};
|
||||
else
|
||||
echo "$> useradd -s /bin/bash -g ${group}${sub_group_opt} -m ${user}";
|
||||
echo "$> useradd -c `date +"%F"` -s /bin/bash -g ${group}${sub_group_opt} -d "${HOME_FOLDER}${username}" -m ${username}";
|
||||
fi;
|
||||
fi;
|
||||
# set the auth file
|
||||
if [ -z "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ]; then
|
||||
SSH_AUTHORIZED_FILE="${HOME_FOLDER}${username}/.ssh/authorized_keys";
|
||||
else
|
||||
SSH_AUTHORIZED_FILE="${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}${username}";
|
||||
fi;
|
||||
skip_ssh=0;
|
||||
# if public pem already exists skip creation
|
||||
if [ ! -f "${ssh_keyfile_check_pub}" ]; then
|
||||
# Note we only create a password if we need it
|
||||
# password + store pwgen 10 1 -1
|
||||
if [ -z "${_password}" ]; then
|
||||
password=$(printf "%s" $(pwgen 10 1));
|
||||
password=$(printf "%s" $(pwgen 14 1));
|
||||
else
|
||||
echo "! Override password set";
|
||||
password=${_password};
|
||||
@@ -210,19 +320,22 @@ while read i; do
|
||||
ssh-keygen \
|
||||
-t ${ssh_keytype} \
|
||||
-f "${ssh_keyfile}" \
|
||||
-C "${hostname}: ${user}@${group}" \
|
||||
-C "${hostname}: ${username}@${group}" \
|
||||
-a 100 -N "${password}"
|
||||
else
|
||||
echo "$> ssh-keygen -t ${ssh_keytype} -f ${ssh_keyfile} -C ${hostname}: ${user}@${group} -a 100 -N ${password}";
|
||||
echo "$> ssh-keygen -t ${ssh_keytype} -f ${ssh_keyfile} -C ${hostname}: ${username}@${group} -a 100 -N ${password}";
|
||||
fi;
|
||||
else
|
||||
found=$(grep "$(cat ${ssh_keyfile_check_pub})" /home/${user}/.ssh/authorized_keys);
|
||||
found='';
|
||||
if [ -f "${SSH_AUTHORIZED_FILE}" ]; then
|
||||
found=$(grep "$(cat ${ssh_keyfile_check_pub})" ${SSH_AUTHORIZED_FILE});
|
||||
fi;
|
||||
if [ ! -z "${found}" ]; then
|
||||
skip_ssh=1;
|
||||
# override previously set with stored one
|
||||
ssh_keyfile_pub=${ssh_keyfile_check_pub};
|
||||
echo "-- Skip SSH Key creation: ${ssh_keygen_id}.pub";
|
||||
else
|
||||
# override previously set with stored one
|
||||
ssh_keyfile_pub=${ssh_keyfile_check_pub};
|
||||
echo " < Use existing public ssh key '${ssh_keygen_id}.pub'";
|
||||
# Password already set notification
|
||||
fi;
|
||||
@@ -231,33 +344,64 @@ while read i; do
|
||||
if [ ${skip_ssh} -eq 0 ]; then
|
||||
# write login info to output file
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
create_output_file="${root_folder}${output_file}";
|
||||
create_output_file="${ROOT_FOLDER}${output_file}";
|
||||
else
|
||||
create_output_file="${root_folder}${output_file}.TEST";
|
||||
create_output_file="${ROOT_FOLDER}${output_file}.TEST";
|
||||
fi;
|
||||
echo $(date +"%F %T")";"${host}";"${_hostname}";"${user}";"${password}";"${ssh_allow_type} >> ${create_output_file};
|
||||
echo $(date +"%F %T")";"${host}";"${_hostname}";"${username}";"${password}";"${ssh_access_type} >> ${create_output_file};
|
||||
# create folder only if we do not have central
|
||||
# create the SSH foler and authorized access file with correct permissions
|
||||
echo " > Create .ssh folder";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
mkdir /home/${user}/.ssh/;
|
||||
else
|
||||
echo "$> mkdir /home/${user}/.ssh/";
|
||||
if [ -z "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ]; then
|
||||
echo " > Create .ssh folder";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
mkdir ${HOME_FOLDER}${username}/.ssh/;
|
||||
else
|
||||
echo "$> mkdir ${HOME_FOLDER}${username}/.ssh/";
|
||||
fi;
|
||||
fi;
|
||||
echo " > Add public into authorized_keys";
|
||||
# add
|
||||
echo " > Add public into authorized_keys file";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
cat "${ssh_keyfile_pub}" > /home/${user}/.ssh/authorized_keys;
|
||||
if
|
||||
[ ! -z "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ] &&
|
||||
[ -f "${SSH_AUTHORIZED_FILE}" ];
|
||||
then
|
||||
chattr -i ${SSH_AUTHORIZED_FILE};
|
||||
fi;
|
||||
cat "${ssh_keyfile_pub}" > ${SSH_AUTHORIZED_FILE};
|
||||
else
|
||||
echo "$> cat ${ssh_keyfile_pub} > /home/${user}/.ssh/authorized_keys";
|
||||
if
|
||||
[ ! -z "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ] &&
|
||||
[ -f "${SSH_AUTHORIZED_FILE}" ];
|
||||
then
|
||||
echo "$> chattr -i ${SSH_AUTHORIZED_FILE}";
|
||||
fi;
|
||||
echo "$> cat ${ssh_keyfile_pub} > ${SSH_AUTHORIZED_FILE}";
|
||||
fi;
|
||||
echo " > Secure folder .ssh and authorized_keys file";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
chown -R ${user}:${group} /home/${user}/.ssh/;
|
||||
chmod 700 /home/${user}/.ssh/;
|
||||
chmod 600 /home/${user}/.ssh/authorized_keys;
|
||||
# secure
|
||||
if [ -z "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ]; then
|
||||
echo " > Secure home directory folder .ssh and authorized_keys file";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
chown -R ${username}:${group} ${HOME_FOLDER}${username}/.ssh/;
|
||||
chmod 700 ${HOME_FOLDER}${username}/.ssh/;
|
||||
chmod 600 ${SSH_AUTHORIZED_FILE};
|
||||
else
|
||||
echo "$> chown -R ${username}:${group} ${HOME_FOLDER}${username}/.ssh/";
|
||||
echo "$> chmod 700 ${HOME_FOLDER}${username}/.ssh/";
|
||||
echo "$> chmod 600 ${SSH_AUTHORIZED_FILE}";
|
||||
fi;
|
||||
else
|
||||
echo "$> chown -R ${user}:${group} /home/${user}/.ssh/";
|
||||
echo "$> chmod 700 /home/${user}/.ssh/";
|
||||
echo "$> chmod 600 /home/${user}/.ssh/authorized_keys";
|
||||
echo " > Secure central authorized_keys file";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
chown ${username}:root ${SSH_AUTHORIZED_FILE};
|
||||
chmod 400 ${SSH_AUTHORIZED_FILE};
|
||||
# set +i so user can't change file
|
||||
chattr +i ${SSH_AUTHORIZED_FILE};
|
||||
else
|
||||
echo "$> chown ${username}:root ${SSH_AUTHORIZED_FILE}";
|
||||
echo "$> chmod 400 ${SSH_AUTHORIZED_FILE}";
|
||||
echo "$> chattr +i ${SSH_AUTHORIZED_FILE}";
|
||||
fi;
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
@@ -267,24 +411,33 @@ if [ ${INFO} -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
# zip everything and remove data in ssh key folder, delete output file with passwords
|
||||
zip -r \
|
||||
"${root_folder}${output_zip_folder}${output_zip}" \
|
||||
"${input_file}" \
|
||||
"${output_file}" \
|
||||
"${ssh_keygen_folder}" \
|
||||
-x\*.gitignore;
|
||||
echo "Download: ${root_folder}${output_zip_folder}${output_zip}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
zip -r \
|
||||
"${ROOT_FOLDER}${output_zip_folder}${output_zip}" \
|
||||
"${input_file}" \
|
||||
"${output_file}" \
|
||||
"${SSH_KEYGEN_FOLDER}" \
|
||||
-x\*.gitignore;
|
||||
else
|
||||
echo "zip -r \\"
|
||||
echo "${ROOT_FOLDER}${output_zip_folder}${output_zip} \\"
|
||||
echo "${input_file} \\"
|
||||
echo "${output_file} \\"
|
||||
echo "${SSH_KEYGEN_FOLDER} \\"
|
||||
echo "-x\*.gitignore;"
|
||||
fi;
|
||||
echo "Download: ${ROOT_FOLDER}${output_zip_folder}${output_zip}";
|
||||
# cleam up user log file and ssh keys
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
# 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
|
||||
rm "${root_folder}${output_file}";
|
||||
rm "${root_folder}${ssh_keygen_folder}"*;
|
||||
rm "${ROOT_FOLDER}${output_file}";
|
||||
rm "${ROOT_FOLDER}${SSH_KEYGEN_FOLDER}"*;
|
||||
else
|
||||
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}${ssh_keygen_folder}*";
|
||||
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}${SSH_KEYGEN_FOLDER}*";
|
||||
fi;
|
||||
|
||||
# __END__
|
||||
|
||||
182
bin/delete_user.sh
Executable file
182
bin/delete_user.sh
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Delete user
|
||||
# - Backup
|
||||
# - delete user
|
||||
# - delete home
|
||||
# - remove ssh-keygen-created-pub files
|
||||
# - remove ssh central auth data if exits
|
||||
# - update user_list.txt and comment (#) line for this user
|
||||
# - write delete log
|
||||
|
||||
# This will permaently remove the user
|
||||
|
||||
TEST=0; # do not run any actions
|
||||
BACKUP=1;
|
||||
while getopts ":tb" opt; do
|
||||
case "${opt}" in
|
||||
t|test)
|
||||
TEST=1;
|
||||
;;
|
||||
b|nobackup)
|
||||
BACKUP=0;
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "Use -t for test";
|
||||
echo "Use -g for actually creation run";
|
||||
echo "Use -b to not make a backup of the home folder and public key"
|
||||
exit 1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
exit;
|
||||
else
|
||||
echo "!!!! Script must be run as root user !!!!";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Must give at least one user name";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# check tar, bzip2 is installed if backup = 1
|
||||
|
||||
host=$(hostname);
|
||||
timestamp=$(date +%Y%m%d-%H%M%S);
|
||||
# character to set getween info blocks
|
||||
separator="#";
|
||||
# base folder for all data
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
root_folder="${BASE_FOLDER}../";
|
||||
backup_folder="${BASE_FOLDER}../backup/";
|
||||
SSH_KEYGEN_FOLDER_CREATED_PUB='ssh-keygen-created-pub/';
|
||||
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;
|
||||
# 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 [ ! -z $(echo "${cf}" | grep "%u") ]; then
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER=$(echo "${cf}" | sed -e 's/%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;
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
|
||||
if [ ! -f "${user_list_file}" ]; then
|
||||
echo "${input_file} is missing";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# $1 ... $n
|
||||
for username in "$@"; do
|
||||
error=0;
|
||||
# skip if there is an option hidden
|
||||
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[*]} " =~ " ${username} " ]]; then
|
||||
echo "[!] User ${username} is in the ignore user list";
|
||||
continue;
|
||||
fi;
|
||||
|
||||
# user must exist in user_list.txt and /etc/passwd
|
||||
# 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";
|
||||
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";
|
||||
error=1;
|
||||
elif [[ "${user_list_entry}" =~ ^#DELETED ]]; then
|
||||
echo "[!!!] User ${username} is flagged as deleted in user_list.txt file";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
if [ $error -eq 1 ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
echo "=> Delete: ${username}";
|
||||
# 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);
|
||||
backup_file="${backup_folder}${host}${separator}${username}.${timestamp}.tar.bz2";
|
||||
files_list="${home_folder}";
|
||||
if [ -f "${SSH_AUTHORIZED_FILE}" ]; then
|
||||
files_list="${files_list} ${SSH_AUTHORIZED_FILE}";
|
||||
fi;
|
||||
echo "[0] Backup ${files_list} to ${backup_file}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
tar cfjp "${backup_file}" ${file_list};
|
||||
else
|
||||
echo "$> tar cfjp \"${backup_file}\" ${files_list};";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
echo "[1] Remove user + home dir";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
userdel -r ${username}
|
||||
else
|
||||
echo "$> userdel -r ${username}";
|
||||
fi;
|
||||
|
||||
# remove ssh files in pub
|
||||
echo "[2] Remove SSH Public key";
|
||||
# Note, we keep the public key in the -created-pub folder
|
||||
if [ -f "${SSH_AUTHORIZED_FILE}" ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
chattr -i "${SSH_AUTHORIZED_FILE}";
|
||||
rm "${SSH_AUTHORIZED_FILE}";
|
||||
else
|
||||
echo "$> chattr -i \"${SSH_AUTHORIZED_FILE}\";";
|
||||
echo "$> rm \"${SSH_AUTHORIZED_FILE}\";"
|
||||
fi;
|
||||
else
|
||||
# Not critical error
|
||||
echo "[?] Cannot find ${SSH_AUTHORIZED_FILE}";
|
||||
fi;
|
||||
|
||||
# Update user_list.txt file and add # for the line
|
||||
echo "[3] Update user_list.txt file";
|
||||
# eg n;foo -> #DELETED-YYYYMMDD_HHmmss:n;foo ...
|
||||
delete_date=$(date +%Y%m%d_%H%M%S)
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
sed -i -e "s/^\([A-Za-z0-9]\{1,\};${username};\)/#DELETED-${delete_date}:\1/" "${user_list_file}";
|
||||
else
|
||||
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}";
|
||||
|
||||
done;
|
||||
|
||||
# __END__
|
||||
@@ -2,26 +2,36 @@
|
||||
|
||||
# disable a user by removing them from the sshallow/sshforward group
|
||||
# and move them to the sshreject group
|
||||
# Note that call is ./lock_user.sh -t <user 1> <user 2> ...
|
||||
# if the -t is not in the first position it will be ignored
|
||||
|
||||
# SET TO 1 to TEST [will not move user in groups]
|
||||
TEST=0; # no creation except ssh keys
|
||||
INFO=0; # no creation of anything, just print info strings
|
||||
while getopts ":ti" opt; do
|
||||
TEST=0; # no delete, just print
|
||||
while getopts ":t" opt; do
|
||||
case "${opt}" in
|
||||
t|test)
|
||||
TEST=1;
|
||||
;;
|
||||
i|info)
|
||||
INFO=1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
exit;
|
||||
else
|
||||
echo "!!!! Script must be run as root user !!!!";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Must give at least one user name";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# ignore users (root and admin users)
|
||||
ignore_users=('root' 'ec2-user' 'ubuntu' 'admin');
|
||||
# ssh reject group
|
||||
ssh_reject_group="sshreject";
|
||||
if [ -z $(cat /etc/group | grep "${ssh_reject_group}:") ]; then
|
||||
@@ -30,20 +40,29 @@ if [ -z $(cat /etc/group | grep "${ssh_reject_group}:") ]; then
|
||||
fi;
|
||||
ssh_allow_group="sshallow";
|
||||
ssh_forward_group="sshfoward";
|
||||
delete_accounts="";
|
||||
user_group_tpl="gpasswd -d %s %s;gpasswd -a %s %s;";
|
||||
user_group_tpl="gpasswd -d %s %s\ngpasswd -a %s %s\n";
|
||||
|
||||
echo "--------------------->"
|
||||
# $1 ... $n
|
||||
for username in "$@"; do
|
||||
# skip if there is an option hidden
|
||||
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[*]} " =~ " ${username} " ]]; then
|
||||
echo "[!] User ${username} is in the ignore user list";
|
||||
continue;
|
||||
fi;
|
||||
# check that user exists in passwd
|
||||
if [ -z $(cat /etc/passwd | grep "${username}:") ]; then
|
||||
echo "[!] User $username does not exists in /etc/passwd file";
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
echo "[!] User ${username} does not exists in /etc/passwd file";
|
||||
continue;
|
||||
fi;
|
||||
# if not check if in reject list
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_reject}"; then
|
||||
echo "[.] User $username already in the ${ssh_reject} list";
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_reject_group}"; then
|
||||
echo "[.] User ${username} already in the ${ssh_reject_group} list";
|
||||
continue;
|
||||
fi;
|
||||
# check if user is in sshallow/forward list
|
||||
@@ -54,25 +73,24 @@ 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 [ ! -z "${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.";
|
||||
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.";
|
||||
break;
|
||||
fi;
|
||||
ssh_remove_group="${ssh_forward_group}";
|
||||
fi;
|
||||
if [ ! -z "${ssh_remove_group}" ]; then
|
||||
# remove user from ssh group and add to reject groups
|
||||
echo "[*] User $username will be removed from ${ssh_remove_group}";
|
||||
delete_accounts="${delete_accounts}"$(printf "${user_group_tpl}" "${username}" "${ssh_remove_group}" "${username}" "${ssh_reject_group}")$'\n';
|
||||
echo "[*] User ${username} will be removed from ${ssh_remove_group}";
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
printf "${user_group_tpl}" "${username}" "${ssh_remove_group}" "${username}" "${ssh_reject_group}";
|
||||
else
|
||||
gpasswd -d "${username}" "${ssh_remove_group}";
|
||||
gpasswd -a "${username}" "${ssh_reject_group}";
|
||||
fi;
|
||||
else
|
||||
# skip not ssh user
|
||||
echo "[?] User $username not in any ssh allow/foward groups";
|
||||
echo "[?] User ${username} not in any ssh allow/foward groups";
|
||||
fi;
|
||||
done;
|
||||
if [ ! -z "${delete_accounts}" ]; then
|
||||
echo "--------------------->"
|
||||
echo "% Run list below to move users to reject ssh group";
|
||||
echo "";
|
||||
echo "${delete_accounts}";
|
||||
fi;
|
||||
|
||||
# __END__
|
||||
|
||||
240
bin/rename_user.sh
Normal file
240
bin/rename_user.sh
Normal file
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Rename user
|
||||
# - rename user name
|
||||
# - rename home folder + owner
|
||||
# - rename public key file in /etc/ssh/
|
||||
# - rename in user_list.txt
|
||||
# - rename created public key file
|
||||
|
||||
TEST=0; # do not run any actions
|
||||
OLD_USERNAME="";
|
||||
NEW_USERNAME="";
|
||||
while getopts ":to:n:" opt; do
|
||||
case "${opt}" in
|
||||
t|test)
|
||||
TEST=1;
|
||||
;;
|
||||
o|old-user)
|
||||
if [ -z "${OLD_USERNAME}" ]; then
|
||||
OLD_USERNAME="${OPTARG}";
|
||||
fi;
|
||||
;;
|
||||
n|new-user)
|
||||
if [ -z "${NEW_USERNAME}" ]; then
|
||||
NEW_USERNAME="${OPTARG}";
|
||||
fi;
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "Use -t for test";
|
||||
echo "-o: Current user";
|
||||
echo "-n: New username";
|
||||
exit 1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
exit;
|
||||
else
|
||||
echo "!!!! Script must be run as root user !!!!";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
error=0;
|
||||
host=$(hostname);
|
||||
timestamp=$(date +%Y%m%d-%H%M%S);
|
||||
# character to set getween info blocks
|
||||
separator="#";
|
||||
# base folder for all data
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
root_folder="${BASE_FOLDER}../";
|
||||
SSH_KEYGEN_FOLDER_CREATED_PUB='ssh-keygen-created-pub/';
|
||||
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
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER='';
|
||||
SSH_AUTHORIZED_FILE='';
|
||||
for cf in $(grep "^AuthorizedKeysFile" /etc/ssh/sshd_config | grep "%u"); do
|
||||
if [ ! -z $(echo "${cf}" | grep "%u") ]; then
|
||||
SSH_CENTRAL_AUTHORIZED_FILE_FOLDER=$(echo "${cf}" | sed -e 's/%u//');
|
||||
if [ ! -d "${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}" ]; then
|
||||
echo "ssh central authorized_file folder could not be found: ${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}";
|
||||
error=1;
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
if [ ! -f "${user_list_file}" ]; then
|
||||
echo "${input_file} is missing";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
if [ -z "${OLD_USERNAME}" ] || [ -z "${NEW_USERNAME}" ]; then
|
||||
echo "[!!!] Current and new username must be provided";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
if [ "${OLD_USERNAME}" = "${NEW_USERNAME}" ]; then
|
||||
echo "[!!!] Current and new username cannot be the same";
|
||||
error=1;
|
||||
fi;
|
||||
|
||||
if ! [[ "${NEW_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 _: ${NEW_USERNAME}";
|
||||
error=1;
|
||||
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[*]} " =~ " ${OLD_USERNAME} " ]]; then
|
||||
echo "[!] User ${OLD_USERNAME} is in the ignore user list";
|
||||
error=1;
|
||||
fi;
|
||||
if [[ " ${ignore_users[*]} " =~ " ${NEW_USERNAME} " ]]; then
|
||||
echo "[!] User ${NEW_USERNAME} is in the ignore user list";
|
||||
error=1;
|
||||
fi;
|
||||
# user must exist in user_list.txt and /etc/passwd
|
||||
# if missing in or another do not continue
|
||||
if ! id "${OLD_USERNAME}" &>/dev/null; then
|
||||
# not in passwd
|
||||
echo "[!!!] User ${OLD_USERNAME} does not exist in /etc/passwd";
|
||||
error=1;
|
||||
fi;
|
||||
if id "${NEW_USERNAME}" &>/dev/null; then
|
||||
# not in passwd
|
||||
echo "[!!!] User ${NEW_USERNAME} exists in /etc/passwd";
|
||||
error=1;
|
||||
fi;
|
||||
if [ -f "${user_list_file}" ]; then
|
||||
user_list_entry=$(grep "${OLD_USERNAME}" "${user_list_file}");
|
||||
if [ -z "${user_list_entry}" ]; then
|
||||
echo "[!!!] User ${OLD_USERNAME} does not exist in user_list.txt file";
|
||||
error=1;
|
||||
fi;
|
||||
# if the old user exists but as DELETED -> no go
|
||||
if [ ! -z $(echo "${user_list_entry}" | grep "#DELETED-") ]; then
|
||||
echo "[!!!] User ${OLD_USERNAME} has been flagged as deleted";
|
||||
error=1;
|
||||
fi;
|
||||
# if new user name already exists in user list file for whatever reason
|
||||
if [ $(grep "${NEW_USERNAME}" "${user_list_file}") ]; then
|
||||
echo "[!!!] User ${NEW_USERNAME} exists in user_list.txt file";
|
||||
error=1;
|
||||
fi;
|
||||
fi;
|
||||
# exit on any error
|
||||
if [ $error -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# parse user list entry for group/hostname/ssh type key to build ssh key list
|
||||
|
||||
# POS 3: groups
|
||||
_group=$(echo "${user_list_entry}" | cut -d ";" -f 3 | tr A-Z a-z | tr -d ' ');
|
||||
group=$(echo "${_group}" | cut -d "," -f 1);
|
||||
# POS 6: override host name, lowercase and spaces removed
|
||||
_hostname=$(echo "${user_list_entry}" | cut -d ";" -f 6 | tr A-Z a-z | tr -d ' ');
|
||||
if [ -z "${_hostname}" ]; then
|
||||
hostname=${host};
|
||||
else
|
||||
hostname=${_hostname};
|
||||
fi;
|
||||
# POS 7: ssh keytype override
|
||||
_ssh_keytype=$(echo "${user_list_entry}" | cut -d ";" -f 7 | tr A-Z a-z | tr -d ' ');
|
||||
if [ "${_ssh_keytype}" = "rsa" ]; then
|
||||
ssh_keytype="${_ssh_keytype}";
|
||||
else
|
||||
ssh_keytype=${default_ssh_keytype};
|
||||
fi;
|
||||
|
||||
echo "* Rename ${OLD_USERNAME} to ${NEW_USERNAME}";
|
||||
|
||||
old_home_dir=$(getent passwd "${OLD_USERNAME}" | cut -d: -f6);
|
||||
new_home_dir=$(echo "${old_home_dir}" | sed -e "s/\/${OLD_USERNAME}$/\/${NEW_USERNAME}/");
|
||||
# rename user
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "usermod with ${new_home_dir}";
|
||||
usermod -l ${NEW_USERNAME} -m -d "${new_home_dir}" ${OLD_USERNAME};
|
||||
else
|
||||
echo "$> usermod -l ${NEW_USERNAME} -m -d \"${new_home_dir}\" ${OLD_USERNAME};";
|
||||
fi
|
||||
# check that home folder is renamed and owned by new user
|
||||
|
||||
# check if spool exists
|
||||
if [ -f "/var/spool/mail/${OLD_USERNAME}" ]; then
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "rename to /var/spool/mail/${NEW_USERNAME}";
|
||||
mv "/var/spool/mail/${OLD_USERNAME}" "/var/spool/mail/${NEW_USERNAME}";
|
||||
else
|
||||
echo "$> mv \"/var/spool/mail/${OLD_USERNAME}\" \"/var/spool/mail/${NEW_USERNAME}\";";
|
||||
fi
|
||||
fi;
|
||||
# check if crontab exists
|
||||
if [ -f "/var/spool/cron/crontabs/${OLD_USERNAME}" ]; then
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "rename to /var/spool/cron/crontabs/${NEW_USERNAME}";
|
||||
mv "/var/spool/cron/crontabs/${OLD_USERNAME}" "/var/spool/cron/crontabs/${NEW_USERNAME}";
|
||||
else
|
||||
echo "$> mv \"/var/spool/cron/crontabs/${OLD_USERNAME}\" \"/var/spool/cron/crontabs/${NEW_USERNAME}\";";
|
||||
fi
|
||||
fi;
|
||||
|
||||
# public key files user must be renamed
|
||||
OLD_SSH_AUTHORIZED_FILE="${SSH_CENTRAL_AUTHORIZED_FILE_FOLDER}${OLD_USERNAME}";
|
||||
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}";
|
||||
chattr -i "${OLD_SSH_AUTHORIZED_FILE}";
|
||||
mv "${OLD_SSH_AUTHORIZED_FILE}" "${NEW_SSH_AUTHORIZED_FILE}";
|
||||
chattr +i "${NEW_SSH_AUTHORIZED_FILE}";
|
||||
else
|
||||
echo "$> chattr -i \"${OLD_SSH_AUTHORIZED_FILE}\";";
|
||||
echo "$> mv \"${OLD_SSH_AUTHORIZED_FILE}\" \"${NEW_SSH_AUTHORIZED_FILE}\";";
|
||||
echo "$> chattr +i \"${NEW_SSH_AUTHORIZED_FILE}\";";
|
||||
fi;
|
||||
else
|
||||
echo "[?] ${OLD_SSH_AUTHORIZED_FILE} is missing";
|
||||
fi;
|
||||
|
||||
# rename keygen public file
|
||||
OLD_ssh_keygen_pub="${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}${hostname}${separator}${group}${separator}${OLD_USERNAME}${separator}${ssh_keytype}.pem.pub";
|
||||
NEW_ssh_keygen_pub="${ROOT_FOLDER}${SSH_KEYGEN_FOLDER_CREATED_PUB}${hostname}${separator}${group}${separator}${NEW_USERNAME}${separator}${ssh_keytype}.pem.pub";
|
||||
|
||||
if [ -f "${OLD_ssh_keygen_pub}" ]; then
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "rename to ${NEW_ssh_keygen_pub}";
|
||||
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";
|
||||
fi;
|
||||
|
||||
# rename entry in user list txt file
|
||||
if [ $TEST -eq 0 ]; then
|
||||
echo "update ${user_list_file}";
|
||||
sed -i -e "s/^\([A-Za-z0-9]\{1,\}\);${OLD_USERNAME};/\1;${NEW_USERNAME};/" "${user_list_file}";
|
||||
else
|
||||
echo "$> sed -i -e \"s/^\([A-Za-z0-9]\{1,\}\);${OLD_USERNAME};/\1;${NEW_USERNAME};/\" \"${user_list_file}\";";
|
||||
fi;
|
||||
|
||||
# __END__
|
||||
114
bin/unlock_user.sh
Executable file
114
bin/unlock_user.sh
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# disable a user by removing them from the sshallow/sshforward group
|
||||
# and move them to the sshreject group
|
||||
# Note that call is ./lock_user.sh -t <user 1> <user 2> ...
|
||||
# if the -t is not in the first position it will be ignored
|
||||
|
||||
# SET TO 1 to TEST [will not move user in groups]
|
||||
TEST=0; # no delete, just print
|
||||
SSH_GROUP_ADD='';
|
||||
while getopts ":ts:" opt; do
|
||||
case "${opt}" in
|
||||
t|test)
|
||||
TEST=1;
|
||||
;;
|
||||
s|sshgroup)
|
||||
if [ -z "${SSH_GROUP_ADD}" ]; then
|
||||
SSH_GROUP_ADD=${OPTARG};
|
||||
fi;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
exit;
|
||||
else
|
||||
echo "!!!! Script must be run as root user !!!!";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Must give at least one user name";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
if [ ! -z "${SSH_GROUP_ADD}" ] && [ "${SSH_GROUP_ADD}" != "allow" ] && [ "${SSH_GROUP_ADD}" != "forward" ]; then
|
||||
echo "sshgroup option can only be 'allow' or 'forward'";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
root_folder="${BASE_FOLDER}../";
|
||||
input_file='user_list.txt';
|
||||
# ignore users (root and admin users)
|
||||
ignore_users=('root' 'ec2-user' 'ubuntu' 'admin');
|
||||
# ssh reject group
|
||||
ssh_reject_group="sshreject";
|
||||
if [ -z $(cat /etc/group | grep "${ssh_reject_group}:") ]; then
|
||||
echo "Missing ssh reject group: ${ssh_reject_group}";
|
||||
exit;
|
||||
fi;
|
||||
ssh_allow_group="sshallow";
|
||||
ssh_forward_group="sshfoward";
|
||||
user_group_tpl="gpasswd -d %s %s\ngpasswd -a %s %s\n";
|
||||
|
||||
echo "--------------------->"
|
||||
# $1 ... $n
|
||||
for username in "$@"; do
|
||||
# skip if there is an option hidden
|
||||
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[*]} " =~ " ${username} " ]]; then
|
||||
echo "[!] User ${username} is in the ignore user list";
|
||||
continue;
|
||||
fi;
|
||||
# check that user exists in passwd
|
||||
if ! id "${username}" &>/dev/null; then
|
||||
echo "[!] User ${username} does not exists in /etc/passwd file";
|
||||
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";
|
||||
continue;
|
||||
fi;
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_forward_group}"; then
|
||||
echo "[.] User ${username} already in the ${ssh_forward_group} list";
|
||||
continue;
|
||||
fi;
|
||||
# try to find user in user_list.txt and get the allow/forward flag from there,
|
||||
# else try to set from option
|
||||
# if not valid use allow
|
||||
ssh_add_group="${SSH_GROUP_ADD}";
|
||||
if [ -z "${SSH_GROUP_ADD}" ] && [ -f "${root_folder}${input_file}" ]; then
|
||||
ssh_add_group=$(grep "${username}" "${root_folder}${input_file}" | cut -d ";" -f 4 | tr A-Z a-z | tr -d ' ');
|
||||
fi;
|
||||
if [ "${ssh_access_type}" != "allow" ] && [ "${ssh_access_type}" != "forward" ]; then
|
||||
ssh_add_group="allow";
|
||||
fi;
|
||||
ssh_add_group="ssh${ssh_add_group}";
|
||||
|
||||
# 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}";
|
||||
if [ ${TEST} -eq 1 ]; then
|
||||
printf "${user_group_tpl}" "${username}" "${ssh_reject_group}" "${username}" "${ssh_add_group}";
|
||||
else
|
||||
gpasswd -d "${username}" "${ssh_reject_group}";
|
||||
gpasswd -a "${username}" "${ssh_add_group}";
|
||||
fi;
|
||||
else
|
||||
# skip not ssh user
|
||||
echo "[?] User ${username} not in the ssh reject group";
|
||||
fi;
|
||||
done;
|
||||
|
||||
# __END__
|
||||
2
config/.gitignore
vendored
Normal file
2
config/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
100
user_create_flow.md
Normal file
100
user_create_flow.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# AWS user create flow
|
||||
|
||||
**NOTE** The script will check in the /etc/ssh/sshd_config for `AuthorizedKeysFile` keyword with `/etc/ssh/authorized_keys/%u`. If this exists it will move the ssk keys from the users home folder the folder `/etc/ssh/authorized_keys` with the created username as file name
|
||||
|
||||
* Step 1: check if main group exists
|
||||
* Step 2: Add user to user_list.txt
|
||||
|
||||
Very basic example with minimum settings:
|
||||
|
||||
SSH Type will default to EP25519
|
||||
|
||||
```txt
|
||||
#user_id;user_name;group,subgroup;ssh access type;override password;override hostname;override ssh type
|
||||
# 2022-12-12
|
||||
1;test.foo;group-a;allow
|
||||
```
|
||||
|
||||
* Step 3: run create script in root/users `bin/create_user.sh`
|
||||
|
||||
Not, if unsure use `-t` for testing or `-i` for info only.
|
||||
|
||||
Example output for `-i`:
|
||||
|
||||
```sh
|
||||
$> bin/create_user.sh -i
|
||||
User: 'test.foo:group-a();sshallow', SSH: hostname.com#grou-a#test.foo#ed25519.pem
|
||||
```
|
||||
|
||||
Run output (example):
|
||||
|
||||
```sh
|
||||
++ Create 'test.foo:group-a()'
|
||||
! Override password set
|
||||
> Create ssh key-pair '/root/users/bin/../ssh-keygen/hostname.com#group-a#test.foo#ed25519.pem'
|
||||
Generating public/private ed25519 key pair.
|
||||
Your identification has been saved in /root/users/bin/../ssh-keygen/hostname.com#group-a#test.foo#ed25519.pem
|
||||
Your public key has been saved in /root/users/bin/../ssh-keygen/hostname.com#group-a#test.foo#ed25519.pem.pub
|
||||
The key fingerprint is:
|
||||
SHA256:IXiHXZrBGuMIHgU34L4DgAwLeFeX37AhQD69TOF1XZI hostname.com: test.foo@group-a
|
||||
The key's randomart image is:
|
||||
+--[ED25519 256]--+
|
||||
|+ o++o+o+.o ...o.|
|
||||
|*o+..+o*+Bo. E. |
|
||||
|++.+.o*+Xo = |
|
||||
|... ..o* oo . |
|
||||
|. . S |
|
||||
| . . |
|
||||
| o |
|
||||
| . |
|
||||
| |
|
||||
+----[SHA256]-----+
|
||||
> Create .ssh folder
|
||||
> Add public into authorized_keys
|
||||
> Secure folder .ssh and authorized_keys file
|
||||
adding: user_list.txt (stored 0%)
|
||||
adding: user_password.20221202-094351.txt (stored 0%)
|
||||
adding: ssh-keygen/ (stored 0%)
|
||||
adding: ssh-keygen/hostname.com#group-a#test.foo#ed25519.pem (deflated 24%)
|
||||
adding: ssh-keygen/hostname.com#group-a#test.foo#ed25519.pem.pub (deflated 2%)
|
||||
Download: /root/users/bin/../zip/users.20221202-094351.zip
|
||||
```
|
||||
|
||||
* Step 4: Move the zip file to a folder where you can download it
|
||||
|
||||
```sh
|
||||
$> mv /root/users/bin/../zip/users.20221202-094351.zip /home/<admin user>/
|
||||
```
|
||||
|
||||
* Step 5: Download ZIP file to local computer and extract
|
||||
|
||||
Overwrite user_list.txt file if it exists
|
||||
|
||||
In the zup file there are the following files:
|
||||
|
||||
* user_password.YYYYMMDD-HHmmss.txt (creation timestamp)
|
||||
* ssh-keygen/hostname#group#user#keytype.pem
|
||||
* ssh-keygen/hostname#group#user#keytype.pem.pub
|
||||
|
||||
The .pem key has to be given to the user, the pub key is for reference only
|
||||
|
||||
* Step 6: test login
|
||||
|
||||
In the folder where the data was extracted
|
||||
|
||||
```sh
|
||||
ssh -i ssh-keygen/hostname#group#user#keytype.pem user@hostname
|
||||
```
|
||||
|
||||
Hand over to the user:
|
||||
|
||||
* username
|
||||
* hostname
|
||||
* PEM key file
|
||||
* PEM key password
|
||||
|
||||
If the password needs to be removed:
|
||||
|
||||
```sh
|
||||
ssh-keygen -p -f ssh-keygen/hostname#group#user#keytype.pem -P <old password> -N ""
|
||||
```
|
||||
Reference in New Issue
Block a user