-
Notifications
You must be signed in to change notification settings - Fork 3
Setting up FreeIPA, KDC and LDAP
Return to main: Kerberos
In our site, this documentation should never be needed. It shows how I set up the initial server. However in no conceivable situation would we start from scratch this way. Even for a major upgrade, where we have to reinstall the servers from scratch, we pull the data from an existing server. In case of a massive failure, we'd use a backup copy of one of the VMs, get it running, and pull the data from there.
However it's still useful to know what ACLs I created, what new LDAP structures, I created, etc. So I'm continuing to maintain this page. Every time I do something outside for normal IPA operations (creating users, and groups, etc) I add it to the documentation here.
But for setting up a server, see the separate page on setting up a new server. We now have a simplified way, where it's mostly done by Ansible.
I am updating this page as we add new services, new ACLs, etc. So in principle it should be possible to reproduce our existing setup. However I can't imagine any situation where we'd actually do that, unless we have to move from IPA to something else.
The obvious installation process, documented below, ,produces a slightly invalid configuration. The default install include a CA with a self-signed cert. We followed a process to install a commercial cert for LDAP and HTTPS. It works fine, but the upgrade scripts assume that if you have a CA, your LDAP and HTTPS certs come from your own CA. The upgrade script fails in our configuration. This is only on krb1. The process for producing a replica by default doesn't copy the CA, so the replica is CA-less and doesn't have this issue. There's some reason to think that krb1 wouldn't even be able to reboot cleanly.
Redhad has a fix, which it to change the certificate's nickname to the one expected by the upgrade script, Server-Cert
Do certutil -L -d /etc/httpd/alias to see what the actual nickname is. It is probably not krb1-cert, but more likely the long name starting in CN-krb1.
certutil -L -d /etc/httpd/alias -n 'krb1-cert' -a -o ~/krb1.cert certutil -D -d /etc/httpd/alias -n 'krb1-cert' certutil -A -d /etc/httpd/alias -n "Server-Cert" -t u,u,u -i ~/krb1.cert emacs /etc/httpd/conf.d/nss.conf change NSSNickname to Server-Cert certutil -d /etc/dirsrv/slapd-CS-RUTGERS-EDU/ -L -a -n 'CN=krb1.cs.rutgers.edu,OU=SAS,O="Rutgers, The State University of New Jersey",STREET=43 College Avenue,STREET=Room 226A,L=New Brunswick,ST=NJ,postalCode=08901,C=US' -o ~/krb1.cert2 certutil -d /etc/dirsrv/slapd-CS-RUTGERS-EDU/ -D -n 'CN=krb1.cs.rutgers.edu,OU=SAS,O="Rutgers, The State University of New Jersey",STREET=43 College Avenue,STREET=Room 226A,L=New Brunswick,ST=NJ,postalCode=08901,C=US' certutil -A -d /etc/dirsrv/slapd-CS-RUTGERS-EDU/ -n "Server-Cert" -t u,u,u -i ~/krb1.cert2 emacs /etc/dirsrv/slapd-CS-RUTGERS-EDU/dse.ldif change nsSSLPersonalitySSL to Server-Cert
You should also remove the requests to update the original certificates:
getcert list -d /etc/dirsrv/slapd-CS-RUTGERS-EDU -n Server-Cert ; find requestid 20171002175930 in output getcert stop-tracking -i 20171002175930 getcert list -d /etc/httpd/alias/ -n Server-Cert getcert stop-tracking -i 20171002175931
Somehow in the process of doing all this I had lost a symlink
mkdir /etc/systemd/system/pki-tomcatd.target.wants ln -s /lib/systemd/system/[email protected] /etc/systemd/system/pki-tomcatd.target.wants/[email protected]
In one try I also messed up permissions. To restore.
cd /etc/httpd/alias chgrp apache *.db chgrp apache kra-agent.pem chgrp apache pwdfile.txt chmod 660 pwdfile.txt
In that state you can restart and upgrade. But attempts to install a replica failed. So the section on setting up a backup server.
It includes an MIT Kerberos KDC with a plugin for two factor authentication (free clients), LDAP, and a web GUI. It has a DNS component available, which allows for easy setup of new clients including putting them into DNS. I haven't turned on DNS.
The initial goal was just to use this system for authentication, but we've now moved users, groups, netgroup and host ssh keys to it.
Two-factor authentication only works for Centos 7 (maybe 6). However if you get a TGT under Centos 7 you can ssh to any system that supports Kerberos, and your tickets will work there.
The package also includes sssd, a daemon designed to support for PAM and nsswitch. We may want to use it, but the server can be used with pam_krb5 and nss_ldap. The main issue with not using sssd is support for one-time passwords, but there are solutions to that.
By default LCSR allows ssh from within Rutgers. The default rules are at /etc/sysconfig/iptables.
I suggest starting with iptables narrowed a bit. Here's what I started with as the main rule set in /etc/sysconfig/iptables
-A INPUT -s 128.6.26.0/24 -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -s 128.6.4.9 -p tcp -m tcp -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j DROPThe second rule allows all access from the primary server
Now for full setup:
The firewall loads from /etc/sysconfig/iptables. Here are my current rules: rules
This uses two ipsets:
- lcsr - all Kerberos clients
- staff - staff systems, current just 128.6.26
yum install ipset yum install ipset-service systemctl start ipset systemctl enable ipset ipset create staff hash:ip ipset create lcsr hash:ip ipset add staff 128.6.26.0/24"service ipset save" will persist the definitions.
I run a script every 10 min that updates lcsr to include all hosts in the database. On the primary a 10 min delay may not be acceptable, but on the backup I think it normally will be.
Make sure ntp is working. We've had issues with it. I'm currently using just ntp.rutgers.edu.
to get enough entropy. otherwise install is very slow
sudo yum install -y haveged sudo systemctl start haveged.service yum install freeipa-server ipa-server-install. defaults work no DNS realm CS.RUTGERS.EDU [upper case] password for both dir server and kdc is the same, but is not in this file for obvious reasons
You should probably kinit as admin then create a user for yourself
ipa user-add --uid=1003 hedrick then ipa passwd hedrick with temp password (you'll have to change it) now kdestroy then kinit as yourself and change your password
login to the web page, pick your own page
I suggest creating something like hedrick.admin Kinit as admin, then do
ipa group-add-member admins --users=YOU.adminYou'll want to require 2FA, which is a checkbox in the GUI. Adding someone to the admins group makes them an admin, with the same access as admin. I recommend not using the actual admin once you've done that setup.
Once 2FA is set, until I come up with a better approach, you can kinit in the following weird way:
klist - if you don't have a ticket do kinit as a non-2FA user copy the cache name, e.g. KEYRING:persistent:1003:krb_ccache_ZZarlR1 kinit -T KEYRING:persistent:1003:krb_ccache_ZZarlR1 YOU.admin type your password following by the one time token on the same line immediately after the password
The -T is needed because where there's 2FA, the password has to be sent in the clear. The normal Kerberos protocol won't work except with simple passwords. To secure that, you need a credentials cache. The credential in the cache is used to do encryption. The credentials don't have to be yours; they just have to be valid. Hence the approach above has you login as your non-admin user and use the credentials cache to armor the request for your admin login. I will set up a better approach shortly.
- Logout of admin and login with your admin account
- pick authenticatin, OTP tokens
- Create a new one and do add and edit. That will show the QR code.
- Install freeotp on your phone and scan the token. At the top of the app there's an icon that looks like a QR code. Pick it and point the camera at the screen
- Now go back to your .admin entry and set the box to require TFA. I actually had to go back in as admin to do that. Not sure why.
- freeotp has an issue. Sometimes you have to kill it and restart it to get it to display a code
ipa user-add or ipa user-mod --random, then ipa-getkeytab Put a keytab in /etc/scripts.keytab. in kadmin.local: modprinc -pwexpire 2030-01-01 scripts.admin verify you can do kinit -k -t /etc/scripts.keytab scripts.adminthat's the way we'll do things in scripts now make sure it can list all of our users:
ipa user-mod --setattr=nsLookThroughLimit=100000 --setattr=nssizelimit=100000 --setattr=nstimelimit=100000 scripts.adminbut had to go into GUI and set search limit to 100000 also. As user admin, this user can manage users, but it's not a full admin
- In gui, IPA Server, RBAC, pull down choose permissino and System: Modify Users
- Under effective attributes add gidnumber, uidnumber, homedirectory
- The UI is marginal. Check the result by doing as admin
- ipa permission-show 'System: Modify Users'
- Should see "Included attributes: gidnumber, uidnumber, homedirectory"
turn on creation of private groups. We currently expect that.
ipa-managed-entries -e "UPG Definition" enable ipa-managed-entries -e "NGP Definition" disable systemctl restart dirsrv.targetTo get a high expiration time you have to hack on ldap.
ldapmodify -x -D "uid=admin,cn=users,cn=accounts,dc=cs,dc=rutgers,dc=edu" -W -f ~/mod with admin password Here is ~/mod for a year.
Also need to change the property in the GUI for kerberos ticket policy. In Policy, Kerberos ticket pokicy. (This may not be needed after the ldap change.)
And the he renew time in /var/kerberos/krb5kdc/kdc.conf. the renewtime in the client's krb5.conf is a default, which kinit can override. Also individual users can be set in the GUI or LDAP. There's already a renewtime in the CS.RUTGERS.EDU section. Just change it to 365d.
I'd restart the server. systemctl restart krb5kdc
dn: krbPrincipalName=K/[email protected],cn=CS.RUTGERS.EDU,cn=kerberos,dc=cs,dc=rutgers,dc=edu changetype: modify replace: krbMaxRenewableAge krbMaxRenewableAge: 31536000 - dn: krbPrincipalName=krbtgt/[email protected],cn=CS.RUTGERS.EDU,cn=kerberos,dc=cs,dc=rutgers,dc=edu changetype: modify replace: krbMaxRenewableAge krbMaxRenewableAge: 31536000 - dn: cn=CS.RUTGERS.EDU,cn=kerberos,dc=cs,dc=rutgers,dc=edu changetype: modify replace: krbMaxRenewableAge krbMaxRenewableAge: 31536000 -
Note that tickets by default aren't renewable. The defaults are set in the libdefaults section of /etc/krb5.conf. I'd be incline to set
ticket_lifetime = 24h renew_lifetime = 365dthough on the server side that has no effect other than for command line users on the server itself.
In Policy / Password policies
Default password lifetine is 90 days. Current opinion says expiring passwords isn't useful, so I'm setting it to 18250 days, which is 50 years. I believe numbers larger than that won't work, though I haven't tried it.
Currently there's a minimum change time of 1 hour. I'm not sure this is needed, but I'm not currently changing it. The default is not to keep password history so you can change a password to what it was before. Since I'm disabling expiration, there's no reason to change.
Follwing are the same as University policies, stricter than the freeipa defaults
- 3 character classes
- min length 10
- max failures 6 in 60 sec
- lockout 10 min
New passwords are set to expire immediately. That applies to accounts created with ipa user-add. We'll be activating by a web app, so I'm not sure this is an issue. I've created lots of users by sync from NIS, with the same password, so I really do want to force a change if one of them manages to login.
In /etc/sysconfig/network, comment out the domain name entry. We don't need NIS, and it confuses scripts.
To allow us to add the "host" and various date attribute to users and groups:
ipa config-mod --addattr=ipaUserObjectClasses=hostObject ipa config-mod --addattr=ipaGroupObjectClasses=hostObject ipa config-mod --addattr=ipaGroupObjectClasses=request ipa permission-mod "System: Read User Standard Attributes" --includedattrs=host ipa permission-mod "System: Read Groups" --includedattrs=host --includedattrs=dateOfCreate --includedattrs=dateOfModify ipa permission-mod "System: Modify Groups" --includedattrs=host --includedattrs=dateOfCreate --includedattrs=dateOfModify ipa permission-mod "System: Modify Users" --includedattrs=hostUnfortunately you still have to add the object to existing users or groups, though new ones get it, e.g.
ipa group-mod ipausers --addattr=objectclass=hostobjectYou can then add the host to entries:
ipa group-mod ipausers --addattr=host=ilabNormally the objectclass will be added when the user or group is created
Similarly, needed to add csRutgersEduPerson, put this in addattr
dn: cn=schema changetype: modify add: attributetypes AttributeTypes: ( 1.2.840.113556.1.4.221 NAME 'sAMAccountName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE -VALUE ) attributeTypes: ( 1.3.6.1.4.1.10962.2.4.2 NAME 'csRutgersEduCredservKeytab' DE SC 'Encoded keytab for credserv' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGI N ( 'cs.rutgers.edu' 'user defined' ) ) attributeTypes: ( 1.3.6.1.4.1.10962.2.4.1 NAME 'csRutgersEduCredservRule' DESC 'Authorization for credserv' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN ( 'cs.rutgers.edu' 'user defined' ) ) attributeTypes: ( 1.3.6.1.4.1.10962.2.4.4 NAME 'dellEmcGroup' DESC 'Role for Dell switches' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) - add: objectclasses objectClasses: ( 1.3.6.1.4.1.10962.2.4.3 NAME 'csRutgersEduPerson' SUP top AUX ILIARY MAY ( csRutgersEduCredservRule $ csRutgersEduCredservKeytab $ sAMAccountName $ dellEmcGroup) X-ORIGIN ( 'cs.rutgers.edu' 'user defined' ) )ldapmodify -ZZ -x -D "cn=Directory Manager" -W -H ldap://localhost -f addattr
ipa config-mod --addattr=ipaUserObjectClasses=csRutgersEduPersonfails for some reason, so do ldapmodify on this:
dn: cn=ipaConfig,cn=etc,dc=cs,dc=rutgers,dc=edu changetype:modify add:ipaUserObjectClasses ipaUserObjectClasses:csRutgersEduPerson
If there are existing users, need to add the objectclass to them. This objectclass is needed for credserv and for the Windows uid/gid mapping.
In GUI,
- Add Permission Rutgers Write Credserv Attributes, which gives all on csRutgersEduCredservRule and csRutgersEduCredservKeytab.
- Add Privildge Rutgers Credserv Data Management with that permission
- Add Role Rutgers Credserv Service with that privilege
- Add credserv/krb1.cs.rutgers.edu to that role; also krb2 when it's created
- Edit Permission System: Read User Standard Attributes, add sAMAccountName
from ipaserver.plugins import user from ipaserver.plugins import group from ipalib.parameters import Str from ipalib import _ user.user.takes_params = user.user.takes_params + ( Str('samaccountname?', cli_name='windowsname', label=_('Windows account name'), ), ) user.user.default_attributes.append('samaccountname') group.group.takes_params = group.group.takes_params + ( Str('businesscategory*', cli_name='categories', label=_('Categories (specify "login" for login group)'), ), ) group.group.default_attributes.append('businesscategory') group.group.takes_params = group.group.takes_params + ( Str('host*', cli_name='hosts', label=_('Hosts (use as cluster names for login group)'), ), ) group.group.default_attributes.append('host') def useradd_precallback(self, ldap, dn, entry, attrs_list, *keys, **options): if 'samaccountname' not in entry.keys(): entry['samaccountname'] = entry['uid'] if 'mail' not in entry.keys(): entry['mail'] = entry['uid'] + '@rutgers.edu' if 'gidnumber' not in entry.keys(): entry['gidnumber'] = '1234' return dn user.user_add.register_pre_callback(useradd_precallback, first=True) # For some reason this ignores the text in cli_name and label group.group.takes_params = group.group.takes_params + ( Str('owner*', cli_name='owners', label=_('Owners'), normalizer=lambda value: value if ',' in value else 'uid=' + value + ',cn=users,cn=accounts,dc=cs,dc=rutgers,dc=edu', ), ) group.group.default_attributes.append('owner')
and then restart httpd. This needs to be done on each server. Clients get the list of attributes, etc, from the server, so they don't need modification.
Setting up IPA installs sssd. You'll want to check authentication and nsswitch.conf afterwards.
- I suggest leaving pam with both ldap and sss enabled. If you loving with your kerberos password you'll get a Kerberos ticket. That's preferred. But ldap pointing to ldap.rutgers.edu will give you a backup way in if the iPad server is down.
- I suggest setting nsswitch.conf so password, shadow and group is just "files." That way only users in /etc/passwd can actually login.
dn: cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu changetype: modify add:aci aci: (targattrfilters="add=objectClass:(|(objectClass=groupOfNames)(objectclas s=top)(objectclass=posixgroup)(objectclass=ipausergroup)(objectclass=ipaobjec t)(objectclass=nestedGroup)(objectclass=hostobject)(objectclass=request))") (target="ldap:///cn=gr oups,cn=accounts,dc=cs,dc=rutgers,dc=edu") (version 3.0; acl "Create Group"; allow (read,search,add) (groupdn="ldap:///cn=group-manager,cn=groups,cn=accou nts,dc=cs,dc=rutgers,dc=edu"); ) aci: (targetfilter=(objectClass=groupOfNames))(targetattr="member||owner||date OfCreate||dateOfModify")(target="ldap:///cn=groups,cn=accounts,dc=cs,dc=rutge rs,dc=edu") (version 3.0; acl "Modify Own Group"; allow (all) (userattr="crea torsName#USERDN" or userattr="owner#USERDN"); ) aci: (targetfilter=(objectClass=groupOfNames))(targetattr="member||owner||host ||businesscategory||dateOfCreate||dateOfModify")(target="ldap:///cn=groups,cn =accounts,dc=cs,dc=rutgers,dc=edu") (version 3.0; acl "Modify Own Group"; all ow (all) (userattr="creatorsName#USERDN" or userattr="owner#USERDN") and grou pdn="ldap:///cn=login-manager,cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu"; ) dn: cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu changetype: modify add:aci aci: (targetfilter=(objectClass=groupOfNames))(targetattr="creatorsName") (target="ldap:///cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu") (version 3.0; acl "Read creator of Own Group"; allow (read, search) (userattr="creatorsName#USERDN" or userattr="owner#USERDN"); ) dn: cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu changetype: modify add:aci aci: (targetfilter=(objectClass=groupOfNames))(target="ldap:///cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu") (version 3.0; acl "Delete Own Group"; allow (delete) (userattr="creatorsName#USERDN" or userattr="owner#USERDN"); ) dn: cn=users,cn=accounts,dc=cs,dc=rutgers,dc=edu changetype:modify add:aci aci: (targetattr = "dellemcgroup")(version 3.0; acl "read dell group"; allow (read,compare,search) userdn="ldap:///all";) -
The first ACI allows anyone in group group-manager to read, search or add items under cn=groups, with objectclass limited to those shown (those used for groups). Without the targattrfilters constraint, they could create users. It's the object class, not the location of an entry in the tree that defines whether it's a user, a group, or something else.
The second ACI allows the person who created the group, or anyone listed as a owner to change member, owner, host or businesscategory attributes. Note that businesscategory=login is used to define something as a login group, so that needs to be controlled. If you decide to let anyone create a group, you'll need an aci that limits who can change the businesscategory, or anyone could let anyone login.
The third ACI allows the creator or owner to see the creator attribute, which is needed to do searches. It's not normally visible.
The fourth ACI allows the creator or owner to delete the group. Note that if they do so they will receive a spurious error message from ipa group-del. That's because it will try to delete any Kerberos group policy for the group. There won't be any, but the attempt will fail. It's harmless.
The fifth ACI allows anyone logged in to read the dellemcgroup attribute. This is used for access control of Dell switches.
Any DN that needs to see all users will need an increased search limit. E.g. the account cleanup tool will need this. I'm using wordpress.cs.rutgers.edu for testing so
ipa host-mod wordpress.cs.rutgers.edu --setattr=nsLookThroughLimit=-1 ipa host-mod wordpress.cs.rutgers.edu --setattr=nsSizeLimit=-1
To allow scripts.admin to read who has tokens, use this with ldapmodify:
dn: cn=otp,dc=cs,dc=rutgers,dc=edu changetype: modify add:aci aci: (target="ldap:///cn=otp,dc=cs,dc=rutgers,dc=edu")(targetattr="managedBy|| ipatokenUniqueID||ipatokenOwner||objectclass")(targetfilter = "objectclass=ip atoken") (version 3.0; acl "read token"; allow (read,search,compare) groupd n="ldap:///cn=User Administrator,cn=roles,cn=accounts,dc=cs,dc=rutgers,dc=edu ";)
I was unable to get the permissions system to do this.
To allow users to create and manage their own hosts, add
dn: cn=computers,cn=accounts,dc=cs,dc=rutgers,dc=edu changetype: modify add:aci aci: (targetfilter=(objectClass=ipahost))(targetattr="managedby") (target="ldap:///cn=computers,cn=accounts,dc=cs,dc=rutgers,dc=edu") (version 3.0; acl "Modify Own ManagedBy"; allow (all) (userattr="creatorsName#USERDN"); )This lets the creator of a host add a managedby entry. That will then let the manager (normally them) get a key table for it and do other things. To add a service, kinit using the host's key table and do ipa service-add and ipa-getkeytable.
Creating password policy for hadoop users. By default if we create a user and get a key tablek the key table is expired. This policy is like the default, but doesn't expire users. So we create the user put them in this group, and then get the key table. (pw policies are associated with groups). It prompted for a priority. I answered 1.
ipa pwpolicy-add nochange --maxlife=0 --minlife=0 --history=0 --minclasses=1 --minlength=10 --maxfail=10 --failinterval=60 --lockouttime=600
To allow NFS servers to see the key table with their existing nfs keys.
dn: cn=computers,cn=accounts,dc=cs,dc=rutgers,dc=edu changetype: modify add:aci aci: (targetfilter=(objectClass=csRutgersEduPerson))(targetattr="csRutgersEduCredservKeytab")(target="ldap:///cn=computers,cn=accounts,dc=cs,dc=rutgers,dc=edu") (version 3.0; acl "Read Own Keytab"; allow (read) (userattr="managedBy#USERDN"); )
The entry must be modified by admin to have objectclass=csRutgersEduPerson and then the csRutgersEduCredservKeytab entry itself
IPA now uses Microsoft-style SIDs. They set up a mapping from the UIDs and GIDs that they generate to SIDs. But we have old UIDs and GIDs that aren't specified in their mapping. With default settings, Kerberos won't get you get a ticket if you don't have a SID. To fix this:
ipa idrange-add CS.RUTGERS.EDU_low_id_range --base-id=1 --range-size=200000 --ri d-base=200000000 --secondary-rid-base=300000000 ipa idrange-add CS.RUTGERS.EDU_mid_id_range --base-id=600000 --range-size=200000 --rid-base=400000000 --secondary-rid-base=500000000 ipa config-mod --add-sids --enable-sid
The ipa config-mod --add-sldapsearch -b cn=users,cn=accounts,dc=cs,dc=rutgers,dc=edu '(&(gidnumber=*)(!(ipaNTSecurityIdentifier=*)))' ids runs a task that adds SIDs that aren't there. Check /var/log/dirsrv/slapd-CS-RUTGERS-EDU/errors to make sure it worked. If you have the same number that's both a UID and GID, it's supposed to use the secondary RID base for one of them to maintain uniqueness. Initially that didn't work. I got errors for the overlap and had to fix the SIDs manually. In a test with a newer version that problem didn't exist. Try
ldapsearch -b cn=users,cn=accounts,dc=cs,dc=rutgers,dc=edu '(&(uid=*)(!(ipaNTSecurityIdentifier=*)))' ldapsearch -b cn=users,cn=accounts,dc=cs,dc=rutgers,dc=edu '(&(gidnumber=*)(!(ipaNTSecurityIdentifier=*)))' <pre> to make sure all were converted. ===DHCP schema=== To support DHCP, loaded the schema. From a system with a copy of the ISC DHCP server installed, there's a file /etc/openldap/schema/dhcp.schema. It is the schema in Openldap format. To convert it, use https://fedorapeople.org/groups/389ds/binaries/ol-schema-migrate.pl ./ol-schema-migrate.pl -b /etc/openldap/schema/dhcp.schema > dhcp.ldif In the resulting file, remove comment lines, and add at the beginning <pre> dn: cn=schema changetype: modify add: attributeTypes
After the attributes before the objectclasses add
- add:objectClasses
There should be no blank lines. The line with the hyphen ends the block of attributetypes.
ldapmodify -ZZ -x -D "cn=Directory Manager" -W -H ldap://localhost -f dhcp.ldif
with the LDAP admin password.
You will also want to index two attributes, to speed up searches done by the DHCP code. Created index.ldif
dn: cn=dhcpHWAddress,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config changetype: add cn: dhcpHWAddress nsIndexType: pres nsIndexType: eq nsSystemIndex: false objectClass: top objectClass: nsIndex dn: cn=dhcpClassData,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config changetype: add cn: dhcpClassData nsIndexType: pres nsIndexType: eq nsSystemIndex: false objectClass: top objectClass: nsIndex
and load using
ldapmodify -ZZ -x -D "cn=Directory Manager" -W -H ldap://localhost -f index sudo db2index.pl -D "cn=Directory Manager" -n userRoot -t dhcpHWAddress -w -You must do this on each server. You'll also want to do db2index for dhcpClassData if there is any existing data.
DHCP config:
ldap-server "krb1.cs.rutgers.edu"; ldap-port 389; # We do an anonymous bind # ldap-username "cn=directorymanagerloginname"; # ldap-password "mypassword"; ldap-base-dn "ou=dhcp,dc=cs,dc=rutgers,dc=edu"; ldap-method dynamic; ldap-debug-file "/var/log/dhcp-ldap-startup.log"; ldap-dhcp-server-cn "server";
Initial setup:
dn: ou=dhcp,dc=cs,dc=rutgers,dc=edu ou: dhcp objectClass: top objectClass: organizationalUnit description: DHCP Servers aci: (target="ldap:///ou=dhcp,dc=cs,dc=rutgers,dc=edu")(targetattr=*)(version 3.0; acl "Manage DHCP Data"; allow (all) (groupdn="ldap:///cn=dhcp-manager,cn=groups,cn=accounts,dc=cs,dc=rutgers,dc=edu"); ) aci: (target="ldap:///ou=dhcp,dc=cs,dc=rutgers,dc=edu")(targetattr=*)(version 3.0; acl "Read DHCP Data"; allow (read,search) (userdn="ldap:///anyone"); ) dn: cn=server,ou=dhcp,dc=cs,dc=rutgers,dc=edu cn: server objectClass: top objectClass: dhcpServer dhcpServiceDN: cn=config,ou=dhcp,dc=cs,dc=rutgers,dc=edu dn: cn=config, ou=dhcp,dc=cs,dc=rutgers,dc=edu cn: config objectClass: top objectClass: dhcpService dhcpPrimaryDN: cn=server,ou=dhcp,dc=cs,dc=rutgers,dc=edu dhcpStatements: ddns-update-style none dhcpStatements: get-lease-hostnames true dhcpStatements: use-host-decl-names true dn: cn=128.6.26.0,cn=config,ou=dhcp,dc=cs,dc=rutgers,dc=edu cn: 128.6.26.0 objectClass: top objectClass: dhcpSubnet objectClass: dhcpOptions dhcpNetMask: 24 dhcpStatements: default-lease-time 600 dhcpStatements: max-lease-time 7200 dhcpOption: subnet-mask 255.255.255.0 dhcpOption: routers 128.6.26.1 dhcpOption: domain-name-servers 128.6.1.1 dhcpOption: domain-name "rutgers.edu" dn: cn=farside.lcsr.rutgers.edu,cn=config,ou=dhcp,dc=cs,dc=rutgers,dc=edu cn: farside.lcsr.rutgers.edu objectClass: top objectClass: dhcpHost dhcpHWAddress: ethernet 00:0c:29:af:cb:ca dhcpStatements: fixed-address 128.6.26.62
DHCP hosts are maintained by the account web application. I have also added commands to the ipa command-line tool to maintain all the LDAP data. See dhcp.py in the ansible setup. This code requires each kdc to have a copy of dhcpd. That's installed an a working directory created by the ansible script kdc2.yml. In addition to needing dhcpd installed, you need the directory /var/lib/dhcptest, protected 01777. (dhcpd is run in an enviornment with its own /tmp. You could probably put the files in /tmp, but debugging is hard because you can't see that from outside httpd.)
See Setting up pw quality check
Run credserv.
I'm assuming you've already added the attributes csRutgersEduCredservRule and csRutgersEduCredservKeytab. That only has to be done on one server. New servers inherit it.
It authenticates as a Kerberos service, so it needs a service principal. That goes in /etc/krb5.keytab, per instructions below.
ipa service-add credserv/krb1.cs.rutgers.edu ipa-getkeytab -p credserv/krb1.cs.rutgers.edu -k /etc/krb5.keytab ipa role-add-member "Rutgers Credserv Service" --services=credserv/krb1.cs.rutgers.edu
This assumes that the role Rutgers Credserv Service already exists. If not, see the man page for credserv for host to create it. It has permission to read and write csRutgersEduCredservRule and csRutgersEduCredservKeytab.
Also need /etc/krb5.anonymous.keytab and /etc/krb5.tgt.keytab. They are created from anonymous.user and krbtgt/CS.RUTGERS.EDU. The second file is very security-sensitive. It should never go anyplace other than the KDCs.
I extracted those keytables using kadmin.local, the ktadd command. Make very sure to use the -norandkey option, or it will change the keys. That will disable the whole system, and won't be easy to restore. I'd copy them from an existing server, and on the first server do this before going into production.
Here's the section in krb5.conf for it:
[appdefaults] credserv= { impersonate=/etc/krb5.tgt.keytab admingroup=admins ldapurl=ldaps://krb2.cs.rutgers.edu,ldaps://krb1.cs.rutgers.edu ldapbase=cn=accounts,dc=cs,dc=rutgers,dc=edu }impersonate points to a key table for the TGT. Without impersonate it will use keytables for users stored in ldap. Impersonate is necessary if you need to support users with two-factor authentication. Using key tables is kind of a hack, but the impersonate code was added later.
admingroup is a group for people who can look at and change other users' data. I'm using admins, which is a group that all the admins belong to. If you want to delegate this to other users, you can use a different group.
ldapurl should point to the local server. I'm not sure whether adding a second server is actually a good idea.
ldapbase is the base for your users' information.
a service file for systemd is included in the source.
I recommend installing chrony. /etc/chrony.conf is installed with it. Remove the default centos servers and add
server 128.6.1.1 iburst initstepslew 10 128.6.1.1
The initstepslew says to adjust the clock immediately rather than gradually if the time is off by more than 10 sec. This is the reason for using chrony rather than ntp. Ntp will leave the clock off for 900 sec, and may exit if it's too far off. Kerberos servers absolutely must have the right time, or two-factor auth won't work, and with some clients, kerberos won't either.
systemctl disable ntpd systemctl enable chronyd
Note that starting ipa will start ntp. That will kill chrony. That's OK. We just need chrony to run once to set the clock if it's too far off. We currently have a cron job on all systems that will restart chrony eventually. That will kill ntp. That's fine too.
When you set up IPA it will generate its own certificate. It will be used for both ldap and http. A CA cert goes into /etc/ipa/ca.cert.
In the long run you want to use a commercial certificate. I got back from the certificate people a key, a cert, and a CA chain. Installing them was a hair-raising experience.
Note that on the backup, the intermediates are already there, because they're copied from the primary. Hence you can go directly to ipa-server-certinstall. This is probably true for renewal as well.
- Before you can install the actual cert, you need to install all the CA certificates for the chain.
- Take apart the intermediate certificates. If you look at the file you'll see it has 3 obvious sections.
- Use openssl x509 --in FILE --text to look at them
- Starting at the top level, install each one using
ipa-cacert-manage -p PASSWORD -n NICKNAME -t C,, install FILE ; PASSWORD is the admin password for the system. ; NICKNAME is a word you pick to identify the CA. ; FILE is the file with the data
- ipa-certupdate ; this actually updates the CA database with the new certs
- ipa-server-certinstall -w -d mysite.key mysite.crt, i.e. the files with the key and the actual cert for this system
- systemctl restart httpd.service
NSSNickname "CN=krb1.cs.rutgers.edu,OU=SAS,O="Rutgers, The State University of New Jersey",STREET=43 College Avenue,STREET=\ Room 226A,L=New Brunswick,ST=NJ,postalCode=08901,C=US"Unfortunately this is a syntax error. To fix it, add \ before the "'s inside the string.
Make sure you can restart httpd.service cleanly. I do *not* recommend rebooting the system until that's fixed.
Now
systemctl restart [email protected]
At this point, in an ideal world, you're done. However I found that after doing this the system would no longer come up after reboot. After about 10 min it will come up, but
systemctl -awill show several services failed. It may also come up without the firewall on, which is a concern.
There appears to be a race condition between dbus and polkit. I fixed it by editing /usr/lib/systemd/system/dbus.service and adding a line:
ExecStartPre=/bin/sleep 2 ExecStart=/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation ExecReload=/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.Reloa\The first (with sleep) is what I added. At that point the system should come up.
This appears to be a known issue with how systemd interacts with the dbus. It's been fixed upstream, but it may be a while before we see it.
There's a cron job, /usr/local/scripts/hosts2fw/update
#!/bin/sh export PATH=/sbin:/bin:/usr/sbin:/usr/bin export KRB5CCNAME=KEYRING:persistent:0:hosts2fw kinit -k -t /etc/scripts.keytab [email protected] ipa host-find | grep "Host name:" | awk 'BEGIN{FS=":"}{gsub(" ", "", $2); print "[" $2 "]"}' | xargs -L 1 ipset add lcsr -exist service ipset save kdestroy
It runs every 10 min from cron. However for ansible there are times when we need to do it immediately. I've added a user "useradd syncipt -u 990 -g 990" to run it. The user's shell is /home/syncipt/update. In that user's home directory we have
.k5login
enroll/[email protected]
update
#!/bin/sh sudo /usr/local/scripts/hosts2fw/update
/etc/sudoers.d/syncipt
syncipt ALL=NOPASSWD:/usr/local/scripts/hosts2fw/update
and in /etc/ssh/sshd_config before the other match block
match user syncipt AuthenticationMethods gssapi-with-mic
This allows the sync to be triggered by principal enroll/[email protected]
To support old code we have temporarily had to support TLS1.0. The system won't support SSL. TLS1.0 is the lowest it will go. However we've configured it for SSL2, because attempts to configure TLS1.0 failed. The system doesn't actually use SSL.
In /etc/crypto-policies/back-ends/nss.config, change "tls-version-min=tls1.2" to "tls-version-min=ssl2".
Stop the system. In /etc/dirsrv/slap*/dse.ldif change cn=encryption,cn=config to have the following
nsSSL3: on nsSSL2: on sslVersionMin: SSL2
Restart. This can probably be done with ldapmodify.
Immediate
- Document how to set up client to use both servers, and test backup
- Optimize hosts2fw script to not re-add all hosts
- Clean up nightly dumps of LDAP data
- Create script to add hosts