Add New User to EC2 Linux Instance with Google MFA: Ubuntu
Tags: linux, aws, security, tutorial
Published: 2022-01-19 21:52:52

![User administration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brxxpf825zgzwd3nzozo.png)
 
**Note**

* This tutorial is not for absolute beginners, but persons with some experience in Linux, CLI and a bit of cloud technology.

* The actions listed here are to be carried out by a superuser (preferrably the root user), unless otherwise stated within context.

* Where your machine or instance does not have the `nano` text editor, use `vi` (for the vim text editor).

* `<...>` represents placeholders in code snippets and configurations.

* `[...]` represents optional parameters in code snippets and configurations.

* Ensure you are logged in to the EC2 instance as a superuser.

## Get Key Pair for The New User Account

You can generate a new key pair, or use an existing one.

To generate a new key pair

```sh
aws ec2 create-key-pair \
    --key-name <key-pair-name> \
    --key-type rsa \
    --query "KeyMaterial" \
    --output text > <key-pair-name>.pem
```

Ensure to get this file and keep it in a safe place where you will not lose it, e.g.:

* in a secure and accessible cloud storage.

* in an accessible key vault.

If your local machine is a Linux or Mac, ensure only the current user has access to this file

```sh
chmod 400 <key-pair-name>.pem
```

Retrieve the public key from the key pair

```sh
ssh-keygen -y -f /<path_to_key_pair>/<key-pair-name>.pem
```

If you would be using the same private key as that which was used to launch the instance, you can get the public key by running the follow command

```sh
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
```

Copy the public key and keep it for later use.

## Create New User

Switch to root

```sh
su -
```

The above might request for password that you did not set, nor do you want to keep inputting passwords. In such situations, go with the below snippet

```sh
sudo -i
```

Add new user

```sh
sudo adduser <username>
```

If user is to be a superuser

```sh
sudo adduser <username> --disabled-password
```

## Make User A Superuser

Add User to Sudo Group

```sh
usermod -aG sudo <username>
```

`-aG`: Append to group.

Verify user belongs to the superusers group

```sh
groups <username>
```

## Update The Superuser to Not Use Password

Superusers are usually not expected to need password for access once authenticated. Hence, the convention overlooking password authorization for superusers.

Open the sudo permissions file

```sh
sudo visudo
```

Add this to the opened file in the editor, save the file and exit the editor.

```sh
<username> ALL=(ALL) NOPASSWD:ALL
```

To prevent the need for using a password for the user at any password prompt, delete the user password

```sh
sudo passwd -d <username>
```

Henceforth, just press Enter whenever there is a password prompt, and you get authenticated.

In the case where the user is not a superuser, and you used the `--disabled-password` flag you can set a new password for the user by the `root` user

```sh
passwd <username>
```

Follow the prompts and press `Enter` when done.

## Implement SSH Authentication

Switch to the new user

```sh
su - <username>
```

Add .ssh directory to the new user’s home directory:

```sh
mkdir .ssh
```

Create the authorized_keys file

```sh
touch .ssh/authorized_keys
```

Restrict read-write access to the new user

```sh
chmod 600 .ssh/authorized_keys
```

Update the new user account credentials by pasting the public key into the file

```sh
nano .ssh/authorized_keys
```

Save the file and close the editor.

You can also verify the user belongs to the superusers group

```sh
id
```

You should get a similar output as follows

```sh
uid=1004(<username>) gid=1004(<username>) groups=1004(<username>,sudo)
```

## Implement Google Auth MFA

Download the Google Auth mobile app on your mobile device if you do not have it. For Android, it is available on Play Store.

Login with your Google account to the mobile app.

Ensure you are on the new user, else switch to the new user

```sh
su - <username>
```

Install the Google Auth app

```sh
sudo yum install google-authenticator -y
```

Initialize the app

```sh
google-authenticator
```

Open the Google Auth mobile app, press the plus button ➕ and scan the QR code in the CLI.

You can rename the new authentication on your mobile app to something more intuitive.

Answer the prompted questions in this manner

```sh
Do you want authentication tokens to be time-based (y/n) y

Do you want me to update your "/home/ec2-user/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication token?
This restricts you to one login about every 30s,
but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y

# Select ‘n’ for the next question for 3 valid codes in a 1:30-minute window
By default,
tokens are good for 30 seconds and in order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time.
If you experience problems with poor time synchronization,
you can increase the window from its default size of 1:30min to about 4min.
Do you want to do so (y/n) n

If the computer that you are logging into isn't hardened against brute-force login attempts,
you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y
```

Configure SSH to use the Google Pluggable Authentication Module

```sh
sudo nano /etc/pam.d/sshd
```

Append the following to the opened file in the editor

```sh
auth required pam_google_authenticator.so [nullok]
auth required pam_permit.so
```

Disable the password requirement by ensuring this line commented out

```sh
#auth       substack     password-auth
```

Change the SSH configuration to prompt for a second authentication

```sh
sudo nano /etc/ssh/sshd_config
```

In the opened file, modify as follows

```sh
#ChallengeResponseAuthentication no
ChallengeResponseAuthentication yes
```

In the same file, let SSH know that it should ask for SSH key and verification code.

```sh
AuthenticationMethods publickey,keyboard-interactive
```

Save the file and close the editor.

Restart the SSH to for the changes to take effect using either

```sh
sudo /etc/init.d/sshd restart
```

OR

```sh
sudo service sshd restart
```

## Test Connection and Privileges

Open a new terminal on your local machine.

SSH into the instance with the new username and the associated private key

```sh
ssh -i /<path_to_key_pair>/<key-pair-name>.pem <username>@<instance-public-dns-name>
```

It should prompt you for a verification code. Open your Google Auth app to get the latest verification code for this instance, input it into the text box, and press the `Enter` key.

You should now be logged in to the instance as the new user who can perform sudo activities.

## Conclusion

It sure was a journey coming this far, and I can but say, well done and congratulations!!! You have found something that works: for Ubuntu and most other Linux instances (some needing little tweaks).

Thanks for reading through. But do not forget the references below: they could open you up to more possibilities beyond the scope of this tutorial.

As much as I have practiced this over time, and tried out different things with different documentations, **your contributions are very welcome in the comments**.

*Enjoy exploring, learning, and growing!!!*

## References

| Title      | Website |
| ----------- | ----------- | ----------- |
| Add New User to a Linux Instance | https://aws.amazon.com/premiumsupport/knowledge-center/new-user-accounts-linux-instance |
| Setup Multi-factor Authentication | https://aws.amazon.com/blogs/startups/securing-ssh-to-amazon-ec2-linux-hosts |
| Create and Retrieve Key Pairs | https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#having-ec2-create-your-key-pair |
| Set or Change User Password | https://www.cyberciti.biz/faq/linux-set-change-password-how-to |
| Poster image | [Freepik](freepik.com) |