NoctisNode
← GuidesSecurity2026-10-238 min

SSH StrictModes, Agent Forwarding (ssh -A) and ssh -a Explained

SSH StrictModes refuses keys if home, ~/.ssh or authorized_keys are writable by others; fix with chmod. Avoid ssh -A on untrusted hosts; ssh -a disables it.

Short answer: `StrictModes yes` (the OpenSSH default) makes sshd check the ownership and permissions of your home directory, `~/.ssh` and `~/.ssh/authorized_keys` before accepting a key, and it refuses login with "Authentication refused: bad ownership or modes" if any of them is writable by group or others or owned by another user. Fix the permissions rather than disabling the check. Agent forwarding with `ssh -A` lets the remote host use your local keys while you are connected, so avoid it on hosts you do not fully trust and use `ssh -J` (ProxyJump) instead; lowercase `ssh -a` explicitly disables agent forwarding.

This guide complements the SSH hardening guide and applies to Debian 12/13, Ubuntu 24.04 and RHEL-family systems such as AlmaLinux 9 and Rocky 9.

What SSH StrictModes checks

StrictModes is a server-side setting in `/etc/ssh/sshd_config`. Its purpose is simple: if another user could write to your `authorized_keys`, they could add their own key and log in as you. So sshd refuses to trust the file unless the whole path is protected. It checks the file and the directories above it, including the home directory.

Confirm the effective value with `sshd -T | grep -i strictmodes`. On Ubuntu 24.04 and Debian 13, also check drop-in files in `/etc/ssh/sshd_config.d/`.

PathRequired by StrictModesRecommended mode
/home/aliceOwned by alice or root, not group/world-writable755, 750 or 700
/home/alice/.sshOwned by alice or root, not group/world-writable700
/home/alice/.ssh/authorized_keysOwned by alice or root, not group/world-writable600
/root and /root/.ssh (root login)Owned by root, not group/world-writable700

Fix "Authentication refused: bad ownership or modes"

The client only shows a generic `Permission denied (publickey)`. The real reason is in the server log, which names the exact path, for example `Authentication refused: bad ownership or modes for directory /home/alice` or `... for file /home/alice/.ssh/authorized_keys`. Use your VPS console or another session to fix it.

  1. 01.Read the log: `journalctl -u ssh -n 50` on Debian and Ubuntu, or `journalctl -u sshd -n 50` on AlmaLinux and Rocky.
  2. 02.Fix ownership of the user's SSH directory: `chown -R alice:alice /home/alice/.ssh`.
  3. 03.Fix modes: `chmod 700 /home/alice/.ssh` and `chmod 600 /home/alice/.ssh/authorized_keys`.
  4. 04.Remove group and world write from the home directory: `chmod go-w /home/alice`.
  5. 05.On SELinux systems (AlmaLinux, Rocky, Fedora), restore labels: `restorecon -Rv /home/alice/.ssh`.
  6. 06.Test from a new terminal with `ssh -v alice@server` while keeping the working session open.
# all-in-one, run as root on the server
chown -R alice:alice /home/alice/.ssh
chmod go-w /home/alice
chmod 700 /home/alice/.ssh
chmod 600 /home/alice/.ssh/authorized_keys
namei -l /home/alice/.ssh/authorized_keys   # shows owner and mode of every path component

Note · Do not set `StrictModes no` to make the error go away. It removes a real protection and hides the misconfiguration instead of fixing it.

StrictModes vs StrictHostKeyChecking

Searches for "ssh strictmode" often mix up two unrelated options. `StrictModes` lives in `sshd_config` on the server and checks file permissions. `StrictHostKeyChecking` lives in `ssh_config` or `~/.ssh/config` on the client and controls what happens when a server's host key is unknown or has changed. The client also has its own permission check: it refuses to use a private key that other users can read, with a warning about an unprotected private key file; `chmod 600 ~/.ssh/id_ed25519` fixes that.

Agent forwarding with ssh -A: the risk

`ssh -A` (or `ForwardAgent yes`) creates a socket on the remote host, referenced by `$SSH_AUTH_SOCK`, that relays signing requests back to the ssh-agent on your machine. Your private key never leaves your machine, but anyone who can access that socket can use your key while you are connected. On the remote host, that includes root and any process running as your user.

If the server is compromised, or administered by someone else, an attacker can silently log in to every other host your key opens, including Git hosting and production servers. That is why the OpenSSH client defaults to `ForwardAgent no`.

  • ▹Never forward your agent to shared, third-party or freshly reinstalled hosts you have not hardened.
  • ▹If you must forward, use `ssh-add -c` so each use of the key requires local confirmation.
  • ▹OpenSSH 8.9 and newer support destination constraints with `ssh-add -h`, limiting which hosts a forwarded key may be used for.
  • ▹Server-side, `AllowAgentForwarding no` in `sshd_config` disables it, though users with shell access can still set up their own forwarders.

Prefer ProxyJump (ssh -J) for bastions

Most agent forwarding is used to hop through a bastion to an internal machine. `ssh -J` does this without exposing your agent: the bastion only forwards an encrypted TCP stream, and authentication to the internal host happens end to end from your laptop. For servers reachable only over a private network, a WireGuard tunnel is another option; see the WireGuard VPN guide or the WireGuard mesh guide, and for keepalive and PSK settings this WireGuard tuning guide.

On a NoctisNode VPS you get full root over SSH on a KVM machine, so a small Wisp plan can serve as a dedicated jump host with nothing else running on it; see VPS plans.

# one-off
ssh -J [email protected] [email protected]

# ~/.ssh/config
Host bastion
    HostName bastion.example.com
    User alice
    ForwardAgent no

Host db1
    HostName 10.88.0.3
    User alice
    ProxyJump bastion

What ssh -a (lowercase) does

Lowercase `ssh -a` disables agent forwarding for that connection, the opposite of `-A`. It is useful when your `~/.ssh/config` enables `ForwardAgent` for a wildcard host and you want to make sure one specific connection does not forward, for example `ssh -a admin@untrusted-host`. Do not confuse it with `ssh-agent -a`, which sets the path of the agent's socket, or `ssh-add`, which loads keys into the agent.

FAQ

QWhat does StrictModes do in sshd_config?

AIt makes sshd check that the user's home directory, ~/.ssh and authorized_keys are owned by the user or root and not writable by group or others. If the check fails, key authentication is refused.

QHow do I fix Authentication refused: bad ownership or modes?

ARun `chmod go-w ~`, `chmod 700 ~/.ssh` and `chmod 600 ~/.ssh/authorized_keys`, and make sure the files are owned by the user. The server log names the exact path that is wrong.

QIs ssh -A agent forwarding safe?

AOnly on hosts you fully trust. While you are connected, root or a compromised account on the remote host can use your forwarded agent to authenticate as you elsewhere; use `ssh -J` instead.

QWhat is the difference between ssh -A and ssh -a?

AUppercase `-A` enables forwarding of your ssh-agent to the remote host. Lowercase `-a` disables agent forwarding for that connection, overriding any `ForwardAgent yes` in your config.

QShould I set StrictModes no?

ANo. Disabling it allows logins even when other users could modify your authorized_keys, which is a real security hole; fix the ownership and permissions instead.

SSH StrictModes, Agent Forwarding (ssh -A) and ssh -a Explained · NoctisNode