# How to Configure SSH Keys


# Overview

SSH keys allow you to login to a remote computer without using your password.

This guide is the culmination of frustrations of a lack of a guide (that I could find) that has all the information I need in one place. Here are some good resources:

- https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server
- https://www.ssh.com/academy/ssh/config

## Generating SSH Keys

We will use `ssh-keygen` to generate the keys. Open the terminal and type the following:

```bash
$ cd ~/.ssh
$ ssh-keygen
```

The command will prompt you for the following:

```bash
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/gwu/.ssh/id_rsa):
```

By default, if you enter nothing (i.e. press enter without typing anything), it will save the private key at `~/.ssh/id_rsa` and the public key at `~/.ssh/id_rsa`. However, if you access multiple different remote servers or think you may do so in the future, then you should specify your own file. For my purposes, the server I was generating keys for was called TITAN, so I saved my file at `./titan`:

```bash
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/gwu/.ssh/id_rsa): ./titan
Enter passphrase (empty for no passphrase):
```

Next, it asks for a passphrase. This is optional and is used to encrypt the private key file. You would need to type this in every time you login to the server, if you choose to specify one. I chose not to use a passphrase:

```bash
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/gwu/.ssh/id_rsa): ./titan
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./titan
Your public key has been saved in ./titan.pub
The key fingerprint is:
SHA256:cAIxo4ZRzWveF7jd9MqdZu74VI+cY49gSKT3aZQt1fc gwu@Geoffreys-MBP.attlocal.net
The key's randomart image is:
+---[RSA 3072]----+
|...o=.           |
| o .o+         . |
|. o  .o.. .   . o|
| .  o .+.o.  +  o|
|   o . oS+o.+ o E|
|    . o oo.+.= + |
|       . ..oB.* .|
|          o==o + |
|          .*+ . .|
+----[SHA256]-----+
```

Now, your key is successfully generated. The final step we need to do before we move to the next section is to change the permissions. Type the following commands into your terminal:

```bash
$ chmod 600 titan
$ chmod 600 titan.pub
```

Replace `titan` and `titan.pub` with the name of your private and public keys. If you used the default name, the two files will be called `id_rsa` and `id_rsa.pub`.

{{<admonition type="warning">}}

This `chmod` step prevents other users on your computer from accessing or tampering with your key. `ssh` is smart and recognizes the potential vulnerability, so if you try to login (as we will do later) _without_ changing the permissions, it will prevent you from doing so:

```bash
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'titan' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "titan": bad permissions
```

{{</admonition>}}

## Copying the SSH Keys to the Remote Server

Next, we will use the `ssh-copy-id` command to copy the key to the remote server. Type in the following command, replacing `titan.pub` with the name of your public key and `kavi@titan.bme.columbia.edu` with your login information:

```bash
$ ssh-copy-id -i titan.pub kavi@titan.bme.columbia.edu
```

It will give the following prompt:

```bash
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "titan.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
kavi@titan.bme.columbia.edu's password:
```

> Note: if you used the default key name, you can omit the `-i titan.pub` part. The `-i` flag specifies an **identity file**, something we'll also see later.

Enter your password, and the following will appear:

```bash
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "titan.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
kavi@titan.bme.columbia.edu's password:

Number of key(s) added:        1

Now try logging into the machine, with:   "ssh 'kavi@titan.bme.columbia.edu'"
and check to make sure that only the key(s) you wanted were added.
```

## Logging in

Now, to login to the server, you can type in your ssh command as before:

```bash
$ ssh kavi@titan.bme.columbia.edu -i titan
```

Notice the key difference: the identity file, specified with the `-i` flag. Replace `titan` with the name of your _private_ key. If you used the default key name, then you do not need to specify an identity file. You should now be able to login to your remote server without entering your password.

{{<admonition type="tip">}}

For convenience, you may find it helpful to [set up an alias](https://www.cyberciti.biz/faq/create-permanent-bash-alias-linux-unix/).

My preferred shell is `fish`, so I like to set up an [abbreviation](https://fishshell.com/docs/current/cmds/abbr.html), like so:

```fish
$ abbr --add kavi ssh kavi@titan.bme.columbia.edu -i ~/.ssh/titan
```

That way, I can just type in

```fish
$ kavi
```

and it will automatically expand to the full command. If you're setting up an alias in `bash` or `zsh`, it's the same idea: alias `kavi` (or whatever you want to call it) to the full command.

{{</admonition>}}

## VSCode Integration

**Note:** This part is optional, especially for those who primarily use a terminal to use `ssh`.

I love VSCode, especially its Remote - SSH extension, as it makes it a lot easier to develop remotely. Fortunately, it's very easy to get the SSH keys to play nice with VSCode. Make sure you have the extension installed, and then click the green button in the bottom-left corner:

![vscode-remote-ssh](vscode-remote-ssh.png)

Then, choose "Open SSH Configuration File". Click on "Settings". In the box to enter a path, enter `~/.ssh/config`.

Next, click on the green button and choose "Open SSH Configuration File" again. Click on the `~/.ssh/config` option that appears in the dropdown (if it doesn't, you should be able to enter that into the box).

Add the following into the end of your file:

```
Host titan.bme.columbia.edu
  HostName titan.bme.columbia.edu
  User kavi
  IdentityFile ~/.ssh/titan
```

Replace `titan.bme.columbia.edu` with your host name and replace `kavi` with your username.

> Note: if you've logged in with these credentials before, then the `HostName` and `User` parts may already be present. In that case, append the `IdentityFile` line.

Finally, in the `IdentityFile` field, include the location of your private key (replacing titan with the name of your own file, such as `id_rsa`).

