Nested netgroups for fun and profit

Imagine you have several hundred systems to manage. The systems are for separate projects and each project has different teams of admins and only assigned admins should be able to log into the system (and at best only be seen on the system). However it should be easy to setup, just be configured on a central system. This is what i came up with.

Obviously the solution for a central system can be adressed with LDAP. Nobody sets up a new NIS Environment today ;)

I wasn’t really keen to configure netgroups directly in LDAP, so i created a file representing this:

root@client1:~# cat netgrouptemplate
wg1 (,ngtc1u1,) (,ngtc1u2,) (,ngtc1u3,) (,ngtc1u4,) (,ngtc1u5,)
wg2 (,ngtc2u1,) (,ngtc2u2,) (,ngtc2u3,)
wg3 (,ngtc2u4,) (,ngtc2u5,)
proj1 wg1
proj2 wg2 wg3
client1 proj1
client2 proj2

The idea is that you group users (ngt*) into working groups (wg*), which are connected to projects (proj*)which are connected to servers (client1 and client2 are the hostnames of two Solaris 11.4 VMs, client is used in the sense of ldap clients). For each server there is a top-level netgroup named like the server.

%3 Servernetgroup Server Netgroup Projectnetgroup project Netgroup Servernetgroup->Projectnetgroup Workgroupnetgroup Workgroup Netgroup Projectnetgroup->Workgroupnetgroup User User Workgroupnetgroup->User

The structure of our organization as represented by the template would be like

%3 client1 client1 proj1 proj1 client1->proj1 client2 client2 proj2 proj2 client2->proj2 wg1 wg1 proj1->wg1 wg2 wg2 proj2->wg2 wg3 wg3 proj2->wg3 ngtc1u1 ngtc1u1 wg1->ngtc1u1 ngtc1u2 ngtc1u2 wg1->ngtc1u2 ngtc1u3 ngtc1u3 wg1->ngtc1u3 ngtc1u4 ngtc1u4 wg1->ngtc1u4 ngtc1u5 ngtc1u5 wg1->ngtc1u5 ngtc2u1 ngtc2u1 wg2->ngtc2u1 ngtc2u2 ngtc2u2 wg2->ngtc2u2 ngtc2u3 ngtc2u3 wg2->ngtc2u3 ngtc2u4 ngtc2u4 wg3->ngtc2u4 ngtc2u5 ngtc2u5 wg3->ngtc2u5

How the users are put into this group is up to the structure you want. There is no necessity to have a netgroup for each server, but it makes the movement of the server to a new admin team easier without touching the server, as you are not bound to any grouping that you have done in the past.

Essentialy you have to do one step on the server. The rest is done in LDAP.

Import the template into the server. By the way, you can use the ldapaddent command to import other preexisting nameservice files like /etc/passwd into the ldap as well. Please consult the man page for this task.

root@client1:~# ldapaddent -D "cn=admin,ou=profile,dc=moellenkamp,dc=internal" -w n0mn0mn0m -c -f netgrouptemplate netgroup

The representation of our template in LDAP looks like this.

version: 1

dn: ou=netgroup,dc=moellenkamp,dc=internal
objectClass: organizationalUnit
objectClass: top
ou: netgroup

dn: cn=wg1,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: wg1
nisNetgroupTriple: (,ngtc1u1,)
nisNetgroupTriple: (,ngtc1u2,)
nisNetgroupTriple: (,ngtc1u3,)
nisNetgroupTriple: (,ngtc1u4,)
nisNetgroupTriple: (,ngtc1u5,)

dn: cn=wg2,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: wg2
nisNetgroupTriple: (,ngtc2u1,)
nisNetgroupTriple: (,ngtc2u2,)
nisNetgroupTriple: (,ngtc2u3,)

dn: cn=wg3,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: wg3
nisNetgroupTriple: (,ngtc2u4,)
nisNetgroupTriple: (,ngtc2u5,)

dn: cn=proj1,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: proj1
memberNisNetgroup: wg1

dn: cn=proj2,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: proj2
memberNisNetgroup: wg2
memberNisNetgroup: wg3

dn: cn=client1,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: client1
memberNisNetgroup: proj1

dn: cn=client2,ou=netgroup,dc=moellenkamp,dc=internal
objectClass: nisNetgroup
objectClass: top
cn: client2
memberNisNetgroup: proj2

Afterwards you have to add the following line to /etc/pam.d/others

account required        pam_list.so.1 allow=/etc/users.allow

Please keep in mind, that you need to add this line as well into PAM services that already have account lines as others is only active when a PAM service has not its own configuration for a section. If you don’t do this, thee service won#t use that line above which is needed to bring this configuration to work.

Now we do the one step that connects the server to the the nested netgroup and thus to the whole idea.

root@client2:/# cat /etc/users.allow
root
jmoekamp
@client2

This is the only place where you have to do something on the client. Everything else is done on the LDAP server. The last line must be an @ followed with the name of the host as explained before. You never change this. The assignment of users is done by nesting other groups into the netgroup with the name of the server.

Let’s check this ngtc2u1 is member of working group 2 (wg2) which is member of Projekt 2 (proj2) which is member of the netgroup for client2.

joergmoellenkamp@MBPvonc0t0d0s0 ~ % ssh ngtc2u1@192.168.30.173
Password: 
Could not chdir to home directory /export/home/ngtc2u1: No such file or directory
Oracle Corporation      SunOS 5.11      11.4    March 2020
-bash-5.0$ exit

ngtc1u1 isn’t part of netgroup client2 or a nested netgroup inside of the netgroup client2 and thus shouldn’t be able to login to the system.

joergmoellenkamp@MBPvonc0t0d0s0 ~ % ssh ngtc1u1@192.168.30.173
Password: 
ngtc1u1@192.168.30.173's password: 
Connection closed by 192.168.30.173 port 22

When you have logged into the system, you are able to su into a different user of the same netgroup client2 (or a nested one).

-bash-5.0$ su  ngtc2u3
Password: 
bash-5.0$

Try the same again with a user outside of this netgroup and it won’t work.

bash-5.0$ su ngtc1u1
Password: 
su: Permission denied