SSH and Keys: Complete Security Guide

THEJORD Team8 min read
securitydevopslinux

Practical guide to SSH and key authentication. Generation, configuration and best practices for secure connections.

SSH and Keys: Complete Security Guide

Understanding SSH Authentication

SSH (Secure Shell) keys provide a more secure and convenient way to authenticate to remote servers and services like GitHub, GitLab, and cloud providers. Instead of typing passwords, SSH keys use cryptographic key pairs to prove your identity.

This guide covers everything you need to know about generating, managing, and securing SSH keys for modern development workflows.

How SSH Key Authentication Works

SSH key authentication uses asymmetric cryptography with a pair of mathematically related keys:

  • Private key: Secret file stored on your computer—never share this
  • Public key: Shareable file placed on servers you want to access

When you connect, the server encrypts a challenge with your public key. Only your private key can decrypt it, proving your identity without transmitting passwords.

Benefits Over Passwords

  • Security: Keys are much harder to brute-force than passwords
  • Convenience: No typing passwords for every connection
  • Automation: Enable secure scripts and CI/CD pipelines
  • Auditability: Track which key accessed what

Generating SSH Keys

Recommended Algorithm: Ed25519

Ed25519 is the modern standard for SSH keys—it's fast, secure, and produces compact keys:

# Generate Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"

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

RSA Alternative

If you need RSA for compatibility with older systems, use at least 4096 bits:

# Generate RSA key (4096 bits)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Key Generation Options

AlgorithmKey SizeSecurity LevelRecommendation
Ed25519256 bits~128-bitBest choice
RSA4096 bits~140-bitLegacy support
ECDSA521 bits~256-bitAvoid (NSA concerns)
DSA1024 bits~80-bitDeprecated

Setting a Passphrase

Always set a strong passphrase to protect your private key:

Enter passphrase (empty for no passphrase): [type your passphrase]
Enter same passphrase again: [confirm passphrase]

A good passphrase is at least 16 characters, memorable to you, and includes mixed characters. Consider using a password manager to generate and store it.

SSH Key File Locations

Default Paths

# Linux/macOS
~/.ssh/id_ed25519        # Private key
~/.ssh/id_ed25519.pub    # Public key

# Windows
C:\Users\YourName\.ssh\id_ed25519
C:\Users\YourName\.ssh\id_ed25519.pub

Correct Permissions

SSH enforces strict file permissions for security:

# Linux/macOS
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config

SSH will refuse to use keys with incorrect permissions.

Adding Your Key to SSH Agent

The SSH agent remembers your passphrase so you don't retype it for every connection:

Linux/macOS

# Start the SSH agent
eval "$(ssh-agent -s)"

# Add your key
ssh-add ~/.ssh/id_ed25519

# Verify loaded keys
ssh-add -l

macOS Keychain Integration

# Add to macOS Keychain (persists after reboot)
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# ~/.ssh/config for automatic loading
Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519

Windows

# Start ssh-agent service (Administrator PowerShell)
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent

# Add key
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Configuring SSH for Multiple Keys

SSH Config File

The ~/.ssh/config file manages multiple keys and hosts:

# Personal GitHub account
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

# Work GitHub account
Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

# Production server
Host prod
    HostName production.example.com
    User deploy
    IdentityFile ~/.ssh/id_ed25519_deploy
    Port 22
    ForwardAgent no

# Jump host (bastion)
Host bastion
    HostName bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_admin

# Internal servers via bastion
Host internal-*
    ProxyJump bastion
    User developer

Usage with Config

# These now use the correct key automatically
git clone git@github.com:user/repo.git
git clone git@github-work:company/repo.git
ssh prod
ssh bastion

Adding Keys to Services

GitHub

# Copy public key to clipboard
# macOS
pbcopy < ~/.ssh/id_ed25519.pub

# Linux
xclip -selection clipboard < ~/.ssh/id_ed25519.pub

# Windows
clip < ~/.ssh/id_ed25519.pub

Then: GitHub → Settings → SSH and GPG keys → New SSH key → Paste

Remote Servers

# Copy key to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server

# Or manually
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Verifying Connection

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

# Test server connection
ssh user@server

SSH Key Security Best Practices

Private Key Protection

  • Never share your private key—it should never leave your machine
  • Always use a passphrase—protects against theft
  • Store in encrypted locations—use encrypted home directories
  • Backup securely—encrypted backups only

Key Rotation

Regularly rotate SSH keys to limit exposure:

  • Generate new keys annually or after suspected compromise
  • Deploy new public keys before removing old ones
  • Remove old keys from authorized_keys and services
  • Keep records of which keys access what

Audit Access

# List authorized keys on a server
cat ~/.ssh/authorized_keys

# Check who has accessed
grep "Accepted publickey" /var/log/auth.log

Disable Password Authentication

Once SSH keys work, disable password login:

# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no

# Restart SSH
sudo systemctl restart sshd

Advanced SSH Features

SSH Agent Forwarding

Access services through jump hosts without copying keys:

# ~/.ssh/config
Host bastion
    ForwardAgent yes

# Or command line
ssh -A user@bastion

Warning: Only use agent forwarding with trusted hosts—malicious admins can use your forwarded agent.

SSH Certificates

For larger organizations, SSH certificates scale better than individual keys:

# Sign a user key with CA
ssh-keygen -s ca_key -I user@example -n user -V +52w user_key.pub

# Configure server to trust CA
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca.pub

FIDO2/Hardware Keys

Use hardware security keys (YubiKey, etc.) for maximum security:

# Generate key requiring hardware touch
ssh-keygen -t ed25519-sk -C "your_email@example.com"

# Each authentication requires physical touch

Troubleshooting SSH Keys

Common Issues

Permission denied (publickey):

  • Verify public key is in authorized_keys
  • Check file permissions (700 for .ssh, 600 for keys)
  • Confirm SSH agent has the key loaded
  • Check SSH config is using the right key

Agent has no identities:

# Add your key to the agent
ssh-add ~/.ssh/id_ed25519

Too many authentication failures:

# Specify exact key
ssh -i ~/.ssh/specific_key user@server

# Or use IdentitiesOnly in config
Host server
    IdentitiesOnly yes
    IdentityFile ~/.ssh/specific_key

Debugging Connections

# Verbose output (increase v's for more detail)
ssh -v user@server
ssh -vv user@server
ssh -vvv user@server

SSH Keys in CI/CD

GitHub Actions

# Store private key as secret
# Settings → Secrets → New repository secret

# workflow.yml
- name: Setup SSH
  run: |
    mkdir -p ~/.ssh
    echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
    chmod 600 ~/.ssh/id_ed25519
    ssh-keyscan github.com >> ~/.ssh/known_hosts

Deploy Keys

For repository access, use deploy keys (one key per repo):

  • Generate a dedicated key pair
  • Add public key to repo's deploy keys
  • Keep private key in CI/CD secrets

Tools for Key Management

  • 1Password/Bitwarden: Store passphrases securely
  • GPG: Encrypt backup copies of keys
  • Vault: Enterprise key management
  • sops: Encrypted secret management

When working with encoded data in SSH configurations or debugging, use tools like our Base64 Encoder/Decoder for handling encoded strings.

For verifying file integrity after key generation, our Hash Generator can create checksums of your key files.

Quick Reference

# Generate Ed25519 key
ssh-keygen -t ed25519 -C "email@example.com"

# Add key to agent
ssh-add ~/.ssh/id_ed25519

# Copy public key
cat ~/.ssh/id_ed25519.pub | pbcopy

# Test connection
ssh -T git@github.com

# Copy key to server
ssh-copy-id user@server

# Debug connection
ssh -v user@server

Conclusion

SSH keys are fundamental to secure development workflows. By following the practices in this guide—using Ed25519 keys, strong passphrases, proper permissions, and regular rotation—you'll have a secure and efficient authentication system.

Key takeaways:

  • Use Ed25519 keys for new setups
  • Always set a strong passphrase
  • Configure SSH agent for convenience
  • Use SSH config for multiple keys/hosts
  • Disable password authentication on servers
  • Rotate keys regularly

For more security tools and resources, explore our free developer tools. For comprehensive SSH documentation, see the OpenSSH manual and GitHub's SSH documentation.