Simplifying Linux User Administration: A Bash Script Approach

The automation of creating linux users with their respective groups


Table of contents


overview

The create_users.sh script is designed to automate the process of creating user accounts on a Linux system. It reads a specified file containing a list of usernames and their associated groups, generates random passwords for each user, creates the user with the generated password, and assigns the user to the specified groups. Additionally, it handles logging and ensures that the script is run with root privileges.


prerequisites

  • A Linux system with bash, openssl, useradd, groupadd, and usermod commands available.
  • Root access or sudo privileges to create users and groups.
  • The input file containing the list of users and groups, formatted as described below.

input file formate

The script expects an input file where each line represents a user and their associated groups, formatted as follows:

username;group1,group2,group3
  • username is the name of the user to be created.
  • the username and its groups are separated by ;
  • group1,group2,group3 are the groups to which the user will be added. Multiple groups are separated by commas.

Lines starting with # are considered comments and ignored. Empty lines are also ignored. Leading and trailing whitespace is removed from the username and group names.


features

  1. Root Privilege Check: Ensures the script is run with root privileges, attempting to elevate privileges if not.
  2. Logging: Logs all operations to /var/log/user_management.log.
  3. Secure Directory and File Handling: Creates a secure directory (/var/secure) and files for logging and storing user passwords with restricted access permissions.
  4. User and Group Management:
    • Reads the input file line by line.
    • Skips empty lines and comments.
    • Generates a random password for each user using openssl.
    • Encrypts the password using SHA-512 hashing.
    • Creates the user with the encrypted password and a home directory.
    • Creates any specified groups that do not already exist.
    • Adds the user to the specified groups.
  5. Error Handling: Provides feedback on the success or failure of user and group creation operations.

script

   #!/bin/bash

   # Step 1: Check if the script is being run as root, if not, request root access
   echo "################# Checking if the script is being run as root..."
   if [[ "$(id -u)" -ne 0 ]]; then
   echo "This script needs to be run as root. Trying to elevate privileges..."
   echo "################# Re-running the script with elevated privileges..."
   sudo -E "$0" "$@"
   exit
   fi

   # Step 2: Create the log and password files and set appropriate permissions
   echo "################# Creating log and password files..."
   secure_dir="/var/secure"
   log_dir="/var/log"
   log_file="/var/log/user_management.log"
   password_file="/var/secure/user_passwords.csv"

   if [[ ! -d "$log_dir" ]]; then # Check if the log directory exists
   echo "################# Log dir does not exist: Creating log directory..."
   mkdir "$log_dir"
   else
   echo "################# Log directory exists..."
   fi

   if [[ ! -d "$secure_dir" ]]; then # Check if the secure directory exists
   echo "################# Secure dir does not exist: Creating secure directory..."
   mkdir "$secure_dir"
   else
   echo "################# Secure directory exists..."
   fi

   touch "$log_file"
   touch "$password_file"

   echo "################# Setting permissions..."
   chmod 640 "$log_file" # Only root and members of root's group can read and write, others cannot access
   chmod 600 "$password_file" # Only root can read and write

   # Step 3: Log all the commands and their output to the file in /var/log/ called user_management.log
   echo "################# Logging all the commands and their output..."
   exec > >(tee -a "$log_file") 2>&1

   # Step 4: Prompt the user to enter the name of the file containing the list of users and groups if not provided as an argument
   echo "################# Prompting for the file containing the list of users and groups..."
   user_file=$1
   if [[ -z "$user_file" ]]; then
   read -p "Enter the name of the file containing the list of users and groups with its full path: " user_file
   fi

   # Step 5: Check if the file exists, if not exit the script, else proceed
   echo "################# Checking if the file exists..."
   if [[ ! -f "$user_file" ]]; then
   echo "################ Error: The file does not exist. Please provide a valid file name."
   exit 1
   else
   echo "################ File exists. Proceeding with the script..."
   fi

   # Step 6: Create a function to create random passwords for the users
   echo "################# Creating a function to generate random passwords..."
   generate_password() {
   # Generate a random password using openssl
   openssl rand -base64 8
   }

   # Step 7: Read the file line by line and create users with a home directory and random password and add them to the appropriate groups
   echo "################# Reading the file and creating users..."
   while IFS=";" read -r username groups; do
   # Skip the line if it starts with a comment
   echo "################# Checking if line is a comment..."
   [[ "$username" =~ ^#.*$ ]] && continue

   # Skip the line if the username or groups is empty
   echo "################# Checking if the username or groups is empty..."
   [[ -z "$username" || -z "$groups" ]] && continue

   # Remove leading and trailing whitespaces
   echo "################# Removing leading and trailing whitespaces..."
   username=$(echo "$username" | xargs)
   groups=$(echo "$groups" | xargs)

   echo "################# Processing user: $username..."

   # Check if the user already exists
   echo "################# Checking if $username already exists..."
   if id "$username" &>/dev/null; then
      echo "################ User $username already exists. Skipping..."
      continue
   fi

   # Generate a random password
   echo "################ Generating a random password for new user..."
   password=$(generate_password)

   # Encrypt the password
   echo "################ Encrypting newly generated password to pass to the user with the -p flag..."
   encrypted_password=$(openssl passwd -6 "$password")

   # Create the user with the encrypted password
   echo "################ Creating $username with the encrypted password..."
   if useradd -m -p "$encrypted_password" "$username"; then
      echo "################ User $username created with password"
   else
      echo "################ Error creating user $username"
      continue
   fi

   # Split groups by comma and iterate over each group
   echo "################ Splitting $groups with ',' into an array of groups..."
   IFS=',' read -ra ADDR <<< "$groups"
   for group in "${ADDR[@]}"; do

   # Remove leading and trailing whitespaces
   echo "################ Removing leading and trailing whitespaces..."
   group=$(echo "$group" | xargs)

      # Check if the group exists, if not, create the group
      echo "################ Checking if $group exists..."
      if ! getent group "$group" > /dev/null 2>&1; then
         groupadd "$group"
         echo "Group $group created."
      fi

      # Add the user to the specified group
      echo "Adding $username to $group..."
      if ! usermod -aG "$group" "$username"; then
         echo "################# Error adding $username to $group..."
      else
         echo "################# User $username added to group $group..."
      fi
   done

   # Store the username and encrypted password in the password file
   echo "$username,$password" >> "$password_file"
   done < "$user_file"

   echo "################# User creation process completed successfully."

usage

  1. Ensure the script has execute permissions:

    chmod +x create_users.sh
    
  2. Run the script with the input file as an argument:

    ./create_users.sh /path/to/user_file.txt
    

    If the input file is not provided as an argument, the script will prompt for it.


testing

Testing was performed on an Ubuntu system with the following input file:

vagrant@vagrant:~/user-management-scripts$ cat test_file.txt
emma;devops,qa,sales
tosin;qa ,sales
femi; hr,devops
tola;admin
shayo;admin,hr

The input file was generated for testing purposes. Some lines have comments, empty lines, and leading/trailing whitespace to test the script's handling of such cases.

The script was executed with the following command:

vagrant@vagrant:~/user-management-scripts$ sudo ./create_users.sh ./images/test_file.txt 
################# Checking if the script is being run as root...
################# Creating log and password files...
################# Log directory exists...
################# Secure directory exists...
################# Setting permissions...
################# Logging all the commands and their output...
################# Prompting for the file containing the list of users and groups...
################# Checking if the file exists...
################ File exists. Proceeding with the script...
################# Creating a function to generate random passwords...
################# Reading the file and creating users...
################# Checking if line is a comment...
################# Checking if the username or groups is empty...
################# Removing leading and trailing whitespaces...
################# Processing user: emma...
################# Checking if emma already exists...
################ Generating a random password for new user...
################ Encrypting newly generated password to pass to the user with the -p flag...
################ Creating emma with the encrypted password...
################ User emma created with password
 with ',' into an array of groups...,sales
################ Removing leading and trailing whitespaces...
################ Checking if devops exists...

Here, an argument is provided to the script specifying the input file, like this ./create_users.sh ./test_file.txt, and the script proceeds to create users and groups as specified in the input file.

vagrant@vagrant:~/user-management-scripts$ sudo ./create_users.sh
################# Checking if the script is being run as root...
################# Creating log and password files...
################# Log directory exists...
################# Secure directory exists...
################# Setting permissions...
################# Logging all the commands and their output...
################# Prompting for the file containing the list of users and groups...
Enter the name of the file containing the list of users and groups with its full path:

If the input file is not provided as an argument, the script will prompt the user to enter the file name.

The script successfully created the users and groups as specified in the input file, handling comments, empty lines, and whitespace appropriately.

vagrant@vagrant:~/user-management-scripts$ sudo cat /var/log/user_management.log
################# Prompting for the file containing the list of users and groups...
################# Checking if the file exists...
################ Error: The file does not exist. Please provide a valid file name.
################# Prompting for the file containing the list of users and groups...
################# Checking if the file exists...
################ Error: The file does not exist. Please provide a valid file name.
################# Prompting for the file containing the list of users and groups...
################# Checking if the file exists...
################ File exists. Proceeding with the script...
################# Creating a function to generate random passwords...
################# Reading the file and creating users...
################# Checking if line is a comment...
################# Checking if the username or groups is empty...
################# Removing leading and trailing whitespaces...
################# Processing user: emma...
################# Checking if emma already exists...
################ Generating a random password for new user...
################ Encrypting newly generated password to pass to the user with the -p flag...
################ Creating emma with the encrypted password...
################ User emma created with password

The log file /var/log/user_management.log contains detailed information about the script execution, including the commands run and their output. You can view the sample log file

The password file contains the usernames and their corresponding passwords as can be seen below:

vagrant@vagrant:~/user-management-scripts$ sudo cat /var/secure/user_passwords.csv 
emma,r523scpEzKo=
tosin,7PQ+2bIs01s=
femi,PI8pb/9yzps=
tola,2tDH94mxLEM=
shayo,rG4cF+lbu/8=

You can see the password was tested on emma and it worked successfully, and also the home directory was created for the user.

vagrant@vagrant:~/user-management-scripts$ su emma
Password: 
$ ls
create_users.sh  images  README.md
$ pwd
/home/vagrant/user-management-scripts
$ cd ~
$ ls
$ pwd
/home/emma
$ exit

Here are the users and groups created on the system:

vagrant@vagrant:~/user-management-scripts$ tail -n 7 /etc/passwd
vagrant:x:1000:1000:vagrant,,,:/home/vagrant:/bin/bash
vboxadd:x:999:1::/var/run/vboxadd:/bin/false
emma:x:1001:1001::/home/emma:/bin/sh
tosin:x:1002:1004::/home/tosin:/bin/sh
femi:x:1003:1005::/home/femi:/bin/sh
tola:x:1004:1007::/home/tola:/bin/sh
shayo:x:1005:1008::/home/shayo:/bin/sh
vagrant@vagrant:~/user-management-scripts$ tail -n 7 /etc/group
qa:x:1003:emma,tosin
tosin:x:1004:
femi:x:1005:
hr:x:1006:femi,shayo
tola:x:1007:
shayo:x:1008:
admin:x:1009:shayo

The script successfully created the users and groups as specified in the input file, demonstrating its ability to automate user management tasks on a Linux system.


security

  • The script sets strict permissions on the log and password files to protect sensitive information.
  • Passwords are generated using openssl rand -base64 8 for randomness and security.
  • It is recommended to review the generated passwords and change them as necessary.
  • All the generated passwords are stored in a secure file with restricted access permissions.

trobleshoot

  • Script not running: Ensure you have execute permissions and are running the script with root or sudo privileges.
  • Users not being created: Check the /var/log/user_management.log file for any error messages related to user or group creation.

The create_users.sh script simplifies the process of creating users and managing groups on a Linux system, ensuring secure handling of passwords and logging all actions for auditability. It is a valuable tool for system administrators looking to automate user management tasks.

Note: This Project is a part of the HNG Internship, and HNG Premium tasks. Check them out for more information.

0
Subscribe to my newsletter

Read articles from emmanuel amiekhame directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

emmanuel amiekhame
emmanuel amiekhame