On Fri, 25 May 2012, Stephen Gallagher wrote:
> You can access nss_nonlocal from here:
> 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
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
Basically, the expectation of both SSSD and libc is that if you add
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
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
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
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
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;
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
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 = \
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
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