SSH

From Dev Wiki
Revision as of 05:07, 31 March 2023 by Brodriguez (talk | contribs) (Add note)
Jump to navigation Jump to search

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

Note: Note that there will never be a universally "best" key type, per say, as new key types are being discovered with time. Furthermore, computers are always improving, so keys that "are very secure" right now may not be so in 10 years.

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: In the below examples, we use a github_rsa key and a bitbucket_ed2 key, respectively.


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.
  • 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:

  • Note that this requires enabling at least one user that can log in with a standard password. AWS EC2, for example, does not create such a user by default.
  • 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


SSH not Prompting for Password

https://askubuntu.com/a/419562