SSH Configuration: Keys, Agents and Tunnels
In this tutorial, you'll learn SSH configuration including key generation, ssh-agent, config file for hosts, port forwarding, jump hosts, and SSH tunneling for secure remote development.
Why SSH Matters
Secure Shell is the foundation of remote server access, Git operations, and secure file transfer. A well-configured SSH setup means passwordless logins, simplified host management, and secure tunnels to remote services. Poor SSH hygiene means repeated password entry, connection errors, and security risks.
By the end of this guide, you will generate and manage SSH keys, configure hosts for quick access, use SSH agent for key forwarding, and create secure tunnels.
What is SSH?
SSH (Secure Shell) is a cryptographic network protocol for operating network services securely over an unsecured network. It provides encrypted communication, authentication, and remote command execution.
flowchart TD A[SSH Client] --> B[SSH Config] B --> C[Host Entry] C --> D[Hostname] C --> E[User] C --> F[Port] C --> G[Identity File] A --> H[SSH Agent] H --> I[Private Keys in Memory] J[SSH Server] --> K[Authorized Keys] A --> L[SSH Tunnel] L --> M[Local Port Forwarding] L --> N[Remote Port Forwarding]
SSH Key Generation
# Generate an ED25519 key (recommended)
ssh-keygen -t ed25519 -C "your-email@example.com"
# Or RSA key (older but widely compatible)
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
You are prompted for a passphrase. Always use one.
Expected Output
$ ssh-keygen -t ed25519 -C "alice@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/alice/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/alice/.ssh/id_ed25519
Your public key has been saved in /home/alice/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:abc123def456 alice@example.com
Key Types Comparison
| Type | Security | Performance | Compatibility |
|---|---|---|---|
| ED25519 | Excellent | Fast | OpenSSH 6.5+ |
| RSA 4096 | Excellent | Slow | Universal |
| ECDSA | Good | Fast | OpenSSH 5.7+ |
| DSA | Weak | Fast | Avoid (deprecated) |
The SSH Config File
The SSH config file (~/.ssh/config) simplifies connections by storing host details.
# ~/.ssh/config
# Default settings
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
IdentityFile ~/.ssh/id_ed25519
# Personal server
Home:
HostName 192.168.1.100
User alice
Port 22
# Work server
Host work
HostName work.example.com
User bob
Port 2222
IdentityFile ~/.ssh/work_ed25519
# GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_ed25519
Using the Config
ssh home # Equivalent to: ssh alice@192.168.1.100 -p 22
ssh work # Equivalent to: ssh bob@work.example.com -p 2222
Copying Public Keys to Servers
# Using ssh-copy-id (recommended)
ssh-copy-id user@server
# Manual method
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Expected Output
$ ssh-copy-id alice@192.168.1.100
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/alice/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'alice@192.168.1.100'"
and check to make sure that only the key(s) you wanted were added.
SSH Agent
The SSH agent holds your decrypted private keys in memory so you do not need to type your passphrase repeatedly.
# Start the agent
eval "$(ssh-agent -s)"
# Add a key
ssh-add ~/.ssh/id_ed25519
# List loaded keys
ssh-add -l
# Remove all keys
ssh-add -D
Agent Forwarding
Enable agent forwarding to use your local SSH keys through an intermediate server.
# In SSH config
Host bastion
HostName bastion.example.com
ForwardAgent yes
# Or on command line
ssh -A bastion
Now you can ssh from the bastion to another server using your local key.
Security Warning
Agent forwarding is powerful but risky. An admin with root access on the intermediate server can use your agent to access other servers. Use ForwardAgent yes only for trusted hosts.
SSH Tunnels
Local Port Forwarding
Forward a port from your local machine to a remote machine through the SSH server.
# Forward local port 8080 to remote server's internal service on port 80
ssh -L 8080:internal-server:80 user@gateway
# Now open http://localhost:8080 to access internal-server:80
Use case: Access a database that is only accessible from the server.
ssh -L 5432:localhost:5432 user@server
# Now connect to localhost:5432 to reach the server's PostgreSQL
Remote Port Forwarding
Forward a port from the remote machine to your local machine.
# Forward remote port 8080 to your local machine's port 3000
ssh -R 8080:localhost:3000 user@server
# Now anyone on the server can access http://localhost:8080 to reach your local dev server
Use case: Share a local development server with a remote colleague.
Dynamic Port Forwarding (SOCKS Proxy)
# Create a SOCKS proxy on local port 1080
ssh -D 1080 user@server
Configure your browser to use localhost:1080 as a SOCKS proxy. All traffic is tunneled through the server.
Jump Hosts
Connect to a target server through a bastion host.
# Direct
ssh -J user@bastion.example.com user@internal-server.local
# In SSH config
Host internal-server
HostName internal-server.local
User alice
ProxyJump bastion.example.com
Host bastion
HostName bastion.example.com
User alice
Then:
ssh internal-server
SCP and SFTP
# Copy file to server
scp file.txt user@server:/home/user/
# Copy file from server
scp user@server:/home/user/file.txt .
# Copy directory recursively
scp -r mydir/ user@server:/home/user/
# SFTP interactive session
sftp user@server
Common Errors
| Problem | Cause | Fix |
|---|---|---|
Permission denied (publickey) |
No matching private key | Add the correct identity file in ~/.ssh/config or use ssh -i |
WARNING: Remote host identification has changed |
Server key changed | Remove old key with ssh-keygen -R hostname |
ssh: connect to host port 22: Connection refused |
SSH server not running on target | Start SSH on target: sudo systemctl start ssh |
Agent admitted failure to sign |
Agent not running or key not added | Run ssh-add -l to check; add key if needed |
Bad permissions on ~/.ssh/config |
Wrong file permissions | Run chmod 600 ~/.ssh/config |
Practice Questions
1. What is the recommended SSH key type for new setups?
ED25519. It is fast, secure, and modern.
2. What is the purpose of the SSH agent?
It holds decrypted private keys in memory to avoid repeated passphrase entry.
3. How do you forward a local port to a remote server via SSH?
ssh -L local_port:destination:destination_port user@server.
4. What does ssh-copy-id user@server do?
It appends your public key to the server's ~/.ssh/authorized_keys file.
5. When would you use a jump host (ProxyJump)?
When you need to reach an internal server that is only accessible through a bastion/gateway host.
Challenge
Configure SSH access to a remote server with key-based authentication, set up the SSH config file with host aliases, enable agent forwarding, and create a tunnel to a database running on the remote server. Write a script that sets all this up on a fresh machine.
Real-World Task
Set up SSH for your daily workflow: generate ED25519 keys for personal and work use, configure ~/.ssh/config with entries for at least three servers (personal, work, and a jump host), add keys to the SSH agent, and verify passwordless login. Set up a local port forwarding tunnel for a database or web service you access regularly.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro