The best solution I can think of is to make .ssh
and authorized_keys
root-owned.
Root-owned .ssh / authorized_keys
SSH is picky with permissions, but not unreasonably so. First, it requires that the user itself has read access to authorized_keys
(which requires read access to all parent directories). Second, it denies access if any user other than the user itself or root has write access to /home
, .ssh
, or authorized_keys
. This disallows o+w
, and g+w
for a group that has other users in it.
This setup works for me, the user can log in:
drwxr-xr-x 19 root root 4096 Sep 22 11:24 /
drwxr-xr-x 3 root root 4096 Sep 22 11:19 /home/
drwx------ 14 test test 4096 Sep 22 11:44 /home/test/
drwxr-x--- 2 root test 4096 Sep 22 11:42 /home/test/.ssh/
-rw-r--r-- 1 root test 98 Sep 22 11:36 /home/test/.ssh/authorized_keys
Since .ssh
and authorized_keys
are root-owned, the user cannot change permissions on them, or remove them. They also cannot edit their own authorized_keys
file.
If you want to allow the user to edit their authorized_keys
, you can add group-write permissions. This requires that the test
group has no other members than test
itself:
-rw-rw-r-- 1 root test 99 Sep 22 12:04 /home/test/.ssh/authorized_keys
With either approach, the user can no longer create their own files under .ssh
, so you may want to provide some extra files for them as well. Some that come to mind are: known_hosts
, config
, and id_rsa{.pub,}
or other key types.
Alternative: chattr
Some Linux filesystems supports file attributes, notably an immutable flag. Files/directories with the immutable flag set cannot be deleted, modified, or have their permissions changed. Only root can set/clear this flag.
This command would do the trick, even with the default ownership/permissions:
# chattr +i ~test/.ssh/{authorized_keys,}
Now .ssh
and authorized_keys
cannot be modified in any way, not even by root. If root needs to update these files, you'll need to chattr -i
them first. Use lsattr
to check for attributes.
This approach is simpler, but less flexible. It also needs filesystem support; I believe it's supported on at least ext2/3/4, XFS, and btrfs.
Posix ACLs?
There's also Posix ACLs (Access Control Lists), which allow a bit finer-grained control. I'm not too familiar with them, and I'm unsure if they are any help here.
StrictModes
Note: highly discouraged, but provided for completeness.
The OpenSSH server has a configuration directive called StrictModes
, which determines how picky SSH is with permissions:
Specifies whether sshd should check file modes and ownership of the user's files and home directory before accepting login. This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is yes
.
If you disable that option, you have more liberty in how to set up ownership and permissions. However, SSH is strict by default for good reasons. A user 777-chmodding their SSH files is a security risk.