Client Security for CephFS


Add enhanced client security for CephFS, limiting access to subtrees of the filesystem.


  • Mike Kelly

Interested Parties

  • Greg Farnum
  • Sage Weil
  • Xiaobing Zhou(xzhou40 (AT)
  • Anip Patel (Arizona State University(student))
  • Danny Al-Gaaf (Deutsche Telekom)

Current Status

Currently, access to CephFS is essentially "all or nothing." While it's possible to assign certain locations in the CephFS tree to store their data in certain RADOS pools, and access to those can be restricted effectively, the same isn't true for file metadata via MDS. This would be an extension of the existing capabilities framework to MDS.

Detailed Description

CephFS would be useful more places if it were possible to restrict access to parts of it to specific client keys. Some proposed capabilities syntax:

mon = "allow r" 
osd = "allow rw pool=guest01-data, allow r pool=common-data" 
mds = "allow rw tree=/guests/guest01, allow r tree=/guests/common" 

This means that a client with these capabilities could mount "/guests/guest01" with full read/write access, and mount "/guests/common" with read-only access. In order to protect the data against someone just sniffing around the 'data' object pool, each of these trees would need to be set up to store their data in a separate pool.
gregaf & sage gave some hints on IRC for how this may be implemented, yesterday and today:

18:23:34 < gregaf> the way to go about it would probably be to add client security caps to the MDS, which specify what part of the tree they're allowed to access
18:23:51 < gregaf> and then on incoming client requests compare those allowances to the dentries that the request is touching
18:25:56 < sage> gregaf: probably yes if you consider the DoS stuff, but we could probably add a pretty simple generic check right after the locking step that verifies inodes are in the right subtrees
18:26:42 < gregaf> sage: I was actually thinking it should be able to do a dentry comparison before it even locks, right?
18:27:06 < sage> that too. may want both to avoid issues with hard links across subtree boundaries and such
18:27:25 < sage> but even a rough check will cover most use cases (no hard links etc)

14:07:30 < gregaf> I think basically you'll want to add a "can_access_path(dentry_path, client_caps)" function to the MDS somewhere
14:07:46 < gregaf> and then all the handle_client_* methods will run that for each path the client message is dealing with
14:07:58 < gregaf> and yes, you probably want to look in that folder, starting from...
14:08:26 < gregaf> MDS::_dispatch in
14:09:06 < gregaf> or perhaps handle_deferrable_message would be easier; which passes stuff on mostly to Server::dispatch, which splits them out into
14:09:39 < gregaf> handle_client_lookup, handle_client_getattr, etc etc etc

Work items
Check discussion on Pad: