Quick introduction to SSH
Tags: ssh, shel, macos, linux
Published: 2022-11-18 20:26:57

_First of all, you might ask yourself, what is SSH?_
Well, in short, SSH stands for **Secure Shell**. It allows you to gain, cryptographically secured, command-line (shell) access on a remote machine.

Remote machine can be your web or build server, or any other machine that can be accessed via SSH.

On **Linux** and **macOS**, command-line SSH client usually comes preinstalled with the system. As such, it can be used directly in the terminal window. For **Windows**, SSH client is not usually installed with the system, but there are plenty of SSH clients that can be installed manually. In this article, focus will be on macOS.

## Password based authentication

Establishing an SSH connection is pretty straightforward. But, before it can be done, you need to know `username` and `hostname`, or `IP` address, of the server.

So basically, you will use the SSH client, on your machine, to connect with the SSH server on the remote machine. Assuming you are on macOS or Linux, you can run the following command to connect via SSH.

```bash
ssh <username>@<hostname>
```

- `username` - server user.
- `hostname` - server host. If not known, IP address can be provided instead.

If you are connecting with the server for the first time, you will be asked to confirm server identity. If you confirm it, the public key of the server will be saved into your local `~/.ssh/known_hosts` file. Next time you try to connect, your `known_hosts` file will be checked and since the server public key is already added there, this step will be skipped.

As a next step, you will be asked for a password to confirm that you are authorized to access the server. If provided password is not correct, connection will be rejected.

As you might have already noticed, every time you want to establish an SSH connection with the remote machine, you will have to enter a password. This approach is good if you don't access the server frequently, but even so, it is still better to use **SSH keys** instead.

If you are currently connected via SSH, go ahead and run following command.

```bash
logout
```

It will terminate the currently running SSH session. Now, let's check out what are those SSH keys.

## SSH keys basics

SSH protocol uses SSH keys as an access credential. This means that, instead of the password that was used before, you can use SSH keys to connect to the server. Other than that, SSH keys are much more robust, longer and complex than any password could ever be. As such, they are a better and more secure method of authentication.

SSH uses a pair of keys, public key and private key. They are generated using [public key cryptographic algorithms](https://en.wikipedia.org/wiki/Public-key_cryptography) and most common of them are [RSA](<https://en.wikipedia.org/wiki/RSA_(cryptosystem)>) and [DSA](https://en.wikipedia.org/wiki/Digital_Signature_Algorithm). These algorithms are based on a mathematical formula that takes 2 very large prime numbers and outputs public and private key.

Public key can be shared freely with others, while private key must be saved securely and only the key owner should know its value.

### Session key

There is one more important key called session key. This key is negotiated by both parties, client and server, during the connection process. Session key is generated using a version of the [Diffie-Hellman](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) algorithm. This algorithm works in a way that both parties contribute equally to the generation of the session key. Because of the nature of the algorithm, the session key represents a shared symmetric key. It means that this key can be used for both encryption and decryption.

### Authentication flow

Before a key-based connection can be established, something called **SSH handshake** is going to happen. SSH cryptographic handshake ensures that both parties, client and server, are authenticated. Below is a sample of communication between client and server during SSH handshake.

![Simplified communication overview during SSH cryptographic handshake](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nng0br8ngtr66s7akbv1.png)

1. Client initializes SSH connection with the server and sends ID of its public key.
2. Server checks `~/.ssh/authorized_keys` file of the user that the client is attempting to log in.  
   If a public key with matching ID is found, the server generates a random number and uses the public key to encrypt the message.  
   Server sends the encrypted message back to the client.
3. Client decrypts the number using its private key.
4. Client combines decrypted number and shared session key to generate [MD5](https://en.wikipedia.org/wiki/MD5) hash value.
5. Client sends this MD5 hash back to the server as an answer to the encrypted number message.
6. Server uses a shared session key and the original number to calculate MD5 hash value.
7. Server compares its calculation with the one that the client has sent.
8. If two values are matched, it proves that the client has the correct private key.  
   Client is authenticated and connection is established.

If the SSH handshake was successful, connection between client and server will be established. This process is secure since it relies on cryptographic authentication to establish connection between client and server.

### Generating SSH keys

_By now, you might ask yourself, how can I generate those SSH keys?_
SSH keys can be generated really quickly using following command.

```bash
ssh-keygen -t rsa -b 4096 -C <email_address> -f <file_name>
```

This command will create SSH keys using your the email address as a label. Optionally, you can pass `-f` flag where you can specify file name for SSH keys.
If `-f` flag is not provided, you will be prompted to provide file name or you can press `enter` to accept default. If you press `enter`, file name `id_rsa` will be used as a default.

Next, you will be asked to enter a passphrase. If a passphrase is provided, it will be required when ever key is used. This can be useful if someone gains access to the machine where private key is stored, since they will not be able to use private key without correct passphrase.

When command finishes running, you shold see following files in your `~/.ssh` directory.

```bash
├── <file_name>
├── <file_name>.pub
└── ...
```

File with the extension `.pub` contains the data about public key and it can be shared with anyone else. The other file, without `.pub` extension, contains the data about private key and it needs to stay secure.

## Enable key-based authentication

To enable key-based authentication with a server, you need to tell the server about your public key. To do so, you need to add your public key to `~/.ssh/authorized_keys` file on the server.

```bash
cat ~/.ssh/<file_name>.pub | pbcopy
```

This command will copy your public key to the clipboard. Now, coppied public key needs to be added into the `~/.ssh/authorized_keys` file on the server. To do so, login to the server using [password authentication](#password-based-authentication).

Once you gain access to the server, run following command.

```bash
pbpaste >> ~/.ssh/authorized_keys
```

It will paste your, previously copied, SSH key and append it at the end of the content in `~/.ssh/authorized_keys` file.

Execute following command to confirm that your public key is saved.

```bash
cat ~/.ssh/authorized_keys
```

You should see content of `authorized_keys` file printed in terminal window. Your public key should be printed as a last item.

Now, execute `logout` command to terminate current SSH session.
Next time you start a new SSH connection with the same server, authentication will be made using SSH keys.

This way of authentication is often used on [CI/CD](https://en.wikipedia.org/wiki/CI/CD) to automate processes and authenticate machines without user interaction.

## Conclusion

Today, SSH and SSH keys are incredibly important and used everywhere. From online services to automatically authenticate each other to your Github account to push the code changes.

You **don't have to be a Secure Shell expert** by any means, but knowing the basics can come a long way. I hope this post has provided you with just that - the basics.

---
This post was first published on [my blog](https://ramomujagic.com/blog/quick-introduction-to-ssh/).