Chapter 1: SSH Keys — Creation, Configuration, and Git Remotes


SSH key-based authentication replaces passwords with cryptography. You generate a key pair: a private key that never leaves your machine, and a public key you share with servers and services. When you connect, the server challenges you to prove you hold the private key — without ever sending it over the network.


Generating a Key Pair

The current recommended algorithm is Ed25519, which is faster and more secure than the older RSA standard:

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

The -C flag adds a comment (usually your email) to help identify the key. You will be prompted for a file location (press Enter to accept the default) and an optional passphrase (recommended for keys used on shared machines).

If you need to connect to older servers that do not support Ed25519, use RSA with a 4096-bit key instead:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

The ~/.ssh/ Directory

After key generation, your keys live in ~/.ssh/:

File Purpose
id_ed25519 Your private key — never share this
id_ed25519.pub Your public key — share this freely
known_hosts Fingerprints of servers you have connected to
authorized_keys Public keys allowed to log in to this machine
config Per-host connection settings (covered below)

The ~/.ssh/ directory must be readable only by you:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

Adding Your Key to GitHub or GitLab

Print your public key:

cat ~/.ssh/id_ed25519.pub

Copy the output. Then:

Test the connection:

ssh -T git@github.com
# Hi username! You've successfully authenticated...

ssh -T git@gitlab.com
# Welcome to GitLab, @username!

From now on, clone repositories using the SSH URL (git@github.com:user/repo.git) rather than HTTPS. Existing HTTPS remotes can be switched:

git remote set-url origin git@github.com:user/repo.git

Connecting to a Remote Server

To connect to a Linux server:

ssh user@192.168.1.100
ssh user@hostname.example.com

The first time you connect to a host, SSH will display its fingerprint and ask you to verify it. Type yes to add it to ~/.ssh/known_hosts.


Copying Your Public Key to a Server

The ssh-copy-id command appends your public key to the server’s ~/.ssh/authorized_keys file:

ssh-copy-id user@hostname.example.com

You will be asked for the user’s password once. After that, key-based login works without a password.

If ssh-copy-id is unavailable, do it manually:

cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

The ~/.ssh/config File

The config file lets you define host aliases with custom settings, so ssh myserver works instead of ssh -i ~/.ssh/special_key -p 2222 user@192.168.1.100.

Host github
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519

Host myserver
    HostName 192.168.1.100
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_rsa

Host work-*
    User jdoe
    IdentityFile ~/.ssh/work_key

With this config, ssh myserver and git clone github:user/repo work directly.


The SSH Agent

If your private key has a passphrase, you would be prompted every time you use it. The ssh-agent daemon caches the decrypted key in memory for the duration of your session:

# Start the agent (usually already running in a desktop session)
eval "$(ssh-agent -s)"

# Add your key (prompted for passphrase once)
ssh-add ~/.ssh/id_ed25519

# List cached keys
ssh-add -l

On Ubuntu, the GNOME Keyring acts as an SSH agent automatically. On a headless server, you may need to start the agent manually in your .bashrc or .profile.


Transferring Files with scp and rsync

Two tools use SSH to transfer files:

# Copy a file to a remote server
scp localfile.txt user@host:/remote/path/

# Copy a directory recursively
scp -r localdir/ user@host:/remote/path/

# rsync: faster for large or repeated transfers (only sends changes)
rsync -avz localdir/ user@host:/remote/path/

rsync is preferred for large transfers because it resumes interrupted transfers and skips files that have not changed.


Key Takeaways


← Introduction Table of Contents Chapter 2: apt and .deb Packages →