#!/usr/bin/env bash # * input file # user_list.txt # ;;[,sub group,sub group];[override password];[override hostname];[override ssh key type] # lines with # are skipped # already created users are skipped # Mandatory: ;; # * 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; # 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 if [ -z $(command -v pwgen) ]; then echo "Missing pwgen application, aborting"; exit; fi; # check for zip # if [ ! command -v zip &> /dev/null ]; then if [ -z $(command -v zip) ]; 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; # 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__