SSH Configuration Guide: Ports, Keys, and Security Hardening

SSH Configuration Guide: Ports, Keys, and Security Hardening

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

Enjoyed this guide?

New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

Scroll to Top