Optimizing My Company's Developers and Group Management with Bash Script Automation
Published: 2024-07-03 11:24:12

### Introduction

Efficient user and group management is crucial for any organization's IT infrastructure. To streamline this process, I've developed a robust Bash script that automates the creation of user accounts and their associated groups. This script not only simplifies user management but also ensures security by generating strong passwords and setting appropriate permissions for home directories.

### Script Overview

The Bash script `create_users.sh` reads a text file containing usernames and group names, creates the users and groups as specified, sets up home directories with appropriate permissions and ownership, generates random passwords for the users, and logs all actions. Additionally, the script stores the generated passwords securely.

### Requirements and Tools

To successfully use the `create_users.sh` script, you'll need the following:

- **Linux Environment:** The script is designed to run on a Linux system with the Bash shell (which is the default on most Linux distributions).
- **Root or Sudo Privileges:** Creating users and groups typically requires administrative privileges.

### The Script

Here's the complete `create_users.sh` script:

```bash
#!/bin/bash

log_file="/var/log/user_management.log"
password_file="/var/secure/user_passwords.txt"

# Initialize log file and secure password file
touch "$log_file"
touch "$password_file"
chmod 600 "$password_file"
echo "Timestamp, Action, User, Details" > "$log_file"

# Function to generate a robust password with special characters
generate_password() {
    cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%^&*()_+=-[]{}|;:,.<>?' | fold -w 16 | head -n 1
}

# Function to create a user and manage group associations
create_user() {
    user=$(echo "$1" | cut -d';' -f1 | xargs)
    groups=$(echo "$1" | cut -d';' -f2 | xargs)

    # Prevent duplicate user creation
    if id "$user" &>/dev/null; then
        echo "$(date +'%Y-%m-%d %H:%M:%S'), User already exists, $user," >> "$log_file"
        return
    fi

    # Create personal group
    groupadd "$user"

    # Create user account with home directory and primary group
    useradd -m -g "$user" "$user"
    if [ $? -ne 0 ]; then
        echo "$(date +'%Y-%m-%d %H:%M:%S'), Failed to create user, $user," >> "$log_file"
        return
    fi
    echo "$(date +'%Y-%m-%d %H:%M:%S'), User created, $user," >> "$log_file"

    # Set correct permissions for the home directory
    chmod 755 "/home/$user"
    chown "$user:$user" "/home/$user"
    echo "$(date +'%Y-%m-%d %H:%M:%S'), Set permissions, $user, Home directory permissions set to 700" >> "$log_file"

    # Add user to specified additional groups
    if [[ -n "$groups" ]]; then
        for group in $(echo "$groups" | tr ',' ' '); do
            if ! getent group "$group" &>/dev/null; then
                groupadd "$group"
                echo "$(date +'%Y-%m-%d %H:%M:%S'), Group created, $group," >> "$log_file"
            fi
            usermod -aG "$group" "$user"
            echo "$(date +'%Y-%m-%d %H:%M:%S'), Group added, $user, Added to '$group'" >> "$log_file"
        done
    fi

    # Generate and set a strong password
    password=$(generate_password)
    echo "$user:$password" | chpasswd
    if [ $? -eq 0 ]; then
        echo "$user,$password" >> "$password_file"
        echo "$(date +'%Y-%m-%d %H:%M:%S'), Password set, $user," >> "$log_file"
    else
        echo "$(date +'%Y-%m-%d %H:%M:%S'), Failed to set password, $user," >> "$log_file"
    fi
}

# Validate the provided input file
if [[ $# -ne 1 ]]; then
    echo "Usage: $0 <input_file>"
    exit 1
fi

input_file="$1"

# Process user data from the input file
while IFS= read -r line; do
    # Skip blank lines or comments
    if [[ -z "$line" || "$line" =~ ^\s*# ]]; then
        continue
    fi

    create_user "$line"
done < "$input_file"

# Notify user that the process is complete
echo "User creation process completed. Check the log file for details: $log_file"

```

### Detailed Breakdown

1. **Initialization and Logging Setup**

```bash
log_file="/var/log/user_management.log"
password_file="/var/secure/user_passwords.txt"
# ... (file creation and initial headers)
```

- **Log File:**  The script establishes `/var/log/user_management.log` to record every action it takes. This log is invaluable for understanding the script's execution history, diagnosing errors, and maintaining an audit trail.
- **Password File:** The `/var/secure/user_passwords.txt` file is designated for securely storing the generated passwords. It's critical to protect this file with strict permissions (e.g., `chmod 600`) so that only authorized users can access it.

2. **Secure Password Generation**

```bash
generate_password() {
    cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%^&*()_+=-[]{}|;:,.<>?' | fold -w 16 | head -n 1
}
```

- **Strong Randomness:**  The function `generate_password` harnesses `/dev/urandom` (a source of high-quality randomness) to create passwords that are difficult to guess.
- **Complex Character Set:** The password includes a diverse mix of uppercase, lowercase, numeric, and special characters, making it resistant to brute-force attacks.

3. **User and Group Creation**

```bash
create_user() { 
    # ... (user and group extraction, duplicate check) 
    groupadd "$user"
    useradd -m -g "$user" "$user" 
    # ... (error handling for user creation)
    # ... (setting permissions for home directory)

    # ... (group management)
    
    # ... (password generation and setting)
}
```

- **Input Parsing:** The function takes a line from the input file (e.g., "john_doe;dev,admin"), extracts the username and group list, and trims any unnecessary whitespace.
- **Duplicate Check:** The script gracefully handles scenarios where a user might already exist, logging the occurrence without causing errors.
- **Personal Group:** A dedicated group is created with the same name as the username. This serves as the user's primary group and simplifies permission management.
- **User Creation:**  The `useradd` command creates the user account, setting the personal group as the primary and the home directory.
- **Permissions:**  The home directory's permissions are set to `755` (owner has read, write, execute; others have read, execute) for a balance of security and usability.
- **Group Management:** The script iterates through the list of specified groups, creating any that don't exist and then adding the user to all relevant groups.
- **Password Setting:**  The `chpasswd` command is used to set the generated password for the new user, and this action is logged for future reference.

4. **Input File Processing and Completion**

```bash
# ... (input file validation)

while IFS= read -r line; do
    # ... (skipping blank lines and comments)
    create_user "$line"
done < "$input_file"

echo "User creation process completed. Check the log file for details: $log_file"
```

- **Input Validation:** The script checks if an input file has been provided as an argument. If not, it displays a usage message and exits.
- **Line-by-Line Processing:** It reads the input file line by line, ignoring empty lines or those starting with `#` (comments).
- **User Creation:** For each valid line, it calls the `create_user` function to handle the setup.
- **Completion Message:** After processing the entire file, it notifies the user that the process is complete and reminds them to review the log for details.

### Running the Script

To execute the script, follow these steps:

1. **Create a User Input File (e.g., `users.txt`)**
   ```
   john_doe;dev,admin
   jane_smith;marketing
   alex_jones;sales,support
   ```
   Each line represents a user. The format is `username;group1,group2,...`.

2. **Ensure the script is executable**:
    ```bash
    chmod +x create_users.sh
    ```

3. **Run the script with `sudo` to have the necessary permissions**:
    ```bash
    sudo ./create_users.sh users.txt
    ```

4. **Verify**: Check the log file and password file for actions and generated passwords.

### Impact and Benefits

The `create_users.sh` script is a valuable asset for our development team, providing several benefits:

- **Efficiency:** It dramatically reduces the time and effort required for onboarding new developers.
- **Consistency:** It ensures that all user accounts are set up according to established standards.
- **Security:**  The script enforces the use of strong, random passwords and carefully manages group memberships.
- **Auditing:** The detailed log file aids in troubleshooting and provides a historical record of all user creation activities.

### Conclusion

Automating user management with a Bash script like `create_users.sh` optimizes efficiency and security within an organization. This script provides a reliable solution to handle user creation, group assignments, and password management, all while maintaining comprehensive logs.

For more insights and opportunities in tech, check out the [HNG Internship](https://hng.tech/internship), [HNG Hire](https://hng.tech/hire), and [HNG Premium](https://hng.tech/premium).