Linux and Bash for Developers · Environment, Networking and Remote Access

SSH Keys, Permissions and Config

Create SSH keys, fix 'unprotected private key' errors, and simplify connections with ~/.ssh/config and jump hosts.

Create a free account to save this page, take notes and track your progress. Sign in

Scenario

A new developer can't log in to the bastion host: SSH ignores their key with UNPROTECTED PRIVATE KEY FILE!. Another team shares one private key in a chat channel, and everyone types long ssh -i ... -p ... user@host commands from a wiki page.

What you see in production

  • Permissions 0644 for 'id_ed25519' are too open and Permission denied (publickey).
  • Shared keys that can't be revoked for one person.
  • Long, error-prone SSH commands, and agent forwarding used to hop between hosts.

The naive code

cp shared_key ~/.ssh/id_rsa          # one key for the whole team
chmod 644 ~/.ssh/id_rsa              # "so it can be read"
ssh -i ~/.ssh/id_rsa -p 2222 -A [email protected]

Reproduce it

A private key with the wrong permissions
mkdir -p "$HOME/.ssh" && chmod 700 "$HOME/.ssh"
ssh-keygen -q -t ed25519 -N '' -C 'ana@laptop' -f "$HOME/.ssh/id_ed25519"
chmod 644 "$HOME/.ssh/id_ed25519"
ssh-keygen -y -f "$HOME/.ssh/id_ed25519" 2>&1 | grep -E 'UNPROTECTED|too open' | head -n 2 | sed "s|$HOME|~|"

Output

@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
Permissions 0644 for '~/.ssh/id_ed25519' are too open.

Run this on your computer — see “Get Started” for setup.

Root cause

SSH refuses private keys that other users could read, because anyone who can read the key can log in as you. Shared keys make it impossible to know who did what or to remove one person's access.

The fix

One key per person (and per machine), correct permissions, and a config file instead of long commands:

Keys, permissions and ~/.ssh/config
mkdir -p "$HOME/.ssh" && chmod 700 "$HOME/.ssh"
ssh-keygen -q -t ed25519 -N '' -C 'ana@laptop' -f "$HOME/.ssh/id_ed25519"
chmod 600 "$HOME/.ssh/id_ed25519"
stat -c '%a %n' "$HOME/.ssh" "$HOME/.ssh/id_ed25519" "$HOME/.ssh/id_ed25519.pub" | sed "s|$HOME|~|"
cat > "$HOME/.ssh/config" <<'EOF'
Host bastion
    HostName bastion.example.com
    User ana
    IdentityFile ~/.ssh/id_ed25519

Host app-*
    User deploy
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519
EOF
chmod 600 "$HOME/.ssh/config"
ssh -F "$HOME/.ssh/config" -G app-1 | grep -E '^(user|proxyjump|hostname) ' | sort

Output

700 ~/.ssh
600 ~/.ssh/id_ed25519
644 ~/.ssh/id_ed25519.pub
hostname app-1
proxyjump bastion
user deploy

Run this on your computer — see “Get Started” for setup.

  • ssh-keygen -t ed25519 creates a modern key; protect it with a passphrase and use ssh-agent.
  • Permissions: ~/.ssh 700, private keys 600, authorized_keys 600.
  • Add public keys to servers (ssh-copy-id or configuration management); remove them when people leave.
  • Use ProxyJump (or -J) to reach private hosts through a bastion instead of agent forwarding (-A), which lets the bastion use your agent.
  • ssh -G host prints the effective configuration without connecting, which is handy for debugging (-F file tests a specific config file).

Trade-offs

  • Passphrases add safety but need an agent for convenience.
  • For larger teams, SSH certificates (signed by a CA, short-lived) or cloud session managers scale better than managing authorized_keys files.
  • Hardware-backed keys (ed25519-sk) protect against key theft but need a security key present.

Detect it in production

  • Audit authorized_keys on servers against your team list.
  • Log and alert on SSH logins to production; prefer short-lived access.
  • ssh -v shows which keys are offered and why authentication fails.

Key points

  • Private keys must be readable only by you (600); ~/.ssh must be 700.
  • One key per person; never share private keys.
  • Use ~/.ssh/config and ProxyJump instead of long commands and agent forwarding.

Further reading: ssh_config(5) · ssh-keygen(1)

Practice questions

Why does SSH reject a private key with mode 644?

Answer

Other users could read the key and impersonate you, so ssh refuses keys that aren't private (600).

What's the advantage of ProxyJump over agent forwarding?

Answer

Your keys stay on your machine; with agent forwarding, anyone with root on the jump host can use your agent while you're connected.

How do you see the effective SSH settings for a host?

Answer

ssh -G host prints the configuration after applying ~/.ssh/config and defaults, without connecting.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?