Mastering SSH Keys with the Knowledge of The Keymaker

Starlight Romero
Nerd For Tech
Published in
8 min readJun 11, 2021

--

After a certain amount of time of deploying applications, you have used SSH to tap into the command line of at least a few servers. Perhaps you use a password, maybe you use a key. Then you begin to wonder, should I use one key file for every server or one key for each server? How do I keep track of all the keys securely? Are the keys themselves secure?

The Keymaker from The Matrix

This article serves to answer all those questions and more. After reading, you will have a more complete knowledge of SSH and some best practices.

🔒 The Lock

The Secure Shell (SSH) Protocol is a protocol for secure remote login
and other secure network services over an insecure network [src]

SSH operates on the Application Layer (layer 7). This is the same layer that HTTP, HTTPS, FTP, and DNS function on. Each protocol functions on a specific port, SSH operates on port 22. Port 22 serves as the insecure door. SSH is the locked doorknob that allows only certain authorized users to enter. If you are interested in learning more about the layers of the OSI model check out this video.

SSH came as the much needed, more secure replacement to Telnet, another application layer protocol. Telnet allowed a connection to be established on port 23 using Network Control Program (NCP) and later, Transmission Control Protocol (TCP). When it was created in 1969 it was used to connect to computers on the same Local Area Network (LAN) in universities, large companies, and governments.

Once the rise of the internet came, Telnet’s security vulnerabilities began to show. The biggest shortcomings was that Telnet did not encrypt any data by default. Secrets such as passwords were being transmitted openly and anyone sniffing packets could intercept the secret. Furthermore, there was no authentication to validate the communication between client and the server meaning that any data sent was not guaranteed to reach the intended destination. You can compare this to HTTP vs HTTPS. (It is highly advised to never enter credentials on a website that does not have HTTPS.) In 1995, SSH came just in time and quickly became the de-facto standard.

Now that we know the origin of SSH and the problems it sought to solve, it is time to get our hands dirty.

🔑 Creating Keys

First, we need to create the keyfile using ssh-keygen. This key is the key to our SSH lock. Accessing servers using passwords is insecure and can be brute forced using Kali Linux and Hydra [src][src]. One way to defer this attack is to change the port which SSH operates on. However, this is security by obscurity. It doesn’t actually make the server more secure, it just abstracts information away. This is never a good practice to use so instead we will explore deeper into keys.

Keygen

ssh-keygen can create keys for use by SSH protocol version 2. The keys will, by default, be generated in the ~/.ssh directory. It is a good practice to keep your keys in this folder unless you have a strong reason otherwise. Another default will be the filename. The default name will be id_ followed by the name of the encryption algorithm specified. We can change the default filename with the -f flag. It makes sense for the name of the keyfile to be the name of the application.

This will create two files in the ~/.ssh directory, a private key test_key, and a public key test_key.pub.

This answers the question of one key for everything or one key for each server. It is best to have a separation of responsibility. You (hopefully) wouldn’t use the same password for everything. Don’t use the same key for everything. Perhaps someone gets the key. If you use you one key for many servers, the other person now has access to all of those servers as well. That is a recipe for disaster.

Never share your keys with anyone. It does not take much resources to create a keyfile for each user. This way you are able to see the logs of who accessed the server. Using separate keys also gives you the power to revoke an individual’s key without having to reissue a new key for everyone else.

Encryption Algorithms

We know how to keep the keyfile safe by having our own and not sharing but how about the security of the key itself? There are six algorithms supported by OpenSSH.

  • 🚨 DSA (Digital Signature Algorithm) is a Federal Information Processing Standard for digital signatures. It’s security relies on a discrete logarithmic problem. Compared to RSA, DSA is faster for signature generation but slower for validation. Security can be broken if bad number generators are used. It is no longer supported on OpenSSH since version 7.
  • ⚠️ RSA (Rivest–Shamir–Adleman) is one of the first public-key cryptosystems and is widely used for secure data transmission. It’s security relies on integer factorization, so a secure RNG (Random Number Generator) is never needed. Compared to DSA, RSA is faster for signature validation but slower for generation. It is recommended to have a key size of 3072 or 4096. Anything under 1024 bits is unsafe.
  • 🤔 ECDSA (Elliptical Curve Digital Signature Algorithm) is an Elliptic Curve implementation of DSA (Digital Signature Algorithm). Elliptic Curve cryptography is able to provide relatively the same level of security level as RSA with a smaller key. It also shares the disadvantage of DSA of being sensitive to bad RNGs.
  • Ed25519, is the EdDSA signature scheme, but using SHA-512/256 and Curve25519. It’s a secure elliptical curve that offers better security than DSA, ECDSA, and EdDSA, plus has better performance (not humanly noticeable). It is the most recommended public-key algorithm.
  • The -sk versions of ECDSA and Ed25519 are used for U2F/FIDO devices.

Along with the encryption algorithm, the KDF (Key Derivation Function) is important to creating a strong key. KDF is a cryptographic hash function that derives one or more secret keys from a secret value such as a main key , a password, or a passphrase using a pseudorandom function. A higher number is slower to verify but more resistant to brute force attacks.

Generation

  • -a: Specifies the number of KDF (key derivation function) rounds used.
  • -b: Specifies the number of bits. ED25519 keys have a fixed length and the -b flag will be ignored.
  • -C: Specifies a comment. A good practice is to comment the email of the key creator. If no comment is specified, the default comment will be username@hostname. Where the user is t
  • -f: Specifies the filename of the keyfile.
  • -N: Provides the new passphrase.
  • -o: Save the key using the newer OpenSSH format as opposed to PEM. The new format has increased resistance to brute-force attacks. Ed25519 keys always use the new private key format.
  • -t: Specifies the type of key to create.

We will generate a key with the filename application. It will have a type of ed25519 and it will be hashed 100 times. We are setting a password of password. Lastly, it will have a comment of starlightromero@protonmail.com.

The newly created keys will be in the .ssh directory. The private key, ~/.ssh/application, and the public key, ~/.ssh/application.pub. Be sure to save your password in a secure, libre, offline password manager like KeePassXC.

Permissions

Running the command ls -la ~/.ssh allows us to see the permissions set for all the files in the ~/.ssh directory. The permissions by default should be as follows:

  • 🕵️ Private Key (application): -rw-------
  • 🚻 Public Key (application.pub): -rw-r--r--

In the past, when I ran the Linux subsystem on Windows, the permission did not always get set correctly by default. If this happens to you, first ensure you edit your WSL config file, /etc/wsl.conf, with the following config options:

You’ll then have to restart the Linux subsystem by running wsl --shutdown.

Now back to permissions. Modify the file permissions using the commands below:

The command chmod, “change mode”, allows us to change the permissions, or “modes” of access for the file. Each digit of the three digit number represents a group in the following order:

  • 👨 User
  • 👨‍👩‍👧‍👦 Group
  • 👨‍🦲👨‍🦰👨‍🦱👨‍🦳 Others

. Each permission corresponds to a number:

  • 📖 Read: 4
  • ✏️ Write: 2
  • 👟 Execute: 1

If you do not want the particular group to have the permission, enter a zero in that place. Once you add the numbers up, that is the number for the specific permission group.

We want the private key to have read and write permissions for the user:

The public key should have read and write permissions for the user along with read permissions for the group and other:

Now running ls -la ~/.ssh should show the correct permissions.

🔓 Using SSH

The keys have been generated securely and the correct permissions have been set. Now we can ssh into the server with the following command:

Where the -i flag represents the path to the Identity File (private keyfile), starlight represents the user, and 127.0.0.1 represents the IP address you are trying to ssh into. These values will need to be changes to suit your needs. You will be prompted for a password. After entering the password we are in! Go ahead and logout before proceeding to the next section.

🔐 Managing Keys

Now that we know how to generate keys and use ssh. How can we manage all of our keys for different applications? By creating a config file in our .ssh directory we can create variable references to the server host name along with other specifications. This will make it easier once we start having more than a couple ssh keyfiles on hand.

Open up the file in an editor, vim ~/.ssh/config.

Line 1 allows us to specify the configuration for all hosts. We want to ensure that for all our hosts we add keys to our ssh-agent. AddKeysToAgent allows us to only enter the password once per session instead of every time we use the keyfile. IdentitiesOnly allows us to override the ssh-agents default setting of trying all our private keys if we do not specify a keyfile. If we do not provide a Identify File (keyfile) and the server has one set, then it would be better if the command failed rather than all our keys being tried and potentially receiving a Too many authentications failures error. Port is simple enough. It allows us to set the default ssh port for all our hosts. We will set the default port to be 22.

For our server specific configuration we move down to line 6. We start by defining a Host. We then define a HostName which is the IP address of the server. User is the username we want to use to ssh into the specified IP address. Normally, in the command line you would see these two as, ssh user@hostname. Lastly, we want to specify an absolute path to our IdentityFile.

Okay great but what does all this configuration ACTUALLY do? After saving the file run the command ssh application, where application is the Host you specified in config. We enter our password AND we are in! Instead of remembering the keyfile location, username, hostname, etc. we can enter a simple name of our choosing, like application, and get access to our sever.

The Keymaker sitting in his office among thousands of keys. From The Matrix.

Go forward from here with the knowledge of The Keymaker. Create keys for all your server. SSH into all of your servers with secure, encrypted, password-protected, organized keys.

Only the One can open the door. And only during that window can that door be opened.

--

--