A key pair is far safer than a password: the private key never leaves your PC and cannot be guessed by bots scanning port 22. Windows 10 and 11 already include OpenSSH, so you can create a key, install it on your VPS Linux Infrawire, keep it loaded in the Windows ssh-agent service and finally turn off password logins.
📋 Prerequisites
- Windows 10 or 11 with the OpenSSH client (check with
ssh -Vin PowerShell). - A Linux VPS (Ubuntu 24.04, Debian 12, AlmaLinux 9 or Rocky 9) where you can still log in with a password: from your customer area you can find the IP and the root password of the VPS.
- About ten minutes, and a second SSH session or the VPS console available as a safety net.
PowerShellssh -V
🔐 Generate an ed25519 key
Open PowerShell (a normal one, not administrator) and run:
PowerShellssh-keygen -t ed25519 -C 'USER@my-pc'
Accept the default path C:\Users\USER\.ssh\id_ed25519 and enter a passphrase. The passphrase encrypts the private key on disk, so a stolen file is useless. Two files are created: id_ed25519 (private, never share it) and id_ed25519.pub (public).
📤 Copy the public key to the VPS
Windows has no ssh-copy-id, so install the key by hand. First display the public key and copy the whole line:
PowerShellGet-Content $env:USERPROFILE\.ssh\id_ed25519.pub
Log in with your password, then append that line on the server (replace the placeholder with your real key between the single quotes):
Bashssh root@VPS_IP mkdir -p ~/.ssh && chmod 700 ~/.ssh echo 'ssh-ed25519 AAAA...your-key... USER@my-pc' >> ~/.ssh/authorized_keys sed -i 's/\r$//' ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
The sed line removes any Windows line ending that would make the key unreadable. Do not use PowerShell pipes with ssh for this job: Windows PowerShell 5.1 can add carriage returns to the data.
🧰 Enable ssh-agent on Windows
Without an agent you must type the passphrase at every login. The ssh-agent service is installed but disabled or manual by default. In an administrator PowerShell:
PowerShellGet-Service ssh-agent | Set-Service -StartupType Automatic Start-Service ssh-agent Get-Service ssh-agent
Then, in a normal PowerShell, load your key once and list the loaded keys:
PowerShellssh-add $env:USERPROFILE\.ssh\id_ed25519 ssh-add -l
The agent keeps the key across reboots, so you will not be asked again.
✅ Test the key login
Connect again. You should get a shell without the server asking for the root password:
PowerShellssh root@VPS_IP
To see exactly which method is used, add -v and look for Server accepts key and Authenticated to ... using publickey:
PowerShellssh -v root@VPS_IP
Do not go further until this works, and keep this session open.
🚫 Disable password authentication on the server
On Ubuntu and Debian, /etc/ssh/sshd_config.d/ may already contain a file (such as 50-cloud-init.conf) that enables passwords. SSH uses the first value it reads, so create a file that sorts earlier. Run this as root on the VPS:
Bashgrep -ri 'PasswordAuthentication' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ cat > /etc/ssh/sshd_config.d/10-keys-only.conf <<'EOF' PasswordAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes PermitRootLogin prohibit-password EOF sshd -t && systemctl reload ssh
On AlmaLinux/Rocky the service is called sshd: use systemctl reload sshd. Make sure the main sshd_config contains the line Include /etc/ssh/sshd_config.d/*.conf near the top (this is the default). sshd -t prints nothing when the syntax is valid.
From a new window, confirm that passwords are now refused while your key still works:
PowerShellssh -o PubkeyAuthentication=no root@VPS_IP
The expected answer is Permission denied (publickey).
🛠️ Troubleshooting
Permission denied (publickey). The key is not in the right account's authorized_keys, was pasted on several lines, or the permissions are wrong. On the server run chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys, and check the line starts with ssh-ed25519.
WARNING: UNPROTECTED PRIVATE KEY FILE. Other Windows accounts can read your private key. Restrict it to your user:
PowerShellicacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r /grant:r "${env:USERNAME}:F"
Error connecting to agent: No such file or directory. The ssh-agent service is not running; start it as shown above.
Locked out after the change. Use the VPS console from your customer area, remove /etc/ssh/sshd_config.d/10-keys-only.conf, run sshd -t and reload the SSH service.
🚀 Your Windows PC now logs in to the VPS with an ed25519 key and passwords are off. Keep a backup of your private key in a safe place.