Public key authentication allows you to connect to an SSH server without using a password, utilizing a pair of cryptographic keys. This method is more secure than traditional passwords and facilitates task automation.
How It Works
The system uses a key pair:
- Private key: Stored on your local computer. Should never be shared.
- Public key: Copied to the server. Can be freely shared.
When you connect, the server verifies that you possess the private key corresponding to the registered public key.
Prerequisites
- SSH access to the server with username and password (for initial setup)
- SSH client installed on your local computer
Quick Method
From Linux / macOS
Run the following command, replacing the values according to your configuration:
REMOTE_USER="user"
REMOTE_HOST="server.example.com"
REMOTE_PORT="22"
# Generate the key (if it doesn't exist) and copy it to the server
if [ ! -f ~/.ssh/id_ed25519 ]; then
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
fi
ssh-copy-id -p $REMOTE_PORT $REMOTE_USER@$REMOTE_HOSTFor systems that don't support Ed25519, use RSA:
REMOTE_USER="user"
REMOTE_HOST="server.example.com"
REMOTE_PORT="22"
if [ ! -f ~/.ssh/id_rsa ]; then
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
fi
ssh-copy-id -p $REMOTE_PORT $REMOTE_USER@$REMOTE_HOSTFrom Windows (PowerShell)
Run the following command, replacing the values according to your configuration:
$REMOTE_USER = "user"
$REMOTE_HOST = "server.example.com"
$REMOTE_PORT = "22"
# Generate the key if it doesn't exist
if (!(Test-Path "$env:USERPROFILE\.ssh\id_ed25519")) {
ssh-keygen -t ed25519 -N '""' -f "$env:USERPROFILE\.ssh\id_ed25519"
}
# Copy the public key to the server
Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" | ssh -p $REMOTE_PORT "$REMOTE_USER@$REMOTE_HOST" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"For systems that don't support Ed25519, use RSA:
$REMOTE_USER = "user"
$REMOTE_HOST = "server.example.com"
$REMOTE_PORT = "22"
if (!(Test-Path "$env:USERPROFILE\.ssh\id_rsa")) {
ssh-keygen -t rsa -b 4096 -N '""' -f "$env:USERPROFILE\.ssh\id_rsa"
}
Get-Content "$env:USERPROFILE\.ssh\id_rsa.pub" | ssh -p $REMOTE_PORT "$REMOTE_USER@$REMOTE_HOST" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"Once executed, verify the connection:
ssh -p $REMOTE_PORT "$REMOTE_USER@$REMOTE_HOST"Manual Step-by-Step Method
If you prefer to perform the process manually or the quick method doesn't work, follow these steps.
Step 1: Generate the Key Pair
Linux / macOS
ssh-keygen -t ed25519 -C "your-email@example.com"Windows (PowerShell)
ssh-keygen -t ed25519 -C "your-email@example.com"The command will ask for:
- File location: Press Enter to accept the default location.
- Passphrase: Enter a password to protect the private key (recommended) or press Enter to leave it empty.
Windows (PuTTYgen)
If you use PuTTY instead of OpenSSH:
- Open PuTTYgen.
- Select EdDSA (or RSA 4096 bits).
- Click Generate and move the mouse to generate randomness.
- Optionally, enter a passphrase.
- Save the private key with Save private key (
.ppkfile). - Copy the text from the "Public key for pasting into OpenSSH authorized_keys file" field.
Step 2: Copy the Public Key to the Server
Option A: Using ssh-copy-id (Linux/macOS)
ssh-copy-id -p 22 user@server.example.comOption B: Manual
- Display your public key:
cat ~/.ssh/id_ed25519.pub- Connect to the server:
ssh user@server.example.com- Create the directory and file if they don't exist, and add the key:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "your-complete-public-key" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysStep 3: Verify the Connection
Disconnect and reconnect:
ssh user@server.example.comIf everything is correct, you'll access without entering the server password.
Disable Password Authentication (optional)
Once you've verified that key authentication works, you can disable password access for greater security.
Warning: Make sure key authentication works before disabling passwords, or you could lock yourself out of the server.
- Edit the SSH configuration file:
sudo nano /etc/ssh/sshd_config- Find and modify the following line:
PasswordAuthentication no- Save the file and restart the SSH service:
# Ubuntu/Debian
sudo systemctl restart ssh
# AlmaLinux/CentOS/RHEL
sudo systemctl restart sshdTroubleshooting
Permission denied (publickey)
- Verify permissions on the server:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys- Confirm that the public key is correctly copied in
authorized_keys. - Verify that you're using the correct private key.
Connection Still Asks for Password
- Verify that
PubkeyAuthentication yesis in/etc/ssh/sshd_config(enabled by default on most servers). - Check the server logs:
sudo tail -f /var/log/auth.log # Ubuntu/Debian
sudo tail -f /var/log/secure # AlmaLinux/CentOS- Make sure the
authorized_keysfile doesn't have broken lines (each key must be on a single line).
Key Not Found
- Verify that the key exists:
ls -la ~/.ssh/- If using a custom location, specify it when connecting:
ssh -i /path/to/your/key user@server.example.comSecurity Best Practices
- Use a passphrase: Protect your private key with a strong password.
- Don't share the private key: Each user should have their own key pair.
- Use Ed25519: It's more secure and efficient than RSA.
-
Disable root SSH access: Configure
PermitRootLogin noinsshd_config. - Regularly review authorized_keys: Remove keys from users who no longer need access.
- Backup your keys: Keep a secure copy of your private key.