Disclaimer: This tutorial uses a fresh Ubuntu 18.x Droplet on DigitalOcean. However, this guide is fairly general and will likely aid you regardless of having your server hosted on DigitalOcean.
So you’ve just spun up a new Droplet on DigitalOcean and discovered that your SSH key won’t allow you to access the server. Or perhaps you’ve just started a new Droplet and realized that you need to add an SSH key after the fact. Either way, you may encounter an error like the following:
$ ssh -i ~/.ssh/your_private_key root@your_droplet_ip
ssh: connect to host your_droplet_ip port 22: Operation timed out
Or even:
$ ssh -i ~/.ssh/your_private_key root@your_droplet_ip
Permission denied (publickey)
Our first step here is to grab our root password (you can have DigitalOcean reset your password if you don’t remember it) and access the Droplet via the DigitalOcean console. Once you’re logged in to your Droplet via the console, the next step is to check the status of the Uncomplicated Firewall (UFW).
$ ufw status
Status: inactive
With this being a new Droplet, the UFW is not currently enabled. We’re going to enable the UFW and open up port 22 to allow SSH access. If your Firewall is already enabled you can just skip the enablement step and follow along.
$ sudo ufw enable
Firewall is active and enabled on system startup
$ ufw allow 22
Rule updated
Rule updated (v6)
Now for our changes to take effect it’s time we restart our Droplet. Once the system is up and running again we’re going to modify our SSH configuration to allow us to authenticate into the system via SSH. At this point if you did not specify your SSH key as part of the initial Droplet setup you will need to append the contents of your public key to /root/.ssh/authorized_keys. Tip: You can type shift+g+a inside of vim to jump to the end of a file and enter insert mode. If you don’t recall whether or not you added your key earlier you can simply cat the file to see it’s contents.
$ cat /root/.ssh/authorized_keys
Once you’ve appended the contents of your public key to the authorized_keys files (or if you’d already taken this step prior to reading this post) you should modify your sshd_config and enable access. The settings we are concerned with are changing the password option to Yes and uncommenting the PubKeyAuthentication and AuthorizedKeysFile lines. You can find these settings under the Authentication heading.
$ vi /etc/ssh/sshd_config
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
PasswordAuthentication yes
PubKeyAuthentication yes
Reload your configuration so that the settings can take effect.
$ systemctl reload sshd
Finally it’s time for us to try authenticating again with our SSH key. Assuming no typos, we should be able to gain access to the server by specifying our private key.
$ ssh -i ~/.ssh/your_private_key root@your_droplet_ip
Bonus
If you’re wondering how do I disable the password prompt for SSH keys? I don’t blame you. You can edit your sshd_config and apply the following settings and reload your sshd:
$ vi ~/.ssh/sshd_config
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
$ systemctl reload sshd
Solving SSH Errors
If your attempt to SSH into the server was unsuccessful you may have received a warning like the following:
$ ssh -i ~/.ssh/your_private_key root@your_droplet_ip
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:somehashgoeshere.
Please contact your system administrator.
Add correct host key in /Users/youruser/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/youruser/.ssh/known_hosts:5
ECDSA host key for your_droplet_ip has changed and you have requested strict checking.
Host key verification failed.
Don’t panic. The solution to this is pretty simple, infact the feedback from the failure provides us with suggestions to resolve this. The command below will remove the entry for your Droplet from the known_hosts file. This way, the next time you connect the host will be entered into your known_hosts with the correct signature.
$ ssh-keygen -R your_droplet_ip
Attempt to reconnect and you should be prompted to verify the identity of the host. Enter Y, provide your password and you should be all set.
Directory and File Permissions:
If you encounter issues with your public key being denied you may need to check your directory/file permissions for your .ssh directory and keys. The following need to be applied both locally and on the remote server:
$ sudo chmod 700 ~/.ssh
$ sudo chmod 644 ~/.ssh/authorized_keys
$ sudo chmod 644 ~/.ssh/known_hosts
$ sudo chmod 644 ~/.ssh/config
$ sudo chmod 600 ~/.ssh/id_rsa
$ sudo chmod 644 ~/.ssh/id_rsa.pub