10

I'm administrating a RedHat server where users log in through SSH with private/pub key based authentication.

I'd like to prevent them from accidentally changing / deleting /chmoding the content of their ~/.ssh folders. Some of them have already recursively 777-chmoded their whole own home folder because "it was easier to share files with colleagues this way" and shot themselves in the foot.

Any idea how I can achieve this? Preferably with standard Linux permission system.

Sam B
  • 103
wecx
  • 203

4 Answers4

21

Short answer is you can't.

SSH is very picky about permissions and will not play with files it doesn't like the look of. Further, the users ssh_config is parsed before the system-wide config.

Having said that, it may be possible to put the files somewhere else and mount the directory as a read-only filesystem under $HOME/.ssh for each user. (It is possible - but I don't know how ssh and associated tools would treat this).

Some of them have already recursively 777-chmoded their whole own home folder

Then you have much bigger SECURITY and training issues.

symcbean
  • 23,767
  • 2
  • 38
  • 58
16

It is hard to protect users from their own ignorance and incompetence.

But depending on how much you need to allow your users to manage themselves and how much you manage for them: you can configure sshd to look for keys in an alternative location outside their home directory and elsewhere than ~/.ssh/authorized_keys.

AuthorizedKeysCommand

A relatively complex solution is the /etc/ssh/sshd_config AuthorizedKeysCommand directive which rather than relying on authorized_keys files specifies a program to be used for lookup of the user's public keys in for example:

  • a LDAP directory

  • a database

  • a (trivial) web service

  • or when your usernames are identical to Github usernames, you can allow users to authenticate with the keypair(s) that they've uploaded there:

    AuthorizedKeysCommand /usr/bin/curl https://github.com/%u.keys
    

As mentioned in this answer; you'll need to created a suitable SELinux policy for the AuthorizedKeysCommand as that gets blocked by the default policies.

I love this approach as it can solve many issues surrounding the management of authorized keys: it adds centralised management, removes the chicken-and-egg problem of getting authorized keys to servers when you want to disable password auth in ssh and more.
It leverages the fact that public keys are not particularly sensitive (unlike their associated private keys) so centralising their management doesn't add risk IMHO and probably even improves your control and reporting capabilities.

AuthorizedKeysFile

Slightly less complex is to store keys in a directory outside of their home directory. For example use /etc/ssh/<username> (replacing <username> with their actual username). This directory should have 755 permissions and be owned by the user. Move the authorized_keys file into it. The authorized_keys file should still have 644 permissions and be owned by the user.

In /etc/ssh/sshd_config adjust the AuthorizedKeysFile setting

AuthorizedKeysFile    /etc/ssh/%u/authorized_keys

And restart the ssh daemon

HBruijn
  • 84,206
  • 24
  • 145
  • 224
8

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.

marcelm
  • 1,168
2

Run a cron job to fix permissions each night.

Deleting files is a bit harder. You could possibly restore missing files from backup from cron also. But, it seems like you could get into weird edge cases with that... may need more intelligence than a script can provide. I'd start small and add features cautiously to a restore function.