Thursday, 29 June 2017

Shell script to add a public key to multiple users

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 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.

No comments:

Post a Comment

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...