SSH Without a Password: Encrypted Key Authentication, ssh-agent, and Server Hardening

SSH without a password: authentication with encrypted keys

Logging in to a server with an SSH password works, but it is not ideal for either security or day-to-day operations. Passwords can be brute-forced, leaked, reused, and shared in unsafe ways. Key-based authentication replaces “something you know” with “something you have”: a private key stored on your device and a public key placed on the server. The server will only accept connections from clients that can prove they own the matching private key—and the private key is never sent across the network.

This approach is especially useful when you manage multiple servers, run automated deployments, execute backups, or collaborate in a team where each admin needs independent access. Modern SSH clients (OpenSSH on Linux/macOS, OpenSSH on Windows, PuTTY, etc.) support key authentication. If your workload runs on Virtual Servers, setting up keys is one of the first hardening steps you should do. The same best practice applies to Dedicated Servers, and for simpler projects you might choose Hosting where SSH access is often used for administration and deployment workflows.

1) How SSH keys work (the practical version)

An SSH key pair consists of a private key (kept only by you) and a public key (safe to store on the server). During login, the server sends a challenge that the client must sign with the private key. The server verifies the signature using the stored public key. If verification succeeds, authentication is granted. Because there is no password to guess, automated brute-force attacks become far less effective—especially when you also disable password authentication.

Protect your private key with a passphrase. That might sound like “still a password”, but it is different: the passphrase protects the key file locally. You can type it once and let an SSH agent cache the unlocked key for the session. If an attacker steals the private key file, a strong passphrase makes it much harder to use.

2) Generate a key pair (Linux/macOS/Windows OpenSSH)

For most environments, ed25519 keys are the recommended default: they are modern, fast, and provide strong security with shorter key material. RSA is still used in some legacy systems, but ed25519 is typically the best first choice today. Always generate keys on your local workstation—not on the server.

ssh-keygen -t ed25519 -a 64 -C "your.name@company"

The command creates two files: a private key (for example, ~/.ssh/id_ed25519) and a public key (for example, ~/.ssh/id_ed25519.pub). The -a option increases key derivation rounds, which strengthens protection if the private key file is ever stolen. After generation, confirm that your ~/.ssh directory and private key permissions are strict (700 for the directory, 600 for the private key).

3) Install the public key on the server

The easiest method is ssh-copy-id, which appends your public key to the server user’s ~/.ssh/authorized_keys and fixes permissions automatically.

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip

If ssh-copy-id is not available, you can do it manually: create ~/.ssh on the server, paste the public key into authorized_keys (one key per line), and set correct permissions. Do not paste your private key into authorized_keys.

mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Now test a login using the key:

ssh -i ~/.ssh/id_ed25519 user@server-ip

If everything is configured correctly, the server will not ask for the account password. You may still be prompted for your key passphrase locally (unless you use an agent).

4) Use ssh-agent for convenience (without sacrificing security)

ssh-agent stores unlocked keys in memory, so you do not have to re-enter your passphrase for every connection. On Linux/macOS it is commonly available; on Windows, the OpenSSH Authentication Agent can provide similar behavior. The goal is simple: unlock once, then connect many times.

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Once loaded, new SSH sessions can authenticate automatically. Remember the tradeoff: if your workstation is unlocked and your agent has the key loaded, anyone with access to your session can open SSH connections. Use screen lock, OS-level encryption, and sensible session timeouts.

5) Harden the server: make keys required and disable passwords

After you confirm key login works, you can dramatically reduce attack noise by disabling password authentication. Public servers are constantly scanned for SSH passwords; removing password auth stops most of that. Do this only after you have at least one working key and a fallback access method (console access from your provider, or an out-of-band channel).

Edit /etc/ssh/sshd_config and set values similar to:

PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no

Then restart SSH:

sudo systemctl restart sshd

Additional hardening steps: disable root login (PermitRootLogin no), create a dedicated admin user with sudo, and restrict SSH with firewall rules or VPN. Changing the SSH port is not a substitute for real security, but IP allowlists and fail2ban-style rate limits can be helpful in practice.

6) Common problems and fast debugging

If the server still asks for a password, common causes include: the public key was not installed under the correct user, permissions on ~/.ssh or authorized_keys are wrong, or the client is not offering the intended key. Verify ownership and permissions first—they are a frequent blocker. Also confirm you are connecting as the expected username.

If you see “Permission denied (publickey)”, enable verbose output on the client:

ssh -vvv user@server-ip

On the server, check authentication logs (for example, /var/log/auth.log on Debian/Ubuntu, or journalctl on systemd-based systems). Messages like “bad ownership or modes” usually point directly to the issue.

If you manage many hosts and multiple keys, create a ~/.ssh/config file to make connections consistent and reduce mistakes. You can define Host aliases, User, IdentityFile, and Port. This also helps when you rotate keys or separate environments (production vs staging).

If you work from Windows, you may use PuTTY or the built-in OpenSSH client. PuTTY often uses its own PPK key format, so you either convert keys or switch to Windows OpenSSH for consistency. In modern environments, standardizing on OpenSSH across Linux, macOS, and Windows reduces friction, especially for teams and documentation.

On key algorithms: ed25519 is a strong default, but some legacy systems or compliance requirements still ask for RSA (for example 3072 or 4096 bits). If you use RSA, make sure your environment supports modern signature algorithms and avoid outdated defaults. When in doubt, generate ed25519 for primary access and keep an RSA key only for compatibility scenarios.

For automation, consider separating keys by purpose. Use one key for human administrator access and a different restricted key for CI/CD, backups, or monitoring. Purpose-specific keys make incidents easier to isolate and allow you to revoke access without breaking unrelated workflows.

You can also restrict what a key can do on the server. In authorized_keys you can add options like from="..." to limit source IPs or command="..." to force a specific command. This is powerful for backup accounts, where you might allow only rsync and deny interactive shells. Restrictions reduce blast radius even if a key is compromised.

Finally, treat keys as an inventory. Periodically review authorized_keys, remove stale entries, and rotate keys when devices are replaced or when you suspect compromise. Put meaningful comments on keys (name, device, date) so future you can quickly understand what belongs to whom.

Checklist and best practices for teams

Before you disable password authentication, follow a checklist: (1) confirm key login from at least two devices (primary laptop and a backup), (2) ensure the private key has a passphrase, (3) use ssh-agent for usability, (4) disable root login and use sudo, (5) restrict SSH access via firewall/VPN where possible, (6) document which keys belong to which people and services.

For teams, never share a single key. Each admin should have their own key so access can be revoked cleanly by removing one public key entry from authorized_keys. For larger fleets, consider centralized key management and configuration automation. Treat key rotation and access reviews as a routine process, not a one-time setup task.