Easy Setup of SSH Keys on Ubuntu + Github
Setup up Github remote repositories on your local repositories to clone, pull and push from your Ubuntu OS to Github's remote servers
Contents
Introduction
Background - Git, Github, HTTPS, SSH
Tutorial - Link Local Repositories to Github with SSH
Introduction
This is a tutorial on how to set up your SSH public-private key pair between your Unix-based computer (macOS or Linux) and Github. Once we’ve set up the private-public key pair “link”, we’ll be able to simply do Git actions without any authentication. This means we’ll be able to clone pull changes from a remote Github repository and push changes up as well. This tutorial will touch a little into what SSH is, terminology like SSH client, server and keygen, and show you step by step how to make this link ready.
Background - Git, Github and SSH
Git is not Github - Github is a company with multiple projects and Git is an open-source project, part of the Linux kernel, and primarily a CLI tool. SSH is a protocol that specifies how to connect to a remote server - in this case, it is how Git sends and receives cloud repository changes from/to Github.
What is Git?
Git is a version control management system
The purpose of Git is to manage changes in a distributed and historical manner so you and many other developers can work in parallel on software projects
Git handles all the historical tracking, as well as merging changes from multiple people and creating individual working blocks (known as branches)
One of Git’s core features is linking a local repository to a remote repository - this allows you to push and pull changes from/to that remote repository - Git doesn’t care where that remote server is and it simply sees it as a server that it needs to communicate with - which is does over HTTPS or SSH protocol
What is Github?
Github is a company whose main product is the hosting and management of Git repositories in a centralized remote (cloud) server that acts as the “source of truth” for all the local repositories on the computers of the developers working on a specific Git repository
As mentioned above, to connect a local repository to a Github repository just means to allow a local repository to pull changes down and push changes back up
Pulling and Pushing
The act of cloning a repository and pulling a repository is very similar and we’ll look at it as one
When you clone or pull a repository, you are invoking Git’s internal program that downloads a cloud repository, specified in location by an HTTPS URL or SSH URI (path). After it successfully downloads the project, it merges it in with your local changes.
In reality, it is NOT downloading the source code that you’ve written and see - what actually does is download a .git directory which has the entire history of your project and every version of every file/directory you’ve created throughout its entire lifetime
When you push changes, the exact same thing occurs but in the opposite direction - you specify where you want to write/push to by a cloud repository HTTPS URL or SSH URI (path), and Git handles everything else
How Git Works: Explained in 4 Minutes
HTTPS and SSH
HTTPS and SSH are two protocols that securely communicate with cloud (remote) servers
HTTPS uses SSL/TLS to encrypt data sent/received between a client and server
It relies primarily on a username/email and password that both client-server have for authentication
Managing credentials became a huge hassle and security risk, which is why Github eventually stopped supporting this method for private repositories
This means that you can pull from public repositories with HTTPS, but you cannot pull or push from private repositories, since Github no longer supports the email/password method
SSH uses cryptographic keys for authentication to send/receive data securely (encrypted)
A private-public key pair must be established between a server-client
The private key is stored on your local machine
The public key is stored on Github
The difference between SSL( HTTPS) protocol and SSH protocol? Medium
Cryptographic Key Pairs
An example of private key and public key files can be seen below
You generate a private/public key pair together with a CLI command and it outputs two files
A private key file
A public key file
When you generate the files, you also get the possibility of encrypting the private key by providing a password/passphrase - which means that even with the files on your computer, you cannot view the private key file’s contents without decrypting the file through the passphrase you provided at creation
What is Public and Private Key in Cryptography?
# PRIVATE KEY - Never Share
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA7Vs5h5/jh62m5tM2Jxz2N/f5vb2EjY9MkZ8/UFeMQBl5VwEx
...
o5u9X7uZFS5KXcIHjTWg+wV77LX8GsqI5RhMAb7+ySnq+1bYl6I9+T0p/D8=
-----END RSA PRIVATE KEY-----
# PUBLIC KEY - Share with Others
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDkq5PbnP6e0weRfNb6FkikcQ7/tW3djPM+FPO8v5+R
...
zJgIhHHoTzQm8G6YrJCrGe8blX6AgwZPiD8r/m9t3eB user@hostname
How Keys Work with Git and Github
Unix-based systems like Linux and macOS have an SSH tool called SSH Agent
The SSH agent is a program that manages your SSH keys and their passphrases
It runs in the background handles all the authentication tasks for you, so you don't have to repeatedly enter your passphrase for each new SSH connection
Example - Typical SSH Connection (without SSH Agent)
Normally an SSH connection works as follows:
Key Pair Generation
A key pair is generated with a tool like ssh-keygen
The private key is kept secure and stored on the client machine (~/.ssh/id_rsa)
The public key is copied to the remote server's ~/.ssh/authorized_keys file
Initiating the SSH Connection
When attempt to connect to a remote server using the ssh command
The client sends an initiation request, requesting a public key to authenticate
Server Challenges the Client
The server looks for the public key in its authorized_keys file
If it finds a matching public key, the server sends a challenge back to the client
This challenge is usually a random number or string encrypted with the public key
Client Responds to the Challenge
The client uses its private key to decrypt the challenge
The decrypted response is sent back to the server
Server Verifies the Response
The server checks if the decrypted response matches the original challenge
If it matches, the server confirms that the client possesses the private key corresponding to the public key and grants access
All these multiple requests and steps are abstracted away into a simple SSH command:
-i specifies the private key file path
You will be prompted for the passphrase to decrypt the private key
In a direct SSH connection command, it will ask you to re-enter the passphrase with each action
$ ssh -i ~/.ssh/id_rsa user@remote_host
$ Enter passphrase for key '/home/user/.ssh/id_rsa':
Testing usage notes for ssh-remote-agent
Example - Typical SSH Connection (with SSH Agent)
The SSH agent stores your private key (decrypted) in memory to avoid the passphrase each time
It remains in memory for the duration of the user session or until the cache time expires
Starting the SSH Agent
You usually start the SSH agent manually with a command like eval "$(ssh-agent -s)"
Alternatively, it can be started automatically when you log into your system
Adding Keys:
You add your private keys to the agent using the ssh-add command
Key Management:
The agent keeps track of all added keys
The agent provides them to the SSH client upon request
# Start up the ssh-agent (background process) if not already active
$ eval "$(ssh-agent -s)"
# Add your private key (decrypted) to the SSH Agent memory and enter passphrase once to decrypt it
$ ssh-add ~/.ssh/id_rsa
Enter passphrase for /home/user/.ssh/id_rsa:
# Standard Connection Syntax: $ ssh user@remote_host
Differences
Without SSH Agent
Manually specify the private key file, with -i
Enter the passphrase each time you start an SSH connection
With SSH Agent
You add the key to the agent once
You don’t specify the file or enter the passphrase each time
The agent securely stores the decrypted private key in memory
The agent provides the key to the SSH client when needed
Purpose of the SSH Agent
Convenience
Enter your passphrase once
Use your key multiple times without re-entering it
Security
The passphrase-protected key is stored in memory
Reduces the risk of it being exposed on disk
Flexibility
Manage multiple keys easily
Use keys across different connections and systems
Example Workflow
Step 1 - Start the SSH Agent as a Background Process
$ eval "$(ssh-agent -s)"
# -s specifies that the agent should output commands suitable for the shell to setup the environment variables
# Outputs typically the SSH_AGENT_PID and SSH_AUTH_SOCK
# SSH_AUTH_SOCK=/tmp/ssh-XXXXXX/agent.1234; export SSH_AUTH_SOCK;
# SSH_AGENT_PID=1234; export SSH_AGENT_PID;
# echo Agent pid 1234;
Step 2 - Generate a Public-Private Key Pair
Enter the Github email address
$ ssh-keygen -t ed25519 -C “email@domain.com”
Step 3 - Add Your Private Key to the SSH Agent (Once) for All Future Requests
$ ssh-add ~/.ssh/id_rsa
Done!
What Does This Do?
Once that’s set, the SSH command will not require entering the passphrase each time for the connections
Git uses the ssh command internally when you do a clone/push/pull/fetch action
Given that the private key is already in memory, the connection is made without any other intervention
However, as you’ve noticed from the steps above, it required that the remote server store the public key on the server to establish an SSH connection - and this is where we’ll jump into the Github tutorial below, since we will have to (1) generate a key pair if we don’t have an existing one, (2) add the private key to the SSH agent, and (3) store the public key inside Github
Tutorial - Create and Link Local + Github Key Pair
Steps
Look for Existing Key Pairs
Generate a Public-Private Key Pair (Optional)
Add the Private Key to the SSH Agent
Add the Public Key to Your Github Account
Step 0 - Start SSH Agent
Start Once
Start the ssh-agent in the background (once)
$ eval “$( ssh-agent -s )”
# Agent pid --
Start Always
Start ssh-agent in the background (always)
Note that keys are only loaded and stored for the duration of a session
To add keys permanently, you can configure your bash-profile user script to supply them on every session
Either in .bashrc | .bash_profile | .zshrc
$ nano ~/.bashrc
Add the following inside the file
# Start ssh-agent
$ eval "$(ssh-agent -s)"
# Add SSH key to the agent
$ ssh-add ~/.ssh/id_rsa
Reload the shell configuration
$ source ~/.bashrc
Step 1 - Look for Existing Key Pairs
Search inside SSH Agent
Before generating a new SSH key, you should check if your local machine has existing keys
$ ssh-add -l
# $ This agent has no identities.
# This means that no keys were found in the SSH Agent
# You may have a key pair on your computer, but it is not loaded into ssh-agent
Search on Local Computer
Lists all the key pairs that you have in your user .ssh/ subdirectory
$ ls -al ~/.ssh
Look inside the .ssh/ subdirectory for any of the following:
$ id_rsa.pub
$ id_ecdsa.pub
$ id_ed25519.pub
Step 2 - Generate a Public-Private Key Pair (Optional)
Generate a Key
This creates a new SSH key, private-public key pair
It will prompt you to store it in a default location (home, ~/.ssh/algorithm)
Enter passphrase (optional but recommended, to encrypt your private key)
$ ssh-keygen -t ed25519 -C “email@domain.com”
Step 3 - Add the Private Key to the SSH Agent
Add your SSH private key to the ssh-agent
$ ssh-add ~/.ssh/private_key_id
Add the SSH public key to your Github account
Step 4 - Add the Public Key to Your Github Account
Steps
Select Settings
Select SSH and GPG Keys Settings
Click New SSH Key
Add a Title for Your Own Reference (Nickname)
Select Authentication Key
Add Public Key
Click Add SSH Key
$ git clone git@github.com:eduardocgarza/app-job-boards-scraper-server.git