SSH
SSH stands for "Secure Shell". It's used to securely connect to remote machines.
Most common uses are to securely access repositories in sites like Github, GitLab, or Bitbucket. Or to gain access to a remote machine's terminal (such as if you're the admin of said machine).
SSH authentication can be done through either a standard "username + password" combination, or through SSH Keys. Note that SSH Keys are generally considered more secure, as it's a physical code that the user needs access to.
SSH Keys
What are SSH Keys
At their core, SSH keys are based of "difficult to solve" mathematical problems. Generally speaking, these problems have "two part" solutions, where the PublicKey and PrivateKey each represent a part of said solution.
The PublicKey is intended to be shared publicly, such as stored on GitHub for future authentication attempts. The PrivateKey is meant to be stored locally on your machine, and should always be kept secret.
Essentially, when you try to authenticate, these two keys can be used together create a valid solution to the mathematical problem, with minimal computational cost. Meanwhile, because the difficulty of the problem they represent, finding the solution is actually very computationally costly without both keys. Usually, this comes down to simply guessing an unfathomably large number of possible pairs for the "correct" solution.
Types of SSH Keys
There are multiple SSH Key types, where each key type represents a different mathematical problem.
As of writing this (in year 2020), there appear to be four main types of SSH keys:
- RSA - Based off the "difficulty of factoring very large numbers".
- Recommend a minimum strength of 2048 bits. 4096 is preferred for systems that support it.
- One of the oldest key types, so virtually all devices support it at this point.
- DSA - Based off the "Discrete Logarithm" problem.
- Considered essentially equal to RSA as far as security.
- Faster than RSA in some respects, while slower in others.
- ECDSA - A specific version of the DSA problem, called the "Elliptic Curve Discrete Logarithm" problem.
- Keys for this can be much smaller than RSA, while still providing as much security as RSA does.
- ED25519 - Yet another improvement of ECDSA, using the "Twisted Edwards Curve".
- Once again, can use smaller key sizes while being as secure as RSA.
- Has the added benefit of being very fast to verify if you have both keys.
- Generally newer than other key types, so not all devices/systems support it yet (even if most do by this point).
Generally speaking as of writing this, it seems ED25519 is the preferred type, with RSA as a fallback for systems that don't yet support ED25519.
Generating SSH Keys
As stated above, it's currently best to try an ED25519 key first. If it's not supported by your system yet, then fallback to RSA of at least 2048 bits.
Creating an ED25519 Key:
ssh-keygen -t ed25519 -C "<your_email>"
Creating a RSA Key:
ssh-keygen -o -t rsa -b <bit_length> -C "<your_email>"
- <bit_length> - Specifies a key bit length of either 2048, 3072, or 4096. Generally higher is better.
Either of the above commands will start the process to create a new key pair.
- Hit enter to use the default path. Alternatively, retype the path and change the
id_rsa
to a filename of your choice.- If you change the filename, make it something useful and descriptive.
- For example, if making a RSA key for GitHub, it might be good to change the name to something like
github_rsa
. - This allows you to have multiple keys, where each key corresponds to a different service or use case.
Connecting Via SSH
Connecting via SSH can be as simple as a single command, at least if authenticating via username + password:
ssh <username>@<server_name_or_ip>
If connecting via an SSH Key, then you probably want to Use a Config file.
Once the config file is set up, then you can connect with:
ssh <config_Host_value>
SSH Config Files
It's possible to create config files for SSH connections. This is particularly recommended when regularly connecting to different servers/repositories on a single machine.
Config file should be located at ~/.ssh/config
.
Syntax is (generally) as follows:
Host <corresponding_value> HostName <corresponding_value> <ssh_option> <corresponding_value>
Comments can also be added with #
.
Possible options are as follows:
- Host - Required. Can be any arbitrary value. This is what is typed locally to call this specific SSH configuration.
- Generally, this is either the same as HostName or an abbreviation of such.
- HostName - Required. This is the actual address to connect to.
- Ex: An IP address if connecting to a production server. Or "github.com" if connecting to GitHub. Etc.
- Port - Required if port is not 22. Self explanatory.
- User - The username to try to authenticate with, on the server itself.
- If not provided, then attempts to use the name of the local user invoking the ssh call.
- PreferredAuthentications - Specifies the order which the client should attempt to authenticate with. Most common options are publickey or password.
- IdentityFile - If applicable, the file to attempt to authenticate through.
- Ex: If connecting to Hybels production servers, then the AWS .pub key. Or if connecting to BitBucket, then the rsa/ed2 key (generated via steps at Generating SSH Keys).
Config File Example
Shows a good example of how a full config may generally look.
# GitHub repo connection. Host github User git Hostname github.com Port 22 PreferredAuthentications publickey IdentityFile /home/my_user/.ssh/github_rsa # BitBucket repo connection. Host bitbucket User my_user Hostname bitbucket.org Port 22 PreferredAuthentications publickey IdentityFile /home/my_user/.ssh/bitbucket_ed2
Passing Your PubKey to the Remote Service
Essentially, this allows secure connections via your credentials, without having to enter your password anymore. It's generally considered more secure, and thus recommended.
Setting Up Keys for Remote Repositories
This allows connect to things like GitHub and Gitlab, and to pull and push repositories of code easier.
The process is generally fairly straightforward:
- First, log into the associated website, and find the page to upload SSH Keys for your user account.
- After Generating a SSH Key, find the newly created PublicKey location.
- On Linux, the default location will be something like
~/.ssh/<key_name>.pub
.
- On Linux, the default location will be something like
- Copy the full contents of the PublicKey file, and paste it into the box on the website.
- Give a meaningful title if provided an option to. Ex:
Home_Desktop_GitHub
. - Save and Test Your SSH Key.
Testing SSH Keys
For remote repositories, they usually have a built in method to test your key once uploaded.
Usually, this is done via terminal, via something like ssh -T git@<website>
.
- Ex: To test a key on GitHub, you would use
ssh -T git@github.com
. - To troubleshoot, you can add the -v, -vv, or -vvv flags, where each one provides a little bit more information.
Setting up Password-less Server Credentials
This allows you to remote into a server (via Terminal) without entering your password every time.
First, you'll need to be able to make SSH connections using passwords. If not already enabled on the server, then enable it with the following:
- Edit the file
/etc/ssh/sshd_config
. - Update the line
PasswordAuthentication
to yes. - Restart the service with
sudo service ssh restart
.
Next, pass your public key to the server with the command:
ssh-copy-id -i <public_key_to_pass> <server_address>
Test that it works by connecting to the server with ssh. It should connect without asking for a password.
Finally, disable ssh connections with passwords to make the server more secure:
- Edit the file
/etc/ssh/sshd_config
. - Update the line
PasswordAuthentication
to no. - Restart the service with
sudo service ssh restart