The thing we need in CloudFS is authentication at the tenant level, so
that we can map a tenant's connection to the appropriate namespace and
UID/GID space. For all practical purposes, this is the same as
machine-level authentication. Trying to authenticate at a finer
granularity, e.g. for separate users on a single machine or set of
machines, is too cumbersome. Tenants will not accept having to register
each individual with a site-wide service, when no such need exists e.g.
on Amazon or Rackspace and integrating that service alongside whatever
auth* service they're already using themselves is likely to be painful.
We give each tenant a sandbox, and they can do whatever the heck they
want within it, just like they can with compute instances and so on already.
So, let's say that we have some way of providing strong authentication
between the login/cloud translators. At the end of the authentication
handshake we know, to a cryptographic certainty, that connection X
belongs to tenant Y. After that, though, all bets are off. Without
transport-level encryption, or at least per-message authentication via
HMAC or similar, we're vulnerable to session high-jacking and other
sorts of tampering with subsequent requests. Here's where we run into a
problem: there's no reasonable way to make GlusterFS (knowingly) use a
connection with these sorts of encryption/authentication properties.
We'd have to change a lot of code in the existing 3500-line socket
transport module, and do a very careful sweep through the management
code to make sure that our new transport can be configured etc.
This pretty much means that we need to use some external means - VPN,
sshuttle, cloud-provided firewalls, manually-set-up ssh tunnels - to
ensure security at the transport level. If we do that, we really
shouldn't need our own separate authentication. We should be able to
re-use whatever authenticated identity was used to establish the
connection in the first place, but I don't happen to know of any
generically-good way to do that e.g. with a VPN. Also, such an approach
might run into the same "requiring integration with a site-wide service
would be bad" problem as with the accounts themselves. That leads us
back to requiring our own authentication even though we're relying on
something else at the transport level, and we have two choices:
* Implement our own authentication using filesystem calls as the
communications channel. This is what we currently do, using setxattr.
It could be modified so that clients do something like read a block of
data from a pseudo-file and then use a private key to generate an HMAC
which is actually used to log in. This could be provably as secure as
other methods, but would be non-standard.
* Use somebody else's authentication. For example, we could use the
OpenSSL suite to generate client certificates signed by the provider.
The server could then open a TLS port for the client to connect to,
verify the cert's validity (using standard mechanisms and code) when the
client does so, and then map the identity in the cert to an internal
tenant ID. This might be more appealing to the "not safe unless it's on
our list" types, but it's a bit unpleasant in other ways (e.g. opening a
second hole in a firewall for the very brief TLS connection).
I'm mostly leaning toward doing our own authentication and leaving the
transport-layer encryption as "somebody else's problem" (with
appropriate documentation) but I'm open to other suggestions. Any ideas?