SSH is how you manage every Linux server. If someone compromises your SSH access, they own the machine. Getting SSH configuration right is not optional — it is the foundation of server security.
This guide covers practical SSH configuration: key-based authentication, port changes, client config, tunnelling, and the hardening steps that protect production servers.
Quick Reference
| Task | Command |
|---|---|
| Connect to a server | ssh user@hostname |
| Connect on custom port | ssh -p 2222 user@hostname |
| Generate SSH key pair | ssh-keygen -t ed25519 |
| Copy key to server | ssh-copy-id user@hostname |
| Local port forward | ssh -L 8080:localhost:80 user@host |
| Test SSH config | sshd -t |
| Restart SSH service | sudo systemctl restart sshd |
SSH Key Authentication
Passwords are guessable. Keys are not. Switch to key-based authentication as your first hardening step.
Generate a Key Pair
# Ed25519 (recommended - fast, secure, short keys)
ssh-keygen -t ed25519 -C "eric@workstation"
# RSA (wider compatibility, use 4096 bits)
ssh-keygen -t rsa -b 4096 -C "eric@workstation"
This creates two files:
~/.ssh/id_ed25519— your private key (never share this)~/.ssh/id_ed25519.pub— your public key (goes on the server)
Always set a passphrase. It protects the key if your workstation is compromised.
Copy Your Public Key to a Server
# Easiest method
ssh-copy-id user@server
# Manual method (if ssh-copy-id is not available)
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Key Permissions (Critical)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
SSH silently refuses to use keys with wrong permissions. If key auth fails, check these first.
The SSH Client Config File
Managing multiple servers with different ports, usernames, and keys gets messy. The ~/.ssh/config file solves this:
# ~/.ssh/config
Host webserver
HostName 192.168.1.50
User eric
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host gitea
HostName git.quarryrogue.uk
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host pi
HostName 192.168.1.100
User pi
IdentityFile ~/.ssh/id_ed25519
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
Now instead of typing ssh -p 2222 -i ~/.ssh/id_ed25519 [email protected], you type:
ssh webserver
The Host * block applies defaults to all connections: keep-alive packets every 60 seconds (prevents timeouts) and auto-add keys to the SSH agent.
Server-Side SSH Hardening
Edit /etc/ssh/sshd_config on the server. Always test before restarting.
Essential Changes
# Disable password authentication (keys only)
PasswordAuthentication no
ChallengeResponseAuthentication no
# Disable root login
PermitRootLogin no
# Change default port (reduces automated scanning)
Port 2222
# Limit login to specific users
AllowUsers eric deploy
# Disable empty passwords
PermitEmptyPasswords no
# Limit authentication attempts
MaxAuthTries 3
# Set login timeout
LoginGraceTime 30
Test and Apply
# Test config for syntax errors BEFORE restarting
sudo sshd -t
# If test passes, restart
sudo systemctl restart sshd
Critical: Before disabling password auth, verify your key works in a separate terminal. If you lock yourself out, you need console access to recover.
SSH Port Forwarding (Tunnelling)
Local Forward
Access a remote service through your local machine:
# Access remote server's port 3000 on your localhost:8080
ssh -L 8080:localhost:3000 user@server
# Access a database behind a firewall
ssh -L 5432:db-server:5432 user@jumphost
Open http://localhost:8080 in your browser and you reach the remote service securely.
Dynamic Forward (SOCKS Proxy)
# Create a SOCKS5 proxy on local port 1080
ssh -D 1080 user@server
Configure your browser to use SOCKS5 proxy at localhost:1080 and all traffic routes through the remote server.
Troubleshooting SSH
# Verbose connection (shows where it fails)
ssh -v user@server
# Extra verbose
ssh -vvv user@server
# Check server logs
sudo journalctl -u sshd -f
Common issues:
- “Permission denied (publickey)” — key not in authorized_keys, wrong permissions on .ssh directory, or wrong key file
- “Connection refused” — sshd not running, wrong port, or firewall blocking
- “Connection timed out” — server unreachable, firewall blocking, or wrong IP
- “Host key verification failed” — server was rebuilt and key changed. Verify it is legitimate, then
ssh-keygen -R hostname
Why This Matters
- Every Linux job uses SSH — it is literally how you access servers
- Security baseline — SSH hardening is the first thing auditors check
- Tunnelling — accessing internal services securely is a daily operation in enterprise environments
- Jump hosts / bastion servers — understanding SSH proxying is essential for cloud infrastructure
Next Steps
- File Permissions — SSH keys require specific permissions to work
- Secure Linux Servers with Ansible — automate SSH hardening across your fleet
- Linux Fundamentals Series — the full series
This guide is part of the Linux Fundamentals series. See the full series for more guides like this.

ReadTheManual is run, written and curated by Eric Lonsdale.
Eric has over 20 years of professional experience in IT infrastructure, cloud architecture, and cybersecurity, but started with PCs long before that.
He built his first machine from parts bought off tables at the local college campus, hoping they worked. He learned on BBC Micros and Atari units in the early 90s, and has built almost every PC he’s used between 1995 and now.
From helpdesk to infrastructure architect, Eric has worked across enterprise datacentres, Azure environments, and security operations. He’s managed teams, trained engineers, and spent two decades solving the problems this site teaches you to solve.
ReadTheManual exists because Eric believes the best way to learn IT is to build things, break things, and actually read the manual. Every guide on this site runs on infrastructure he owns and maintains.
Enjoyed this guide?
New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

