[SSSD] Securing remote domains

Geoffrey Thomas geofft at MIT.EDU
Mon May 28 23:13:44 UTC 2012


On Fri, 25 May 2012, Stephen Gallagher wrote:

>> You can access nss_nonlocal from here:
>>
>>     http://debathena.mit.edu/nss_nonlocal/
>>     git://andersk.mit.edu/nss_nonlocal
>>     http://andersk.mit.edu/gitweb/nss_nonlocal.git
>>
>> It also contains the code for our security checks, so if you're
>> interested in the precise semantics, I suggest taking a look.
>> (And yes, we use internal glibc APIs, check nsswitch-internal.h)
>>
>
> Ok, I get the gist of this. It's pretty hackish though (and will likely
> only work with glibc, which is a problem because we're at least *trying*
> to maintain compatibility with any libc in SSSD).

It is very much a hack. :) At this point, though, changing glibc semantics 
upstream is hard, but SSSD is still young enough that we're hoping we can 
advocate for such a feature here, should the implementation be elegant and 
straightforward enough. We're certainly not suggesting that SSSD should 
incorporate that approach into its NSS module.

One possible way for this to be implemented more elegantly is if SSSD 
takes responsibility for handling /etc/passwd users too, such that it can 
implement the filtering logic internally before any data reaches libc (or 
any other potential consumer). I don't know how involved this change would 
be, or how compatible it would be with other libcs.

> Also, as I originally suspected, I'm pretty sure this code is not going
> to work with the new initgroups() semantics added to the last two
> releases of glibc.

Sigh. Our fault for relying on a hack anyway... I've made a note to test 
it out.

> Basically, the expectation of both SSSD and libc is that if you add a
> source for NSS data, it's *authoritative*. As in, you're asserting that
> what's in that central database is the correct answer for your
> environment. If that's not the case, then it's worth looking into fixing
> your central store (which is usually easier than futzing with individual
> clients).

So there are two use cases here, which are sufficiently related that we've 
solved them with the same approach of blacklisting all local uid/gids from 
the remote source:

1) Some of our systems, e.g. the public workstations we operate, may as 
well trust the central database, except for a couple of users/groups that 
overlap with system/local users, and we know those uids and gids. This is 
more or less solvable with a minimum uid constraint, but also quite 
solvable by the rule that local uids and gids hide matching remote uids 
and gids (and somewhat more automatic).

2) We do have privately-owned systems (folks coming in with laptops, etc.) 
that would like to have remote accounts but that aren't in any sense owned 
or operated by us, and so it's preferable for us not to require even the 
theoretical ability to spoof local accounts on their machine. Remote 
accounts are fine, but they are generally unprivileged and don't have root 
access. Allowing those accounts to do things like add themselves to the 
local wheel/sudo/etc. group would be problematic.

This is exacerbated in our environment because for legacy reasons we're 
using Hesiod, which is over DNS, without DNSSEC. We've been working for 
the last few years to either get LDAP (over SSL) usable for account 
lookups, or get DNSSEC on our Hesiod realm, but in a large organization 
with an overcommitted IT staff, these changes don't happen quickly, and 
writing a small NSS module let us get on with things. And even if we do 
get one of these usable (and switching to SSSD seems like the best way to 
fix the client-side issues we've run into with LDAP), we'd still want the 
same protection scheme.

> Also, there are valid reasons that you might want to extend local groups
> from the central server. For example, an application like a database
> might use a hard-coded group ID to determine which users can access the
> management console. Being able to add users to this list centrally is a
> significant advantage.

We do have some whitelisting capabilities; for instance, if you add the 
local (/etc/passwd) user named "nss-nonlocal-users" to a local group, then 
nss-nonlocal will permit the remote source to claim that users are in that 
local group. This isn't much used and we don't configure this 
out-of-the-box, but some of our end users have found this useful and 
requested it, e.g. to share files in a group-owned/setgid directory on 
local disk between a set of remote users.

> I'm not sure we want to build a specialized control in SSSD to suppress
> IDs that exist in /etc/group. For one thing, it's only a stop-gap
> solution, as a client still might have groups added from other NSS
> sources that we won't know about.

Sure. Note that in our implementation, we do query all NSS sources; 
something like

passwd: files db nis nonlocal
passwd_nonlocal: hesiod ldap

would work, and would allow /etc/passwd, /etc/passwd.db, and NIS to claim 
whatever they want, and filter all uids and gids in any of those out of 
Hesiod and LDAP results.

If SSSD takes responsibility for all nameservice sources, then this 
problem can be solved in SSSD's own configuration in roughly the same way 
(though with a much less hackish implementation).

> In recent versions of SSSD (1.7.0 and later), we have added support for
> more complex group search base filtering. You can now specify an LDAP
> search filter as part of the group search base to specifically eliminate
> groups you don't want to make visible to the local machine. For example:
>
> ldap_group_search_base = \
> cn=groups,dc=ex,dc=com?subtree?(!(|(gidNumber=10)(gidNumber=11)))
>
> This search base means that we'll look up and use any group in the
> cn=groups subtree except for those that have gidNumber 10 or 11.

So this doesn't really work for us because it involves trusting the remote 
server to do the filtering. In case 1 above that'd be fine, but in case 2 
above, a malicious or even just buggy directory server could fail to 
implement the filtering properly.

It's also somewhat complex to update this to match all local gids, which 
is a model that's been working well for us.

> On the whole, I think we have different concepts about the expectations
> of a central identity store. Everything we're discussing here suggests
> that you have concerns about trusting your identity store. That says to
> me that you're not in control of it, which is a security breach waiting
> to happen. I think you need to examine why you are relying on identities
> you don't control.

That's a fair perspective to take. Part of the reason we have concerns is 
less because _we're_ not in control of it as that our users are not in 
control of it, and would not be too happy to use a configuration that 
allows us (theoretically) to silently and remotely control their machines. 
We don't, for instance, add our SSH keys to people's laptop's 
/root/.ssh/authorized_keys, convenient as that might be for debugging, so 
why should we be able to spoof their local accounts that existed before 
they connected to our domain?

For the scripts.mit.edu project specifically, which is a web hosting 
environment using multiple servers for redundancy/reliability, one 
specific reason we have these concerns is to limit the ability of a breach 
on one server to escape to other servers. We synchronize user accounts 
through LDAP multimaster replication (using 389); each server's 
ldap://localhost is protected with nss_nonlocal. Should we accidentally 
misconfigure one server in a way that's exploitable, it's helpful that 
it's not trivially easy for the attacker to spoof root (or equivalent) on 
the rest of our servers. On the one or two occasions we've had security 
incidents in the last several years, we just took down the one problematic 
server and the rest of the system could run.

It's also an excellent defense-in-depth strategy for particularly 
sensitive servers like build machines. It's convenient to have the usual 
stack installed so e.g. `ls -l` displays useful usernames, but no remote 
accounts have any form of administrative access on the build server. We've 
reserved a remote account name and uid for the "builder" user, but the 
account exists locally, overriding the remote one.

If no account from the remote domain has any sort of administrative access 
to the local machine, it isn't particularly problematic for those users to 
exist. And in our scenario of a large environment where it's useful for 
UIDs to match throughout all systems should they ever need to interoperate 
-- UNIX machines, Windows boxes, files in networked storage, web 
applications, etc. etc. -- restricting the ability of the directory server 
to have a "master key" to every computer on campus that happens to be 
interacting with it is useful to maintain the principle of least 
privilege.

-- 
Geoffrey Thomas
geofft at mit.edu



More information about the sssd-devel mailing list