In this article I'd like to share a script I wrote to add the rsa_id.pub public key of a user belonging to one server to a given list of users present on another server. The script will be executed on the destination server.
The task sounds simple enough to accomplish with the help of a simple for loop but I've added some checks to make the script more user friendly so that you may be in a position to share this script with your clolleagues and perhaps even end users if they have sufficient privileges to add keys. I've added some code that I might like to reuse in the future.
So, here is the script:
#!/bin/bash
###############################################
#Purpose: Add public ssh key to multiple users #
#Author; Sahil Suri #
#date: 24/06/2017 #
###############################################
cat /dev/null > sftp_user_not_found.txt
cat /dev/null > sftp_user_key_add.txt
#This will only check for existance of the user and .ssh directory within home directory of the user#
function check_dir() {
echo "Please supply list of users: "
read USER_LIST
for USERNAME in `cat ${USER_LIST}`
do
echo "Checking if user ${USERNAME} exists"
grep -w ${USERNAME} /etc/passwd > /dev/null
if [ $? -eq 0 ]
then
echo -e "The user ${USERNAME} exists on server $(hostname) \n"
echo "The user ${USERNAME} exists on server $(hostname)"
HOME_DIR=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $6}')
HOME_DIR_PERM=$(ls -ld ${HOME_DIR} | awk '{print $1}' | tr -d "d")
GID_NUMERIC=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $4}')
GID_WORD=$(grep -w ${GID_NUMERIC} /etc/group | awk -F: '{print $1}')
echo -e "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM} \n"
echo "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM}" >> sftp_user_key_add.txt
echo "Checking if .ssh directory exists for user ${USERNAME}"
ls -l ${HOME_DIR}/.ssh > /dev/null 2> /dev/null
if [ $? -ne 0 ]
then
echo -e ".ssh directory does not exist for user ${USERNAME} \n"
fi
else
echo -e "The user ${USERNAME} does not exist on server $(hostname) \n"
echo "The user ${USERNAME} does not exist on server $(hostname) " >> sftp_user_not_found.txt
fi
done
}
#This will check for existance of the user and .ssh directory within home directory of the user#
#and add the key supplied to it in authorized_keys file for the user list provided to it#
function add_key() {
echo "Please supply list of users: "
read USER_LIST
echo "Please supply the key file you wish to append authorized_keys files of these users: "
read KEY_FILE
for USERNAME in `cat ${USER_LIST}`
do
echo "Checking if user ${USERNAME} exists"
grep -w ${USERNAME} /etc/passwd > /dev/null
if [ $? -eq 0 ]
then
echo -e "The user ${USERNAME} exists on server $(hostname) \n"
echo "The user ${USERNAME} exists on server $(hostname)"
HOME_DIR=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $6}')
HOME_DIR_PERM=$(ls -ld ${HOME_DIR} | awk '{print $1}' | tr -d "d")
GID_NUMERIC=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $4}')
GID_WORD=$(grep -w ${GID_NUMERIC} /etc/group | awk -F: '{print $1}')
echo -e "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM} \n"
echo "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM}" >> sftp_user_key_add.txt
echo "Checking if .ssh directory exists for user ${USERNAME}"
ls -l ${HOME_DIR}/.ssh > /dev/null 2> /dev/null
if [ $? -ne 0 ]
then
echo -e ".ssh directory does not exist for user ${USERNAME} \n"
echo "Creating .ssh directory and setting permissions for ${USERNAME} user"
sudo mkdir ${HOME_DIR}/.ssh
sudo chmod 700 ${HOME_DIR}/.ssh
sudo chown ${USERNAME}:${GID_WORD} ${HOME_DIR}/.ssh
sudo touch ${HOME_DIR}/.ssh/authorized_keys
sudo chown ${USERNAME}:${GID_WORD} ${HOME_DIR}/.ssh/authorized_keys
sudo chmod 644 ${HOME_DIR}/.ssh/authorized_keys
sudo cat ${KEY_FILE} >> ${HOME_DIR}/.ssh/authorized_keys
sudo chmod 750 ${HOME_DIR}
fi
else
echo -e "The user ${USERNAME} does not exist on server $(hostname) \n"
echo "The user ${USERNAME} does not exist on server $(hostname) " >> sftp_user_not_found.txt
fi
done
}
#pass an argument to the script suggesting how you'd like to execute it#
OPTION="$1"
if [ "$#" -ne 1 ]
then
echo "You must specify an option to run the script"
echo "-h for help or -r to run the script. Exiting now"
exit
fi
#Required case statement logic to implement user option#
case $OPTION in
"-h")
echo "Displaying help"
echo "To run the script type: ./add_public_key.bash -r"
echo "You need to become root via sudo su - before running the script"
echo "Enter the file containing list of users within whose home key is to be added when prompted"
echo "Enter the file containing the public key when prompted"
;;
"-r")
echo "Running the script"
echo "type 1 and press enter if you wish to check for the presence of .ssh directory"
echo "type 2 and press enter if you wish to copy the key file right now"
read USER_SEL
if [ $USER_SEL -eq 1 ]
then
check_dir
elif [ $USER_SEL -eq 2 ]
then
add_key
else
echo "Invalid option"
exit
fi
;;
*)
echo "invalid execution"
;;
esac
The task sounds simple enough to accomplish with the help of a simple for loop but I've added some checks to make the script more user friendly so that you may be in a position to share this script with your clolleagues and perhaps even end users if they have sufficient privileges to add keys. I've added some code that I might like to reuse in the future.
So, here is the script:
#!/bin/bash
###############################################
#Purpose: Add public ssh key to multiple users #
#Author; Sahil Suri #
#date: 24/06/2017 #
###############################################
cat /dev/null > sftp_user_not_found.txt
cat /dev/null > sftp_user_key_add.txt
#This will only check for existance of the user and .ssh directory within home directory of the user#
function check_dir() {
echo "Please supply list of users: "
read USER_LIST
for USERNAME in `cat ${USER_LIST}`
do
echo "Checking if user ${USERNAME} exists"
grep -w ${USERNAME} /etc/passwd > /dev/null
if [ $? -eq 0 ]
then
echo -e "The user ${USERNAME} exists on server $(hostname) \n"
echo "The user ${USERNAME} exists on server $(hostname)"
HOME_DIR=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $6}')
HOME_DIR_PERM=$(ls -ld ${HOME_DIR} | awk '{print $1}' | tr -d "d")
GID_NUMERIC=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $4}')
GID_WORD=$(grep -w ${GID_NUMERIC} /etc/group | awk -F: '{print $1}')
echo -e "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM} \n"
echo "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM}" >> sftp_user_key_add.txt
echo "Checking if .ssh directory exists for user ${USERNAME}"
ls -l ${HOME_DIR}/.ssh > /dev/null 2> /dev/null
if [ $? -ne 0 ]
then
echo -e ".ssh directory does not exist for user ${USERNAME} \n"
fi
else
echo -e "The user ${USERNAME} does not exist on server $(hostname) \n"
echo "The user ${USERNAME} does not exist on server $(hostname) " >> sftp_user_not_found.txt
fi
done
}
#This will check for existance of the user and .ssh directory within home directory of the user#
#and add the key supplied to it in authorized_keys file for the user list provided to it#
function add_key() {
echo "Please supply list of users: "
read USER_LIST
echo "Please supply the key file you wish to append authorized_keys files of these users: "
read KEY_FILE
for USERNAME in `cat ${USER_LIST}`
do
echo "Checking if user ${USERNAME} exists"
grep -w ${USERNAME} /etc/passwd > /dev/null
if [ $? -eq 0 ]
then
echo -e "The user ${USERNAME} exists on server $(hostname) \n"
echo "The user ${USERNAME} exists on server $(hostname)"
HOME_DIR=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $6}')
HOME_DIR_PERM=$(ls -ld ${HOME_DIR} | awk '{print $1}' | tr -d "d")
GID_NUMERIC=$(grep -w ${USERNAME} /etc/passwd | awk -F: '{print $4}')
GID_WORD=$(grep -w ${GID_NUMERIC} /etc/group | awk -F: '{print $1}')
echo -e "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM} \n"
echo "Home directory for user ${USERNAME} is ${HOME_DIR} and its permissions are ${HOME_DIR_PERM}" >> sftp_user_key_add.txt
echo "Checking if .ssh directory exists for user ${USERNAME}"
ls -l ${HOME_DIR}/.ssh > /dev/null 2> /dev/null
if [ $? -ne 0 ]
then
echo -e ".ssh directory does not exist for user ${USERNAME} \n"
echo "Creating .ssh directory and setting permissions for ${USERNAME} user"
sudo mkdir ${HOME_DIR}/.ssh
sudo chmod 700 ${HOME_DIR}/.ssh
sudo chown ${USERNAME}:${GID_WORD} ${HOME_DIR}/.ssh
sudo touch ${HOME_DIR}/.ssh/authorized_keys
sudo chown ${USERNAME}:${GID_WORD} ${HOME_DIR}/.ssh/authorized_keys
sudo chmod 644 ${HOME_DIR}/.ssh/authorized_keys
sudo cat ${KEY_FILE} >> ${HOME_DIR}/.ssh/authorized_keys
sudo chmod 750 ${HOME_DIR}
fi
else
echo -e "The user ${USERNAME} does not exist on server $(hostname) \n"
echo "The user ${USERNAME} does not exist on server $(hostname) " >> sftp_user_not_found.txt
fi
done
}
#pass an argument to the script suggesting how you'd like to execute it#
OPTION="$1"
if [ "$#" -ne 1 ]
then
echo "You must specify an option to run the script"
echo "-h for help or -r to run the script. Exiting now"
exit
fi
#Required case statement logic to implement user option#
case $OPTION in
"-h")
echo "Displaying help"
echo "To run the script type: ./add_public_key.bash -r"
echo "You need to become root via sudo su - before running the script"
echo "Enter the file containing list of users within whose home key is to be added when prompted"
echo "Enter the file containing the public key when prompted"
;;
"-r")
echo "Running the script"
echo "type 1 and press enter if you wish to check for the presence of .ssh directory"
echo "type 2 and press enter if you wish to copy the key file right now"
read USER_SEL
if [ $USER_SEL -eq 1 ]
then
check_dir
elif [ $USER_SEL -eq 2 ]
then
add_key
else
echo "Invalid option"
exit
fi
;;
*)
echo "invalid execution"
;;
esac
The script can be run in two modes:
Help mode: If you add the -h option with the script it'll run in help mode displaying information on how to use the script.
Run/execution mode: If you add the -r option with the script then it'll run in execution mode and you'll be prompted for yet another selection this time you can choose to check for the presence of .ssh directory for the list of users or add the key for the source user from where password less authentication needs to be configured.
The script has built in checks to look for the presence of the user supplied in the list, check for the presenece of .ssh directories of the users, a check to terminate the script if the user does not supply any options and I've also added logging of some of the command output.
I hope this has been a nice read and look forward towards your feedback.
Help mode: If you add the -h option with the script it'll run in help mode displaying information on how to use the script.
Run/execution mode: If you add the -r option with the script then it'll run in execution mode and you'll be prompted for yet another selection this time you can choose to check for the presence of .ssh directory for the list of users or add the key for the source user from where password less authentication needs to be configured.
The script has built in checks to look for the presence of the user supplied in the list, check for the presenece of .ssh directories of the users, a check to terminate the script if the user does not supply any options and I've also added logging of some of the command output.
I hope this has been a nice read and look forward towards your feedback.