Skip to content

SSH Configuration

Complete guide to SSH key generation, configuration, and management for secure connections to remote servers and Git repositories.

Generate SSH Keys

RSA Keys (Traditional)

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

# From README example
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
bash
# Generate Ed25519 key (faster, more secure)
ssh-keygen -t ed25519 -C "your_email@example.com"

# With custom filename
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_github -C "your_email@example.com"

Key Generation Options

bash
# Specify key file location
ssh-keygen -t ed25519 -f ~/.ssh/custom_key -C "your_email@example.com"

# Change passphrase of existing key
ssh-keygen -p -f ~/.ssh/id_ed25519

# Generate key without passphrase (not recommended)
ssh-keygen -t ed25519 -N "" -C "your_email@example.com"

# Generate key with specific number of rounds (higher = more secure but slower)
ssh-keygen -t ed25519 -a 100 -C "your_email@example.com"

SSH Key Types Comparison

TypeSecuritySpeedCompatibilityKey Size
Ed25519ExcellentFastModern systems256 bits
RSA 4096ExcellentSlowerUniversal4096 bits
RSA 2048GoodModerateUniversal2048 bits
ECDSAGoodFastMost systems256-521 bits

Recommendation: Use Ed25519 for modern systems, RSA 4096 for maximum compatibility.

Adding Keys to SSH Agent

Linux/macOS

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

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

# Add specific key
ssh-add ~/.ssh/id_ed25519_github

# Add key with specific lifetime (1 hour)
ssh-add -t 3600 ~/.ssh/id_ed25519

# List added keys
ssh-add -l

# Remove all keys
ssh-add -D

macOS (Persistent)

Add to ~/.ssh/config:

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

Windows (PowerShell)

powershell
# Start SSH agent service
Start-Service ssh-agent
Set-Service ssh-agent -StartupType Automatic

# Add key
ssh-add C:\Users\YourName\.ssh\id_ed25519

# List keys
ssh-add -l

SSH Config File

Create or edit ~/.ssh/config for convenient SSH connections.

Basic Configuration

# GitHub
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github
    PreferredAuthentications publickey

# Personal Server
Host myserver
    HostName 192.168.1.100
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519

Multiple GitHub Accounts

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

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

# Usage:
# git clone git@github.com:personal/repo.git
# git clone git@github-work:company/repo.git

Advanced Configuration

# Development Server with Jump Host
Host prod-server
    HostName 10.0.1.50
    User deploy
    ProxyJump jumphost
    IdentityFile ~/.ssh/id_prod

Host jumphost
    HostName bastion.company.com
    User admin
    IdentityFile ~/.ssh/id_bastion

# Multiple Servers with Same Settings
Host server-*
    User admin
    Port 2222
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null

Host server-1
    HostName 192.168.1.101

Host server-2
    HostName 192.168.1.102

Common Config Options

Host example
    HostName server.example.com
    User username
    Port 22
    IdentityFile ~/.ssh/id_rsa
    ForwardAgent yes                    # Forward SSH agent
    ForwardX11 yes                      # Forward X11 (GUI)
    Compression yes                     # Enable compression
    ServerAliveInterval 60              # Keep connection alive
    ServerAliveCountMax 3               # Retry count
    StrictHostKeyChecking ask           # Host key verification
    UserKnownHostsFile ~/.ssh/known_hosts
    LogLevel INFO
    TCPKeepAlive yes
    ControlMaster auto                  # Reuse connections
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Adding SSH Keys to Services

GitHub

  1. Copy public key:

Linux:

bash
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard
# Or
cat ~/.ssh/id_ed25519.pub

macOS:

bash
pbcopy < ~/.ssh/id_ed25519.pub
# Or
cat ~/.ssh/id_ed25519.pub

Windows:

powershell
Get-Content ~/.ssh/id_ed25519.pub | clip
# Or
cat ~/.ssh/id_ed25519.pub
  1. Go to GitHub:

    • Settings → SSH and GPG keys
    • Click "New SSH key"
    • Paste your public key
    • Give it a descriptive title
  2. Test connection:

bash
ssh -T git@github.com

GitLab

Same process as GitHub:

  1. Copy public key
  2. GitLab Settings → SSH Keys
  3. Paste and add key
  4. Test:
bash
ssh -T git@gitlab.com

Bitbucket

  1. Copy public key
  2. Bitbucket Settings → SSH keys
  3. Add key
  4. Test:
bash
ssh -T git@bitbucket.org

Testing SSH Connections

Test GitHub Connection

bash
# Basic test
ssh -T git@github.com

# Verbose output (for debugging)
ssh -vT git@github.com

# Very verbose
ssh -vvv -T git@github.com

Expected output:

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

Test Server Connection

bash
# Test connection
ssh user@server.com

# Test with specific key
ssh -i ~/.ssh/custom_key user@server.com

# Test with verbose output
ssh -v user@server.com

Managing Known Hosts

View Known Hosts

bash
# View known hosts file
cat ~/.ssh/known_hosts

# Search for specific host
ssh-keygen -F github.com

Remove Host from Known Hosts

bash
# Remove specific host
ssh-keygen -R github.com

# Remove host by IP
ssh-keygen -R 192.168.1.100

# Remove and re-add
ssh-keygen -R github.com && ssh -T git@github.com

SSH Key Permissions

Correct permissions are crucial for SSH security:

bash
# Set correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/known_hosts
chmod 600 ~/.ssh/authorized_keys

Fix All SSH Permissions

bash
# One-liner to fix all SSH permissions
chmod 700 ~/.ssh && \
chmod 600 ~/.ssh/id_* && \
chmod 644 ~/.ssh/*.pub && \
chmod 600 ~/.ssh/config && \
chmod 600 ~/.ssh/known_hosts && \
chmod 600 ~/.ssh/authorized_keys

SSH Agent Forwarding

Allow remote servers to use your local SSH keys:

# In ~/.ssh/config
Host remote-server
    HostName server.com
    ForwardAgent yes

Or use -A flag:

bash
ssh -A user@server.com

Security Note: Only use agent forwarding with trusted servers.

Troubleshooting

Permission Denied

bash
# Check key permissions
ls -la ~/.ssh/

# Fix permissions
chmod 600 ~/.ssh/id_ed25519

# Test with verbose output
ssh -vT git@github.com

# Try specific key
ssh -i ~/.ssh/id_ed25519 -T git@github.com

SSH Agent Not Running

bash
# Start agent
eval "$(ssh-agent -s)"

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

# Verify
ssh-add -l

Host Key Verification Failed

bash
# Remove old host key
ssh-keygen -R github.com

# Or disable strict checking (not recommended for production)
ssh -o StrictHostKeyChecking=no user@host

Connection Timeout

bash
# Test connectivity
ping github.com

# Try different port
ssh -p 443 git@ssh.github.com

# Check DNS
nslookup github.com

Debugging Connection Issues

bash
# Maximum verbosity
ssh -vvv user@host

# Test specific auth method
ssh -o PreferredAuthentications=publickey -vvv user@host

# Disable all auth methods except key
ssh -o PubkeyAuthentication=yes -o PasswordAuthentication=no user@host

Best Practices

Security

  1. Use Ed25519 keys (or RSA 4096 for compatibility)
  2. Always use passphrases for private keys
  3. Use different keys for different services
  4. Rotate keys regularly (annually)
  5. Never share private keys
  6. Use SSH agent instead of removing passphrases
  7. Limit key lifetime with ssh-add -t

Organization

  1. Use descriptive filenames: id_ed25519_github, id_ed25519_work
  2. Document in ~/.ssh/config: Add comments
  3. Backup keys securely: Encrypted backup of private keys
  4. Remove old keys: From both local and services

Configuration

# ~/.ssh/config with best practices
Host *
    AddKeysToAgent yes
    UseKeychain yes          # macOS only
    ServerAliveInterval 60
    ServerAliveCountMax 3
    Compression yes
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Host github.com
    IdentityFile ~/.ssh/id_ed25519_github
    IdentitiesOnly yes       # Only use specified key

Host work-*
    User devops
    IdentityFile ~/.ssh/id_ed25519_work
    StrictHostKeyChecking yes

See Also

External Resources

Released under the MIT License.