# Locking down root privileges on a cloud instance

When I was writing [my last blog post](https://blog.saleshorse.org/managing-multiple-ssh-keys-on-both-ends), I ended up having to enable `root` access to my Vultr instance so that I could reset my SSH configuration and document it properly for the blog post.

But now I'm done with that blog post, and `root` is still available for login with a password (I didn't use my real domain name in that blog post, calm down).

Naturally, I'd like to lock it back down to the status it was in before I wrote that blog post. I figured I'd document the process and share my findings along the way.

## Prework

Before disabling `root` login on the Vultr instance, I need to make sure that I'm able to ssh in as a non-root user.

This is because some `ssh` configuration has to be done as the `root` user on the Vultr instance. Once that configuration is done, then we can be done with `root`.

### Vultr documentation

Referencing [Vultr's documentation for this use case](https://www.vultr.com/docs/using-your-ssh-key-to-login-to-non-root-users), they present three options:

* create a new SSH key
    
    * not a fan of this because getting the key from the server to my local machine is more involved than the other way around
        
* move the root SSH key to the non-root user
    
    * this immediately jumped out as the approach I wanted to use
        
* startup scripts
    
    * seems too involved
        
    * docs say it's best suited for deploying many instances
        

So I proceed with option #2: move the root SSH key to the non-root user

## Check existing keys

The Vultr instructions say to

* make a `~/.ssh` folder for the non-root user
    
* move the `authorized_keys` file from `/root/.ssh/` to `/home/<nonRootUser>/.ssh/`
    
* make the non-root user the owner of the `/home/<nonRootUser/.ssh` directory
    

...but I think I may have already done some of these steps.

So I log into the Vultr instance as `root`, and start poking around:

```bash
# root@vultr

ls -la ~/.ssh # press enter

# output
drwx------  2 root  wheel  512 May 14 16:15 .
drwx------  3 root  wheel  512 May 14 15:54 ..
-rw-------  1 root  wheel  185 May 14 19:34 authorized_keys
```

I can see that `/root/authorized_keys` exists, so I see what's in it:

```bash
# root@vultr

cat /root/.ssh/authorized_keys # press enter

# output
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEbll4kwbvR/um3/zzMxEZs7+Jmj8NpAPkqQj8SC6cia idev@MSI
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICaQ9obHa6yYVZPqjQSaeG5OadwxxYguPJVNA7zJpuEm jester@devbox
```

I see that there are two public keys, one from each of my laptops. I believe these are the keys that I generated and copied over in the last blog post.

To confirm these are the correct keys, I go to each client machine:

```bash
# idev@MSI

ls -la ~/.ssh # press enter

# output
drwx------  2 idev idev 4096 May 14 12:15 .
drwxr-x--- 34 idev idev 4096 May 15 18:18 ..
-rw-------  1 idev idev 1342 May 14 11:30 known_hosts
-rw-------  1 idev idev 1120 May 14 11:30 known_hosts.old
-rw-------  1 idev idev  399 May 14 12:11 vultr_ed25519
-rw-r--r--  1 idev idev   90 May 14 12:11 vultr_ed25519.pub
```

I see what looks like a Vultr public key, so I check its contents:

```bash
# idev@MSI

cat ~/.ssh/vultr_ed25519.pub # press enter

# output
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEbll4kwbvR/um3/zzMxEZs7+Jmj8NpAPkqQj8SC6cia idev@MSI
```

I can see that the public key on the client machine matches what is in the `/root/authorized_keys` file on the Vultr instance. So far so good.

Now I do the same thing on my other laptop:

```bash
# jester@devbox

ls -la ~/.ssh # press enter

# output
drwx------  2 jester jester 4096 May 14 19:37 .
drwxr-x--- 21 jester jester 4096 May 15 18:26 ..
-rw-------  1 jester jester  201 May 14 19:37 config
-rw-------  1 jester jester 1484 May  2 17:22 known_hosts
-rw-------  1 jester jester  506 Apr 29 12:41 known_hosts.old
-rw-------  1 jester jester  399 May 14 19:29 rpi_ed25519
-rw-r--r--  1 jester jester   95 May 14 19:29 rpi_ed25519.pub
-rw-------  1 jester jester  399 May 14 15:33 vultr_ed25519
-rw-r--r--  1 jester jester   95 May 14 15:33 vultr_ed25519.pub
```

I see an additional key pair and a config file, but right now I'm just concerned with the Vultr key, so I view the contents of the file to see if it matches what's on the server:

```bash
# jester@devbox

cat ~/.ssh/vultr_ed25519.pub # press enter

# output
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICaQ9obHa6yYVZPqjQSaeG5OadwxxYguPJVNA7zJpuEm jester@devbox
```

It does indeed match, so I'm ready to move on to the next step.

### Check the non-root user

Recall that the instructions said to make a `.ssh` folder for the non-root user, but I think I already created it, so I go ahead and check:

```bash
# root@vultr

ls -la /home/sharif/.ssh # press enter

# output
drwx------  2 sharif  sharif  512 May 14 15:01 .
drwxr-xr-x  4 sharif  sharif  512 May 14 14:55 ..
-rw-------  1 sharif  sharif  747 May 14 15:04 authorized_keys
```

Yep, there it is. I suspect the `authorized_keys` file is not up-to-date because of the configuration changes I made during my last blog post, so I view the contents:

```bash
# root@vultr

cat /home/sharif/.ssh/authorized_keys 
```

Sure enough, I've got some old keys that don't match what's on the client machines, so I remove the file:

```bash
# root@vultr

rm /home/sharif/.ssh/authorized_keys
```

Now I can follow Vultr's instructions and move the `root` user's `authorized_keys` file over to my non-root user:

```bash
# root@vultr

mv /root/.ssh/authorized_keys /home/sharif/.ssh/ # press enter

# make sure it worked

ls -la /home/sharif/.ssh/ # press enter

# output 
drwx------  2 sharif  sharif  512 May 15 22:43 .
drwxr-xr-x  4 sharif  sharif  512 May 14 14:55 ..
-rw-------  1 root    wheel   185 May 14 19:34 authorized_keys
# end output

cat /home/sharif/.ssh/authorized_keys # press enter

# output -- correct keys confirmed
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEbll4kwbvR/um3/zzMxEZs7+Jmj8NpAPkqQj8SC6cia idev@MSI
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICaQ9obHa6yYVZPqjQSaeG5OadwxxYguPJVNA7zJpuEm jester@devbox
```

Now to adjust the permissions so that the non-root user can properly access the `authorized_keys` file:

```bash
# root@vultr

chown -R sharif:sharif /home/sharif/.ssh # press enter

# make sure it worked
ls -la /home/sharif/.ssh # press enter

# output -- non-root ownership confirmed
drwx------  2 sharif  sharif  512 May 15 22:43 .
drwxr-xr-x  4 sharif  sharif  512 May 14 14:55 ..
-rw-------  1 sharif  sharif  185 May 14 19:34 authorized_keys
```

The non-root user's configuration looks good; now to test it from both clients.

## Test SSH as the non-root user

This part should (hopefully) be pretty painless since I set up SSH configuration files in the last blog post.

Theoretically, I should just be able to change the user from `root` to `sharif` in the config, use that config for both laptops, and all should be well.

Let's try it:

```bash
# idev@MSI

# /home/idev/.ssh/config
Host myvultrserver.com
    HostName myvultrserver.com
    User sharif
    IdentityFile ~/.ssh/vultr_ed25519
```

Moment of truth:

```bash
# idev@MSI
ssh myvultrserver.com
```

Success!

The process should be the same on my other laptop:

```bash
# jester@devbox

# /home/jester/.ssh/config
Host myvultrserver.com
    HostName myvultrserver.com
    User sharif
    IdentityFile ~/.ssh/vultr_ed25519

# save the config file

# test ssh
ssh myvultrserver.com
```

Now that I've confirmed I can SSH into the server with both my client machines (laptops), I can finally move on to removing the ability to:

* log in as root
    
* log in with a password
    

## Disable root and password login

I'll need to log in to my Vultr as `root` one last time:

```bash
ssh root@myvultrserver.com
```

Now I need to edit the `/etc/ssh/sshd_config` file to disable root and password login:

```bash
# root@vultr

# /etc/ssh/sshd_config

# change 'PermitRootLogin' from 'yes' to 'no'
PermitRootLogin no
# add 'PasswordAuthentication no' to bottom of file
PasswordAuthentication no
```

Once the file is saved, I need to restart the `sshd` service on the server:

```bash
# root@vultr

rcctl restart sshd # press enter

# output
sshd(ok)
sshd(ok)
```

Now I can log out of the instance and see if the changes took effect:

```bash
# root@vultr
exit # press enter

# idev@MSI
ssh root@myvultrserver.com # press enter

# output
root@sharif.gg: Permission denied (publickey,keyboard-interactive).
```

This is what I wanted to see -- an error message when trying to log in as `root` via `ssh`.

As a final test, I want to see if I can run an elevated command as my non-root user:

```bash
# idev@MSI

ssh myvultrserver.com # press enter

# login successful -- sharif@vultr

# attempt to edit a readonly file with sudo
sudo vim /etc/ssh/sshd_config # press enter

# prompted for password
Password: # enter password

sharif is not in the sudoers file. # error
This incident has been reported to the administrator.
```

I'm feeling pretty good about this, but there is a looming question...

## What if I need root?

There is a good chance I'll want to change something else on my server that requires `root` privileges.

But how do I do that if I just disabled root login and password login?

Thankfully, cloud services like Vultr offer a backdoor through their web console, where you can access a special web terminal with root access.

The web console is usually located in the dashboard/account management area for your cloud provider and is only available once you've logged into your account.
