In this project, we want to onboard 20 new Linux users onto a server. Create a shell script that reads a CSV file of a list of users to be onboarded. Each user requires the following:
Must have a default /home directory, ie /home/cdrani/ for user cdrani
Each user must be added to a developers group
An .ssh folder with an authorized_keys file that includes the rsa.pub key of the current user ($USER)
STEP 1: Setup Private & Public keys for $USER
Generating ssh private (id_rsa) and public key (id_rsa.pb) for $USER. The public key will be copied over to each onboarded user's .ssh/authorized_keys file. We will make use of ssh-keygen and just press Enter/Return key to accept the default file names and placement. In the end, we should have both id_rsa and id_rsa.pub keys in ~/.ssh folder.
sudo ssh-keygen

STEP 2: Onboarding Script
Now for the script itself. It's heavily documented with comments, but some additional criteria I included are to verify that the script is run by a root user, a .csv file is passed as an argument and a default password of password is set for each onboarded user with an expiration date of 7 days.
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root."
exit 1
fi
if [ $# -eq 0 ]; then
echo "Please provide the name of the CSV file."
exit 1
fi
file="$1"
if [ "${file##*.}" != "csv" ]; then
echo "The file must be a CSV file."
exit 1
fi
if ! getent group developers > /dev/null 2>&1; then
groupadd developers
fi
while IFS=',' read -r name
do
username=$name
if id "$username" >/dev/null 2>&1; then
echo "User $username already exists."
continue
fi
useradd "$username" -g developers -m
echo "$username:default_password" | chpasswd
chage -m 7 "$username"
home_dir=$(eval echo "~$username")
ssh_dir="$home_dir/.ssh"
if [ ! -d "$ssh_dir" ]; then
mkdir "$ssh_dir"
chmod 700 "$ssh_dir" $username
fi
auth_keys="$ssh_dir/authorized_keys"
touch "$auth_keys"
chmod 600 "$auth_keys" $username
chown $username:developers "$auth_keys"
echo $(cat ~/.ssh/id_rsa.pub) >> "$auth_key"
done < "$file"
To run the script we need a *.csv file with a list of names:
# names.csv
beth
mark,
lucy,
fred,
liza
Then we need our script to be executable before we run it:
sudo chmod +x onboard_users.sh
sudo ./onboard_users.sh names.csv
Let's test out some of the conditionals we have in place:

We now should have /home/$user (for ex. /home/beth/) directories for each user in the names.csv file:

Finally, we should be able to log in as any of the newly onboarded users, however, our new users don't use the same private key that we set up when launching our ec2 instance - we must use the one we generated above (id_rsa).
First, we need to ensure our key is not publicly viewable, i.e it is not writable:
sudo chmod -w id_rsa

After the above, we can then copy the private key from our remote server (ec2) to our local environment using scp:
scp -i ~/Desktop/webserver-ec2.pem ubuntu@35.85.56.192:~/.ssh/id_rsa ~/.ssh/aux_id_rsa
With that complete, from our local computer, we can log in as an onboarded user:
ssh -i ~/.ssh/aux_id_rsa fred@38.85.56.192

Only users with the auth key can log in:

Note: One can log in using the *.pem key for the ec2 instance as well.
Bonus:
Testing the script several times to address issues necessitated removing users as well. This quickly turned into a pain point that required a deboard.sh script. It has the same checks as the onboard.sh one which could be refactored out into a separate script that runs before both of them, but it's good enough.
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root."
exit 1
fi
if [ $# -eq 0 ]; then
echo "Please provide the name of the CSV file."
exit 1
fi
file="$1"
if [ "${file##*.}" != "csv" ]; then
echo "The file must be a CSV file."
exit 1
fi
while IFS=',' read -r fname lname
do
username=$fname
if ! id "$username" >/dev/null 2>&1; then
echo "User $username does not exist."
continue
fi
sudo userdel -r "$username"
done < "$file"