SSH as Simple as Possible

SSH, which stands for Secure Shell, is a network protocol that allows users to operate computers and servers over the Internet. It provides a secure channel over a very unsecured network. SSH uses encryption to ensure that the traffic between two connected devices can not be interpreted.

But first some History Overview

The first version of the protocol - SSH-1, was designed by Tatu Ylönen. The original version of the SSH software used various pieces of free software. The latest versions evolved into increasingly proprietary software. As a result, alternative forks began to gain in popularity. The most popular fork, OSSH, by Swedish programmer Bjoern Groenvall, was chosen as a starting point by some developers from the OpenBSD project. They worked to clean up and improve OSSH to include it in OpenBSD’s 2.6 release in December 1999. It was quickly ported and adopted for all major versions of Linux and is now ubiquitous in the world of POSIX-compliant operating systems.

How does it work: The Overview

SSH uses the server-client model. The connection is initiated and established by the SSH client connecting over the network to an SSH server. The client uses public-key cryptography to verify the server’s identity. After the authentication is successful, the protocol uses symmetric encryption and hashing to ensure the privacy and integrity of the exchanged data.

So we can say that SSH consists of three components:

  • Authentication, which conducts the entire user authentication process and communicates the supported authentication methods.
  • Connection, which manages the channels and communication between the connected machines after successful authentication.
  • Transport, which oversees data encryption, decryption, and integrity of the transport information. As an extra, it provides data compression and caching.

Common uses of SSH

The most common usages of SSH, at least according to my experience, are:

  • Remote Access ensures encrypted, remote connections for users and processes.
  • File transfers through SFTP, which uses SSH user authentication to provide a safe way to transfer and manipulate files over the Internet.
  • Port Forwarding, where a TCP/IP connection that would otherwise be insecure is tunneled through a secure SSH link

SSH Verification and Authentication

SSH server Verification

A running SSH server listens to default port 22 for connections from SSH clients. A client initiates a connection with the server with the command ssh <user>@<host>. The <user> represents the account to connect, and the <host> means the computer to connect to and can be either an IP or a domain name. Upon an SSH client’s request, the server answer with the following unencrypted information: the host key, the server key, a list of protocols that the server supports, and a sequence of eight random bytes.

The client verifies the server’s identity by matching the host’s key with the key in the .ssh/known_hosts file. If the client connects to the server for the first time, the client will verify the server manually, either with the help of ssh-keyscan or by asking the end-user and then will add the key to the known_hosts file. The client needs to verify the server’s identity to mitigate spoofing or man-in-the-middle attacks.

After the server is verified, the client randomly generates a session key, which will send to the server. Both parties use the session key to encrypt and decrypt messages sent between them. Since the communication between the two parties is not secure yet, the client double encrypts the key, first with the host’s public key and then with the server’s key. The server will acknowledge with an encrypted message using the session key it received. And with all that, the secure channel has been established.

SSH client Authentication

Given the secure channel, the next step is for the SSH client to authenticate against the server. The SSH protocol provides six different authentication methods. The most common and the one presented here is the Public Key Authentication, aka SSH keys

SSH keys

SSH keys are a pair of keys, a public, and a private key. This article from Blake Smith is an excellent intuitive explanation of how public/private key (asymmetric cryptography) works:

  • Think of a public key as being the lock. It’s not a key; it’s a padlock you can make many copies of and distribute wherever you want. For example, if you want to put your ‘padlock’ on an ssh account on another machine, you would copy it to ‘authorized_keys’ in the ~/.ssh folder.
  • Think of a private key as the actual key; it is used to open the various padlocks you have distributed to other machines. Just like a regular key, you keep it secret, safe, and out of the wrong hands.

Client Authentication flow

The client sends an authentication request with an ID for the key pair it would like to use. The server checks for the key ID in the authorized_keys file of the account the client is attempting to log into. If there is an entry, the server generates a random 256-bit number, encrypts it with the client’s public key, and sends it back. The client can decrypt the random number with its private key. It will combine it with the shared session key and will calculate the MD5 hash of this value. The client sends the outcome of the previous step back to the server. The server computes the same MD5 hash of the random file and the session ID, and if the numbers match, the client is successfully authenticated.

SSH Software

The OpenSSH suite, which is one of the implementations of the SSH protocol, includes the following commands and daemons:

  • sshd - the SSH server daemon.
  • ssh-keygen - is the tool to inspect and generate the SSH keys
  • ssh-agent - agent to hold private key for single sign-on
  • ssh-add - tool to add a key to the agent
  • ssh-keyscan - is the tool that scans a list of hosts and collects their public keys.
  • ssh - the command used to start the SSH client program.
  • sftp - file transfer client with FTP-like command interface.
  • scp - file transfer client with RCP-like command interface

SSH-keygen

The ssh-keygen is a command/tool for creating new authentication key pairs for SSH. By default, the ssh-keygen will generate keys using the RSA algorithm. The generated keys are stored by default inside the user’s home folder under .ssh. When you generate key pairs, you are asked to provide a passphrase, which is being used for encrypting the key and should be cryptographically strong.

Algorithms and Key size

SSH supports several algorithms for authentication keys. Some of them are:

  • rsa - an algorithm based on the difficulty of factoring large numbers. The recommended key size is at least 2048 bits, while 4096 bits are better. The RSA algorithm may become practically breakable in the foreseeable future.
  • dsa - it is the US government Digital Signature Algorithm. It is based on the difficulty of computing discrete logarithms. The recommended key size is 1025 bits. DSA algorithm is no longer advised.
  • ecdsa - it is the new Digital Signature Algorithm standardized by the US government. It uses elliptic curves and supports only three key sizes: 256, 384, and 521 bits. Most SSH clients now support this algorithm.
  • ed25519 - is the newest algorithm added in OpenSSH. Not all SSH clients support this algorithm.

You can select which algorithm to use with the -t option and the key size with the -b option.

SSH-Agent

The ssh-agent is a helper program that keeps track of users’ identity keys and passphrases. The agent can then use the keys to log into other servers without having the user type in a password or passphrase again. By default, the agent uses SSH keys stored in the .ssh directory. The ssh-add command is used to interact with the ssh-agent; for example, the ssh-add -l will list private keys currently accessible to the agent. The primary operations of the agent are:

  • Add a regular key pair.
  • Add a constrained key pair.
  • Add a key from a smart card.
  • Remove a key
  • List keys stored in the agent
  • Sign a message with a key stored in the agent
  • Lock or unlock the entire agent with a passphrase

The ssh-agent keeps private keys safe because it does NOT write any key material to disk, and it does NOT allow your private keys to be exported.

The ssh-agent creates a UNIX domain socket, which is stored in the environmental variable SSH_AUTH_SOCK, and then listens for connections from /usr/bin/ssh on this socket. It relies on simple UNIX permissions to prevent access to this socket, which means that any keys put into the agent are available to anyone who can connect to this socket. Using the -c when adding a key to the agent will indicate that added identities should be subject to confirmation before being used for authentication.

SFTP File Transfer protocol

SSH File Transfer Protocol is a file transfer protocol, which runs over the SSH protocol. It supports the complete security and authentication functionality of SSH. It has pretty much replaced legacy FTP as a file transfer protocol and is quickly replacing FTP/S. It provides all the functionality offered by these protocols, but more securely and more reliably, with a more straightforward configuration.

SSH and Yubikey

As we have seen so far, SSH is being used to access remote systems securely and uses public-key cryptography to authenticate the user. The user is responsible for keeping the private (SSH) key secure. One way to secure the private keys is by importing them directly on a Yubikey.

Although we will explore more around Yubikey and SSH in subsequent blog posts, the Yubikey supports the below methods for enabling hardware-backed SSH authentication:

  • PIV is a security standard detailed in NIST FIPS 201-2 that creates a framework for multi-factor authentication (MFA) on a smartcard. The yubikey stores and manages RSA and Elliptic Curve (EC) asymmetric keys within its PIV module. This method will work with SSH clients that can communicate with smart cards through the PKCS#11 interface.
  • PGP, The yubikey stores and manages OpenPGP keys within its OpenPGP module. It will work with SSH clients that have integrated with the OpenPGP standard.

Conclusion

This blog post is the result of my attempt to integrate SSH with Yubikey. To understand how to achieve it, I had to revisit some basic knowledge and acquire some new. I hope it becomes helpful to some out there, and stay tuned.