Tame the User Herd: Effective User Management with Bash Automation
Managing user accounts across systems can be a tedious process and also a time consuming task, as they say a "lazy programmer is a good programmer" because they will have a secure and easy way to make life easier, in the same vein, this article explores creating a secure bash script that automate the user management process especially when dealing with a large number of employees or users.
Understanding the Requirements
To get started with this tutorial, you must have the following:
A Linux machine with administrative privileges.
Basic knowledge of Linux commands.
A text editor of choice (vim, nano, etc).
Requirements:
Before going into the script, security is paramount. Here are some crucial aspects to consider:
Permissions: The script should run with the least privilege necessary, typically the root user. However, explore using mechanisms like sudo
with specific permissions granted for the script's execution.
Password Security: Never store passwords in plain text within the script. Consider using a password hashing function to securely store passwords in a separate file.
Input Validation: The script should validate user input to prevent errors and malicious attacks like injection vulnerabilities.
Personal Groups: Each user should have a dedicated group with the same name as their username.
Group Membership: Users can belong to additional groups, listed in a comma-separated format within a user data file.
Reading User Data: It takes a user data file path as an argument. This file defines usernames and corresponding groups in a specific format: username; groups.
Creating User Accounts and Groups: For each user in the data file, the script generates a unique username (personal group name). It creates a user account with a home directory, setting ownership and permissions appropriately.
Assigning Group Memberships: The script iterates through comma-separated groups listed for each user and adds them to those additional groups.
Generating Secure Passwords: A random password is generated for each user. The script stores the passwords securely in a separate file (/var/secure/user_passwords.txt)
with strict permissions (only root can read it). It sets a temporary password for the user account.
Logging Actions: All script activities are logged to a file (/var/log/user_management.log)
for tracking and troubleshooting
Prepare User Data
The first step involves creating a text file to store user information. This file will house each employee's username and the groups they should belong to.
Create the User Data File
Open your terminal and use the touch
command to create a new file named user_passwords.txt
:
Bash
touch user_passwords.txt
Populate the User Data File
Paste the following content into the user_passwords.txt
file. Each line represents an employee with their username followed by a semicolon (;
) and then a comma-separated list of groups:
Alice: Quality Assurance
Henry: Design, Research
Elizabeth: Manager
Frank: DevOps
David: Support
Isabella: Marketing
Charlotte: Content
Jack: Development, QA
Grace: Design, Research
Ben: DevOps, SE
This format allows the script to easily parse the data and create users with their assigned groups.
Writing the Bash Script
Now that the user data is prepared, let's move on to writing the Bash script that will automate user creation and group assignment.
To provide a more detailed understanding of the script, let's analyze each code snippet line by line:
# Script configuration
USER_DATA_FILE="\$1" # First argument is the user data file path
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
This section sets up the script configuration by assigning values to variables.
USER_DATA_FILE
is set to the first argument passed to the script, which should be the user data file path.LOG_FILE
is set to the path where the log file will be created.PASSWORD_FILE
is set to the path where the password file will be created.PASSWORD_FILE
is set to the path where the password file will be created.
# Function to create a user with error handling
create_user() {
local username="\$1"
local groups="\$2"
# Create personal group
if ! groupadd "$username" &> /dev/null; then
echo "Error creating group '$username'" >> "$LOG_FILE"
return 1
fi
# Check if user already exists
if id -u "$username" &> /dev/null; then
echo "User '$username' already exists. Skipping..." >> "$LOG_FILE"
return 1
fi
# Create user with home directory and set ownership/permissions
if ! useradd -m -g "$username" -s /bin/bash "$username" &> /dev/null; then
echo "Error creating user '$username'" >> "$LOG_FILE"
return 1
fi
chown -R "$username:$username" "/home/$username"
chmod 700 "/home/$username"
# Generate random password, store securely, and set temporary password
password=$(head /dev/urandom | tr -dc A-Za-z0-9 | fold -w 16 | head -n 1)
echo "$username:$password" >> "$PASSWORD_FILE"
echo "Setting temporary password for user '$username'" >> "$LOG_FILE"
echo "$password" | passwd --stdin "$username" &> /dev/null
# Add user to additional groups (comma separated)
for group in $(echo "$groups" | tr ',' ' '); do
if ! usermod -a -G "$group" "$username" &> /dev/null; then
echo "Error adding user '$username' to group '$group'" >> "$LOG_FILE"
fi
done
# Log successful user creation
echo "User '$username' created successfully." >> "$LOG_FILE"
}
This section defines the
create_user()
function, which is responsible for creating a user with error handling.The function takes two parameters:
username
andgroups
.Inside the function, the following steps are performed:
Create a personal group using the
groupadd
command.Check if the user already exists using the
id -u
command.Create the user with a home directory using the
useradd
command.Set ownership and permissions for the home directory.
Generate a random password, store it securely in the password file, and set a temporary password for the user.
Add the user to additional groups specified in the
groups
parameter.Log the successful user creation.
# Check if user data file exists
if [ ! -f "$USER_DATA_FILE" ]; then
echo "Error: User data file '$USER_DATA_FILE' not found." >&2
exit 1
fi
This code block checks if the user data file specified in the
USER_DATA_FILE
variable exists using the-f
flag with thetest
command.If the file does not exist, an error message is printed, and the script exits.
# Check for root privileges
if [[ $EUID -ne 0 ]]; then
echo "This script requires root privileges." >&2
exit 1
fi
This code block checks if the script is being run with root privileges by comparing the
$EUID
environment variable to0
.If the script is not run as root, an error message is printed, and the script exits.
# Ensure log and password files exist with appropriate permissions
touch "$LOG_FILE" "$PASSWORD_FILE"
chmod 640 "$PASSWORD_FILE"
This code block ensures that the log file and password file exist.
The
touch
command is used to create the files if they don't exist.The
chmod
command is used to set the appropriate permissions for the password file.
# Process user data file line by line
while IFS=';' read -r username groups; do
create_user "$username" "$groups"
done < "$USER_DATA_FILE"
This code block reads the user data file line by line and calls the
create_user()
function for each line.The
IFS
variable is set to';'
to specify the delimiter used in the user data file.The
read
command reads each line and assigns the values to theusername
andgroups
variables.The
create_user()
function is called with theusername
andgroups
variables as arguments.The user data file is specified using the
<
redirection operator.
echo "User creation completed. Refer to '$LOG_FILE' for details."
After processing all the user data, a completion message is printed, indicating the location of the log file.
Run the ScriptTo execute the Bash script without calling Bash in your terminal, make the script executable:
chmod +x create_users.sh
Once the script is executable, run it from the directory where it resides:
./create_users.sh user_passwords.txt
Verify the Script Executed Tasks Successfully
Several checks should be carried out to ensure that the script executed all the user management tasks successfully.
To verify user existence, run:
id <username>
To verify that the user password file was successfully created in the /var/secure/ directory, run:
cat /var/secure/user_passwords.txt
To verify group existence, run:
getent group <username>
To verify the log file as created and all actions are logged correctly without any errors or unexpected behaviors, run:
cat /var/log/user_management.log
- To verify that each user has a personal group with the same name as their username, run:
getent passwd <username>
getent group <username>
Conclusion
This article highlights the automation of user management tasks using Bash scripts. It explores how scripting enhances efficiency in creating users, managing groups, setting permissions, and securing passwords on Linux systems.
This article is stage 1 task at HNG internship program. HNG is an internship that helps people improve their tech skills. To learn more about the HNG internship, visit their website. If you are looking to hire talented Developers and Designers from the internship, visit HNG hire.
Subscribe to my newsletter
Read articles from odelana David directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by