Notes on user/group manipulation in ldap¶
Security issues:¶
End users can overwrite shadowlastchange settings thereby circumventing password aging restrictions
ssh/pka does not honor forced password resets (pwdrest=true), pwd aging restrictions when using ppolicy pwdmaxage, nor pwd locking via pwdAccountLockedTime.
ssh/pka does honor these settings for local accounts
ssh does honor these settings (not using keys)
Goals:¶
How to enforce pwd aging and restrictions (ppolicy: pwdmaxage: done)
How to force a pwd change upon first acess after a pwd reset. (pwdreset: done)
How to administratively (un)lock an account. (pwdAccountLockedTime: done)
How to force password complexity.
Experiment with alternate password policies.
How to lock users to a specific set of hosts
host object done:
sssd ldap_access_filter in the works
How to add/delete users from groups (done)
How to configure sudo privs via ldap
Update centos installation doc with requisite overlays:
ppolicy
memberof
Update centos installation doc with updates to group definitions required by rfc2307bis:
member
objectclass: groupofnames
Status:¶
01/10/14:
Working on a blog entry at http://itdavid.blogspot.com/2012/05/howto-openldap-2.html
IMMEDIATELY got irritated w/the constant ldif crap that has to come about…
So, I wrote and documented a script
That’ll get me past the tedious crap and we can continue on with more interesting aspects.
Script covered the past few days so I’m going to take a break for awhile.
Password restrictions:¶
W/openldap 2.4, this is apparently done as an overlay. While reading through the overlay section of the admin guide, I see something called Reverse Group Membership Maintenance which provides support for identifying which groups an entry is a member of without performing an additional search. Examples for the usefulness is using the DIT for access control based on group authorization. Guide doesn’t go into how to configure that authentication, though.
From the slapo-ppolicy(5) man page:
Every account that should be subject to password policy control should have a pwdPolicySubentry attribute containing the DN of a valid pwdPolicy entry, or they can simply use the configured default.
Enables having different password policies for different users. Could be useful for system accounts, ones that have NP set as their encrypted password (and, thusly disabling password authentication).
Aging parameters measured in seconds.
pwdMaxAge : 7776000 = 90 days.
Nothing specific for password complexity. There is a pwdCheckModule which looks like it’d fit the bill; but nothing pre-defined.
Finding out what I don’t know. I need to add a module section of the cn=config. Apparently, I don’t have one of those…
The ldif looks like:
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModuleLoad: ppolicy
olcModulePath: /usr/lib64/openldap
and the command:
# ldapadd -Y EXTERNAL -H ldapi:/// -f ./module.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=module,cn=config"
Well, that’s a good sign. The guide from which I’m taking this says I should restart slapd. Got a warning, though. Not too happy about that. Continuing, in the hopes that the warning is simply missing policy info
# service slapd restart Stopping slapd: [ OK ] Checking configuration files for slapd: [WARNING] config error processing cn=module,cn=config,cn=config: config file testing succeeded Starting slapd: [ OK ]
Not so good… it won’t let me do anything anymore w/any authentication.
Restoring my backup to see if I can regain access. That’s good…
//later that same day. I re’genned the ldap directory and then made another copy of the ldapsvr disk so that I can always get back to the clean ldap server. The reason I did this is that I was suspecting permissions issues with the ppolicy addition. Now that everything’s back up and running, I don’t believe that’s the case; however, it’s good to have the new starting point anyway.
01/16/14: It seems I’ve gotten further. This time around, I added the policies ou then added the module. When I restarted slapd, no warnings…
Interesting. Wonder what was different from the other day. The password policy is currently active. Steps:
Add the policies ou - (top part of policies.oci.com.ldif), as cn=admin
Add the loadable module: module.ldif: as cn=config
Add the ppolicy overlay: ppolicy-overlay.ldif as cn=config
Add default policy as cn=admin
dn: cn=default,ou=policies,dc=oci,dc=com cn: default objectClass: top objectClass: device objectClass: pwdPolicyChecker objectClass: pwdPolicy pwdAttribute: userPassword pwdInHistory: 8 pwdMinLength: 8 pwdMaxFailure: 3 pwdFailureCountInterval: 900 pwdCheckQuality: 1 pwdMustChange: TRUE pwdGraceAuthNLimit: 0 pwdMaxAge: 7776000 pwdExpireWarning: 604800 pwdLockoutDuration: 300 pwdLockout: TRUE
01/18/14
After getting everything added as described above, I found that any log ins
to client1 were repeatedly getting forced to change passwords and I could
cycle them back and forth. Examining everything showed that I messed up the
ppolicy overly by having olcPPolicyDefault: cn=default,ou=policies,dc=example,dc=com
.
dc=example vs dc=oci
Correcting that should have been simple but it took me a bit to find:
# cat modify_ppolicy-overlay.ldif
dn: olcOverlay={0}ppolicy,olcDatabase={2}bdb,cn=config
changetype: modify
replace: olcPPolicyDefault
olcPPolicyDefault: cn=default,ou=policies,dc=oci,dc=com
# ldapmodify -Y EXTERNAL -H ldapi:/// -f ./modify_ppolicy-overlay.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcOverlay={0}ppolicy,olcDatabase={2}bdb,cn=config"
That corrected, user accesses to client1 still constantly forced a pwd reset. On a whim, I tried one of the other systems and the pwd policy’s working. WTF? Oh yea, client1 is using legacy nslcd vs sssd authentication. Another troubleshooting thing to go on the list.
I’m going to reset client1 to use sssd so I have three clients with which to play.
While that’s going on, the next challenge was how to figure out that an account is actually locked. Turns out that it’s not that easy. I purposely locked an account, then viewed the entry:
# ldapsearch -LLLxD cn=admin,dc=oci,dc=com -w "${pwd}" \
-b dc=oci,dc=com uid=aaaa
dn: uid=aaaa,ou=users,dc=oci,dc=com
cn: aaaa
gecos: aaaa test user
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
shadowMin: 0
shadowMax: 90
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 604
gidNumber: 614
homeDirectory: /home/aaaa
uid: aaaa
userPassword:: [[snipped]]
Nothing in there says locked. After much searching, I finally found out
the parameter is that I’m looking for is pwdAccountLockedTime
and that
it’s not displayed in the normal uid.
# ldapsearch -LLLxD cn=admin,dc=oci,dc=com -w "${pwd}" \
-b dc=oci,dc=com uid=aaaa pwdaccountlockedtime
dn: uid=aaaa,ou=users,dc=oci,dc=com
pwdAccountLockedTime: 20140118190653Z
I updated the ldap script to show that parameter on searches:
# ldap -search uid=dddd
------------------------------------------------------------------------
dn:uid=dddd,ou=users,dc=oci,dc=com
cn: dddd
gecos: dddd test user
objectClass: top
account
posixAccount
shadowAccount
shadowMin: 0
shadowMax: 90
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 940
gidNumber: 614
homeDirectory: /home/dddd
uid: dddd
userPassword: [[snipped]]
pwdAccountLockedTime: 20140119043611Z
Also had some practice with modifying the password policy. The LDIF is:
# cat modify_policies.ldif
dn: cn=default,ou=policies,dc=oci,dc=com
changetype: modify
replace: pwdMustChange
pwdMustChange: TRUE
-
replace: pwdCheckQuality
pwdCheckQuality: 0
Just changed lockout time to half an hour to give me some time to work out the process for unlocking the poor dear.
LDIF to reset a pwd and forcing a pwd reset on next login:
# cat reset_pwd.ldif
dn: uid=aaaa,ou=users,dc=oci,dc=com
changetype: modify
replace: userPassword
userPassword: {SSHA}GP5kKswAvk+PBRvZDsPKzcG6rD4lTp8E
-
add: pwdReset
pwdReset: TRUE
That encrypted pwd is ‘1changeme’
Interestingly, the next login wouldn’t let me use my standard pwds which should meet just about any complexity guidelines… Which, turned out to be the pwd history depth. Very misleading message.
Password change failed. Server message: Please make sure the password meets the complexity constraints.
passwd: Authentication token is no longer valid; new one required
Connection to client1 closed.
Reset the pwd history to 2 while I work through the pwd policy.
Next step is to modify the ldap script to reset passwords. Don’t want to do that today, though.
// later that same day
OK; so that’s done. the ldap command re-enables accounts and resets passwords with an optional force arg. nice.
Reviewing today’s progress:
To set up password policies:
Enable the ppolicy module and restart slapd:
# cat module.ldif dn: cn=module,cn=config objectClass: olcModuleList cn: module olcModuleLoad: ppolicy olcModulePath: /usr/lib64/openldap # ldapadd -Y EXTERNAL -H ldapi:/// -f ./module.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=module,cn=config" # service slapd restart Stopping slapd: [ OK ] Starting slapd: [ OK ]
Define the ppolicy overlay and default policy:
# cat ppolicy-overlay.ldif dn: olcOverlay=ppolicy,olcDatabase={2}bdb,cn=config objectClass: olcPPolicyConfig olcOverlay: ppolicy olcPPolicyDefault: cn=default,ou=policies,dc=oci,dc=com # olcPPolicyUseLockout: TRUE # olcPPolicyHashCleartext: TRUE # ldapadd -Y EXTERNAL -H ldapi:/// -f ./ppolicy-overlay.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "olcOverlay=ppolicy,olcDatabase={2}bdb,cn=config"
Create the policies ou and the default policy:
# cat policies.oci.com.ldif dn: ou=policies,dc=oci,dc=com objectClass: organizationalUnit objectClass: top ou: policies dn: cn=default,ou=policies,dc=oci,dc=com cn: default objectClass: top objectClass: device objectClass: pwdPolicyChecker objectClass: pwdPolicy pwdAttribute: userPassword pwdInHistory: 8 pwdMinLength: 8 pwdMaxFailure: 3 pwdFailureCountInterval: 900 pwdCheckQuality: 1 pwdMustChange: TRUE pwdGraceAuthNLimit: 0 pwdMaxAge: 7776000 pwdExpireWarning: 604800 pwdLockoutDuration: 300 pwdLockout: TRUE # ldapadd -x -D cn=admin,dc=oci,dc=com -w "${pwd}" -f ./policies.oci.com.ldif adding new entry "ou=policies,dc=oci,dc=com" adding new entry "cn=default,ou=policies,dc=oci,dc=com"
Other useful ldifs:
To identify if an account is locked:
# ldapsearch -LLLxD cn=admin,dc=oci,dc=com -w "${pwd}" \ -b dc=oci,dc=com uid=aaaa pwdaccountlockedtime dn: uid=aaaa,ou=users,dc=oci,dc=com pwdAccountLockedTime: 20140118190653Z
if pwdAccountLockedTime is present and the time is within the pwdLockoutDuration, then the account is locked.
To reenable a locked account: (use the ldap script or):
# cat enable_acct.ldif dn: uid=aaaa,ou=users,dc=oci,dc=com changetype: modify delete: pwdAccountLockedTime # ldapmodify -x -D cn=admin,dc=oci,dc=com -w "${pwd}" -f ./enable_acct.ldif
To reset an account’s password:
ldappasswd (automatically encrypts password):
ldappasswd -xD cn=admin,dc=oci,dc=com -w "${pwd}" \ -s "new_secret" uid=aaaa,ou=users,dc=oci,dc=com
Use the ldap script
ldif:
# cat reset_pwd.ldif dn: uid=dddd,ou=users,dc=oci,dc=com changetype: modify replace: userPassword userPassword: ${new_hash_from_slappasswd} # ldapmodify -x -D cn=admin,dc=oci,dc=com -w "${pwd}" -f ./reset_pwd.ldif
To force a passwd change on next access:
Use the ldap script
ldif:
# cat reset_pwd.ldif dn: uid=dddd,ou=users,dc=oci,dc=com changetype: modify replace: userPassword userPassword: {SSHA}9AqxMA9lUKLmYAmjLADsBMbttu0FRJ2k - add: pwdReset pwdReset: TRUE # ldapmodify -x -D cn=admin,dc=oci,dc=com -w "${pwd}" -f ./reset_pwd.ldif
Tomorrow’s goal is to:
(done) First and foremost, redo the updates to ldap wrapper script
(done) Reset ldapsvr to empty directory
(done) Reset clients to clean set ups, using sssd authentication
(done) Verify end to end ppolicy configuration
Write up an ll entry
01/19/14: Like a dumb fuck, I reverted the ldapsvr image before backing up the ldap wrapper script so I lost my changes to the fucker. Damn me as a dumb fuck!
Finally got smart and created a bare repo on mgmt to hold any updates to the ldap govno.
Interesting: I’m finding evidence that the shadow entries in the account aren’t used anymore - particularly once the the ppolicy is in place. I finally have a need to update the ldap command to add/replace/delete arbitrary shit in a dn. This should make it incredibly dangerous.
Updating today’s goals:
Research different impacts of pwdchangetime/shadowlastchange on policy standards of pwdMaxAge/shadowMax
That’s going to be a bit interesting. I was hoping I’d be able to set the pwdchangedtime back; but, apparently, I can’t edit that parameter. Nice! Attempts to do so resulted in:
failed to alter attribute: pwdchangedtime: no user modification allowed
I can change the pwdmaxage parameter in the policy to be something like 5 minutes; that’d at least let me experiment with expired passwords - how to verify them and how to repair them.
I also parameterized the userdn and groupdn so the ldap wrapper script should be finished. Time to update the ll entry
01/20/14: Not going to get a lot of time today. I want to play around w/passwd expiration via the ppolicy overlay. I set the pwdmaxage to 300 seconds - 5 minutes. Boy, that’d irritate the little darlin’s, wouldn’t it?
Set the pwdmaxage to 5 minutes and verified that anyone not changing their passwords in that five minutes were forced to change them again. That sure would upset the poor darlins, wouldn’t it? That, and set the pwdinhistory to 50. heh.
Next, I just verified that a normal user can rewrite the shadowLastChange parameter with a simple ldapmodify command:
# cat reset_shadowLastChange.ldif
dn: uid=aaaa,ou=users,dc=oci,dc=com
changetype: modify
replace: shadowLastChange
shadowLastChange: 16045
ldapmodify -xD uid=aaaa,ou=users,dc=oci,dc=com -w "${pwd}" \
-f ./reset_shadowLastChange.ldif
modifying entry "uid=aaaa,ou=users,dc=oci,dc=com"
I wonder if I can do that @ work…
Fuck, sure enough, that’s not just a openldap issue.
So, an incredibly good reason to convert from the shadow functionality to the ppolicy. That goes into the lessons learned…
02/15/14: Been a bit since I’ve been able to work on this. Got the password policy functionality pretty well hammered down. I want to play around with some alternate password polices, maybe ones that say no password expiration or password different password complexities.
Next on the hit list is password complexity
//later that same day: Out-f’ing-standing! ldap honors the password comlexity settings defined in /etc/pam.d/system-auth.
password required pam_cracklib.so retry=3 minlen=12 difok=4 ucredit=1 lcredit=0 dcredit=1 ocredit=2
password required pam_pwhistory.so use_authtok remember=2
password [success=2 default=ignore] pam_unix.so obscure remember=2 use_authtok try_first_pass sha512
password [success=1 user_unknown=ignore default=die] pam_sss.so remember=2 use_authtok try_first_pass
password requisite pam_deny.so
password required pam_permit.so
Once I got that working for a local user, I reset a’s password and tried it. Sure enough, it maintained the restriction. This has some interesting possibilities. Thoughts, in no particular order:
Could be used to avoid whole issue of setting a ldap based password complexity module which, seemingly, has to be compiled.
One issue is that we’d have to update system-auth everywhere; however, if we’re already doing that for group access, then it doesn’t seem like that big a deal.
Potentially bigger issue would be a mixed env in which a user could change his password to something simpler, matching the reqs on an older or different variant. If it’s accepted on the old system, I imagine it’d be accepted by the directory which means the guy could log in on the more restrictive system with the simpler password. Turns out that’s not quite as easy as it sounds, but it does, in fact, work that way.
03/23/13: Been a bit since the last bit of studying. In that time, though, I found out that ssh/pka does not honor pwdreset=true or pwd aging via the ppolicy pwdmaxage parm. Put out questions to the centos forums and to the openldap mailing list without any successful answers. Seems like someone would have fixed this already.
I want to verify how to administratively lock and unlock a user account. Maybe add those as functions to the ldap script. Mostly previously identified:
Account is locked if pwdAccountLockedTime is set.
Account automatically gets unlocked after pwdLockoutDuration is set in the ppolicy.
To manually unlock an account, remove the pwdLockoutDuration entry from the account.
To permanently lock an account, set pwdAccountLockedTime to 000001010000Z
OK: 2 hours today. Hammered the account lock one and for all. Try to remember that.
Next goal is to experiment w/pwd complexity rules. As I found out about 5 weeks back, I can use the system-auth to enforce complexity. That kind of circumvents the whole centralized management, though. Would like to get something internal to the directory server.
05/06/14: Been awhile. Went and got my rhce so that took a wee bit of studying. It was also looking like I was going to be rolling off of Multiplan; however, the buggers came up with a salary I can live with. Won’t be great, but it’ll be livable.. So, back to the ldap studying
First goal of the return should be reasonably easy - getting the ldap script able to update group membership.
// a few minutes later. Well, that turned out even easier than I expected. The logic’s aleady in the ldap script. It’s a simple modify run.
# ldap -modify -dn cn=infra,ou=groups,dc=oci,dc=com add memberuid=ddddd
alter: add -> memberuid -> ddddd: done
# ldap -search cn=infra
------------------------------------------------------------------------
dn:cn=infra,ou=groups,dc=oci,dc=com
cn: infra
objectClass: top
posixGroup
gidNumber: 635
description: System Admins
memberUid: d
dd
ddd
dddd
ddddd
# ldap -modify -dn cn=infra,ou=groups,dc=oci,dc=com delete memberuid=ddddd
alter: delete -> memberuid -> ddddd: done
# ldap -search cn=infra
------------------------------------------------------------------------
dn:cn=infra,ou=groups,dc=oci,dc=com
cn: infra
objectClass: top
posixGroup
gidNumber: 635
description: System Admins
memberUid: d
dd
ddd
dddd
Also updated the ldap_wrapper doc to include examples of adding/deleting group membership.
On to restricting access.
Found a reasonable pdf that described how to set up pam_ldap. Unfortunatley, as I read further, I found that pam_ldap is obsolete in rhel6. The short version of configuring pam_ldap is:
* Add ``pam_check_host_attr yes`` to /etc/openldap/ldap.conf * Update /etc/pam.d/system-auth to include the line below as the first account line: ::
account [success=done new_authtok_reqd=done perm_denied=bad default=ignore] pam_ldap.so
Add host entries to individual accounts.
As mentioned, though, that’s not working on my centos 6.5 variant.
rhel6/sssd - using host object in user entry:
After running authconfig, verify authentication is working. First, get it working globally before trying to limit it.
Once it is, rearrange /etc/sssd/sssd.conf (not strictly required, but helps figure out WTF is going on):
[sssd] ... [domain/default] ... ${rest-o-them}
Add three entries:
access_provider = ldap ldap_access_order = host ldap_user_authorized_host = host
Total domain/default entry:
[domain/default] id_provider = ldap auth_provider = ldap chpass_provider = ldap access_provider = ldap #----------------------------- cache_credentials = True ldap_search_base = dc=oci,dc=com krb5_realm = EXAMPLE.COM krb5_server = kerberos.example.com ldap_uri = ldaps://ldapsvr.olearycomputers.com ldap_tls_cacertdir = /etc/openldap/cacerts ldap_tls_reqcert = allow #----------------------------- ldap_access_order = host ldap_user_authorized_host = host
Tests show that only hosts allowed in users’ entries are allowed in.
for u in d dd ddd do ldap -search uid=${u} done ------------------------------------------------------------------------ dn:uid=d,ou=users,dc=oci,dc=com cn: d gecos: test user: d objectClass: top account posixAccount shadowAccount shadowMin: 0 shadowMax: 90 shadowWarning: 7 loginShell: /bin/bash uidNumber: 856 gidNumber: 639 homeDirectory: /home/d uid: d pwdChangedTime: 20140427175416Z host: client1 ------------------------------------------------------------------------ dn:uid=dd,ou=users,dc=oci,dc=com cn: dd gecos: test user: dd objectClass: top account posixAccount shadowAccount shadowMin: 0 shadowMax: 90 shadowWarning: 7 loginShell: /bin/bash uidNumber: 920 gidNumber: 639 homeDirectory: /home/dd uid: dd pwdChangedTime: 20140427175435Z host: * !client3 ------------------------------------------------------------------------ dn:uid=ddd,ou=users,dc=oci,dc=com cn: ddd gecos: test user: ddd objectClass: top account posixAccount shadowAccount shadowMin: 0 shadowMax: 90 shadowWarning: 7 loginShell: /bin/bash uidNumber: 936 gidNumber: 639 homeDirectory: /home/ddd uid: ddd pwdChangedTime: 20140427175440Z
Well, this got a bit longer than expected. Got the hostobject style of access restriction down. Next, I was originally going to look at authorized_service; however, I now believe those are authorized sssd services.. I think. I want to do some more research on authorized_service style. Lastly, it’ll be the groups that are used at MPI.
05/11/14: Working on the group access to systems. I found where to input the access filter but I can’t get it working right. The syntax is supposed to be something like:
ldap_access_filter = (|(memberOf=cn=dba,ou=groups,dc=oci,dc=com)(memberOf=cn=infra,ou=groups,dc=oci,dc=com))
Interestingly, even simplifying that to infra alone didn’t work. Now, check this:
# h
client1
# groups d
d : infra
# ldapsearch -xLLL cn=infra dn
dn: cn=infra,ou=groups,dc=oci,dc=com
# ldapsearch -xLLL cn=infra,ou=groups,dc=oci,dc=com
#
I suspect that inability to resolve fully qualifie search filtes is what’s causing the sssd issue. Every access attempt results in:
May 10 14:56:39 client1 sshd[2642]: Connection from 192.168.122.20 port 39420 May 10 14:56:39 client1 sshd[2642]: Failed publickey for d from 192.168.122.20 port 39420 ssh2 May 10 14:56:43 client1 sshd[2642]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=ldapsvr user=d May 10 14:56:43 client1 sshd[2642]: pam_sss(sshd:auth): authentication success; logname= uid=0 euid=0 tty=ssh ruser= rhost=ldapsvr user=d May 10 14:56:43 client1 sshd[2642]: pam_sss(sshd:account): Access denied for user d: 6 (Permission denied) May 10 14:56:43 client1 sshd[2642]: Failed password for d from 192.168.122.20 port 39420 ssh2 May 10 14:56:43 client1 sshd[2643]: fatal: Access denied for user d by PAM account configuration
To see if it’s something I fucked up in the pam configuration files, I’m recreating a new client. I don’t think it is; but, it’s an easy check.
//later that same day.
OK: the fully qualified search is not the issue as I’m not able to run those queries at
work either. I am able to run getent group ${group}
queries, though, whereas I
can’t on my ldap environment. So, let’s figure that one out…
More detail: based on searches, there’s the possibility that openldap will display group numbers, but not group names. Sure enough, that’s the symptom:
# h
client4.olearycomputers.com
# getent group 635
infra :*:635:d,dd,ddd,dddd
# getent group infra
#
I noticed the space in the entry above. Searching for ‘infra ‘ shows the data.
# getent group ‘infra ‘ infra :*:635:d,dd,ddd,dddd
Deleted, recreated the groups w/o spaces. Still having the same access issue <sigh>
I finally posted a message on the centos forum. No answer yet, though, unfortunately.
If nothing comes of it by tomorrow, I’ll try playing around with it a little more then move on to something a little more productive. sudo
05/11/14: Some major progress. It’s not working quite yet, but I know what the core problem was. After several google searches, I finally figured out that the memberof search wasn’t working out because the memberof overlay wasn’t installed. I finally got that installed by, basically, following the same procedure as the ppolicy overlay. An overlay… Fuck! What a long time to get to this point.
So, overlay’s installed. I removed and re-added the groups so the memberof searches should be working by now.
//later
I’m getting closer. There is a major discrepancy, though. Appears I can’t have normal group definitions that have both objectclass: posixgroup and objectclass: groupofnames. If I define posixgroup, I can’t seem to use member; but, if I use groupofnames, I can’t use the other group definitions. Reason is that they’re both structural. Fuck. One interesting comment that I found:
There seem to be two possible approaches. Either use the OpenLDAP dynlist
extension to dynamically fake one list from the other, or to drop the default
'nis' schema and replace it with RFC2307bis, which does permit the two to co-
exist.
05/12/14: OK; got the sssd ldap_access_filter working but what a kludge. I updated the ldap script to automatically generate a groupofnames group whenever a posixgroup is added. I also added d, dd, ddd, and dddd to the groupofnames group infra:
# ldap -b ${gondn} -search cn=infra
------------------------------------------------------------------------
dn:cn=infra,ou=gon,dc=oci,dc=com
cn: infra
objectClass: top
groupOfNames
description: System Admins
member: uid=place_holder,ou=users,dc=oci,dc=com
uid=d,ou=users,dc=oci,dc=com
uid=dd,ou=users,dc=oci,dc=com
uid=ddd,ou=users,dc=oci,dc=com
uid=dddd,ou=users,dc=oci,dc=com
Finally, the memberof search is returning valid data:
ldapsearch -xLLL \
'(&(uid=d)(objectclass=posixAccount)(memberof=cn=infra,ou=gon,dc=oci,dc=com))'
dn: uid=d,ou=users,dc=oci,dc=com
cn: d
gecos: test user d
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
shadowMin: 0
shadowMax: 90
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 856
gidNumber: 639
homeDirectory: /home/d
uid: d
And, once all that was done, and client4’s sssd.conf file updated with the new group ou, I’m able to limit who has access to the system via sssd.conf. As long as it’s not too complex…
I really object to having duplicate groupnames. That’s just asking for trouble even if the updates are automated.
Just to press on with the ldap_access_filter, I tried a couple of different ways to make the access filter more readable and more maintainable. All failed. This is going to be an ugly way of going about it. So, the line, with two groups, looks like:
ldap_access_filter = (|(memberof=cn=infra,ou=gon,dc=oci,dc=com)\
(memberOf=cn=dba,ou=gon,dc=oci,dc=com))
That has to be one line - no line breaks, no new lines. I also tried setting the lda_group_search_base to see if I could get away with short group names. No joy.
So, the long and the short of it:
posixgroup groups are used for unix related activities.
groupofnames groups can be used for access filtering.
Those two are not the same; but, procedures/scripts can be developed to help make them look like the same.
The syntax is positively heinous for maintenance and readability.
Wow; host object is bad and ldap_access_filter is bad. yikes.
05/18/14: I’m going to see if I can get the ingroup govno working via /etc/pam.d/system-auth. That seems like the cleanest, easiest method of limiting access to linux systems. Starting out with a clean system, though. Blasting client1 and 4 and rebuilding client1.
Heh: in my effort to be more efficient, I have to rebuild client1 again. After the power outage, mgmt rebooted with a firewall running, so the nfs exports weren’t functional which means my archive_vm script killed client1 without backing it up. Need to update that little functionality too…
First thing, once we have client1 back, is to see if I can get the ingroup lines working outside of ldap. Then, we add ldap and see if it’s still working and troubleshoot from there.
Line should look like:
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth sufficient pam_ldap.so use_first_pass
auth required pam_deny.so
account required pam_unix.so broken_shadow
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 500 quiet
# account sufficient pam_succeed_if.so uid < 100 quiet
# account sufficient pam_succeed_if.so user ingroup backup-ops
# account sufficient pam_succeed_if.so user ingroup monitor-ops
# account sufficient pam_succeed_if.so user ingroup devfees
# account sufficient pam_succeed_if.so user ingroup dev
# account sufficient pam_succeed_if.so user ingroup devsolr
# account sufficient pam_succeed_if.so user ingroup dba
# account sufficient pam_succeed_if.so user ingroup ops
# account sufficient pam_succeed_if.so user ingroup its
account sufficient pam_succeed_if.so user ingroup scm
account sufficient pam_succeed_if.so user ingroup infosec
account requisite pam_succeed_if.so user ingroup infra
account [default=bad success=ok user_unknown=ignore] pam_ldap.so
account required pam_permit.so
password requisite pam_cracklib.so try_first_pass retry=3 type=
password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok
password sufficient pam_ldap.so use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
session optional pam_oddjob_mkhomedir.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
session optional pam_ldap.so
# add if you need ( create home directory automatically if it's none )
session optional pam_mkhomedir.so skel=/etc/skel umask=077
Delete some of those lines when you get this working. Don’t want live data in a lessons learned entry.
1230: 2 hours and no joy. I can’t even get pam to display text via the pam_echo. I’ve tried it in sshd password-auth and system-auth to no avail. The reason I’m trying the pam_echo is that the ingroup lines I tried in both system-auth and password-auth are not working.
While researching this, I did find this little bit of trivia here: http://wpollock.com/AUnix2/PAM-Help.htm
The Linux pam_unix module in a PAM configuration file with the context
(module type) of “account” checks that an account exists and isn't
expired. It does not check if an account has been locked or has an invalid
shell! (Apparently pam_unix assumes the auth component will fail if the
account is locked.) This means that users using SSH keys to log in will
be allowed to do, so even if you lock their accounts with the “passwd -l”
command (since sshd doesn't use the PAM auth modules in this case)!
Setting an invalid shell is checked with the Linux pam_shells module,
but that is usually included only in the configuration files for FTP
servers. (I've been locking users out this way for years and I've never
realized the danger. Now I always add pam_shells in the account part of
my PAM configuration (as required), and lock accounts by specifying an
invalid shell such as /bin/false, for login, sshd, and other remote
access services.)
So, ssh doesn’t use the auth modules which is why the keys work. That’s the cause; how do we work out the solution?
05/23/14: I got the pam stuff above working. The short version is that the pam_localuser.so had sufficient as its permission setting. Since a and d were both local accounts, it was sufficient and they were permitted. I tried changing that to optional and, suddenly, only the infra group was allowed access.
OK: That gets an understanding of pam; but, I still have the posixgroup vs groupofnames issue to deal with. Looks like the right answer is to recreate the directory with rfc2307bis support. The best site I’ve seen so far, in my limited research on it is: http://www.omnisys.com/docs/newdevbox/slapd.html Once I get done upgrading my laptop (again, I really shouldn’t wait so long…) I’m going to regenerate the ldap server virtual and try the steps out for rfc2307bis support. Assuming I can get all that working, I’ll be a happy camper, and I’ll have to update the lessons learned entry again.
05/25/14: Getting a few more whacks at this. I got the rfc2307bis schema installed and enambed. I also added the memberof overlay and it’s working. One interesting search that doesn’t appear to work at work is the memberof:
# ldapsearch -xLLL -s sub '(cn=admin)' memberof
dn: cn=admin,dc=oci,dc=com
memberOf: cn=backup-ops,ou=groups,dc=oci,dc=com
memberOf: cn=bamboo-consult,ou=groups,dc=oci,dc=com
memberOf: cn=dba,ou=groups,dc=oci,dc=com
memberOf: cn=dbusers,ou=groups,dc=oci,dc=com
memberOf: cn=dev,ou=groups,dc=oci,dc=com
memberOf: cn=devsolr,ou=groups,dc=oci,dc=com
memberOf: cn=devweblogic,ou=groups,dc=oci,dc=com
memberOf: cn=tomcat,ou=groups,dc=oci,dc=com
memberOf: cn=infosec,ou=groups,dc=oci,dc=com
memberOf: cn=infra,ou=groups,dc=oci,dc=com
memberOf: cn=intadmin,ou=groups,dc=oci,dc=com
memberOf: cn=ldap-Administrators,ou=groups,dc=oci,dc=com
memberOf: cn=ldap-Monitors,ou=groups,dc=oci,dc=com
memberOf: cn=ldap-users,ou=groups,dc=oci,dc=com
memberOf: cn=manager,ou=groups,dc=oci,dc=com
memberOf: cn=middleware,ou=groups,dc=oci,dc=com
memberOf: cn=monitor-ops,ou=groups,dc=oci,dc=com
memberOf: cn=oem12cinstall,ou=groups,dc=oci,dc=com
memberOf: cn=oinstall,ou=groups,dc=oci,dc=com
memberOf: cn=Operations,ou=groups,dc=oci,dc=com
memberOf: cn=ops,ou=groups,dc=oci,dc=com
memberOf: cn=rdcms,ou=groups,dc=oci,dc=com
memberOf: cn=scm,ou=groups,dc=oci,dc=com
memberOf: cn=tomcat-managers,ou=groups,dc=oci,dc=com
memberOf: cn=weblogic,ou=groups,dc=oci,dc=com
memberOf: cn=wlsqadeploy,ou=groups,dc=oci,dc=com
Need to figure out how to get that into the ldap search functionality.
I’m still flumoxed, though. In order to support posixgroup and groupofnames functionality, I still have to create two member types:
memberuid: doleary
member: uid=doleary,ou=users,dc=oci,dc=com
If I’m stuck with that, I can’t really see the puprose of groupofnames - which might be why it got dropped from IETF consideration. Going to try poinsting another question to openldap forum and see if anyeone, other than that flaming asshole, will answer.
10/05/14: Been at openldap users the better part of a year. Time to put ldap users to bed and move on to hosts/puppet interaction.
New server, time to reinstall, reinvigorate, re-everything.
New environment:
3xldap servers on different networks (wonder where these names came from?) Only nap to be build initially in order to finish the users. Others when I start playing with replication
nap: 192.169.122.0/24
rock: 192.168.100.0/24
wall: 192.168.110.0/24
At least 1xclient in each:
napc1
rockc1
walc1
syslog server:
OK: All done. Ready for the next step…
# virsh list --all
Id Name State
----------------------------------------------------
6 syslog running
10 nap running
11 napc1 running
14 rockc1 running
15 walc1 running
- xymon shut off
10/07/14: had some time today to take a whack at my new directory. Have to update the install directions. If installing rfc2307bis, I need to update the group addition to include a few extra lines: groupofnames object class and a member.:
# cat qwer.group.ldif
dn: cn=qwer,ou=groups,dc=oci,dc=com
objectClass: posixGroup
objectclass: groupofnames
objectClass: top
cn: qwer
userPassword: {crypt}x
gidNumber: 100000
member: uid=qwer,ou=users,dc=oci,dc=com
I don’t remember having to do that before; but, the latest ldap script does have the member attrbite in the add group function.
I can wrestle with that some more. Finish the install/config.
10/09/14: Got everything running; tried enabling the sssd auth on the nap host and, of course, it doesn’t work. Fuck me to tears. I’ll search more on that later. I’m just happy I got the directory working, the ldap wrapper script working, the memberof searches, etc.
Authentication… Damn..
After running on that for a few minutes, I dropped it. I got it working before, I’ll do it again. I wanted to find host schemas - and ran into a wall there, too. No pre-defined schema. The puppet one looks pretty close though…
Of the list of attributes from the mpi cmdb, several are already defined:
Field |
ldap attr |
---|---|
Host: |
host |
IP: |
iphostnumber |
NM: |
ipnetmasknumber |
GW: |
Nope |
Console: |
Nope |
Arch: |
Nope |
Serial: |
Nope |
Application: |
Nope |
Contacts: |
Nope |