SSH is quite an interesting protocol in itself. A lot of people are using it for a secure communication between two machines. This blog post hits behind the scenes that go on, between machines connected via SSH.
You might have an experience of remote login on SSH. But have you ever wondered about how internally these ssh-client and ssh-server respond? And If you want to explore the same? You are on the right page!
Brief about SSH
- SSH or we can say Secure Shell is a cryptographic network protocol that’s used to provide security in communication between two machines over an unsecured network like our Internet.
- SSH uses different authentication and encryption-decryption methods to make our connection secure between two remote machines.
- It is better than other communication protocols like FTP, telnet, etc. The picture below describes how SSH encryption doesn’t let someone sniff in its signals. If someone tries to intercept the signal, s/he would receive nothing but an encrypted data packet. To know more about how SSH better than others visit here.
- For use cases of SSH, you may see this.
How SSH works?
Before we actually get into the protocol, there is something that needs to be discussed.
Symmetric and Asymmetric Encryption:
Symmetric Encryption is that in which only one key (let’s say private key or secret key) is used both for encryption and decryption of the data transferred between client and server.
However, Asymmetric Encryption is that in which both keys (private as well as public key) is used for encryption and decryption.
The server uses client’s public key to encrypt data for it. The client, on the other hand, uses its private key to decrypt the data on the other end that was encrypted by its public key. Similarly, server’s public key is used by the client to encrypt the signal and server’s private key is used by the server to decrypt the signal.
So, which one is used in SSH?
The answer is, SSH uses both symmetric and asymmetric encryption. Since asymmetric encryption is more time consuming, most of the SSH connections use symmetric encryption. The idea behind is that asymmetric encryption is used only to share a secret key (session key) using which, symmetric encryption can be done for further communication.
Now there are 2 versions of SSH that are commonly used. These are SSH version 1 and SSH version 2. The overall architecture in both versions differs a bit, so we’ll discuss the protocol version 1 in detail and then see how does it differ from version 2 protocol.
SSH Protocol Version 1
The SSH connection is always invoked by a client to a server. Therefore, server authentication comes first than client authentication.
STEP 1: Connect to simple FTP connection
For a successful SSH establishment. A simple connection between a client and a server is a must. For the same reason, first of all, a simple (FTP/Telnet) connection is created between the client and the server. And with telnet, we get details like this:
coderunner@geekyshacklebolt:~$ telnet thegeekyway.com 22
Connected to thegeekyway.com.
Escape character is '^]'.
Here one can see that “SSH-2.0“ (in the last line). This is the version of SSH protocol that server is using. We also see the package version of OpenSSH is visible. This is how the client knows which version of SSH the server is using.
Now, it is the sole responsibility of the client to continue with the session if it supports the version shown by the server.
STEP 2: Both server and client, now switch to a packet-based protocol
In this, each packet consists of a 32-bit length field, 1-8 bytes of random padding to foil known-plaintext attacks (KPA), a one-byte packet type code, the packet payload data, and a four-byte integrity check field.
STEP 3: Server provides session parameters to client
As soon as the connection is established, server authentication starts. For this, the server will send some critical data to the client. This data includes:
- 1) Server’s host key: It is an RSA public key, which is stored in “known_hosts” file of the client (if you have already connected before with that server). You may see your known_hosts file here:
coderunner@geekyshacklebolt:~$ cd .ssh/
authorized_keys id_rsa id_rsa.pub known_hosts
At this point, the client will search for this “rsa_public” key in client’s
known_hosts file and if the key is not already present, then it may be the case of connecting with that server for the first time. So, in this case, what you would get is a “WARNING!” like: “Are you sure you want to continue connecting?”
coderunner@geekyshacklebolt:~$ ssh geekyshacklebolt
The authenticity of host 'geekyshacklebolt (192.168.42.222)' can't be established.
ECDSA key fingerprint is SHA256:Ql/KnGlolY9eCGuYK3OX3opnSyJQzsbtM3DW/UZIxms.
Are you sure you want to continue connecting (yes/no)?
If you’re not connecting with the server for the first time but see this warning, then maybe the server’s public key has been changed or you’re trying to access a different machine altogether (may be going in hands of an attacker). Therefore this warning is quite useful.
- 2) Server’s server key: (There is no concept of server key in SSH-2) With host key, server also provide one server key.
This server key goes on changing every hour or so. And this key may be of 768 bits or 1024 bits it depends on the configuration. You may find it at “/etc/ssh/” in “sshd_config” file. Let me see mine.
# Lifetime and size of ephemeral version 1 server key
Yeah, mine is 1024 bits.
- 3) 8 Random Bytes: These random bytes are known as check bytes. It is necessary for the client to send these check bytes in its next reply.
- 4) Authentication methods and list of encryption algorithms supported by server: So, that client may decide which encryption algorithm it supports and which authentication methods the client has to follow. The symmetric encryption algorithm that is used to encrypt and decrypt large amounts of data is known as bulk cipher.
At this point, both sides also compute a common 128-bit session identifier, which is used in some subsequent protocol operations to uniquely identify this SSH session. This is an MD5 hash of the host key, server key, and check bytes taken together.
STEP 4: Session key generation and sending it to server
Now the client has server’s host key, server key, 8 random bytes, authentication methods and encryption algorithms list.
The client creates a symmetric session key for a bulk cipher that both client and server support. This key will be used for the entire session of SSH for both encryption and decryption. For a secure transmission, client double encrypts this key before sending it to server. First encryption is done by “server’s host key” and second encryption is done by “server key”. Encrypting the session key a second time with the server key provides a property called perfect forward secrecy. This double encryption enhances the security to great extent.
After double encrypting the session key, the client sends it to the server, along with the check bytes and a choice of algorithms.
Since it is difficult to have both server’s private key and the server key (which keep changing in a fixed interval duration), it is very difficult to know the key. On the other hand, server has its private key and the “session key” that is shared by both client and server. With this data, the server can decrypt and get the session key for further communication.
STEP 5: Confirmation from the server
After sending the “session key” client just wait for the server to respond. Because only if the server is original and the one whose host key was provided to the client, then only it would be able to decrypt this session key using the server key, and the corresponding private key of server’s host key.
The server receives this session key and decrypts it, to use it for further transmission of signals. This was the end of asymmetric cryptography. Now, when both server and client posses this symmetric key. The complete communication session would be dealing only with this key.
STEP 6: Client Authentication begins
To authenticates a client, the server may use the following methods:
- Host keys based
We’ll explain each part in brief, and ‘host keys based’ in detail, as it is the most secured.
It is as simple as you log into any of your social websites. The server just asks you for your password to establish the SSH connection, and client takes the responsibility to transfer this password to the server. The session gets started as soon as you give your password. This method is not much recommended. Because if you are really security conscious that you are using SSH for remote login, then password-based authentication can be easily attacked. This type of authentication is convenient for the first time SSH users and those who travel a lot and don’t carry their machines.
It is a computer network authentication protocol that works on the basis of tickets to allow nodes communicating over a non-secure network to prove their identity to one another in a secure manner. It is not much used nowadays. OpenSSH provides Kerberos support only when using the SSH-1 protocol.
In this, the server has a list of host keys stored in /etc/ssh_known_host, and additionally, each user has host keys in $HOME/.ssh/known_hosts. SSH uses the naming service to obtain the canonical name of the client host, looks for its public key in its known_host files, and requires the client to prove that it knows the private host key. This prevents IP and routing spoofing attacks (as long as the client machine private host key has not been leaked), but is still vulnerable to DNS (domain name server) attacks (to a limited extent), and relies on the integrity of the client machine as to who is requesting to log in. If maximal security is desired, only RSA authentication (host keys authentication) should be used.
4. Host keys based:
It is the most secure method of authentication for an SSH session. In this, client authentication is based on a pair of host keys i.e: the public key and the private key that can be seen in “~/.ssh/” directory.
coderunner@geekyshacklebolt:~$ cd .ssh/
authorized_keys id_rsa id_rsa.pub known_hosts
Here, id_rsa is your private (secret) key which should be kept a secret (not to be shared with anyone ever) and id_rsa.pub is your public key, which should be present to every server’s (to whom you want to connect to) “authorized_keys” file.
If you don’t have these key pair, you may generate it using the command:
$ ssh-keygen -t rsa -b 1024 -C "email@example.com"
*note: these public and private keys are never used for either encryption or decryption of SSH session. These are only used to authenticate a client.
An RSA public key has 2 parts, the exponent, and the modulus.The modulus is the long number in the public key file.
- The client sends the modulus of its public key as an identifier, encrypted using the session key.
- The server decrypts this identity and starts searching for its corresponding public key in “authorized_keys” file.
- If the authorized public key is not found or is restricted to connect, then this authentication request fails. Otherwise, the process continues.
STEP 7: The Game of Challenge and Response
- Now, server prepares a random 256 bit-string, and encrypt this string using the client’s public key. Then this encrypted string is sent to the client as a challenge. The challenge for the client is to decrypt this random string and prove that it has the corresponding private key.
- The client receives this encrypted string, and decrypts using its private key, and send it back to the server. But, this string should not be transmitted as it is. Therefore, client combines this challenge with session identifier to prepare an MD5 hash. And then sends its response to the server.
- The server receives this response in the form of an MD5 hash. And, the server itself regenerate this, since it is already having the random string and the session identifier. The server compares the 2 hashes with each other, and if both come out to be same, then it means that client had successfully decrypted the string.
The client is now authenticated, and SSH session starts with a terminal allotted to you to start writing commands.
It is the process of comparing the state of currently stored data to the state of previously stored data. This protocol uses a weak integrity check e.i a 32-bit cyclic redundancy check or CRC-32. This sort of check is insufficient for detecting deliberate corruption but effective against accidental changes to data.
SSH Protocol Version 2
There are a lot of places where SSH-1 needed more improvements to make the protocol more secure. Therefore, this version 2 comes into play. It provides some necessary changes in protocol 1 to enhance its security. We will only discuss the changes and won’t repeat the common steps.
SSH-1 consists of multiple functions in a single protocol. However, SSH-2 is build up in modules and consists of multiple protocols which work together like:
- SSH transport layer protocol (SSH-TRANS)
- SSH authentication protocol (SSH-AUTH)
- SSH connection protocol (SSH-CONN)
Let’s see their differences in brief.
SSH-TRANS: This layer of protocol provides initial connection, packet-based protocol, server authentication, basic encryption and integrity check.
SSH-AUTH: This layer of protocol is used by the client over SSH-TRANS to authenticate itself to server. And, it supports 3 authentication methods:
- Public key: It is similar to “host based” of SSH-1. But, it is more general and can accommodate any public-key signature algorithm.
- Hostbased: It is similar to RhostsRSA of SSH-1 by providing cryptographic assurance of client’s host identity.
- Password: It is similar to “Password Based” of SSH-1.
The Key differences between SSH-1 and SSH-2 are as follows.
- Expanded algorithm negotiation
- No server key
- Certificates authorities for public keys
- More flexible authentication
- Stronger integrity checking
- Periodic replacement of session key (“re-keying”)
1. Expanded algorithm negotiation:
In SSH-1, client used to select only one algorithm out of the list of algorithms supported by server, for all category works like, hash function, message authentication, session key exchange, etc. But, SSH-2 provides support for one algorithm per category.
2. No server key:
It was recommended that the session key shouldn’t be developed alone by the client (as done in SSH 1). The idea was, neither the client nor the server should dictate the SSH session by giving a session key that is created only by one side. So, a new method was adopted in which both server and client equally contribute to the development of session key. This method was based on Diffie – Hellman algorithm.
The classic procedure of Diffie – Hellman algorithm to develop a session key is discussed below step-by-step:
- Firstly, both client and server agree on a large prime number, which will serve as a seed value.
- Then, both parties agree on an encryption generator (typically AES), which will be used to manipulate the values in a predefined way. This encryption generator method is the one which will be supported by both server and client.
- Independently, each party comes up with another prime number which is kept secret from the other party. This number is used as the private (secret) key for this interaction (this private key is different than the private SSH key used for authentication).
- The generated private key (the secret to themselves), the encryption generator (common to both), and the shared prime number (common to both) are used to generate a public key, but which can be shared with the other party.
- Both participants then exchange their generated public keys.
- The receiving party uses their own private key, the other party’s public key, and the original shared prime number to compute a shared secret key. Although this is independently computed by each party, using opposite private and public keys, will result in the same shared secret key.
- The shared secret is then used to encrypt all communication that follows. This key is again known as a session key or symmetric key.
3. Certificate authorities for public keys:
In SSH-1, there was no method to verify the ownership of the key. But, in SSH-2 we have a room for this as well. This is another layer of security in SSH-2. In which, the public keys of users are signed by some certificate authorities. The certificate attests and confirms the binding between a public key and a particular identity. The attestation is represented by a digital signature from a trusted third party.
4. More flexible authentication:
In SSH-1, client could authenticate itself to server using any one of the allowed authentication methods. And if it fails, then it means the connection is refused. But in SSH-2, if initial attempts of any authentication method (say public key) are failed, then the protocol may switch to other methods of authentication (say password). That’s why SSH-2 gives more chances to establish a connection.
5. Stronger Integrity checking:
SSH-1 uses CRC-32 integrity check which is really weak and ineffective against deliberate corruption. On the other hand, SSH-2 uses cryptographically strong Message Authentication Code (MAC) algorithms to provide strong integrity and data origin assurance.
6. Periodic replacement of session key (“re-keying”)
The concept was improved with an idea that the session key should not remain same for the complete session as we see in SSH-1. Therefore, in SSH 2, we may have a no. of session keys that keeps on changing with sessions, periodically.
7. Implementation Differences
There are mainly 4 Implementation differences in SSH-1 and SSH-2.
- Host keys: SSH-1 and SSH-2 both manage host keys in different directory structures.
- No fallback to rsh: If a remote host has no SSH server running, then SSH can invoke
rshautomatically, because SSH-1 supports
rsh-style authentication as well. But SSH-2 don’t have this feature, due to poor security of
- Setuid client: In SSH-1, the client needs to be
setuidroot, so that it has access to read for the private host key file, which is usually installed as readable only by the root user. But in SSH-2, the client doesn’t need to be
setuidroot, due to its programs like
- SSH-1 backward compatibility: SSH-2 provide backward compatibility to SSH-1, if and only if SSH-1 package is installed on the same machine. The SSH-2 client and server simply run their SSH-1 counterparts, when they connect to a partner running the older protocol.
We’ll leave the rest for readers to explore on their own. If you’ve any questions, please feel free to ask in the comments section below.