Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
ebddac7f67 | ||
|
|
fe08fa10c2 | ||
|
|
6e53d1bdec | ||
|
|
cae5c8a19a | ||
|
|
aa0594e17f | ||
|
|
16e6b98399 | ||
|
|
424277ff2e | ||
|
|
ede5f1a2b8 | ||
|
|
27516a6474 | ||
|
|
9f61b3c523 | ||
|
|
54f4d69da6 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,3 @@
|
||||
user_list.txt
|
||||
user_password*.txt
|
||||
user_password*.txt*
|
||||
*.zip
|
||||
|
||||
137
Readme.md
137
Readme.md
@@ -11,21 +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.
|
||||
@@ -41,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
|
||||
@@ -56,11 +63,13 @@ It can also be left empty. It is not used at the moment
|
||||
The file can hold comments. The first character in the line must be a *#*
|
||||
|
||||
Example file
|
||||
```
|
||||
user1;some.name;group-a;;hostname
|
||||
user2;othername;group-a;;
|
||||
|
||||
```csv
|
||||
#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;;
|
||||
...
|
||||
```
|
||||
|
||||
@@ -96,10 +105,11 @@ The current directory **MUST** be the directory where '*user_list.txt*' is store
|
||||
|
||||
Then run the script without any options
|
||||
|
||||
`$> /root/bin/user_create.sh`
|
||||
`$> /root/bin/create_user.sh`
|
||||
|
||||
Sample output for above example file
|
||||
```
|
||||
|
||||
```txt
|
||||
++ Create 'some.name:group-a'
|
||||
> Create ssh key-pair '/root/users/ssh-keygen/hostname#group-a#some.name#ed25519.pem'
|
||||
Generating public/private rsa key pair.
|
||||
@@ -125,9 +135,10 @@ The key's randomart image is:
|
||||
```
|
||||
|
||||
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
|
||||
@@ -136,7 +147,8 @@ If the public pem file is already provided the output will be a bit different
|
||||
There is no SSH key generate output but *Use existing public ssh key* information line
|
||||
|
||||
If the user has been created, the creating will be skipped
|
||||
```
|
||||
|
||||
```txt
|
||||
-- Skip 'some.name:group-a'
|
||||
```
|
||||
|
||||
@@ -145,7 +157,8 @@ If the user has been created, the creating will be skipped
|
||||
The generated users and the passwords are stored in the '*user_password.YYYYMMDD-hhmmss.txt*' file
|
||||
|
||||
For above the output will be
|
||||
```
|
||||
|
||||
```csv
|
||||
2020-11-27 13:51:01;sever.hostname.org;hostname;some.name;Aeh9uph8Oo
|
||||
2020-11-27 13:51:02;sever.hostname.org;;othername;AePejoo9ch
|
||||
2020-11-27 13:51:02;sever.hostname.org;;username;setpassword
|
||||
@@ -155,7 +168,8 @@ Note that the *sever.hostname.org* is set from the hostname of the server where
|
||||
The name *hostname* is set if the hostname field in hser `user_list.txt` file is set
|
||||
|
||||
If a existing pem public key is used, the entry for a new user will be
|
||||
```
|
||||
|
||||
```csv
|
||||
2020-11-27 13:53:18;sever.hostname.org;;some.name;[ALREADY SET]
|
||||
```
|
||||
|
||||
@@ -180,10 +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
|
||||
|
||||
@@ -191,4 +204,74 @@ 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
|
||||
|
||||
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.
|
||||
|
||||
Data is stored in `auth-log/user_auth.log` folder as `user;last login date`
|
||||
|
||||
This script should be run every day via crontab as root:
|
||||
|
||||
```crontab
|
||||
0 1 * * * root /root/users/bin/collect_login_data.sh
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Currently only information is printed out and no action is done itself.
|
||||
|
||||
The script can be put into the crontab and run once a month, it prints to STDOUT so a mail pipe with a proper subject is recommended
|
||||
|
||||
```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
auth-log/.gitignore
vendored
Normal file
2
auth-log/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
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__
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
# base folder
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
# which group holds the ssh allowed login users (outside of admin users)
|
||||
ssh_group='sshallow';
|
||||
# which groups holds the ssh allowed login users (outside of admin users)
|
||||
ssh_groups=('sshforward' 'sshallow');
|
||||
ssh_reject_group='sshreject';
|
||||
# date now for compare
|
||||
now=$(date +"%s");
|
||||
@@ -16,10 +16,11 @@ max_age_create=30;
|
||||
# one day in seconds
|
||||
day=86400;
|
||||
# delete account strings
|
||||
delete_accounts="";
|
||||
user_group_tpl="deluser %s %s;adduser %s %s;";
|
||||
lock_accounts="";
|
||||
# log base folder
|
||||
LOG="${BASE_FOLDER}/../log";
|
||||
# auth log file user;date from collect_login_data script
|
||||
AUTH_LOG="${BASE_FOLDER}/../auth-log/user_auth.log";
|
||||
|
||||
if [ $(whoami) != "root" ]; then
|
||||
echo "Script must be run as root user";
|
||||
@@ -36,67 +37,97 @@ echo "Hostname : "$(hostname);
|
||||
echo "Run date : "$(date +"%F %T");
|
||||
echo "Max age last login: ${max_age_login} days";
|
||||
echo "Max age no login : ${max_age_create} days";
|
||||
for user in $(cat /etc/group|grep "${ssh_group}:" | cut -d ":" -f 4 | sed -e 's/,/ /g'); do
|
||||
# for user in clemens test42; do
|
||||
account_age=0;
|
||||
delete_user=0;
|
||||
out_string="";
|
||||
#echo "* Checking user ${user}";
|
||||
# check user create time, if we have set it in comment
|
||||
user_create_date=$(cat /etc/passwd | grep "${user}:" | 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);
|
||||
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";
|
||||
user_create_date=$(stat -c %Z "${home_dir}");
|
||||
fi;
|
||||
# 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);
|
||||
search="Never logged in";
|
||||
# if we have "** Never logged in**" the user never logged in
|
||||
if [ ! -z "${last_login_string##*$search*}" ]; then
|
||||
# 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
|
||||
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 logged in ${last_login} days ago";
|
||||
delete_user=1;
|
||||
else
|
||||
out_string="OK";
|
||||
for ssh_group in ${ssh_groups[@]}; do
|
||||
echo "--------------------->"
|
||||
echo "Checking Group : ${ssh_group}";
|
||||
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;
|
||||
elif [ ! -z "${user_create_date}" ]; then
|
||||
user_create_date=$(echo "${user_create_date}" | date +"%s" -f -);
|
||||
# if all empty, we continue with only check if user has last login date
|
||||
# else get days since creation
|
||||
#account_age=$[ ($(date +"%s")-$(date -d "${user_create_date}" +"%s"))/24 ];
|
||||
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;
|
||||
else
|
||||
out_string="OK";
|
||||
account_age=0;
|
||||
lock_user=0;
|
||||
out_string="";
|
||||
#echo "* Checking user ${username}";
|
||||
# check user create time, if we have set it in comment
|
||||
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 ${username} | cut -d " " -f 3);
|
||||
fi;
|
||||
else
|
||||
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';
|
||||
fi;
|
||||
printf "* Checking user %-20s: %s\n" "${user}" "${out_string}";
|
||||
# last try is user home .bash_logout
|
||||
if [ -z "${user_create_date}" ]; then
|
||||
home_dir=$(cat /etc/passwd | grep "${username}:" | cut -d ":" -f 6)"/.bash_logout";
|
||||
user_create_date=$(stat -c %Z "${home_dir}");
|
||||
fi;
|
||||
|
||||
# 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";
|
||||
found="";
|
||||
# problem with running rep check in if
|
||||
if [ -f "${AUTH_LOG}" ]; then
|
||||
found=$(grep "${username};" "${AUTH_LOG}");
|
||||
fi;
|
||||
if [ ! -z "${found}" ]; then
|
||||
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";
|
||||
lock_user=1;
|
||||
else
|
||||
out_string="OK [ssh]";
|
||||
fi;
|
||||
elif [ ! -z "${last_login_string##*$search*}" ]; 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
|
||||
last_login=$(awk '{printf("%.0f\n",($1-$2)/$3)}' <<<"${now} ${last_login_date} ${day}");
|
||||
if [ ${last_login} -gt ${max_age_login} ]; then
|
||||
out_string="[!] last terminal log in ${last_login} days ago";
|
||||
lock_user=1;
|
||||
else
|
||||
out_string="OK [lastlog]";
|
||||
fi;
|
||||
elif [ ! -z "${user_create_date}" ]; then
|
||||
user_create_date=$(echo "${user_create_date}" | date +"%s" -f -);
|
||||
# if all empty, we continue with only check if user has last login date
|
||||
# else get days since creation
|
||||
#account_age=$[ ($(date +"%s")-$(date -d "${user_create_date}" +"%s"))/24 ];
|
||||
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";
|
||||
lock_user=1;
|
||||
else
|
||||
out_string="OK [first login]";
|
||||
fi;
|
||||
else
|
||||
out_string="[!!!] Never logged in and we have no create date";
|
||||
fi;
|
||||
# build delete output
|
||||
if [ ${lock_user} = 1 ]; then
|
||||
lock_accounts="${lock_accounts} ${username}"
|
||||
fi;
|
||||
printf "* Checking user %-20s: %s\n" "${username}" "${out_string}";
|
||||
done;
|
||||
done;
|
||||
if [ ! -z "${delete_accounts}" ]; then
|
||||
echo "--------------------->"
|
||||
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 "${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] ===============>"
|
||||
|
||||
|
||||
140
bin/collect_login_data.sh
Executable file
140
bin/collect_login_data.sh
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# * check we are root
|
||||
# if we are not root, bail out
|
||||
# if [ $(whoami) != "root" ]; then
|
||||
if [[ "$EUID" -ne "0" ]]; then
|
||||
echo "Must be run as root or with sudo command";
|
||||
exit;
|
||||
fi;
|
||||
|
||||
# base folder
|
||||
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
|
||||
# auth log file
|
||||
AUTH_LOG="${BASE_FOLDER}/../auth-log/user_auth.log";
|
||||
if [ ! -f "${AUTH_LOG}" ]; then
|
||||
touch "${AUTH_LOG}";
|
||||
fi;
|
||||
# debug flag
|
||||
DEBUG=0;
|
||||
# check all logs flag
|
||||
RUN_FULL_LOG=0;
|
||||
# option parsing
|
||||
while getopts ":fd" opt; do
|
||||
case "${opt}" in
|
||||
f|full)
|
||||
echo "[!!!] Run through all log files to collect data";
|
||||
RUN_FULL_LOG=1;
|
||||
;;
|
||||
d|deubg)
|
||||
DEBUG=1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
|
||||
function prD()
|
||||
{
|
||||
message="${1}";
|
||||
debug=${2:-0};
|
||||
lb_off=${3:-0};
|
||||
if [ ${debug} -eq 1 ]; then
|
||||
if [ ${lb_off} -eq 1 ]; then
|
||||
echo -n "${message}";
|
||||
else
|
||||
echo "${message}";
|
||||
fi;
|
||||
fi;
|
||||
}
|
||||
|
||||
function parseLog()
|
||||
{
|
||||
# do we have a key entry, if not add new with last log date
|
||||
# clean up date from YYYY nam dd to YYYY-MM-DD HH:II:SS
|
||||
line="${1}";
|
||||
auth_log="${2}";
|
||||
start_year="${3}";
|
||||
logger="${4}";
|
||||
debug=${5:-0};
|
||||
|
||||
#prD "Line: $line" ${debug};
|
||||
# auth user has . at the end, remove that one
|
||||
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);
|
||||
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);
|
||||
fi;
|
||||
auth_date=$(echo "${auth_date}" | date +"%F %T" -f -);
|
||||
|
||||
# $(printf "USER: %-20s: %19s" "${auth_user}" "${auth_date}")
|
||||
# prD "USER: $auth_user | DATE: $auth_date" ${debug} 1;
|
||||
printf -v msg "Source: %-10s | Year: %4s | Last auth user: %-20s: %19s" "${logger}" "${start_year}" "${auth_user}" "${auth_date}"
|
||||
prD "${msg}" ${debug} 1;
|
||||
# find auth user in current auth file
|
||||
# if not there attach, else replace date only
|
||||
found=$(grep "${auth_user};" "${auth_log}");
|
||||
if [ -z "${found}" ]; then
|
||||
prD " | Write new" ${debug};
|
||||
echo "${auth_user};${auth_date}" >> "${auth_log}";
|
||||
else
|
||||
prD " | Replace old" ${debug};
|
||||
sed -i "s/${auth_user};.*$/${auth_user};${auth_date}/" "${auth_log}";
|
||||
fi;
|
||||
}
|
||||
|
||||
printf -v msg "Run date: %s %s" $(date +"%F %T")
|
||||
prD "${msg}" ${DEBUG};
|
||||
|
||||
# Collector script for login information via journalctl
|
||||
# if no systemd installed, try to get info from /var/log/secure or /var/log/auth.log
|
||||
readonly init_version=$(/proc/1/exe --version | head -n 1);
|
||||
if [ -z "${init_version##*systemd*}" ]; then
|
||||
LOG_TARGET="systemd";
|
||||
# for journalctl
|
||||
START_DATE=$(date +%F -d "1 day ago");
|
||||
END_DATE=$(date +%F);
|
||||
OPT_START_DATE='';
|
||||
if [ $RUN_FULL_LOG -eq 0 ]; then
|
||||
OPT_START_DATE="-S ${START_DATE}";
|
||||
OPT_END_DATE="-U ${END_DATE}";
|
||||
fi;
|
||||
# READ as other format so we get the YEAR -o short-iso
|
||||
START_YEAR=$(date +%Y -d "1 day ago");
|
||||
journalctl -u systemd-logind --no-pager -o short-iso ${OPT_START_DATE} ${OPT_END_DATE} | grep ": New session" |
|
||||
while read line; do
|
||||
# # Nov 21 14:15:46 we.are.hostname.com systemd-logind[1865]: New session 12345 of user some^user.
|
||||
# date: 5 chars
|
||||
# time: 8 chars
|
||||
# hostname
|
||||
# systemd-logind pid ...
|
||||
# " of user <username>"
|
||||
# we want date + time + username
|
||||
# prefix year with start date year
|
||||
parseLog "${line}" "${AUTH_LOG}" "${START_YEAR}" "${LOG_TARGET}" ${DEBUG};
|
||||
done;
|
||||
else
|
||||
LOG_TARGET="syslog";
|
||||
# for secure/auth log
|
||||
if [ $RUN_FULL_LOG -eq 1 ]; then
|
||||
# we loop over EACH file and get the DATE so we can have the correct YEAR
|
||||
for sfile in $(ls -1 /var/log/secure*bz2); do
|
||||
tz=$(stat -c %Z "${sfile}");
|
||||
START_YEAR=$(date +%Y -d @${tz});
|
||||
bunzip2 -ck "${sfile}" | grep ": session opened for user" | grep " by (uid=0)" |
|
||||
while read line; do
|
||||
parseLog "${line}" "${AUTH_LOG}" "${START_YEAR}" "${LOG_TARGET}" ${DEBUG};
|
||||
done;
|
||||
done;
|
||||
# read all
|
||||
START_DATE="sshd"
|
||||
fi;
|
||||
START_YEAR=$(date +%Y -d "1 day ago");
|
||||
cat /var/log/secure | grep "${START_DATE}" | grep ": session opened for user" | grep " by (uid=0)" |
|
||||
while read line; do
|
||||
parseLog "${line}" "${AUTH_LOG}" "${START_YEAR}" "${LOG_TARGET}" ${DEBUG};
|
||||
done;
|
||||
fi;
|
||||
|
||||
# __END__
|
||||
443
bin/create_user.sh
Executable file
443
bin/create_user.sh
Executable file
@@ -0,0 +1,443 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# * input file
|
||||
# user_list.txt
|
||||
# <ignored id>;<user name>;<group>[,sub group,sub group];<ssh access type>;[override password];[override hostname];[override ssh key type]
|
||||
# lines with # are skipped
|
||||
# already created users are skipped
|
||||
# Mandatory: <ignored id>;<user name>;<group>;<ssh access type>
|
||||
# <ssh access type> can be
|
||||
# allow (full login access)
|
||||
# forward (forward/jump host only)
|
||||
# * output file
|
||||
# <date>;<target connect host name>;<hostname>;<username>;<password>;<ssh access type>
|
||||
# If already existing PEM key is used then <password> is [ALREADY SET]
|
||||
#
|
||||
# * PEM KEY
|
||||
# <hostname>#<group>#<user>#<ssh key type>.pem
|
||||
# * PUBLIC KEY
|
||||
# <hostname>#<group>#<user>#<ssh key type>.pem.pub
|
||||
# stored as zip in
|
||||
# zip/
|
||||
#
|
||||
# If a previously exsting PEM key should be used, put the public pem file
|
||||
# into the ssh-keygen/ folder
|
||||
# They pem pub key must follow the set rules above
|
||||
|
||||
# SET TO 1 to TEST [will not create user/group/folder]
|
||||
TEST=0; # no actions will be run
|
||||
INFO=0; # no creation of anything, just print info strings
|
||||
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
|
||||
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/';
|
||||
# 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}";
|
||||
fi;
|
||||
# check if zip folder is missing
|
||||
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";
|
||||
error=1;
|
||||
fi;
|
||||
# check for zip
|
||||
# if [ ! command -v zip &> /dev/null ]; then
|
||||
if [ -z $(command -v zip) ]; then
|
||||
echo "Missing zip application, aborting";
|
||||
error=1;
|
||||
fi;
|
||||
# check if sshallow or sshfoward group exists
|
||||
if [ -z $(cat /etc/group | grep "sshallow:") ]; then
|
||||
echo "Missing ssh access group: sshallow";
|
||||
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}";
|
||||
error=1;
|
||||
fi;
|
||||
# make sure my own folder is owned by root and 600 (except for testing)
|
||||
if [ $(stat -c %a .) != "600" ]; then
|
||||
echo "!!!! RECOMMENDED TO HAVE BASE FOLDER SET TO '600' AND USER 'root' !!!!"
|
||||
fi;
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ] && [ ${INFO} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
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}" |
|
||||
while read i; do
|
||||
# skip rows start with # (comment)
|
||||
if [[ "${i}" =~ ^\# ]]; then
|
||||
continue;
|
||||
fi;
|
||||
# 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
|
||||
echo "[!!] Not valid ssh access type ${ssh_access_type}, set to allow";
|
||||
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 ${username}";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
break;
|
||||
fi;
|
||||
fi;
|
||||
ssh_group="ssh${ssh_access_type}";
|
||||
# sshallow group is always added
|
||||
sub_group_opt=" -G ${ssh_group}";
|
||||
# check if "," inside and extract sub groups
|
||||
if [ -z "${_group##*,*}" ]; then
|
||||
sub_group=$(echo "${_group}" | cut -d "," -f 2-);
|
||||
sub_group_opt=" -G ${sub_group}";
|
||||
fi;
|
||||
# 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;
|
||||
# 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 "${username}" ] || [ -z "${_group}" ]; then
|
||||
echo "[!!!!!] Missing user or group entry for ${username}/${_group}";
|
||||
echo "[*** ABORT RUN ***]"
|
||||
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}${username}${separator}${ssh_keytype}.pem";
|
||||
# the full file including folder name
|
||||
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";
|
||||
|
||||
if [ ${INFO} -eq 1 ]; then
|
||||
# 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";
|
||||
fi;
|
||||
if [ -f "${ssh_keyfile_check_pub}" ]; then
|
||||
echo -n ", SSH Pub key OK";
|
||||
fi;
|
||||
# line break
|
||||
echo "";
|
||||
continue;
|
||||
fi;
|
||||
|
||||
# add group for each entry in _group
|
||||
for create_group in ${_group//,/ }; do
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
groupadd -f ${create_group};
|
||||
else
|
||||
echo "$> groupadd -f ${create_group}";
|
||||
fi;
|
||||
done;
|
||||
# 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})'";
|
||||
else
|
||||
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} -d "${HOME_FOLDER}${username}" -m ${username};
|
||||
else
|
||||
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 14 1));
|
||||
else
|
||||
echo "! Override password set";
|
||||
password=${_password};
|
||||
fi;
|
||||
# create SSH key
|
||||
echo " > Create ssh key-pair '${ssh_keyfile}'";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
ssh-keygen \
|
||||
-t ${ssh_keytype} \
|
||||
-f "${ssh_keyfile}" \
|
||||
-C "${hostname}: ${username}@${group}" \
|
||||
-a 100 -N "${password}"
|
||||
else
|
||||
echo "$> ssh-keygen -t ${ssh_keytype} -f ${ssh_keyfile} -C ${hostname}: ${username}@${group} -a 100 -N ${password}";
|
||||
fi;
|
||||
else
|
||||
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;
|
||||
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;
|
||||
password="[ALREADY SET]";
|
||||
fi;
|
||||
if [ ${skip_ssh} -eq 0 ]; then
|
||||
# write login info to output file
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
create_output_file="${ROOT_FOLDER}${output_file}";
|
||||
else
|
||||
create_output_file="${ROOT_FOLDER}${output_file}.TEST";
|
||||
fi;
|
||||
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
|
||||
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;
|
||||
# add
|
||||
echo " > Add public into authorized_keys file";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
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
|
||||
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;
|
||||
# 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 " > 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;
|
||||
|
||||
# End before anything because this is just info run
|
||||
if [ ${INFO} -eq 1 ]; then
|
||||
exit;
|
||||
fi;
|
||||
# zip everything and remove data in ssh key folder, delete output file with passwords
|
||||
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}";
|
||||
# delete the rest
|
||||
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}*";
|
||||
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__
|
||||
96
bin/lock_user.sh
Executable file
96
bin/lock_user.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/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
|
||||
while getopts ":t" opt; do
|
||||
case "${opt}" in
|
||||
t|test)
|
||||
TEST=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
|
||||
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;
|
||||
# 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";
|
||||
continue;
|
||||
fi;
|
||||
# check if user is in sshallow/forward list
|
||||
ssh_remove_group='';
|
||||
if id -nGz "${username}" | grep -qzxF "${ssh_allow_group}"; then
|
||||
ssh_remove_group="${ssh_allow_group}";
|
||||
fi;
|
||||
# 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.";
|
||||
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}";
|
||||
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";
|
||||
fi;
|
||||
done;
|
||||
|
||||
# __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__
|
||||
@@ -1,268 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# * input file
|
||||
# user_list.txt
|
||||
# <ignored id>;<user name>;<group>[,sub group,sub group];[override password];[override hostname];[override ssh key type]
|
||||
# lines with # are skipped
|
||||
# already created users are skipped
|
||||
# Mandatory: <ignored id>;<user name>;<group>
|
||||
# * output file
|
||||
# <date>;<target connect host name>;<hostname>;<username>;<password>
|
||||
# If already existing PEM key is used then <password> is [ALREADY SET]
|
||||
#
|
||||
# * PEM KEY
|
||||
# <hostname>#<group>#<user>#<ssh key type>.pem
|
||||
# * PUBLIC KEY
|
||||
# <hostname>#<group>#<user>#<ssh key type>.pem.pub
|
||||
# stored as zip in
|
||||
# zip/
|
||||
#
|
||||
# If a previously exsting PEM key should be used, put the public pem file
|
||||
# into the ssh-keygen/ folder
|
||||
# They pem pub key must follow the set rules above
|
||||
|
||||
# SET TO 1 to TEST [will no create user/group/folder]
|
||||
TEST=0; # no creation except ssh keys
|
||||
INFO=0; # no creation of anything, just print info strings
|
||||
while getopts ":ti" opt; do
|
||||
case "${opt}" in
|
||||
t|test)
|
||||
TEST=1;
|
||||
;;
|
||||
i|info)
|
||||
INFO=1;
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
# 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)'/';
|
||||
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_group='sshallow';
|
||||
# check if ssh key folder exists
|
||||
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}";
|
||||
fi;
|
||||
# check if password generate software is installed
|
||||
if [ ! command -v pwgen &> /dev/null ]; then
|
||||
echo "Missing pwgen application, aborting";
|
||||
exit;
|
||||
fi;
|
||||
# check for zip
|
||||
if [ ! command -v zip &> /dev/null ]; then
|
||||
echo "Missing zip application, aborting";
|
||||
exit;
|
||||
fi;
|
||||
# check if sshallow group exists
|
||||
if [ -z $(cat /etc/group|grep "${ssh_group}:") ]; then
|
||||
echo "Missing ssh access group: ${ssh_group}";
|
||||
exit;
|
||||
fi;
|
||||
# check if user list file exists
|
||||
if [ ! -f "${root_folder}${input_file}" ]; then
|
||||
echo "Missing ${root_folder}${input_file}";
|
||||
exit;
|
||||
fi;
|
||||
exit;
|
||||
# make sure my own folder is owned by root and 600 (except for testing)
|
||||
if [ $(stat -c %a .) != "600" ]; then
|
||||
echo "!!!! RECOMMENDED TO HAVE BASE FOLDER SET TO '600' AND USER 'root' !!!!"
|
||||
fi;
|
||||
if [ $(whoami) != "root" ]; then
|
||||
if [ ${TEST} -eq 0 ] && [ ${INFO} -eq 0 ]; then
|
||||
echo "Script must be run as root user";
|
||||
exit;
|
||||
else
|
||||
echo "!!!! Script must be run as root user !!!!";
|
||||
fi;
|
||||
fi;
|
||||
# create users
|
||||
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 ' ');
|
||||
_group=$(echo "${i}" | cut -d ";" -f 3 | tr A-Z a-z | tr -d ' ');
|
||||
group=$(echo "${_group}" | cut -d "," -f 1);
|
||||
sub_group="";
|
||||
# sshallow group is always added
|
||||
sub_group_opt=" -G ${ssh_group}";
|
||||
# check if "," inside and extract sub groups
|
||||
if [ -z "${_group##*,*}" ]; then
|
||||
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 ' ');
|
||||
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 ' ');
|
||||
if [ "${_ssh_keytype}" = "rsa" ]; then
|
||||
ssh_keytype="${_ssh_keytype}";
|
||||
#echo "[!!] BACKWARDS COMPATIBLE RSA TYPE SELECTION [!!]";
|
||||
fi;
|
||||
# user & group not set
|
||||
if [ -z "${user}" ] || [ -z "${_group}" ]; then
|
||||
echo "[!!!!!] Missing user or group entry for ${user}/${_group}";
|
||||
echo "[*** ABORT RUN ***]"
|
||||
break;
|
||||
fi;
|
||||
# SSH file name part without folder
|
||||
ssh_keygen_id="${hostname}${separator}${group}${separator}${user}${separator}${ssh_keytype}.pem";
|
||||
# the full file including folder name
|
||||
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";
|
||||
|
||||
if [ ${INFO} -eq 1 ]; then
|
||||
# test if pub file exists or not, test if user exists
|
||||
echo -n "User: '${user}:${group}(${sub_group})', SSH: ${ssh_keygen_id}";
|
||||
if getent passwd ${user} > /dev/null 2>&1; then
|
||||
echo -n ", User exists";
|
||||
fi;
|
||||
if [ -f "${ssh_keyfile_check_pub}" ]; then
|
||||
echo -n ", SSH Pub key OK";
|
||||
fi;
|
||||
# line break
|
||||
echo "";
|
||||
continue;
|
||||
fi;
|
||||
|
||||
# add group for each entry in _group
|
||||
for create_group in ${_group//,/ }; do
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
groupadd -f ${create_group};
|
||||
else
|
||||
echo "$> groupadd -f ${create_group}";
|
||||
fi;
|
||||
done;
|
||||
# check if user is not already created
|
||||
if getent passwd ${user} > /dev/null 2>&1; then
|
||||
echo "-- Skip '${user}:${group}(${sub_group})'";
|
||||
else
|
||||
echo "++ Create '${user}:${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};
|
||||
else
|
||||
echo "$> useradd -s /bin/bash -g ${group}${sub_group_opt} -m ${user}";
|
||||
fi;
|
||||
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));
|
||||
else
|
||||
echo "! Override password set";
|
||||
password=${_password};
|
||||
fi;
|
||||
# create SSH key
|
||||
echo " > Create ssh key-pair '${ssh_keyfile}'";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
ssh-keygen \
|
||||
-t ${ssh_keytype} \
|
||||
-f "${ssh_keyfile}" \
|
||||
-C "${hostname}: ${user}@${group}" \
|
||||
-a 100 -N "${password}"
|
||||
else
|
||||
echo "$> ssh-keygen -t ${ssh_keytype} -f ${ssh_keyfile} -C ${hostname}: ${user}@${group} -a 100 -N ${password}";
|
||||
fi;
|
||||
else
|
||||
found=$(grep "$(cat ${ssh_keyfile_check_pub})" /home/${user}/.ssh/authorized_keys);
|
||||
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
|
||||
echo " < Use existing public ssh key '${ssh_keygen_id}.pub'";
|
||||
# Password already set notification
|
||||
fi;
|
||||
password="[ALREADY SET]";
|
||||
fi;
|
||||
if [ ${skip_ssh} -eq 0 ]; then
|
||||
# write login info to output file
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
echo $(date +"%F %T")";"${host}";"${_hostname}";"${user}";"${password} >> ${root_folder}${output_file};
|
||||
else
|
||||
echo $(date +"%F %T")";"${host}";"${_hostname}";"${user}";"${password} >> ${root_folder}${output_file}".TEST";
|
||||
fi;
|
||||
# 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/";
|
||||
fi;
|
||||
echo " > Add public into authorized_keys";
|
||||
if [ ${TEST} -eq 0 ]; then
|
||||
cat "${ssh_keyfile_pub}" > /home/${user}/.ssh/authorized_keys;
|
||||
else
|
||||
echo "$> cat ${ssh_keyfile_pub} > /home/${user}/.ssh/authorized_keys";
|
||||
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;
|
||||
else
|
||||
echo "$> chown -R ${user}:${group} /home/${user}/.ssh/";
|
||||
echo "$> chmod 700 /home/${user}/.ssh/";
|
||||
echo "$> chmod 600 /home/${user}/.ssh/authorized_keys";
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
|
||||
# End before anything because this is just info run
|
||||
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}";
|
||||
# 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}";
|
||||
# delete the rest
|
||||
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}*";
|
||||
fi;
|
||||
|
||||
# __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 ""
|
||||
```
|
||||
@@ -1 +1 @@
|
||||
#user_id;user_name;group,subgroup;override password;override hostname;override ssh type
|
||||
#user_id;user_name;group,subgroup;ssh access type;override password;override hostname;override ssh type
|
||||
|
||||
Reference in New Issue
Block a user