Automating User Management with Bash: A Comprehensive Guide
Managing users on a Unix-like system can often be a challenging and error-prone endeavor, particularly when faced with a high volume of users. Automating this process not only saves valuable time but also guarantees uniformity in user management.
In this article, we will delve into a Bash script that streamlines the creation of users and groups by utilizing input from a text file. The script is designed to establish home directories with precise permissions, generate random passwords, and meticulously log all actions for auditing purposes. Furthermore, it ensures the secure storage of the generated passwords.
By implementing this automated approach, system administrators can efficiently manage users on a Unix-like system while maintaining a high level of security and consistency.
Prerequisites
To follow along, you should have a basic understanding of the following:
Unix/Linux command line
Bash scripting
User and group management in Unix/Linux
Below is a step by step implementation
#!/bin/bash
- The script should be started by shebang (
#!/bin/bash
), which specifies that it should be run using the Bash shell.
INPUT_FILE=$1
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
- Here we are defining variables and setting to file directories that we will create to house logs and password file. For the "INPUT_FILE" = "$1", the $1 is a special variable in bash scripting that represents the first argument passed to the script on the command line.
mkdir -p /var/secure
chmod 700 /var/secure
- This creates the
/var/secure
directory if it doesn't exist and sets its permissions so that only the owner can access it.
> "$LOG_FILE"
> "$PASSWORD_FILE"
- These lines clear the log and password files if they already exist or create them if they don't.
generate_password() {
openssl rand -base64 12
}
- This is a function that generates a random 12 character password using the OPENSSL.
while IFS=';' read -r username groups; do
- This is a loop that reads the input file line by line, splitting each line into
username
andgroups
using;
as the delimiter.
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)
- These lines trim any leading or trailing whitespace from the
username
andgroups
variables.
echo "Creating user: $username" >> "$LOG_FILE"
- This creates a log and outputs it into the log file defined above
if id "$username" &>/dev/null; then
echo "User $username already exist. Skipping." >> "$LOG_FILE"
continue
fi
- This is an if statement checks if the user already exist. If so, it logs a message to the log file and skips to the next user.
if getent group "$username" &>/dev/null; then
echo "User personal group already exist" >> "$LOGFILE"
else
groupadd "$username"
fi
- The snippet above creates a personal group for the user with his username. It checks if the group exist and if not, it creates the group.
useradd -m -g "$username" "$username"
echo "User $username created with home directory and personal group." >> "$LOG_FILE"
chmod 700 "/home/$username"
chown "$username:$username" "/home/$username"
- These lines create the user with a home directory and a personal group, set the home directory permissions to
700
(owner has full access), and set the ownership of the home directory to the user and their personal group.
password=$(generate_password)
echo "$username:$password" | chpasswd
echo "Password for user $username set." >> "$LOG_FILE"
echo "$username:$password" >> "$PASSWORD_FILE"
- This generates a random password, sets it for the user, logs the action, and stores the password securely in the password file set above.
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo "$group" | xargs) # Trim whitespace
if getent group "$group" &>/dev/null; then
usermod -aG "$group" "$username"
echo "Added user $username to group $group." >> "$LOG_FILE"
else
echo "Group $group does not exist. Creating group $group." >> "$LOG_FILE"
groupadd "$group"
usermod -aG "$group" "$username"
echo "Group $group created and user $username added to group $group." >> "$LOG_FILE"
fi
done
- This checks the group variable in the loop expecting a comma "," as a delimiter to separate groups in case of multiple groups, then checks if the group exist before creating them. If the group exists it adds the user to the existing group, and if not it creates the group and then adds the user.
echo "User creation process completed." >> "$LOG_FILE"
- This signifies the end of the script.
Below is the full script
#!/bin/bash
# Define input file and log file
INPUT_FILE=$1
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
# Ensure the /var/secure directory exists and set permissions
mkdir -p /var/secure
chmod 700 /var/secure
# Create or clear the log and password files
> "$LOG_FILE"
> "$PASSWORD_FILE"
# Function to generate a random password
generate_password() {
# Use openssl to generate a random password
openssl rand -base64 12
}
# Read the input file line by line
while IFS=';' read -r username groups; do
# Trim whitespace from username and groups
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)
# Log the creation process
echo "Creating user: $username" >> "$LOG_FILE"
# Check if the user already exists
if id "$username" &>/dev/null; then
echo "User $username already exists. Skipping." >> "$LOG_FILE"
continue
fi
# Create the user with a home directory and personal group
if getent group "$username" &>/dev/null; then
echo "User personal group already exist" >> "$LOGFILE"
else
groupadd "$username"
fi
useradd -m -g "$username" "$username"
echo "User $username created with home directory and personal group." >> "$LOG_FILE"
# Set the home directory permissions
chmod 700 "/home/$username"
chown "$username:$username" "/home/$username"
# Generate a random password and set it for the user
password=$(generate_password)
echo "$username:$password" | chpasswd
echo "Password for user $username set." >> "$LOG_FILE"
# Store the password securely
echo "$username,$password" >> "$PASSWORD_FILE"
# Add the user to additional groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo "$group" | xargs) # Trim whitespace
if getent group "$group" &>/dev/null; then
usermod -aG "$group" "$username"
echo "Added user $username to group $group." >> "$LOG_FILE"
else
echo "Group $group does not exist. Creating group $group." >> "$LOG_FILE"
groupadd "$group"
usermod -aG "$group" "$username"
echo "Group $group created and user $username added to group $group." >> "$LOG_FILE"
fi
done
done < "$INPUT_FILE"
echo "User creation process completed." >> "$LOG_FILE"
Use the script above as you wish, but before you go, if you wish to take part in an program that takes your tech prowess to the next level I have just the right thing for you. HNG is an organization that organizes a yearly internship program just for this purpose Kindly visit Here to get further information about the internship program. Also if you are looking for your next job in tech, HNG has you covered visit https://hng.tech/premium for more information.
Till we meet again good bye!