SSH, you must’ve heard the acronym SSH. But what is it, and why to bother about it? Let’s find that out.
SSH is short for Secure SHell. It’s a secure alternative to Telnet that’s a remote login client. That is, it allows you to login to a remote server and execute commands, actually various commands. Depending on the port you are able to access telnet offers various functionality. Like if you are able to access port 25, you can send emails using it! . But all that telnet had a serious security issue. It transmitted all the data in plain text. Which means, the content of whatever you do on telnet are sent through the connection as is, without any encryption. So, a person who can access the network packets can easily see all the data being transmitted, even usernames and passwords if transmitted. See this page for an example.
Here comes SSH, it is a secure alternative to telnet, it’s a secure remote login client that encrypts the traffic. So even if the network packets are captured, the data is useless, since one cannot decrypt the data, since it requires the shared key between client and the server.
Understanding the working
Generating Session Key
SSH uses symmetrical encryption for encrypting traffic. That is, it uses same key for encryption and decryption. So, client encrypts using the secret key and server de-crypts the message using the same key. But, how they have the same key? You might think that sending the key over the connection would make all this useless, since it’s all about security of the connection! Yups, you are right! The key ain’t sent over the connection but it’s generated on both sides via some shared parts. Let’s see how it’s generated.
They use Diffie-Hellman algorithm to generate the secret key on both Client and Server side. It’s interesting and yet simple!
Let’s see the steps:
- Client and Server first agree on a large prime number (Probably, to avoid the brute force decryption)
- Both then decide an algorithm to help generate our public and private key using the data we are creating. It’s typically AES. The way to decide the algorithm is:
The first option from the list of algorithms available to client that is also available to server is used.
- Now both generate another prime number that they don’t tell to each other. Till now, this is the only part which is kept secret from the other side. It can be said of as a private key.
- Each side now has 3 parts: the first number they mutually agreed, the algorithm they decided and the number they kept secret. Combining all these three, a sort of public key is generated (It’s different from the normal public and private key, as the public key mostly doesn’t contain the private key)
- This public key is transmitted to the other party. It can be over an insecure network, because even if it’s captured by an attacker, reversing encryption to get the useful data is an expensive process.
(Each side now has 4 parts: first number, algorithm, secret number, and public key.)
- Now, both mix there secret number with this public key to obtain a final key.
- This key obtained now is *SAME* though it was generated *almost* independently.
And this is now used as the *Session Key*!
All the data is encrypted and decrypted using this session key.
The point you might wonder now, is, if both computed individually, then how they landed to the same Session key!
Well, this time, it’s simple!
Notice the breakdown of these components:
- Large prime number: Shared by both. So currently both parties have equal information.
- Algorithm: Shared by both. Both parties are still equal.
- Secret Number: Kept secret by both. Now both parties have 1 extra detail.
- Public Key: Transmitted to opposite party.
Client’s Public Key: Large prime + Server’s secret number
Server’s Public Key: Large prime + Client’s Secret number
- Session key: Generated by public key + secret number.
Client’s Session Key: Large prime + Server’s secret number + Client’s Secret number
Server’s Session Key: Large prime + Client’s Secret number + Server’s secret number
Probably now it’s visible that Server and client, both session key turns out to be same!
The session’s secure. One task accomplished. But SSH is not only about the secure transmission of traffic but also authenticating the client and server to each other.
Let’s see the steps of authentication:
- When a client wants to connect to a server it informs the server about creating the connection and using which public key the client wants to authorize.
- Server searches for the public key in its
~/.ssh/folder, in a file name
authorized_keys. (In this file each line contains a new public key of trusted or authorized users)
- Now, server generates a random string and encrypts it using the public key.
Here, remember that a data encrypted using a public key can only be decrypted using the private key part of the key pair.
- Server sends this encrypted data to client, and if client is in possession of private key then he/she should be able to decrypt the data and prove that he is indeed the user that he wishes to login as.
This all is Challenge-response authetication where server gives a challenge to a client and client has to response accordingly.
- Client now has to decrypt the data sent by server using his private key. The, client then combines this decrypted string with the Session key or Session ID that we just generated.
- Client then creates an MD5 hash of this information and sends it to server.
(Hashes are meant to be irreversible, that is, it’s very hard or expensive to get back the information from hashes. Mostly it’s impossible since hashes are kind of summary of the information, and they are always unique for unique information.)
- Server also computes the hash using the session ID and the random string it generated.
- Server then compares the hash it generated to the hash sent by Client. If both turn out to be same, then it means that client has the private key.
Now, let’s generate an SSH key pair and try some things out.
Generating an SSH key pair
Now, as you know that SSH works with a public and private keys, both work together in SSH and hence it’s said a key pair always.
Let’s get started with generating it.
ssh-keygen -t rsa -b 4096 -C "email@example.com"
Here ssh-keygen is the command that generates the key pair and
- -t : specifies the type of key to be generated we are generating (We use RSA in example, though there are other options like dsa, ed25519 that you may use after reading about them a little)
- -b : specifies the number of bits to be used in the key
- -C : is for comment. Generally, it’s a good idea to add a comment so that if you have multiple keys, you can identify different ones
- You can remove or change that part, it doesn’t effect your key.
Now, you’ll be prompted for a location for keys. You can use the default one.
Next, enter a passphrase. I suggest to enter one, rather than leaving it empty. Because if your private key file is leaked accidentally or due to an attack. Without the passphrase it can be used be anybody who has the file. But if you have passphrase for a key, then only the person in possession of passphrase AND the private key file will be able to use it. You can optionally add your keys to ssh-agent which saves you from entering the passphrase again and again during a login session. After adding your key to it, the agent stays for the length of the login session.
You are ready with your SSH key pair now. If you chose default location then your keys would be in ~/.ssh/ folder. Here, id_rsa is your private key and id_rsa.pub is your public key. Make sure that you NEVER EVER share your private key. Though public keys are meant to be shared.
SSH and GitHub
Best part about SSH that you can use without going into much deep about SSH is that you can use it with your GitHub account to push and pull without getting in the hassle of entering the username and password again and again!
For it you must have an SSH key pair. (That we just generated in previous step)
Integrating SSH and GitHub is very easy.
Copy the content of id_rsa.pub file that we just created.
Now go over to your GitHub profile (by clicking your profile photo and clicking on settings)
Click SSH and GPG keys option
There click the New SSH key option and type a title for the key, like from what place do you use this key.
Paste the key in ‘key-field’ and press Add SSH key to save it.
You can view your or anybody’s public keys by appending. keys after there github url like mine is https://www.github.com/storymode7.keys
Now, to push and pull using SSH you must clone a repo using the ssh url given example for cpython repo it’s firstname.lastname@example.org:python/cpython.git
It’s usually of the form email@example.com:username/repository.git
Or if you cloned using HTTPS URL then you can remove the previous remote and add the SSH ones.
Typing passphrase repeatedly?
Even though you have configured the SSH to avoid typing the password. You still need to type in the passphrase (That you set on you private key) everytime you require the private key. Well, you can easily (and safely) avoid this.
For this purpose you need to add the SSH keys to the ssh-agent that manages your private key as in the given terminal session.
Starting the SSH agent (If it’s not already started)
Read about eval command earlier?
It’s a very interesting shell builtin command that performs the command specified to it in it’s arguments. If you type ssh-agent in your terminal and press enter. It’ll show you some variables that need to be set. But to set them, either you type in each variable and required path in terminal or you execute the output of ssh-agent command itself!
Now you need to add the keys to the ssh-agent. Type
It’ll ask you for the passphrase and then this adds your private key file to the agent.
If you have only one private key, then it’s fine. Else you can specify which key to add by giving ssh-add the path of the private key as an argument.
Connecting to servers
Well, SSH has many uses. One main use turns out to be sending remote commands to server. That is, managing the server (mostly remotely). So let’s start with how to connect to servers and do some basic things like executing commands remotely.
Remember how SSH works? It uses public and private keys. But if you want to connect using SSH without the password the server must have your private key. The server must know who is trying to login so that it can authenticate. Though it’s entirely possible to follow the password based approach. Entering passwords repeatedly. But it’s not recommended. Since, neither it’s safe nor easy. Wrong to say outdated or the worst method. Yes, even though this whole blog is about SSH and in heart of it lies key based authentication. There are still cons to it. The following is a really convincing answer regarding password based authentication. As a crux, it claims the loss of private key and getting into wrong hands as the main disadvantage. Whereas password can be changed easily if leaked. But this can be a completely another topic, let’s keep it for some other day.
Acquainting yourself to the server
For key based authentication (and non-repeated-passphrase-asking if you set up ssh-agent), this plainly means the server should be aware of your public key. Let’s copy our public key to the server now. The simple command is:
This will ask you for your password, for the user you are logging in as.
Though this is one of the simplest methods, there are many ways to do it. You can copy the public key file’s content to
~/.ssh/authorized_keys file. And for that there are numerous ways. You can pipe different commands and use the syntax for executing a single command using SSH (we’ll be discussing it shortly).
Opening an SSH session
To open a session, the syntax is quite simple.
To use a specific port for loggin in:
ssh -p port_number username@hostname
Exititing the session
To exit the session you can type ctrl + d
Or you can type exit followed by enter.
But if your session hangs up you can’t do any of the above then you need to escape what you type. Since, in an SSH session the keys you press are forwarded over the connection. Then you can follow these:
Press enter followed by
~. This, according to the man page of ssh is the escape sequence to disconnect.
Saving some configurations
To save some of the ways of how you connect. You might want to create an entry for that in the
~/.ssh/config file. It really eases the process by alloting an alias and configurations for specific hosts.
Firstly, create the config file in
.ssh folder of your home directory.
Then, let’s see basic syntax of configuration file :
(Well, actually that’s the minimal configuration. It just creates an alias.)
It’s easier to relate while seeing commands, so here they are
command before setting
after the configuration file it’s equivalent to
You can also specify settings for every connection you do, using wildcards ,so for every connection to specify some configuration we can go like:
This will apply the configuration to all hosts. Important thing here is that the file is read top to down. So, if you want particular aliases to have different configuration, you can list them after this command, so that there setting will be changed. And do not forget the indentation.
Infact this config file is so useful, it has it’s own man page! You can access it by typing
There are many options for the ssh config file. We’ll be discussing them pretty soon.
Checking your github and keys settings
You can check them by trying to clone, push or pull (for an ssh remote url) but github also has another way to check it.
ssh -T firstname.lastname@example.org
This will display a message like:
Hi storymode7! You've successfully authenticated, but GitHub does not provide shell access.
The -T is disables the pseudo terminal allocation. And you can execute the command without it, but it’ll result in an error of failing PTY (short for pseudo terminal) allocation request. Also, you have to mention the user as git otherwise it’ll result in an error of permission denied.
I have not had access to an ssh server to try some things, but as soon as I get access to one, I’ll be updating the blog with any necessary changes!
Till then, shhh!