Author: Daniel Waters
Modern SSH setups revolve around a keypair you control locally. The private key unlocks the connection, and the public half is all you ever copy to servers.
Create an Ed25519 keypair on your workstation (the algorithm is fast, secure, and resistant to brute-force attacks):
ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-keygen writes the private key to ~/.ssh/id_ed25519 and the public key to ~/.ssh/id_ed25519.pub.Install the public key onto the remote account so the server recognizes you:
ssh-copy-id username@server_ip
ssh-copy-id appends the public key to ~/.ssh/authorized_keys and fixes permissions for you.id_ed25519.pub to the same file with your editor of choice.Once the key lives in authorized_keys, OpenSSH can complete the challenge-response handshake without ever asking for a password.
Save a host entry on your local machine so every future connection automatically presents the correct private key and skips password prompts.
Open (or create) ~/.ssh/config on your workstation and add a block for the server:
vi ~/.ssh/config
Paste something similar to the following, adjusting the host alias, actual hostname or IP, and username to match your environment:
Host my-server
HostName server_ip
User username
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host defines a shortcut so you can connect with ssh my-server instead of typing the full address.IdentityFile points OpenSSH at the keypair you generated earlier, guaranteeing the correct credential is offered first.IdentitiesOnly yes tells the client not to fall back to other keys or the SSH agent, preventing confusing password prompts when additional keys exist on your machine.Lock down the client configuration file so the SSH client trusts it:
chmod 600 ~/.ssh/config
SSH ignores overly permissive client configs, so this step ensures the host alias and key selection remain active.
With the config in place, ssh my-server immediately uses the hardened key-only workflow you set up on the remote host.
Disabling password logins means editing the SSH server configuration so only keys are accepted and risky defaults are turned off.
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
PermitRootLogin no
PubkeyAuthentication yes ensures the daemon listens for key-based attempts.PasswordAuthentication, ChallengeResponseAuthentication, and UsePAM prevents any fallback to passwords or one-time codes.AuthorizedKeysFile at .ssh/authorized_keys keeps the lookup consistent with the copy step above.PermitRootLogin no forces administrators to use a non-root account plus sudo, limiting the blast radius of any compromise.Reload the service after saving your changes so they take effect without waiting for a reboot:
sudo systemctl restart sshd
Keep an existing SSH session open while you test in case you need to undo a typo or re-enable passwords temporarily.
OpenSSH refuses to honor keys stored in world-readable locations. Tighten the directory and file permissions so the daemon trusts the key material:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R youruser:youruser ~/.ssh
chmod 700 ~/.ssh allows only the owner to enter the directory.chmod 600 ~/.ssh/authorized_keys restricts the key list so only the user can read or modify it.chown -R youruser:youruser ~/.ssh guarantees the directory tree isn’t owned by root, which would cause OpenSSH to skip it entirely.If the server still prompts for a password, gather more context with verbose output:
ssh -v username@server_ip
The -v flag prints each authentication attempt. Look for Authentication succeeded (publickey) to confirm success, or follow the rejection messages (such as “bad owner or permissions”) to resolve lingering issues.
When password logins are disabled, every new account needs a key in place before its first connection.
Create the Unix account with your usual workflow:
sudo adduser newusername
Even though adduser prompts for a password, the SSH daemon will ignore it because password authentication is disabled. You can leave the field blank or set a random value for bookkeeping.
Build the .ssh directory tree and seed the user’s public key:
sudo mkdir -p /home/newusername/.ssh
sudo vi /home/newusername/.ssh/authorized_keys
Paste their id_ed25519.pub (or equivalent) into authorized_keys. This file lists every key that may act as that user.
Lock down the directory ownership and permissions so OpenSSH accepts the key:
sudo chown -R newusername:newusername /home/newusername/.ssh
sudo chmod 700 /home/newusername/.ssh
sudo chmod 600 /home/newusername/.ssh/authorized_keys
These commands mirror the permission expectations outlined earlier, ensuring the new account’s keys are trusted immediately.
With the key in place, the user can log in over SSH without ever receiving a password, keeping the server hardened against brute-force attempts while remaining easy to administer.