Key-based SSH login to a Linux server fails with `Permission denied (publickey)` even though the right public key is present in `/home/deploy/.ssh/authorized_keys`, and the server's auth log shows `Authentication refused: bad ownership or modes for directory /home/deploy/.ssh`. What is sshd checking, and which ownership and permissions does it require?
answer
- the server ignored the file
- who else could edit it
- not just .ssh — the whole path
- group-writable home is enough
- 700 and 600, owned by the user
basics
~20 sOpenSSH's sshd runs with StrictModes yes by default: it ignores a key file that anyone but the owner could modify. The account's home directory must not be group- or world-writable, ~/.ssh should be 700 and authorized_keys 600, all owned by that user.
solid answer
~40 sThat log line is `StrictModes` doing its job. Before trusting `authorized_keys`, sshd walks the path to it and refuses if the home directory, `~/.ssh`, or the file itself is writable by group or others, or is not owned by the logging-in user (root-owned is also tolerated). The reasoning is simple: if another account can write that file, another account can add its own key and become this user, so a loose mode is treated as no key at all. The fix is `chown -R deploy:deploy /home/deploy/.ssh`, `chmod 700 /home/deploy/.ssh`, `chmod 600 /home/deploy/.ssh/authorized_keys`, and `chmod g-w,o-w /home/deploy` — a group-writable *home* directory is the case people miss, because the `.ssh` directory itself looks fine. Note the client enforces the mirror-image rule on your private key and refuses to use one that is world-readable.
code
bash · 5 linesnamei -l /home/deploy/.ssh/authorized_keys
chmod g-w,o-w /home/deploy
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.sshgo deeper
Remember the two numbers — 700 on ~/.ssh, 600 on authorized_keys and on your private key — and that loosening them further makes SSH refuse the key, not accept it.
Explain the reasoning: sshd will not trust a key list that a second account could edit, so it checks ownership and write bits along the whole path including the home directory itself.
Show a triage order for Permission denied (publickey) — server log first, then account, modes, filesystem label, login shell — and say why the client's message is intentionally uninformative.
Frame it as provisioning: on a fleet, loose home permissions come from a tool's umask or an image, so the durable fix is in the build and the config-management convergence, not a one-off chmod on the box that paged you.
## Why a working key can be ignored Public-key authentication is only as trustworthy as the file that lists the keys. If any account other than the owner can append a line to `~/.ssh/authorized_keys`, that account can log in as the owner. OpenSSH therefore does not just read the file — it checks who could have written it. The switch is `StrictModes`, which defaults to `yes`, and when the check fails sshd behaves as if the file were empty: the login falls through to whatever else is allowed, and the client sees the generic `Permission denied (publickey)`. The real reason appears only in the server's log: ``` Authentication refused: bad ownership or modes for directory /home/deploy/.ssh ``` That asymmetry — a useless client message and a precise server message — is the whole lesson of the question. When public-key login fails, the server log is the primary source, not the client. ## What exactly is checked sshd checks the *chain*, not just the file: - **The home directory.** Must be owned by the user (or root) and must not be group- or world-writable. `drwxrwxr-x deploy deploy` fails. - **`~/.ssh`.** Same rule. Conventionally 700. - **`authorized_keys`.** Same rule. Conventionally 600. Group-writable is enough to fail even when the group contains only that one user, because sshd cannot know that group membership will not change tomorrow. This is why the home directory is the usual culprit: someone ran `chmod -R g+w` over a shared project tree, or a provisioning tool created the home with a permissive umask, and `~/.ssh` underneath still looks textbook-correct. The canonical repair: ``` chown -R deploy:deploy /home/deploy/.ssh chmod 700 /home/deploy/.ssh chmod 600 /home/deploy/.ssh/authorized_keys chmod g-w,o-w /home/deploy ``` ## The mirror-image rule on the client The same idea applies to private keys, enforced by the `ssh` client rather than the server. A private key readable by others produces a loud refusal: ``` @@@@ WARNING: UNPROTECTED PRIVATE KEY FILE! @@@@ Permissions 0644 for '/home/alice/.ssh/id_ed25519' are too open. ``` and the key is simply not used, which again surfaces as `Permission denied (publickey)`. `chmod 600` on the private key fixes it. The public `.pub` file has no such requirement. ## Related causes with the same symptom Because the client message is identical for every public-key failure, keep a short ordered list for triage: 1. **Wrong account.** The key is in a different user's `authorized_keys`. 2. **Modes and ownership.** The case above; confirm from the server log. 3. **Filesystem label on SELinux hosts.** A `~/.ssh` restored from a backup or created by an unusual tool can carry a label sshd is not permitted to read, which produces a denial in the audit log rather than a modes message; `restorecon -Rv ~/.ssh` puts the default labels back. 4. **The account cannot log in at all** — a locked password field or a shell of `/usr/sbin/nologin` will refuse a perfectly good key. 5. **Encrypted or unreadable home directory.** With a home directory that is only decrypted after login, `authorized_keys` does not exist yet at authentication time, so key login cannot work from that path. ## Should you ever turn StrictModes off? It exists as a setting, so the question comes up. Turning it off does not fix anything — it removes the check that was telling you the file is writable by someone who should not have it. The underlying exposure remains, and it is a real one: a group-writable home on a multi-user box is a privilege-escalation path that has nothing to do with SSH specifically. Fix the modes. The only defensible discussion is about environments where home directories are provisioned by something you do not control, and there the answer is to fix the provisioning. ## How to confirm it in ten seconds ``` namei -l /home/deploy/.ssh/authorized_keys ``` `namei -l` prints the owner and mode of every component along the path, which makes a group-writable ancestor obvious at a glance and is faster than three separate `ls -ld` calls. Pair it with the server log line and you have both the symptom and the cause in one screen.
- Why does the client only ever print `Permission denied (publickey)` instead of naming the real reason?Deliberate. Telling an unauthenticated caller *why* a key was refused would leak whether the account exists, whether a key is installed, and how the server is configured. The detail is written to the server's auth log instead — `journalctl -u sshd` or the auth log file — which is why server-side logs are the first place to look for any public-key failure.
- The modes are correct and the log still refuses the key on a RHEL host. What else would you check?The filesystem label. On a host with SELinux enforcing, a `~/.ssh` created by a restore or an unusual tool can carry a type sshd is not allowed to read, and the refusal appears as an audit denial rather than a modes message. `restorecon -Rv ~/.ssh` restores the default labels. Also confirm the account is not locked and its shell is not `nologin`.
- A colleague proposes setting `StrictModes no` to make the problem go away. What is your response?It suppresses the warning, not the exposure. A group- or world-writable home means another account can append its own key to `authorized_keys` and impersonate the user, which is exactly the escalation the check exists to catch. Fix the permissions, and if a provisioning tool keeps recreating loose homes, fix the tool's umask instead.
saying these in an interview costs you the question
- Chmods 777 on ~/.ssh so sshd can definitely read it
- Checks only the file, never the home directory
- Thinks the client message names the real cause
- Says StrictModes off is a legitimate fix
- Claims the key file must be owned by root