SSH Key Access and Hardening
A user key proves who is logging in: its private half stays on WSL2 and its public half is appended to ~/.ssh/authorized_keys on the VPS. A host key proves which server answered: its private half stays under /etc/ssh, while the client records its public fingerprint.
ssh-keygen -lf "$LOCAL_SSH_PUBLIC_KEY"
ssh-copy-id -i "$LOCAL_SSH_PUBLIC_KEY" "$VPS_USER@$VPS_PUBLIC_IPV4"
ssh -i "$HOME/.ssh/id_ed25519" \
-o IdentitiesOnly=yes \
-o PreferredAuthentications=publickey \
-o PasswordAuthentication=no \
"$VPS_USER@$VPS_PUBLIC_IPV4"
The explicit test must succeed in a second session while the original session stays open. ssh-copy-id appends rather than replacing keys. Verify remote permissions:
stat -c '%a %U:%G %n' ~/.ssh ~/.ssh/authorized_keys
# directory 700, file 600
Ubuntu reads /etc/ssh/sshd_config.d/*.conf. OpenSSH uses the first obtained value for most directives, so a late 99-...conf may not override an earlier cloud-init snippet. Inspect includes and effective values before selecting a filename.
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
sudo sshd -t
sudo sshd -T | grep -E \
'^(permitrootlogin|passwordauthentication|pubkeyauthentication) '
sudo systemctl reload ssh
Expect no, no, and yes, then open a third fresh public-key-only session. Do not delete users or existing keys.
For an unfamiliar host-key prompt, compare it through a known-good path:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Only accept an exact match. For failures, keep the working session and inspect sshd -t, sshd -T, journalctl -fu ssh.service, and client ssh -vvv output after redacting addresses and names.