> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/imthenachoman/How-To-Secure-A-Linux-Server/llms.txt
> Use this file to discover all available pages before exploring further.

# SSH Public/Private Keys

> Set up secure key-based authentication for SSH

## Why

Using SSH public/private keys is more secure than using a password. It also makes it easier and faster to connect to your server because you don't have to enter a password.

## How It Works

Public/private keys work by using a pair of keys to verify identity:

1. One key, the **public** key, **can only encrypt data**, not decrypt it
2. The other key, the **private** key, can decrypt the data

For SSH, a public and private key is created on the client. You want to keep both keys secure, especially the private key. Even though the public key is meant to be public, it is wise to make sure neither keys fall in the wrong hands.

When you connect to an SSH server, SSH will look for a public key that matches the client you're connecting from in the file `~/.ssh/authorized_keys` on the server you're connecting to. Notice the file is in the **home folder** of the ID you're trying to connect to.

After the keys have been created and the public key has been appended to `~/.ssh/authorized_keys` on the host, SSH uses the public and private keys to verify identity and then establish a secure connection. Identity is verified by the server encrypting a challenge message with the public key, then sending it to the client. If the client cannot decrypt the challenge message with the private key, the identity can't be verified and a connection will not be established.

They are considered more secure because you need the private key to establish an SSH connection. If you set `PasswordAuthentication no` in `/etc/ssh/sshd_config`, then SSH won't let you connect without the private key.

### Why Ed25519?

We will be using Ed25519 keys which, according to [linux-audit.com](https://linux-audit.com/using-ed25519-openssh-keys-instead-of-dsa-rsa-ecdsa/):

> It is using an elliptic curve signature scheme, which offers better security than ECDSA and DSA. At the same time, it also has good performance.

## Goals

* Ed25519 public/private SSH keys:
  * Private key on your client
  * Public key on your server

<Note>
  You'll need to do this step for every computer and account you'll be connecting to your server from/as.
</Note>

## Steps

<Steps>
  <Step title="Generate the SSH key pair">
    From the computer you're going to use to connect to your server (**the client**, not the server itself), create an Ed25519 key with `ssh-keygen`:

    ```bash theme={null}
    ssh-keygen -t ed25519
    ```

    You'll see output like:

    ```text theme={null}
    Generating public/private ed25519 key pair.
    Enter file in which to save the key (/home/user/.ssh/id_ed25519):
    Created directory '/home/user/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/user/.ssh/id_ed25519.
    Your public key has been saved in /home/user/.ssh/id_ed25519.pub.
    The key fingerprint is:
    SHA256:F44D4dr2zoHqgj0i2iVIHQ32uk/Lx4P+raayEAQjlcs user@client
    The key's randomart image is:
    +--[ED25519 256]--+
    |xxxx  x          |
    |o.o +. .         |
    | o o oo   .      |
    |. E oo . o .     |
    | o o. o S o      |
    |... .. o o       |
    |.+....+ o        |
    |+.=++o.B..       |
    |+..=**=o=.       |
    +----[SHA256]-----+
    ```

    <Info>
      **About Passphrases**: If you set a passphrase, you'll need to enter it every time you connect to your server using this key, unless you're using `ssh-agent`.

      `ssh-agent` is a program that is shipped in many Linux distros (and usually already running) that will allow you to hold your unencrypted private key in memory for a configurable duration. Simply run `ssh-add` and it will prompt you for your passphrase. You will not be prompted for your passphrase again until the configurable duration has passed.
    </Info>
  </Step>

  <Step title="Copy the public key to your server">
    Now you need to **append** the public key `~/.ssh/id_ed25519.pub` from your client to the `~/.ssh/authorized_keys` file on your server.

    Since we're presumable still at home on the LAN, we're probably safe from MIM (Man-in-the-middle) attacks, so we will use `ssh-copy-id` to transfer and append the public key:

    ```bash theme={null}
    ssh-copy-id user@server
    ```

    You'll see output like:

    ```text theme={null}
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub"
    The authenticity of host 'host (192.168.1.96)' can't be established.
    ECDSA key fingerprint is SHA256:QaDQb/X0XyVlogh87sDXE7MR8YIK7ko4wS5hXjRySJE.
    Are you sure you want to continue connecting (yes/no)? yes
    /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
    user@host's password:

    Number of key(s) added: 1

    Now try logging into the machine, with:   "ssh 'user@host'"
    and check to make sure that only the key(s) you wanted were added.
    ```
  </Step>

  <Step title="Test the connection">
    Try connecting to your server with SSH. You should be able to connect without entering a password (or by entering your key passphrase if you set one):

    ```bash theme={null}
    ssh user@server
    ```

    If this works, you've successfully set up SSH key authentication!
  </Step>
</Steps>

<Tip>
  Now would be a good time to perform any tasks specific to your setup, such as:

  * Configuring network settings
  * Configuring mount points in `/etc/fstab`
  * Creating additional user accounts
  * Installing core software packages
</Tip>

## References

* [SSH Public Key Authentication](https://www.ssh.com/ssh/public-key-authentication)
* [Ubuntu SSH Keys Guide](https://help.ubuntu.com/community/SSH/OpenSSH/Keys)
* [Using Ed25519 OpenSSH Keys](https://linux-audit.com/using-ed25519-openssh-keys-instead-of-dsa-rsa-ecdsa/)
* [Understanding SSH Encryption and Connection Process](https://www.digitalocean.com/community/tutorials/understanding-the-ssh-encryption-and-connection-process)
* [Arch Linux SSH Keys Wiki](https://wiki.archlinux.org/index.php/SSH_Keys)
* [ssh-copy-id Documentation](https://www.ssh.com/ssh/copy-id)
* `man ssh-keygen`
* `man ssh-copy-id`
* `man ssh-add`
