Using SSH to Connect Local Git to Remote Repositories

7 min read

Github, Gitlab, Bitbucket and many more are plaftorms to host Remote Repositories using Git. The two most common ways to connect to a remote repository from local Git are HTTPS and SSH.

Each has their own advantages and disadvantages, but throughout this blog post we will be focusing on SSH since it is the most commonly used method and it offers many benefits compared to HTTPS.

Note: Make sure you have git installed on your local machine. Since this blog post can also be used as a practical guide everytime you want to setup a new SSH connection to a remote repository, or you can jump straight to Generating SSH Keys.

SSH and Git

SSH is a protocol that allows you to securely do a communication between a local machine and a remote host. Git is a distributed version control system designed to track changes in files and directories over time.

Git is basically a collaboration tool that allows you to work on something cleverly and using SSH will help you communicate your changes to other people in a secure way.

Benefits of Using SSH over HTTPS

Security

When using HTTPS to connect to a remote repository, you usually using a password based authentication. The password and data are encrypted, so they’re not easily readable by anyone on the network. However, HTTPS typically relies on a single password that you type in each time, which can be vulnerable if someone manages to intercept your network during entry or if the password is guessed or stolen.

Meanwhile when using SSH you are using a private and public key pair for authentication. which works differently:

Your local machine uses the private key to prove your identity without sending the private key itself over the network. Instead, the server will send a challenge to your local machine that only your private key can solve. The challenge will be newly generated every time we try to make a connection to the remote server. After solving the challenge, the server will then reverify it with your public key on the remote server, and if it matches, you are now authenticated. That said, only the challenge is sent over the network, and it is always changing to make it harder to guess when there is a network interception.

Convenience

Using SSH is more convenient than HTTPS for connecting to a remote server because it eliminates the need to enter your password every time. Instead, you can use an SSH-Agent, which securely stores your passphrase in memory, and it will handle the authentication process for subsequent connections.

Generate SSH Keys

There are several algorithms that can be used to generate SSH keys. In this blog post, we will use Ed25519 (Edwards-curve Digital Signature Algorithm) because it is modern and faster than other algorithms. In your terminal, run:

Check existing SSH keys

Before generating a new SSH key, you should check if you already have one because we dont want to accidentally overwrite an existing key.

### input
ls -al ~/.ssh

Look for id_ed25519 and id_ed25519.pub as this is usually the default file name for default SSH keys generation

### output
total 40
drwx------@  7 username  staff   224 Nov  5 15:45 .
drwxr-x---+ 42 username  staff  1344 Nov  5 19:18 ..
-rw-r--r--@  1 username  staff   185 Sep 11 19:00 config
-rw-------@  1 username  staff   464 Sep 11 18:24 id_ed25519
-rw-r--r--@  1 username  staff   104 Sep 11 18:24 id_ed25519.pub
-rw-------@  1 username  staff  1842 Oct 25 16:47 known_hosts
-rw-------@  1 username  staff  1106 Oct 25 16:43 known_hosts.old

If you see id_ed25519 and id_ed25519.pub then you already have generated SSH keys, which means if you don’t want to overwrite it, we need to specify a different or custom path for next generation. If you want to use your existing SSH keys you can skip creating step and continue to Connecting to a remote repository.

Create a new SSH key

# input
ssh-keygen -t ed25519 -C "your_email@example.com"

-t is the algorithm type, -C (optional) is custom comment.

# output
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/username/.ssh/id_ed25519):

Press enter to accept the default path or provide custom path with the file name.

# output
Enter passphrase (empty for no passphrase):

Passhprase is optional, but i highly recommend entering one to protect the use of your private SSH key. We will be using ssh-agent later so that we don’t have to enter the passphrase every time we want to make a connection.

# output
# dummy data
Your identification has been saved in /Users/username/.ssh/id_ed25519
Your public key has been saved in /Users/username/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:nds92nn/dsNDsadbjndkansdjsknadkj your_email@example.com
The key's randomart image is:
+--[ED25519 256]--+
|             o.**|
|              o**|
|             ++**|
|          .   +=*|
|        S. . +o*o|
|         o..=.o.=|
|          --o+o+o|
|         ..  o=*=|
|             o+E=|
+----[SHA256]-----+

Locate a newly Generated SSH Key

Verify whether the key was generated successfully by running:

For public key:

# input
cat ~/.ssh/id_ed25519.pub

Adjust the path if you are using custom path.

# output
# dummy data
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB8Dkha0+XZ9sjd34fGFkeGZkHZck9TZx7Hnm0Dd9e2j bry@yourhost

For private key:

# input
cat ~/.ssh/id_ed25519

Adjust the path if you are using custom path.

# output
# dummy data
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktZDI1NTE5AAAAIB8Dkha0+XZ9sjd34fGFkeGZkHZck9TZx7Hnm
0Dd9e2j+AAAAAAAAAAAAAAAAAAEAAAAIB8Dkha0+XZ9sjd34fGFkeGZkHZck9TZx7
Hnm0Dd9e2j+AAAAAlkdiJHDU6FOSZDa7yxptjMNxzHxgtid7YKm2GFjdjXaAAAAAE
2jxKVmksl3Dbjoef1H5/tf1sgYnJe+JqfgvUhrBgkgmfhdAAAAAAEAAAXLS1mhdhd
bHJdkfHZ9GFFX3NNMgVdk+KfbkhTgyg==
-----END OPENSSH PRIVATE KEY-----

If everything is done correctly, you should see your public and private key in the output as shown above.

Connect to a Remote Repository

Add Public Key to Remote Repository

We need to put your public key in your remote server, in this case your remote repository platform of your choice. Visit one of these links based on what you are using:

Note: Link provided may become invalid in the future as I don’t have control over any changes the platform might make.

Click New SSH Key or Add SSH Key

Give name to your key

Copy your public key from your local machine:

# input
pbcopy < ~/.ssh/id_ed25519.pub

Adjust the path if you are using custom path.

Paste your public key in the Key field and Save.

Add your Private SSH key to the ssh-agent

First we need to start our ssh-agent running in the background.

Mac:

exec ssh-agent zsh

WSL using bash:

exec ssh-agent bash

Windows (I haven’t tested this):

CMD:

start-ssh-agent

PowerShell:

Start-Service ssh-agent

And then start

ssh-add C:\path\to\your\key

Setting up SSH config file

Check if you have existing ssh config.

cat ~/.ssh/config

Create a new config file if you don’t have one.

touch ~/.ssh/config
open ~/.ssh/config

Update your config file based on your remote host that you are using.

For example:

Host github.com -> for github
  AddKeysToAgent yes
  UseKeychain yes -> mac only
  IdentityFile ~/.ssh/id_ed25519

UseKeychain will save your passphrase in the keychain, which will be used to unlock your private key when you make a connection. This way, you don’t have to re-enter the passphrase every time you start a new session or restart your computer.

Testing SSH connection

# input
# github
ssh -T git@github.com
# gitlab
ssh -T git@gitlab.com
# bitbucket
ssh -T git@bitbucket.org

If everything goes well, you should see the following output:

# output
Hi username! You've successfully authenticated, but GitHub does not provide shell access.

Now you are ready to make a connection, cloning repository, and add changes to your remote repository!