Provisioning users and groups in Linux

Your company has employed many new developers. As a SysOps engineer, you're tasked to write a bash script called create_users.sh that reads a text file containing the employee’s usernames and group names, where each line is formatted as user;groups. The script should then proceed to create users and groups as specified, set up home directories with appropriate permissions and ownership, generate random passwords for the users which should be stored securely in /var/secure/user_passwords.txt, and log all actions to /var/log/user_management.log.

Shell scripting, the language of the command line, is your ticket to automating repetitive tasks such as this. This article highlights my thought process when I had to implement something similar

  1. Initial setup

    We start by defining the log and secure password file locations. We then ensure that the necessary directories exist, and clear any previous logs and password files

     LOG_FILE="/var/log/user_management.log"
     SECURE_PASSWORDS_FILE="/var/secure/user_passwords.txt"
    
     mkdir -p /var/log
     mkdir -p /var/secure
    
     > $LOG_FILE
     > $SECURE_PASSWORDS_FILE
    
  2. Logging function

    A simple logging function captures and timestamps all actions performed by the script, helping in tracking and debugging

     log_message() {
         echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
     }
    
  3. Function handling creation of user accounts

    The create_user function is the core of the script:

    • Existence Check: Ensures that users and groups are only created if they don't already exist.

    • Group and User Creation: Each user is given a personal group and added to specified groups.

    • Home Directory Setup: Configures the user's home directory with appropriate permissions.

    • Password Generation: Generates a random password for the user and stores it securely.

    create_user() {
        local username="$1"
        local groups="$2"

        if id "$username" &>/dev/null; then
            log_message "User $username already exists. Skipping."
            return
        fi

        if ! getent group "$username" &>/dev/null; then
            groupadd "$username"
            log_message "Group $username created."
        else
            log_message "Group $username already exists."
        fi

        useradd -m -g "$username" -G "$groups" "$username"
        log_message "User $username created and added to groups $groups."

        chmod 700 "/home/$username"
        chown "$username:$username" "/home/$username"
        log_message "Home directory for $username set up with appropriate permissions."

        password=$(openssl rand -base64 12)
        echo "$username:$password" | chpasswd
        log_message "Password for user $username set."

        echo "$username,$password" >> $SECURE_PASSWORDS_FILE
    }
  1. Processing Input File

    The script processes each line of the input file, extracting usernames and groups, and passing them to the create_user function.

     if [ -z "$1" ]; then
         echo "Usage: $0 <input_file>"
         exit 1
     fi
    
     while IFS=';' read -r username groups; do
         username=$(echo "$username" | xargs)
         groups=$(echo "$groups" | xargs)
    
         create_user "$username" "$groups"
     done < "$1"
    
  2. ¡Finalmente!

    Finally, the script sets strict permissions on the password file to ensure only the file owner can read it, enhancing security.

     chmod 600 $SECURE_PASSWORDS_FILE
     log_message "Permissions for $SECURE_PASSWORDS_FILE set to 600."
     echo "User management script completed. Check $LOG_FILE for details."
    

    Thank you for reading, until next time!