Tutorial

SSH Key Authentication: Generate Keys, Disable Passwords, Lock Down Your Server

March 19, 2026

Back to Blog

Every second, thousands of automated bots scan the internet for SSH servers and attempt to log in using common username and password combinations. If your server relies on password authentication, it is only a matter of time before an attacker gets in — or at the very least, fills your logs with thousands of failed attempts and consumes resources.

SSH key authentication eliminates this threat entirely. Instead of a password that can be guessed, SSH keys use public-key cryptography that is mathematically unfeasible to brute-force. This guide walks you through generating keys, deploying them, disabling password authentication, and hardening your SSH configuration for production.

2.5K
Average SSH brute-force attempts per day on a public server
0
Successful brute-force attacks with key-only auth
2255
Possible Ed25519 key combinations
~5m
Time to set up key authentication

How SSH Key Authentication Works

SSH key authentication uses asymmetric cryptography — a matched pair of keys where one encrypts and only the other can decrypt:

You generate
a key pair
Public key
goes to server
Private key
stays on your machine
Server sends
a challenge
Your key signs
the challenge
Server verifies
signature = access

The private key never leaves your local machine. The server only needs the public key. Even if someone compromises the server and gets your public key, they cannot use it to authenticate — the private key is required to prove identity.

Analogy
Think of it like a padlock and a key. You send an open padlock (public key) to the server. The server uses the padlock to lock a box (challenge). Only your unique key (private key) can open it. Anyone can see the padlock, but that does not help them open the box.

Choosing the Right Key Type

SSH supports several key algorithms. Here is a comparison of the most common ones:

AlgorithmKey SizeSecurity LevelSpeedRecommendation
Ed25519256 bitsExcellentFastestBest choice in 2026
RSA3072-4096 bitsExcellentSlowerUse 4096-bit for legacy compatibility
ECDSA256-521 bitsGoodFastOK, but Ed25519 is better
DSA1024 bitsWeakModerateDeprecated, do not use
Use Ed25519
Ed25519 is the recommended algorithm for all new SSH keys. It offers the best security-to-performance ratio, produces small keys (68 characters for the public key), and is immune to several side-channel attacks that affect other algorithms. The only reason to use RSA is if you need to connect to a very old server (OpenSSH < 6.5, pre-2014) that does not support Ed25519.

Step 1: Generate Your SSH Key Pair

Run this command on your local machine (your laptop or desktop — not the server):

Ed25519 (Recommended)

local$ ssh-keygen -t ed25519 -C "yourname@yourlaptop"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519): [Press Enter for default]
Enter passphrase (empty for no passphrase): [type a strong passphrase]
Enter same passphrase again: [confirm passphrase]
Your identification has been saved in /home/you/.ssh/id_ed25519
Your public key has been saved in /home/you/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:xR4jK9mN2pL5qR8tV1wY4zA6cE0fH3jK7nQ9sU2b yourname@yourlaptop
The key's randomart image is:
+--[ED25519 256]--+
| .o+. |
| .o=o+ |
| . =+B. |
| o.B+o |
| . S+=.+ |
| . o.=.= . |
| +.+.o . |
| ..+.o . |
| E+o. |
+----[SHA256]-----+

RSA 4096-bit (For Legacy Compatibility)

local$ ssh-keygen -t rsa -b 4096 -C "yourname@yourlaptop"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/you/.ssh/id_rsa): [Press Enter]
Enter passphrase: [type passphrase]
Always Use a Passphrase!
A passphrase encrypts your private key on disk. Without it, anyone who gains access to your laptop can use your key to log into all your servers. With a passphrase, the key file is useless without the passphrase. Use SSH agent to avoid typing it repeatedly.

Step 2: View Your Keys

After generation, you will have two files:

local$ ls -la ~/.ssh/id_ed25519*
-rw------- 1 you you 464 Mar 17 10:30 /home/you/.ssh/id_ed25519
-rw-r--r-- 1 you you 104 Mar 17 10:30 /home/you/.ssh/id_ed25519.pub

# View your public key (this is what goes on the server)
local$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBt8J3kX... yourname@yourlaptop
FilePermissionsPurposeShare?
id_ed25519600 (owner read/write only)Private keyNEVER share
id_ed25519.pub644 (world readable)Public keySafe to share

Step 3: Deploy the Public Key to Your Server

The easiest way to copy your public key to the server is with ssh-copy-id:

local$ ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/you/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed
[email protected]'s password: ********

Number of key(s) added: 1
Now try logging in: "ssh [email protected]"

Manual Method (if ssh-copy-id is unavailable)

On Windows or systems without ssh-copy-id, you can copy the key manually:

# Copy your public key content
local$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBt8J3kX... yourname@yourlaptop

# SSH into the server and add the key
server$ mkdir -p ~/.ssh && chmod 700 ~/.ssh
server$ nano ~/.ssh/authorized_keys
# Paste the public key on a new line
server$ chmod 600 ~/.ssh/authorized_keys

Step 4: Test Key-Based Login

Before disabling password authentication, verify that your key works:

local$ ssh [email protected]
Enter passphrase for key '/home/you/.ssh/id_ed25519': [your passphrase]
deploy@vps:~$

# If you see a password prompt instead of a passphrase prompt,
# the key is not being used. Check permissions:
deploy@vps:~$ ls -la ~/.ssh/
drwx------ 2 deploy deploy 4096 Mar 17 10:35 .
-rw------- 1 deploy deploy 104 Mar 17 10:35 authorized_keys
Critical: Test Before Disabling Passwords!
Always keep your existing SSH session open when changing SSH settings. Open a new terminal window to test. If key authentication fails and you have already disabled passwords, you will be locked out of your server.

Step 5: Disable Password Authentication

Once you have confirmed key-based login works, disable password authentication on the server:

deploy@vps:~$ sudo nano /etc/ssh/sshd_config

# Find and change/add these lines:
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
PubkeyAuthentication yes

# Validate config before restarting
deploy@vps:~$ sudo sshd -t
# No output means config is valid

deploy@vps:~$ sudo service sshd restart

Verify the change took effect:

# From a new terminal, try to connect with password (should fail)
local$ ssh -o PubkeyAuthentication=no [email protected]
[email protected]: Permission denied (publickey).

# Password auth is disabled. Key auth still works:
local$ ssh [email protected]
Enter passphrase for key '/home/you/.ssh/id_ed25519':
deploy@vps:~$ # Connected with key!

Step 6: Full SSH Hardening Configuration

Beyond disabling passwords, there are several additional sshd_config settings that significantly improve security:

# /etc/ssh/sshd_config - Hardened configuration

# Authentication
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password
MaxAuthTries 3
AuthenticationMethods publickey

# Session management
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
MaxSessions 5
MaxStartups 10:30:60

# Security restrictions
X11Forwarding no
AllowAgentForwarding no
PermitEmptyPasswords no
PermitUserEnvironment no

# Logging
LogLevel VERBOSE

# Only allow specific users (optional)
AllowUsers deploy admin

Here is what each setting does:

SettingValuePurpose
PermitRootLoginprohibit-passwordRoot can login only with keys, never password
MaxAuthTries3Disconnect after 3 failed attempts
ClientAliveInterval300Send keepalive every 5 minutes
ClientAliveCountMax2Disconnect after 2 missed keepalives (10 min idle)
LoginGraceTime3030 seconds to authenticate or disconnect
MaxStartups10:30:60Rate limit new connections (starts dropping at 10)
AllowUsersdeploy adminOnly these users can SSH in
LogLevelVERBOSEDetailed logging for security auditing

SSH Config File: Managing Multiple Servers

If you manage multiple servers, typing full SSH commands gets tedious. The SSH client config file lets you create shortcuts:

# ~/.ssh/config

Host web
HostName 203.0.113.50
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519

Host staging
HostName 198.51.100.10
User ubuntu
Port 2222
IdentityFile ~/.ssh/staging_key

Host db
HostName 10.0.1.50
User admin
ProxyJump web # Jump through web server to reach internal network

# Now you can simply type:
local$ ssh web # Instead of full command with -i flag
local$ ssh staging # Automatically uses port 2222 and staging key
local$ ssh db # Automatically jumps through web server

SSH Agent: Avoid Typing Your Passphrase Repeatedly

If your key has a passphrase (and it should), SSH agent caches the decrypted key in memory so you only type the passphrase once per session:

# Start the SSH agent
local$ eval "$(ssh-agent -s)"
Agent pid 12345

# Add your key (type passphrase once)
local$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/you/.ssh/id_ed25519: ********
Identity added: /home/you/.ssh/id_ed25519 (yourname@yourlaptop)

# List loaded keys
local$ ssh-add -l
256 SHA256:xR4jK... yourname@yourlaptop (ED25519)

# Now SSH connections use the cached key - no passphrase prompt!
local$ ssh [email protected]
deploy@vps:~$ # Connected instantly!
macOS Keychain Integration
On macOS, add UseKeychain yes and AddKeysToAgent yes to your ~/.ssh/config to automatically store the passphrase in your macOS Keychain. You will only need to type it once — ever.

Adding Two-Factor Authentication (2FA)

For maximum security, you can combine SSH keys with TOTP (Time-based One-Time Password) using Google Authenticator. This means an attacker would need both your private key AND your phone to log in:

# Install Google Authenticator PAM module
server$ sudo apt install -y libpam-google-authenticator

# Run setup for your user
server$ google-authenticator
Do you want authentication tokens to be time-based (y/n)? y
[QR CODE APPEARS - scan with your authenticator app]
Your emergency scratch codes are:
12345678
87654321
...

# Configure PAM
server$ sudo nano /etc/pam.d/sshd
# Add at the top:
auth required pam_google_authenticator.so

# Configure SSH to use both key and TOTP
server$ sudo nano /etc/ssh/sshd_config
AuthenticationMethods publickey,keyboard-interactive
ChallengeResponseAuthentication yes

server$ sudo service sshd restart
SSH Key
Verified
TOTP Code
Prompted
Code Verified
Against Phone App
Access
Granted

Security Checklist

Here is the complete SSH security hardening checklist:

Essential (Do These)

  • Use Ed25519 keys (not RSA/DSA)
  • Add a passphrase to your private key
  • Disable password authentication
  • Set PermitRootLogin to prohibit-password
  • Limit MaxAuthTries to 3
  • Install and configure Fail2Ban

Advanced (Highly Recommended)

  • Use AllowUsers to restrict SSH users
  • Change default SSH port
  • Enable 2FA with Google Authenticator
  • Use SSH agent forwarding carefully
  • Set up SSH config for multiple servers
  • Audit authorized_keys files regularly

Panelica SSH Management

Panelica provides comprehensive SSH access control through its web interface, eliminating the need for manual sshd_config editing:

  • Per-user SSH access control — enable or disable SSH access for each user independently
  • Chroot jails — restrict users to their home directories so they cannot see or access other users' files
  • SFTP-only mode — grant file transfer access without shell access for users who only need to upload files
  • Configurable shell access — choose between full bash access (chrooted) and restricted SFTP-only mode per user
  • Fail2Ban integration — automatic IP banning after failed SSH attempts, manageable through the panel
  • 5-layer isolation — SSH access is just one layer; users are also isolated by cgroups, namespaces, PHP-FPM pools, and Unix permissions
SSH Security Without the Terminal
Instead of manually editing sshd_config, managing authorized_keys files, and configuring chroot jails, Panelica handles SSH access control through a clean web interface. Each user's SSH access, shell type, and resource limits are configured in a few clicks.
Share: