Automating Linux User Management with a Bash Script
Tags: devops, linux, bash
Published: 2024-07-03 08:36:25

Managing user accounts in a Linux environment can be a tedious and error-prone process, especially when dealing with a large number of users. As a SysOps engineer, ensuring that each user is created with the correct permissions, groups, and secure credentials is crucial for maintaining system security and efficiency. 
As part of HNG Internship, was assigned a real-world scenario of writing a Bash script designed to automate the process of user and group creation, home directory setup, and password management. This script not only simplifies the user management process but also ensures consistency and security across the system. 

This project is also available on my [github repository](https://github.com/Zkyusya/stage1_hnginternship/tree/main)

<u>**Task**</u>

Your company has employed many new developers. As a SysOps engineer, write a bash script called `create_users.sh `that reads a text file containing the employee’s usernames and group names, where each line is formatted as user;groups.

The script should create users and groups as specified, set up home directories with appropriate permissions and ownership, generate random passwords for the users, and log all actions to `/var/log/user_management.log.` Additionally, store the generated passwords securely in `/var/secure/user_passwords.txt.`

Ensure error handling for scenarios like existing users and provide clear documentation and comments within the script.

<u>**Project Setup**</u>

To begin with, the script should automate the following;

**1.Read User and Group Information:** The script will read from a text file that contains user and group details.
**2. Create User and Group:** For each user in the file, the script will create a user account and a corresponding personal group.
**3. Assign Additional Groups:** If additional groups are specified for a user (e.g., hng;hng0,hng1), the script will add the user to those groups.
**4. Create Home Directories:** A dedicated home directory will be created for each user.
**5. Generate Random Passwords:** Secure random passwords will be generated for each user and stored in `var/secure/user_passwords.csv.`
**6. Log Actions:** All activities performed by the script will be logged to `/var/log/user_management.log.`

<u>**Creating the User List File**</u>

The Bash script relies on a text file to define the users and groups it needs to create.
Create a text file named `user-list.txt` that contains the usernames and groups.
Example content for `user-list.txt`:

```
light;sudo,dev,www-data
idimma;sudo
mayowa;dev,www-data
```

You can replace the usernames and groups with the names you are working with.

Next, we create a bash script file that interacts with this text file.

<u>**Creating the Bash Script File**</u>

Now, we create a bash script called `create_users.sh` using a text editor (nano).
This script checks for root privileges, reads the user list file, creates users and groups, assigns users to groups, generates random passwords, and logs all actions.

<u>**Step by Step Guide on Creating the Bash Script**</u>

**1. Check Root Permissions**
Ensures the script is run by the root user.
If the script is not run as root user, it exits with an error message.

```
bash
Copy code
#!/bin/bash

# Check if the script is run as root
if [ "$EUID" -ne 0 ]; then
      echo "This script must be run as root"
      exit 1
fi
```

**2. Validate Input File**

The script checks if a filename was provided as an argument. If not, it exits with a usage message.

```

# Check if the input file is provided
if [ -z "$1" ]; then
    echo "Usage: $0 <user_list_file>"
    exit 1
fi

```

**3. Create environment variables for the file**

Create environment variables to hold the paths for the input text file `(text_file.txt)`,log file `(/var/log/user_management.log) `and the password file `(/var/secure/user_passwords.csv)`.

```
# Log file and password file paths
INPUT_FILE="$1"
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
```

**4. Create or clear log and password files with root privileges**

Create the log and password files and give them the necessary permissions

```
# Create or clear log and password files with root privileges

mkdir -p /var/log
mkdir -p /var/secure
touch $LOG_FILE
chmod 700 /var/secure  # Set permissions for the log file
: > $LOG_FILE  # Clear the log file
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE  # Set secure permissions for the password file
: > $PASSWORD_FILE  # Clear the password file
```


- `touch $LOG_FILE `Creates a `/var/log/user_management.log `file if they don't exist.
- `mkdir -p /var/secure` Creates a `/var/secure` directory that will hold the password file.
- `chmod 700 /var/secure `Sets the permissions so that only the user has read, write, and execute permissions for the `/var/secure` directory
- `touch $PASSWORD_FILE `Creates a `/var/secure/user_passwords.csv `file if they don't exist.
- `chmod 600 $PASSWORD_FILE `Sets the permissions so that only the user has read and write permissions for the `/var/secure/user_passwords.csv` file.
- The `: > `command clears the contents of the log and password files.

**5. Generate Random Passwords**
create the `log_message()` and `generate_password()` functions. These functions will handle creating log messages for each action and generating user passwords.

```
# Function to generate logs and random passwords
    log_message() {
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
    }

    generate_password() {
        openssl rand -base64 12
    }
```

**6. Process User List**
Reads the input file line by line, processes each username and associated groups

```
# Read the user list file and process each line
while IFS=';' read -r username groups || [ -n "$username" ]; do
    username=$(echo "$username" | xargs) # Trim whitespace
    groups=$(echo "$groups" | xargs)
```

**7. Create Users and Groups**
Creates users, personal groups, and additional groups if they do not exist and adds user to each group.  

```
# Check if the personal group exists, create one if it doesn't
        if ! getent group "$username" &>/dev/null; then
            echo "Group $username does not exist, adding it now"
            groupadd "$username"
            log_message "Created personal group $username"
        fi


 # Check if the user exists
        if id -u "$username" &>/dev/null; then
            echo "User $username exists"
            log_message "User $username already exists"
        else

            # Create a new user with the created group if the user does not exist
            useradd -m -g $username -s /bin/bash "$username"
            log_message "Created a new user $username"
        fi

# Check if the groups were specified
        if [ -n "$groups" ]; then
            # Read through the groups saved in the groups variable created earlier and split each group by ','
            IFS=',' read -r -a group_array <<< "$groups"
            # Loop through the groups 
            for group in "${group_array[@]}"; do
     # Check if the group already exists
                if ! getent group "$group" &>/dev/null; then
                    # If the group does not exist, create a new group
                    groupadd "$group"
                    log_message "Created group $group."
                fi

                # Add the user to each group
                usermod -aG "$group" "$username"
                log_message "Added user $username to group $group."
            done
        fi
```

**8. Trimming Whitespace**
Remove any leading or trailing spaces from the username and groups variables.                

```
# Remove the trailing and leading whitespaces and save each group to the group variable
                group=$(echo "$group" | xargs) # Remove leading/trailing whitespace
```
- `xargs` command removes any whitespace at the beginning or end of the variable values.

**9. Generating and Setting a User Password**
Generates a random password for the user, logs it in the password file, and logs the action in the log file.         

```
   # Create and set a user password
        password=$(generate_password)
        echo "$username:$password" | chpasswd
        # Save user and password to a file
        echo "$username,$password" >> $PASSWORD_FILE
```

**10. Feeding the Input File into the Loop**
The operator, `<` tells the while loop to read its input from the file specified by `$INPUT_FILE`  

```
  done < "$INPUT_FILE"
```
**11. Final Log Message**
Logs the completion of the user creation process.

```
log_message "User created successfully"

    echo "Users have been created and added to their groups successfully"
```

The final script file should [look like this ](https://github.com/Zkyusya/stage1_hnginternship/edit/main/create_users.sh)

<u>**Running the Script**</u>

To execute this script, you need to be logged as a root user and run script using the bash command; `create_users.sh user-list.txt`

**1. Ensure the script is executable** using the following command

```
chmod +x create_users.sh
```
**2. Run the script**

```
 ./create_user.sh ./user-list.txt
```
The use of `./ `before the script name ensures that the script is executed from the current directory. If the script is located in a different directory, navigate to that directory first using the `cd` command.

Also, check your `/var/log/user_management.log` file to see your logs by running this command: 

```
cat /var/log/user_management.log
```
Check your `/var/secure/user_passwords.csv` file to see the users and their passwords using the command

```
cat /var/secure/user_passwords.csv
```

If the script is running successfully, you should see the following in the terminal

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oybmz3ffq70d1pv6af0i.PNG)

To ensure that the script performs its functions well, I edited the `user-list.txt` file for different users and groups. The script successfully created the non-existent users, groups, and added the users to the new groups.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rui5irffzgv07pcf7z2c.PNG)




<u>**Key Points**</u>

**•User and Group Creation:** The script ensures each user has a personal group with the same name. It handles the creation of multiple groups and adds users to these groups.
**•Home Directory Setup:** Home directories are created with appropriate permissions and ownership.
**•Password Generation and Security:** Random passwords are generated and stored securely. Only the file owner can read the password file.
**•Logging:** All actions are logged for auditing purposes.
This script simplifies the task of user management in a Linux environment, ensuring consistency and security.

I hope you enjoyed reading this article and can now manage users, groups, and their passwords using bash script.

Learn more about the HNG Internship and opportunities to grow as a developer:

[HNGInternship Cohort 11](https://hng.tech/internship)

[HNGInternship2024](https://hng.tech/hire)