In modern IT environments, efficient user and group management is key to maintaining security and operational integrity. Manually creating and managing users across multiple systems is time-consuming and very prone to errors due to its repetitiveness. Automation becomes a handy tool for handling repetitive tasks like creating and managing users, groups and permissions. This article will walk you through a Bash script that automates the processes of user and group creation, and group assignment based on a structured input file. The bash script also contains a logging mechanism for reviewing all operations of the script.
Objective
The script is named create_users.sh. It reads a text file containing usernames and their respective groups, creates users, assigns them to specified groups, generates random passwords securely for each user and stores them. It then logs all actions.
Prerequisites
To successfully follow this tutorial, you need the following:
A Linux machine with root privileges: The script requires administrative rights to create users, groups, and manage file permissions (sudo or root access).
Basic Knowledge of Bash commands and scripting: Familiarity with navigating the command line and editing scripts will help in understanding and customizing the provided script.
A text editor of choice (vi, nano, vim, etc): You'll use a text editor to modify the script and prepare input files. Choose one that you're comfortable with or have experience using.
Overview
The script automates the creation of users and groups by reading input from a text file formatted as username;groups. In a nutshell, the script does the following:
- Reads a text file passed as an argument to the script at runtime.
- Validates root privileges and the existence of a secure directory for password storage (/var/secure).
- Creates usernames and assigns them to their respective groups specified in the input file.
- Generates strong (16 digit), random passwords for each user and securely stores them in /var/secure/user_passwords.txt.
- Logs all actions to /var/log/user_management.log for audit purposes.
Writing our script.
Create script file
Open your terminal and create an empty file named create_user.sh
.
touch create_user.sh
Using your preferred editor, open the create_user.sh
file we just created. For this tutorial, we will be using vim text editor. feel free to use your editor of choice.
vim create_user.sh
Add the shebang line
At the top of the script, add the shebang line.
#!/bin/bash
Check if the script is run with root privileges.
In a linux system, creating users and groups, setting permissions, etc typically involve using administrative privileges. After the shebang line, add the following code.
# Check if running as root
if [[ $(id -u) -ne 0 ]]; then
echo "This script must be run as root."
exit 1
fi
The code check above if [[ $(id -u) -ne 0 ]]; then
retrieves the user's id then it checks if the retrieved id does not equal to 0. If it does, it means the user running the script has admin privileges and continues to the next phase of the script. It terminates if the user does not have root privileges.
Ensure /var/secure directory exists for storing passwords securely
The "/var/secure" directory is used for typically used as a secure directory where sensitive information, such as user passwords, can be stored with restricted access.
if [[ ! -d "/var/secure" ]]; then
mkdir -p /var/secure
chown root:root /var/secure
chmod 700 /var/secure
fi
If the "/var/secure"
directory does not exist, it is immediately created with all permissions (read, write, execute) set for the user.
Setting Up Our Variables
Before proceeding, we need to set up some variables that would be reused in other parts of the script.
# Variables
INPUT_FILE="$1"
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
- INPUT_FILE variable is set to $1 which is the text file that is passed as an argument to our script.
LOG_FILE variable is to the
user_management.log
in/var/log/
and used for storing logs from our script.PASSWORD_FILE variable is set to the
user_passwords.txt
file in/var/secure/
directory which was created earlier by our script after initial checks if the directory doesn't exist.
Creating The Generate Password Utility Function
The script contains a utility function that act as a helper function for performing the task of generating a secure password which we would use in the core part of the script.
generate_password
This helper function helps to generate a strong a strong random password using the /dev/urandom
linux kernel interface for generating random passwords.
generate_password() {
tr -dc 'A-Za-z0-9!@#$%^&*()_+=-[]{}|;:<>,.?/~' </dev/urandom | head -c 16
}
The above code generates a 16-digit random password using the Kernel's built-in random number generator. The generated password consists of uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and some special characters.
User and Group Creation:
This is the core part of the script. It reads each line from the input file ($1) to create users and assign them to specified groups and logs all action to the
while IFS=";" read -r user groups; do
# Remove whitespaces from user and groups
user=$(echo "$user" | xargs)
groups=$(echo "$groups" | xargs)
# Validate username before creating user
if [[ -z "$user" ]]; then
echo "Invalid username. Skipping user creation."
continue
fi
# Check if user already exists
if id "$user" >/dev/null 2>&1; then
echo "User $user already exists. Skipping user creation."
continue
fi
# Create a personal group for the user
groupadd "$user" 2>/dev/null
usermod -aG "$user" "$user"
# Add user to specified groups
IFS=',' read -ra group_list <<< "$groups"
for group in "${group_list[@]}"; do
group=$(echo "$group" | xargs)
if [ -n "$group" ]; then
groupadd "$group" 2>/dev/null
usermod -aG "$group" "$user"
fi
done
# Generate and store password securely
password=$(generate_password)
echo "$user:$password" >> "$PASSWORD_FILE"
# Log actions
echo "$(date +'%Y-%m-%d %H:%M:%S') Created user '$user' and added to groups: $groups" >> "$LOG_FILE"
done < "$INPUT_FILE"
Detailed breakdown of the above code blocks:
Read in the file
Firstly, we begin a while loop which is used to read in the file and set our IFS (Internal Field Seperator) to the semi-colon ";".
while IFS=";" read -r user groups; do
. The content of the text file is read in and it is then separated by ";" to denote which part of the content are user names and group names.Trim whitespaces
Next, we trim all whitespaces around the user names and group names using the xargs command-line utility.
user=$(echo "$user" | xargs)
groups=$(echo "$groups" | xargs)
- Validate users
We validate user names using two criteria
- The user name is not empty:
if [[ -z "$user" ]];
- The user name does not already exist:
if id "$user" >/dev/null 2>&1; then
if the user name is empty or exists, it is skipped and the script continues.
- Create user own groups We then create a group specifically for the user and adds the user to their groups.
groupadd "$user" 2>/dev/null
usermod -aG "$user" "$user"
- Add user to specified groups Here, we read in the text file again passed as an argument to the script but this time, the IFS is set to ','. This way, we can get the group names even if the user belongs to more than one specified groups.
IFS=',' read -ra group_list <<< "$groups"
for group in "${group_list[@]}"; do
group=$(echo "$group" | xargs)
if [ -n "$group" ]; then
groupadd "$group" 2>/dev/null
usermod -aG "$group" "$user"
fi
done
- Generate and Store passwords for each user
Recall that we earlier created a generate_password
helper function for our script and we can now use it to generate and store each user's password to the $PASSWORD_FILE.
password=$(generate_password)
echo "$user:$password" >> "$PASSWORD_FILE"
- Log actions After all operations, we add a new log entry to our log file for each user operation.
echo "$(date +'%Y-%m-%d %H:%M:%S') Created user '$user' and added to groups: $groups" >> "$LOG_FILE"
- End the Loop
done < "$INPUT_FILE"
Run Our Script
set execute permission for the create_user.sh
file.
chmod +x create_user.sh
Here is an sample user input file you can use for testing our bash script: vim user_groups.txt
and paste the below text:
nelson;cloudeng,sre
victor;backend
john;qa
jane;dev,manager
robert;marketing
emily;design,research
michael;devops
olivia;design,research
william;support
sophia;content,marketing
daniel;devops,sre
ava;dev,qa
now run the script using:
./create_users.sh user_groups.txt
Checking Our Script Logs:
cat /var/log/user_management.log
Conclusion
Thanks for following me on this tutorial. This technical article was created as part of my Stage 1 task for HNG Internship.
HNG is an internship that helps people hone and improve their tech skills. To learn more, visit the HNG Internship website: https://hng.tech/internship
Top comments (0)