Automating user and group management with Bash
Oluwasegun Oni (Drxy_Shantel)
Posted on July 5, 2024
Introduction
As a SysOps engineer, managing users and groups on a server is one of your routine tasks. This process can be quite time-consuming and susceptible to errors, particularly when handling numerous users. Automating these tasks is crucial for achieving efficiency and reliability. This article will guide you through a Bash script that automates the creation of users and groups, sets up home directories with correct permissions, generates random passwords, and logs all actions.
Bash
Bash which stands for "Bourne Again Shell" is a command language interpreter and scripting language commonly used in Unix-like operating systems, such as linux and macOS. It's the default shell for most linux distributions and is widely used for automation tasks, managing system operations, and write scrips.
What is Bash script?
A Bash script is a file typically ending with the extension .sh that contain a logical series of related commands to be executed
This project was inspired by HNG internship 11 https://hng.tech/hire, DevOps track of stage one.
visit https://hng.tech/internship to learn more about the program
Prerequisite
Before we start, ensure you have:
- Access to a linux server with root privileges
- Basic knowledge of Bash scripting
Script Overview
The script we'll create will:
- Create users and groups
- set up home directories with the correct permissions
- Generate random passwords for users
- Log all actions to a specified log file
User Management Automation project
Let's dive into an extensive project that will show us a step by step guide on how to create user and group management with Bash script.
Here is a step by step guide on how to create user and groups management:
Creating the script file
First and foremost, Create a new Bash script file
touch create_user.sh
Open the file in your preferred text editor:
vim create_user.sh
Create an employee file where users and group would be located
touch employeefile.txt
edit your user_data.txt file with a text editor and enter the following user and group below:
vim employeefile.txt
Example Input File
light; sudo,dev, www-data
idimma;sudo
mayowa;dev,www-data
Insert the following script below into your 'create_users.sh' file
The Script
#!/bin/bash
# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE
# Function to log messages
log_message() {
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}
# Function to generate random password
generate_password() {
tr -dc A-Za-z0-9 </dev/urandom | head -c 12 ; echo ''
}
# Check if the input file is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <input_file>"
exit 1
fi
# Read the input file
INPUT_FILE=$1
# Check if the input file exists
if [ ! -f $INPUT_FILE ]; then
echo "Input file not found!"
exit 1
fi
while IFS=';' read -r username groups; do
# Remove leading and trailing whitespaces
username=$(echo $username | xargs)
groups=$(echo $groups | xargs)
if id "$username" &>/dev/null; then
log_message "User $username already exists. Skipping..."
continue
fi
# Create a personal group for the user
groupadd $username
if [ $? -ne 0 ]; then
log_message "Failed to create group $username."
continue
fi
log_message "Group $username created successfully."
# Create user and add to personal group
useradd -m -g $username -s /bin/bash $username
if [ $? -ne 0 ]; then
log_message "Failed to create user $username."
continue
fi
log_message "User $username created successfully."
# Create additional groups if they don't exist and add user to groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo $group | xargs)
if [ -z "$group" ]; then
continue
fi
if ! getent group $group >/dev/null; then
groupadd $group
if [ $? -ne 0 ]; then
log_message "Failed to create group $group."
continue
fi
log_message "Group $group created successfully."
fi
usermod -aG $group $username
log_message "User $username added to group $group."
done
# Set up home directory permissions
chmod 700 /home/$username
chown $username:$username /home/$username
log_message "Permissions set for home directory of $username."
# Generate random password and store it
password=$(generate_password)
echo "$username:$password" | chpasswd
echo "$username:$password" >> $PASSWORD_FILE
log_message "Password set for user $username."
done < "$INPUT_FILE"
log_message "User and group creation process completed."
exit 0
Make the script executable
chmod +x create_user.sh
Execute the script
sudo bash ./create_users.sh employeefile.txt
Defining the Script
Start by defining the script header and setting some initial variables:
Define Log and Password Files
#!/bin/bash
# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
These lines set the paths for the log file and the file where passwords will be stored.
Create Log and Password Files if They Don't Exist
# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE
- touch $LOG_FILE creates the log file if it doesn't already exist.
- mkdir -p /var/secure creates the directory /var/secure if it doesn't exist.
- touch $PASSWORD_FILE creates the password file if it doesn't exist.
Function to Log Messages
# Function to log messages
log_message() {
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}
This function logs messages with a timestamp. tee -a $LOG_FILE appends the log message to the log file while also displaying it on the console.
Function to Generate Random Password
# Function to generate random password
generate_password() {
tr -dc A-Za-z0-9 </dev/urandom | head -c 12 ; echo ''
}
This function generates a random 12-character password using characters from A-Z, a-z, and 0-9.
Check if the Input File is Provided
# Check if the input file is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <input_file>"
exit 1
fi
This part ensures that the script is called with exactly one argument (the input file). If not, it displays a usage message and exits.
Read the Input File
# Read the input file
INPUT_FILE=$1
This assigns the first argument (input file) to the variable INPUT_FILE.
Check if the Input File Exists
# Check if the input file exists
if [ ! -f $INPUT_FILE ]; then
echo "Input file not found!"
exit 1
fi
This checks if the input file exists. If not, it prints an error message and exits.
Process Each Line of the Input File
while IFS=';' read -r username groups; do
# Remove leading and trailing whitespaces
username=$(echo $username | xargs)
groups=$(echo $groups | xargs)
- IFS=';' read -r username groups reads each line of the input file, splitting the line into username and groups using ; as a delimiter.
- xargs is used to trim leading and trailing whitespaces from username and groups.
Check if the User Already Exists
if id "$username" &>/dev/null; then
log_message "User $username already exists. Skipping..."
continue
fi
This checks if the user already exists. If the user exists, it logs a message and skips to the next iteration.
Create a Personal Group for the User
# Create a personal group for the user
groupadd $username
if [ $? -ne 0 ]; then
log_message "Failed to create group $username."
continue
fi
log_message "Group $username created successfully."
- groupadd $username creates a new group with the same name as the user.
- $? checks the exit status of the groupadd command. If it's not zero (indicating an error), it logs a failure message and skips to the next iteration.
- If the group is created successfully, it logs a success message.
Create the User and Add to Personal Group
# Create user and add to personal group
useradd -m -g $username -s /bin/bash $username
if [ $? -ne 0 ]; then
log_message "Failed to create user $username."
continue
fi
log_message "User $username created successfully."
- useradd -m -g $username -s /bin/bash $username creates the user with a home directory and assigns the personal group.
- The exit status is checked, and appropriate messages are logged.
Create Additional Groups and Add User to Them
# Create additional groups if they don't exist and add user to groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo $group | xargs)
if [ -z "$group" ]; then
continue
fi
if ! getent group $group >/dev/null; then
groupadd $group
if [ $? -ne 0 ]; then
log_message "Failed to create group $group."
continue
fi
log_message "Group $group created successfully."
fi
usermod -aG $group $username
log_message "User $username added to group $group."
done
- IFS=',' read -ra group_array <<< "$groups" splits the groups string into an array.
- The script iterates over the array, trims whitespaces, checks if the group is empty, and continues to the next iteration if it is.
- It checks if each group exists using getent group $group. If the group does not exist, it creates it.
- The user is added to the group using usermod -aG $group $username. Appropriate messages are logged throughout
Set Up Home Directory Permissions
# Set up home directory permissions
chmod 700 /home/$username
chown $username:$username /home/$username
log_message "Permissions set for home directory of $username."
- chmod 700 /home/$username sets the permissions of the user's home directory.
- chown $username:$username /home/$username changes the ownership of the home directory to the user.
- A log message is recorded.
Generate Random Password and Store It
# Generate random password and store it
password=$(generate_password)
echo "$username:$password" | chpasswd
echo "$username:$password" >> $PASSWORD_FILE
log_message "Password set for user $username."
- password=$(generate_password) generates a random password.
- echo "$username:$password" | chpasswd sets the user's password.
- The password is stored in the password file.
- A log message is recorded.
Complete the Process
done < "$INPUT_FILE"
log_message "User and group creation process completed."
exit 0
- The done statement ends the while loop.
- A log message indicates that the process is complete.
- exit 0 exits the script successfully.
This detailed breakdown should help you understand each part of the script and its function as you run it in your terminal.
Posted on July 5, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.