As a DevOps engineer, it is quite a common task to create, update and delete users and groups. Automating this process can save time and reduce errors, especially when onboarding multiple new developers. In this article, we'll walk through a Bash script designed to automate the creation of users and their respective groups, set up home directories, generate random passwords, and log all actions.
Objectives
Create users and their personal groups.
Add users to specified groups.Set up home directories with appropriate permissions.
Generate and securely store random passwords.Log all actions for auditing purposes.
Requirements
- Input File: A text file containing usernames and groups, formatted as username;group1,group2.
- Log File: A log file to record all actions.
- Password File: A file to securely store generated passwords.
Let's Begin
First and foremost, at the beginning of any shell script we're writing, we start the first line with a line called a "shebang", sounds catchy right?
#!/bin/bash
The presence of a shebang indicates that a file is executable.
Now that that is out of the way we can move on to the juicy details.
Script Initialization
The script starts by defining the locations of the log file and the password file(you can name these file whatever you want, ):
LOGFILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
Check File Input
The script checks if an input file is provided as an argument:
if [ -z "$1" ]; then
echo "Usage: $0 <name-of-text-file>"
exit 1
fi
If no file is provided, the script exits with a usage message, telling our users how to use our script.
Create Log and Password Files
This code snippet creates the necessary directories and files, setting appropriate permissions:
mkdir -p /var/secure
touch $LOGFILE $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
We make a directory called "/var/secure/" which will keep our passwords. After that we create the two files that were defined above for logging and saving passwords. Modifying our $PASSWORD_FILE with chmod 600
will ensure that only the user with appropriate permissions can view it(which happens to be the current user we are logged in as).
Generate Random Password Function
We're gonna write a function to generate some random and secure passwords for our different users.
generate_random_password() {
local length=${1:-10} # Default length is 10 if no argument is provided
tr -dc 'A-Za-z0-9!?%+=' < /dev/urandom | head -c $length
}
The function takes an argument which is how long you want the passwords to be, if none is passed, it defaults to 10.
tr -dc 'A-Za-z0-9!?%+='
: This command is used to translate and delete characters that are not in the regexA-Za-z0-9!?%+=
< /dev/urandom
: uses the Linux kernel's random number generator and passes the result to the command above.| head -c $length
: outputs the length of the random string specified.
Logging Function
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOGFILE
}
Takes an argument and logs the date and time of the message in the $LOGFILE
Create User Function
The create_user()
function handles the creation of users and their groups. It takes two arguments: username and groups.
create_user() {
local username=$1
local groups=$2
if getent passwd "$username" > /dev/null; then
log_message "User $username already exists"
else
useradd -m $username
log_message "Created user $username"
fi
# Add user to specified groupsgroup
groups_array=($(echo $groups | tr "," "\n"))
for group in "${groups_array[@]}"; do
if ! getent group "$group" >/dev/null; then
groupadd "$group"
log_message "Created group $group"
fi
usermod -aG "$group" "$username"
log_message "Added user $username to group $group"
done
# Set up home directory permissions
chmod 700 /home/$username
chown $username:$username /home/$username
log_message "Set up home directory for user $username"
# Generate a random password
password=$(generate_random_password 12)
echo "$username:$password" | chpasswd
echo "$username,$password" >> $PASSWORD_FILE
log_message "Set password for user $username"
}
Let's break it down.....
- Checking if User Already Exists
if id "$username" > /dev/null; then
log_message "User $username already exists"
else
useradd -m $username
log_message "Created user $username"
fi
If a user exists our script logs it and moves on else the user is created and then logged.
NOTE: > /dev/null
is passing the response to null so that it doesn't interfere with our logs.
NOTE: We are not going to create a personal group for each user because unix does this for us automatically when we create a new user
- Adding User to Specified Groups
We then proceed to add the users to their different groups
groups_array=($(echo $groups | tr "," "\n"))
for group in "${groups_array[@]}"; do
if ! getent group "$group" > /dev/null; then
groupadd "$group"
log_message "Created group $group"
fi
usermod -aG "$group" "$username"
log_message "Added user $username to group $group"
done
The code snippet splits the groups string by commas and saves them in a groups_array variable. It then loops through each group and adds the user to it, also making sure to create the group if it doesn't exist:
- Setting Up Home Directory Permissions
chmod 700 /home/$username
chown $username:$username /home/$username
log_message "Set up home directory for user $username"
chmod 700 /home/$username:
: Sets the home directory permissions so only the user has full access (read, write, execute).
chown $username:$username /home/$username
: Changes the ownership of the home directory to the specified user and their group.
echo "Set up home directory for user $username" | tee -a $LOGFILE
: Logs a message indicating the home directory setup to a specified log file.
- Assigning A Random Password To Each User
password=$(generate_random_password 12)
echo "$username:$password" | chpasswd
echo "$username,$password" >> $PASSWORD_FILE
log_message "Set password for user $username"
This snippet uses the function we wrote earlier to create a password, update the user's password to the generated password, saves the username and the corresponding password to the $PASSWORD_FILE
and finally logs a message indicating it has been successfully changed.
Reading the Input File
The script reads the input file line by line, calling the create_user()
function for each line and passing the $username and $groups as arguments:
while IFS=';' read -r username groups; do
create_user "$username" "$groups"
done < "$1"
Now Put It All Together...
#!/bin/bash
# Log file location
LOGFILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
# Check if the input file is provided
if [ -z "$1" ]; then
echo "Error: No file was provided"
echo "Usage: $0 <name-of-text-file>"
exit 1
fi
# Create log and password files
mkdir -p /var/secure
touch $LOGFILE $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
generate_random_password() {
local length=${1:-10} # Default length is 10 if no argument is provided
LC_ALL=C tr -dc 'A-Za-z0-9!?%+=' < /dev/urandom | head -c $length
}
# Function to create a user
create_user() {
local username=$1
local groups=$2
if getent passwd "$username" > /dev/null; then
echo "User $username already exists" | tee -a $LOGFILE
else
useradd -m $username
echo "Created user $username" | tee -a $LOGFILE
fi
# Add user to specified groupsgroup
groups_array=($(echo $groups | tr "," "\n"))
for group in "${groups_array[@]}"; do
if ! getent group "$group" >/dev/null; then
groupadd "$group"
echo "Created group $group" | tee -a $LOGFILE
fi
usermod -aG "$group" "$username"
echo "Added user $username to group $group" | tee -a $LOGFILE
done
# Set up home directory permissions
chmod 700 /home/$username
chown $username:$username /home/$username
echo "Set up home directory for user $username" | tee -a $LOGFILE
# Generate a random password
password=$(generate_random_password 12)
echo "$username:$password" | chpasswd
echo "$username,$password" >> $PASSWORD_FILE
echo "Set password for user $username" | tee -a $LOGFILE
}
# Read the input file and create users
while IFS=';' read -r username groups; do
create_user "$username" "$groups"
done < "$1"
echo "User creation process completed." | tee -a $LOGFILE
Conclusion
This script provides an efficient way to manage user and group creation, ensuring that all necessary steps are handled securely and logged for auditing. By automating these tasks, SysOps engineers can save time and reduce the risk of errors during user onboarding.
To learn more and kickstart your programming journey you can visit:
https://hng.tech/internship or https://hng.tech/premium
Feel free to reach out with questions or suggestions for improvements. Happy automating!