Automating Linux User Management with Bash
As a SysOps engineer, one of your responsibilities is to efficiently manage user accounts on Linux systems. With the influx of new developers, creating and managing user accounts manually can be time-consuming and prone to errors. To streamline this process, we’ll create a Bash script that automates the creation of users and groups, sets up home directories with appropriate permissions, generates random passwords, and logs all actions for auditing purposes.
Introduction
Managing user accounts on Linux involves several repetitive tasks, such as creating user accounts, setting up groups, and ensuring appropriate permissions. Automating these tasks can save time and reduce errors. In this article, we'll walk through a Bash script that reads a list of usernames and groups from a text file, creates the necessary users and groups, sets up home directories, generates random passwords, and logs all actions.
Prerequisites
To follow along, you’ll need:
- A Linux environment (we'll use Ubuntu on Windows Subsystem for Linux (WSL)).
- Visual Studio Code with the Remote - WSL extension.
- Basic knowledge of Bash scripting.
The Script
Here's the create_users.sh
script:
#!/bin/bash
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
INPUT_FILE="$1"
# Ensure the log file exists
sudo touch "$LOG_FILE"
sudo chmod 644 "$LOG_FILE"
# Ensure the secure directory and password file exist
sudo mkdir -p /var/secure
sudo touch "$PASSWORD_FILE"
sudo chmod 600 "$PASSWORD_FILE"
# Function to log messages
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | sudo tee -a "$LOG_FILE"
}
# Function to create users and groups
create_user() {
local username=$1
local groups=$2
# Check if user already exists
if id "$username" &>/dev/null; then
log_message "User $username already exists. Skipping user creation."
return 1
fi
# Create a group with the same name as the user
if ! getent group "$username" &>/dev/null; then
sudo groupadd "$username"
log_message "Group $username created."
fi
# Create the user and add to their own group
sudo useradd -m -g "$username" -s /bin/bash "$username"
log_message "User $username created."
# Add user to additional groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
if ! getent group "$group" &>/dev/null; then
sudo groupadd "$group"
log_message "Group $group created."
fi
sudo usermod -aG "$group" "$username"
log_message "Added $username to group $group."
done
# Set a random password
password=$(openssl rand -base64 12)
echo "$username:$password" | sudo chpasswd
log_message "Password set for user $username."
# Store the username and password in the secure file
echo "$username,$password" | sudo tee -a "$PASSWORD_FILE" > /dev/null
log_message "Stored password for user $username."
# Set the home directory permissions
sudo chown "$username:$username" "/home/$username"
sudo chmod 700 "/home/$username"
log_message "Home directory for $username set with appropriate permissions and ownership."
}
# Read input file and process each line
while IFS=';' read -r username groups || [ -n "$username" ]; do
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)
create_user "$username" "$groups"
done < "$INPUT_FILE"
log_message "User creation script completed."
How It Works
- Logging Setup: The script starts by setting up log and password files with appropriate permissions.
- User and Group Creation: For each user, the script checks if the user and their group exist before creating them. It ensures that each user has a group with the same name and adds the user to any additional groups specified.
-
Password Generation: A random password is generated using
openssl
and assigned to the user. - Home Directory Setup: The script sets the ownership and permissions of the user’s home directory.
-
Logging Actions: All actions, including errors, are logged to
/var/log/user_management.log
.
Let's break down the create_users.sh
script step by step to understand each part of the code and its purpose.
Script Breakdown
1. Shebang and Variable Definitions
#!/bin/bash
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
INPUT_FILE="$1"
-
#!/bin/bash
: This is the shebang line that specifies the script should be run using the Bash shell. -
LOG_FILE
: Defines the path to the log file where actions will be recorded. -
PASSWORD_FILE
: Defines the path to the file where user passwords will be securely stored. -
INPUT_FILE
: Captures the first argument passed to the script, which is the name of the text file containing usernames and groups.
2. Ensure Log and Password Files Exist
# Ensure the log file exists
sudo touch "$LOG_FILE"
sudo chmod 644 "$LOG_FILE"
# Ensure the secure directory and password file exist
sudo mkdir -p /var/secure
sudo touch "$PASSWORD_FILE"
sudo chmod 600 "$PASSWORD_FILE"
-
sudo touch "$LOG_FILE"
: Creates the log file if it doesn't already exist. -
sudo chmod 644 "$LOG_FILE"
: Sets permissions for the log file so it is readable by all users but writable only by the owner. -
sudo mkdir -p /var/secure
: Creates the/var/secure
directory if it doesn't exist. -
sudo touch "$PASSWORD_FILE"
: Creates the password file if it doesn't exist. -
sudo chmod 600 "$PASSWORD_FILE"
: Sets permissions for the password file so only the owner can read and write it.
3. Logging Function
# Function to log messages
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | sudo tee -a "$LOG_FILE"
}
-
log_message()
: A function that takes a message as an argument and appends it to the log file with a timestamp. -
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | sudo tee -a "$LOG_FILE"
: Formats the log message with a timestamp and writes it to the log file.
4. User and Group Creation Function
# Function to create users and groups
create_user() {
local username=$1
local groups=$2
# Check if user already exists
if id "$username" &>/dev/null; then
log_message "User $username already exists. Skipping user creation."
return 1
fi
# Create a group with the same name as the user
if ! getent group "$username" &>/dev/null; then
sudo groupadd "$username"
log_message "Group $username created."
fi
# Create the user and add to their own group
sudo useradd -m -g "$username" -s /bin/bash "$username"
log_message "User $username created."
# Add user to additional groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
if ! getent group "$group" &>/dev/null; then
sudo groupadd "$group"
log_message "Group $group created."
fi
sudo usermod -aG "$group" "$username"
log_message "Added $username to group $group."
done
# Set a random password
password=$(openssl rand -base64 12)
echo "$username:$password" | sudo chpasswd
log_message "Password set for user $username."
# Store the username and password in the secure file
echo "$username,$password" | sudo tee -a "$PASSWORD_FILE" > /dev/null
log_message "Stored password for user $username."
# Set the home directory permissions
sudo chown "$username:$username" "/home/$username"
sudo chmod 700 "/home/$username"
log_message "Home directory for $username set with appropriate permissions and ownership."
}
-
create_user()
: A function to create a user and their groups. -
local username=$1
andlocal groups=$2
: Capture the username and groups as local variables. -
if id "$username" &>/dev/null; then
: Check if the user already exists using theid
command. -
if ! getent group "$username" &>/dev/null; then
: Check if the user's primary group exists. -
sudo groupadd "$username"
: Create the primary group for the user. -
sudo useradd -m -g "$username" -s /bin/bash "$username"
: Create the user with a home directory and set their shell to Bash. -
IFS=',' read -ra group_array <<< "$groups"
: Split the groups string into an array. -
for group in "${group_array[@]}"; do
: Loop through each group in the array. -
sudo usermod -aG "$group" "$username"
: Add the user to each additional group. -
password=$(openssl rand -base64 12)
: Generate a random password usingopenssl
. -
echo "$username:$password" | sudo chpasswd
: Set the user's password. -
echo "$username,$password" | sudo tee -a "$PASSWORD_FILE" > /dev/null
: Store the username and password in the secure file. -
sudo chown "$username:$username" "/home/$username"
andsudo chmod 700 "/home/$username"
: Set ownership and permissions for the user's home directory.
5. Process Each Line in the Input File
# Process each line in the input file
while IFS=';' read -r username groups || [ -n "$username" ]; do
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)
create_user "$username" "$groups"
done < "$INPUT_FILE"
log_message "User creation script completed."
-
while IFS=';' read -r username groups || [ -n "$username" ];
: Read each line in the input file, splitting the line intousername
andgroups
using;
as the delimiter, and ensure the last line is processed even if it doesn't end with a newline. -
username=$(echo "$username" | xargs)
andgroups=$(echo "$groups" | xargs)
: Trim any leading or trailing whitespace fromusername
andgroups
. -
create_user "$username" "$groups"
: Call thecreate_user
function for each user and their groups. -
log_message "User creation script completed."
: Log the completion of the script.
Testing the Script
To test the script on a Windows machine using WSL and VS Code, follow these steps:
-
Set Up WSL:
- Install WSL and a Linux distribution (e.g., Ubuntu) as described in the WSL installation guide.
-
Install VS Code and WSL Extension:
- Download and install Visual Studio Code.
- Install the Remote - WSL extension from the Extensions view in VS Code.
-
Create Project Directory and Files:
- Open a WSL terminal in VS Code and create a project directory:
mkdir create_users_project cd create_users_project
- Create the
create_users.sh
script andusers.txt
file in this directory.
- Make the Script Executable:
chmod +x create_users.sh
- Run the Script:
sudo ./create_users.sh users.txt
-
Verify Results:
- Check the log file:
cat /var/log/user_management.log
-
Check the password file:
cat /var/secure/user_passwords.csv
Conclusion
This script automates the process of creating users, assigning them to groups, generating passwords, and setting up home directories. By logging all actions and securely storing passwords, it ensures transparency and security in user management.
Top comments (0)