diff --git a/.gitignore b/.gitignore index 5525332..2cdf2e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ user_list.txt -user_password.txt -ssh-keygen/* +user_password*.txt *.zip diff --git a/Readme.md b/Readme.md index 839dbf9..fe9d8a2 100644 --- a/Readme.md +++ b/Readme.md @@ -6,29 +6,35 @@ Two files to create new user entries with an SSH key and zip all the data for do The application **pwgen** and **zip** must be installed. -Copy the two files '*user_create.sh*', '*user_zip.sh*' to any target folder on the target aws server. -For exmaple `/root/bin` +Checkout the scripts from git into the `/root/` folder or any other folder. +The folder holding the script must be owned by *root* and have *600* permissions -`$> mkdir /root/bin` +```sh +cd /root/ +git clone http://git.tequila.jp/ScriptsCollections/AwsUserCreate.git users +chown root. users +chgrp 600 users +``` -Create a base folder where all the user lists and keys are stored. -For example `/root/users` +## Folders -`$> mkdir /root/users` - -The script will automatically create `/ssh-keygen` as as sub folder to above set `/root/users` +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 ## User list creation -In the `/root/users` folder there needs to be a file called '*user_list.txt*' +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 --|-|-|- +ID | Username | Group | Optional Password | Override host name +-|-|-|-|- 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` The ID can be any string in any form. It can also be left empty. It is not used at the moment @@ -37,10 +43,10 @@ The file can hold comments. The first character in the line must be a *#* Example file ``` -user1;some.name;group-a -user2;othername;group-a +user1;some.name;group-a;;hostname +user2;othername;group-a;; # I am a comment -;username;groupC;setpassword +;username;groupC;setpassword; ... ``` @@ -48,29 +54,25 @@ user2;othername;group-a If we want to create a user that already has a PEM key or we want to have the user use the same PEM key for login we can copy the existing pub key into the ssh key folder -If the folder `ssh-keygen` does not exist, create it as as sub folder to the folder where the '*user_list.txt*' is located - -In our example - -`$> mkdir /root/users/ssh-keygen` +If the folder `ssh-keygen` does not exist, the folder is automatically created as a sub folder to the folder where the '*user_list.txt*' is located. An additional `zip` folder is created that will hold the current run created user data. The public PEM key file format is as followed -**group name**-**user name**.pem.pub +**hostname**#**main group name**#**user name**#**ssh key type**.pem.pub In the example above for *user1* the file name would be for **some.name** and **group-a** -`group-a-some.name.pem.pub` +`hostname#group-a#some.name#ssh-keytype.pem.pub` Copy this file into the ssh-keygen folder and add the user to the '*user_list.txt*' file. This must be with the same name and group as set in the PEM public key. Example: -PEM public key file is `Bgroup-foobar.pem.pub` +PEM public key file is `hostname#Bgroup#foobar#ed25519.pem.pub` Then the line for the '*user_list.txt*' must be -`[some user id];foobar;Bgroup` +`[some user id];foobar;Bgroup;;` Note that *[some user id]* can be any string or left empty @@ -87,10 +89,10 @@ Then run the script without any options Sample output for above example file ``` ++ Create 'some.name:group-a' - > Create ssh key-pair '/root/users/ssh-keygen/group-a-some.name.pem' + > Create ssh key-pair '/root/users/ssh-keygen/hostname#group-a#some.name#ed25519.pem' Generating public/private rsa key pair. -Your identification has been saved in /root/users/ssh-keygen/group-a-some.name.pem. -Your public key has been saved in /root/users/ssh-keygen/group-a-some.name.pem.pub. +Your identification has been saved in /root/users/ssh-keygen/hostname#group-a#some.name#ed25519.pem. +Your public key has been saved in /root/users/ssh-keygen/hostname#group-a#some.name#ed25519.pem.pub. The key fingerprint is: SHA256:Ufalh41IRLJTHZlsaEJVK5N7cOYhxRdqf3fCDxhHdCA egrp10070.globalad.org: some.name@group-a The key's randomart image is: @@ -113,7 +115,7 @@ The key's randomart image is: If the public pem file is already provided the output will be a bit different ``` ++ Create 'some.name:group-a' - < Use existing public ssh key '/root/users/ssh-keygen/group-a-some.name.pem.pub' + < Use existing public ssh key '/root/users/ssh-keygen/hostname#group-a#some.name#ed25519.pem.pub' > Create .ssh folder > Add public into authorized_keys > Secure folder .ssh and authorized_keys file @@ -132,16 +134,17 @@ The generated users and the passwords are stored in the '*user_password.txt*' fi For above the output will be ``` -2020-11-27 13:51:01;sever.hostname.org;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 +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 ``` -Note that the *sever.hostname.org* is set from the hostname of the server where the script is unr +Note that the *sever.hostname.org* is set from the hostname of the server where the script is run +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 ``` -2020-11-27 13:53:18;sever.hostname.org;some.name;[ALREADY SET] +2020-11-27 13:53:18;sever.hostname.org;;some.name;[ALREADY SET] ``` Not that the password field has now *[ALREADY SET]* @@ -169,21 +172,5 @@ The public key part can be extracted from the SSH PEM key with ## Get the user data -To copy the user data with the SSH PEM file and password list the following command can be used. -Like the create user command it **MUST** be run in the folder where the '*user_list.txt*' - -`$> cd /root/users` - -The script needs to be run with one parameter that is the folder where the output file '*users.zip*' is stored. - -`$> /root/bin/user_zip.sh [target folder]` - -In the *[target folder]* a file name '*users.zip*' will be created. -This file has the following data data inside -- user_list.txt -- user_password.txt -- ssh-keygen/*.pem -- ssh-keygen/*.pem.pub - -When extracted this will **NOT** create a sub folder. -Create a folder where to store this data on the local side is highly recommended +In the `zip/` folder there is a file named `users.YYYYMMDD-hhmmss.zip`; +This file should be copied localy and then removed from the server diff --git a/bin/user_create.sh b/bin/user_create.sh new file mode 100755 index 0000000..37a9c42 --- /dev/null +++ b/bin/user_create.sh @@ -0,0 +1,210 @@ +#!/bin/bash + +# * input file +# user_list.txt +# ;;[;override password][;override hostname] +# lines with # are skipped +# already created users are skipped +# * output file +# ;;;; +# If already existing PEM key is used then is [ALREADY SET] +# +# * PEM KEY +# %%%.pem +# * PUBLIC KEY +# %%%.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; +while getopts ":t" opt; do + case "${opt}" in + t|test) + TEST=1; + ;; + esac; +done; +# hostname for output file only +host=$(hostname); +timesamp=$(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.${timesamp}.txt"; +output_zip_folder='zip/'; +output_zip="users.${timesamp}.zip" +ssh_keygen_folder='ssh-keygen/'; +ssh_keytype='ed25519'; +# 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 user list file exists +if [ ! -f "${root_folder}${input_file}" ]; then + echo "Missing ${root_folder}${input_file}"; + exit; +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 ]; 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 + echo -e ""; + else + # 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=""; + sub_group_opt=""; + # 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); + # user & group not set + if [ -z "${user}" ] || [ -z "${_group}" ]; then + echo "[!!!!!] Missing user or group entry for ${user}/${_group}"; + echo "[ABORT RUN]" + break; + 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; + # 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}"; + # 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 + useradd -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}.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}'"; + ssh-keygen \ + -t ${ssh_keytype} \ + -f "${ssh_keyfile}" \ + -C "${hostname}: ${user}@${group}" \ + -a 100 -N "${password}" + else + found=$(grep "$(cat ${ssh_keyfile}.pub)" /home/${user}/.ssh/authorized_keys); + if [ ! -z "${found}" ]; then + skip_ssh=1; + echo "-- Skip SSH Key creation: ${ssh_keygen_id}.pub"; + else + echo " < Use existing public ssh key '${ssh_keyfile}.pub'"; + # Password already set notification + password="[ALREADY SET]"; + fi; + fi; + if [ ${skip_ssh} -eq 0 ]; then + # write login info to output file + echo $(date +"%F %T")";"${host}";"${_hostname}";"${user}";"${password} >> ${root_folder}${output_file}; + # 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; + fi; +done; + +# 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 + rm "${root_folder}${output_file}"; + rm "${root_folder}${ssh_keygen_folder}"*; +else + echo "$> rm ${root_folder}${output_file}"; + echo "$> rm ${root_folder}${ssh_keygen_folder}*"; +fi; diff --git a/ssh-keygen/.gitignore b/ssh-keygen/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/ssh-keygen/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/user_create.sh b/user_create.sh deleted file mode 100755 index e89369e..0000000 --- a/user_create.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/bash - -# * input file -# user_list.txt -# ;;[;optional override password] -# lines with # are skipped -# already created users are skipped -# * output file -# ;;; -# If already existing PEM key is used then is [ALREADY SET] -# -# * PEM KEY -# -.pem -# * PUBLIC KEY -# -.pem.pub -# store in -# ssh-keygen/ -# -# 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; -# hostname for output file only -host=$(hostname); -# base folder for all data -root_folder=$(pwd)'/'; -input_file='user_list.txt'; -output_file='user_password.txt'; -ssh_keygen_folder='ssh-keygen/'; -# check if ssh key folder exists -if [ ! -d "${root_folder}${ssh_keygen_folder}" ]; then - mkdir "${root_folder}${ssh_keygen_folder}"; -fi; -# check if password generate software is installed -if [ ! command -v pwgen &> /dev/null ]; then - echo "Missing pwgen application, aborting"; - exit; -fi; -# check if user list file exists -if [ ! -f "${root_folder}${input_file}" ]; then - echo "Missing ${root_folder}${input_file}"; - exit; -fi; -# create users -cat "${root_folder}${input_file}" | -while read i; do - # skip rows start with # (comment) - if [[ "${i}" =~ ^# ]]; then - echo -e ""; - else - user=$(echo "${i}" | cut -d ";" -f 2 | tr A-Z a-z); - group=$(echo "${i}" | cut -d ";" -f 3 | tr A-Z a-z); - # user & group not set - if [ -z "${user}" ] || [ -z "${group}" ]; then - echo "[!!!!!] Missing user or group entry for ${user}/${group}"; - echo "[ABORT RUN]" - break; - fi; - # do we have a password preset - _password=$(echo "${i}" | cut -d ";" -f 4); - # add group - if [ ${TEST} -eq 0 ]; then - groupadd -f ${group}; - else - echo "$> groupadd -f ${group}"; - fi; - # SSH key base name (removed ${host}- so we can use it more easy for multi server same key) - ssh_keygen_id="${group}-${user}.pem"; - # check if user is not already created - if getent passwd ${user} > /dev/null 2>&1; then - echo "-- Skip '${user}:${group}'"; - else - echo "++ Create '${user}:${group}'"; - if [ ${TEST} -eq 0 ]; then - useradd -s /bin/bash -g ${group} -m ${user}; - else - echo "$> useradd -s /bin/bash -g ${group} -m ${user}"; - fi; - # if public pem already exists skip creation - if [ ! -f ${root_folder}${ssh_keygen_folder}${ssh_keygen_id}".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 '${root_folder}${ssh_keygen_folder}${ssh_keygen_id}'"; - ssh-keygen -f ${root_folder}${ssh_keygen_folder}${ssh_keygen_id} -C "${host}: ${user}@${group}" -N "${password}" - else - echo " < Use existing public ssh key '${root_folder}${ssh_keygen_folder}${ssh_keygen_id}.pub'"; - # Password already set notification - password="[ALREADY SET]"; - fi; - # write login info to output file - echo $(date +"%F %T")";"${host}";"${user}";"${password} >> ${root_folder}${output_file}; - # 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 ${root_folder}${ssh_keygen_folder}/${ssh_keygen_id}.pub > /home/${user}/.ssh/authorized_keys; - else - echo "$> cat ${root_folder}${ssh_keygen_folder}/${ssh_keygen_id}.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; - fi; -done; - -if [ -f "${root_folder}${output_file}" ]; then - chmod 600 ${root_folder}${output_file}; -fi; diff --git a/user_list.txt-sample b/user_list.txt-sample new file mode 100644 index 0000000..ee933b8 --- /dev/null +++ b/user_list.txt-sample @@ -0,0 +1 @@ +#user_id;user_name;group,subgroup;optional override password;optional override hostname diff --git a/user_zip.sh b/user_zip.sh deleted file mode 100755 index 3b51f52..0000000 --- a/user_zip.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -root_folder=$(pwd)'/'; - -if [ ! command -v zip &> /dev/null ]; then - echo "Missing zip application, aborting"; - exit; -fi; - -# arg 1 must be valid path to where we store the zip file -if [ ! -d "${1}" ]; then - echo "${1} is not a valid path"; - exit; -fi; - -# zip key folder, user list, user password into users.zip -echo "Zipping data to: ${1}/users.zip" -$(cd "${root_folder}"; zip -FSr "${1}/users.zip" "user_list.txt" "user_password.txt" "ssh-keygen/"); -echo "Data zipped"; diff --git a/zip/.gitignore b/zip/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/zip/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore