'+ escapeHtml(title) + '
' + escapeHtml(summary) +'
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..a87f141f --- /dev/null +++ b/404.html @@ -0,0 +1,212 @@ + + +
+ + + + + + + +Page not found
+This section is for archives. Most of these pages were created by one of our late +contributors and have not been updated since his passing. As such, we have moved +most of them here as clean up.
This page goes over various ways that installs can be automated without the use of PXE. Instead, we can use templated scripts with pre-configured commands, boot images, and mirrors for builds. We cover the following here:
+This page is a series of notes and information that goes over how to +install and configure FreeIPA on Enterprise Linux 8/9 servers with +replicas, as well as configuring client machines to connect and utilize +FreeIPA resources, policies (eg sudo), and host based access control +methods. We will also go over a scenario of configuring a trust with an +Active Directory domain. The client setup will work for Fedora users as +the packages are the same, just newer versions.
+FreeIPA is an integrated security information management system +combining Linux, a Directory Server (389), Kerberos, NTP, DNS, DogTag. +It's a system that can be loosely compared to Active Directory in what +it attempts to solve for Linux and UNIX clients and even mixed +environments. While it is not an active directory, it is an +integrated Identity and Authentication solution for Linux/UNIX +environments, which means it does not support Windows clients. One +problem that FreeIPA attempts to solve is giving back control to the +Linux/UNIX administration teams of access, authentication, and +authorization rather than trying to integrate directly into Active +Directory, where the controls do not work the same or do not work at +all. And because of this, no third party software is required to be +installed.
+Here are the list of requirements below.
+Potential Pitfalls!
+Recommended Information
+DNS - You must be careful when using DNS. Here are + recommendations.1
+Consider setting up a trust with Active Directory if you are in a + mixed environment, eg Active Directory already exists - winsync is + available, but deprecated and not recommended.
+Trust Information
+If you are in a mixed environment (both Windows and Linux/UNIX), it is +recommended to setup a trust between FreeIPA and Active Directory. +Because of this, they will need to be in different domains (eg, +example.com and ipa.example.com, or example.com and example.net). This +way, you do not have to create duplicate users if a windows user logs +into Linux resources nor use winsync.
+As noted in the previous section, you must try not to hijack a domain. +You can migrate records over to FreeIPA's DNS if you'd like, but care +must be taken with that approach.
+While FreeIPA can do the typical DNS server work such as forward/reverse +zones and various types of records, it should not be considered a full +solution. It does not support views (eg, you can't have internal and +external views, assuming you have domains that are publically facing). +In the event you need to have views, that's when you need a different +DNS server or service to provide this to you.
+There are two ways you can have DNS entries updated dynamically:
+--enable-dns-updates
for ipa-client-install and DHCP dynamic DNS
+updates. Both are sufficient. The latter requires additional work and is
+outside the scope of this write up.
Throughout this guide, you may find or see examples of domain delegation +where there is an AD trust, as it would be a more real world example of +bringing in FreeIPA to an environment that is already in place, working, +with a DNS hosted by AD or by an appliance. Majority of the examples +assume both IPA and AD is delegated (when it's normally IPA that's +just delegated while AD hosts the actual parent zone). Using this type +of setup, it is not required for clients to have entries in the IPA +domain. In fact, they can be in other domains as long as they have +A/AAAA/PTR records associated with them. This assumes that there could +be dynamic dns associated with DHCP or everything is static and lives in +the parent zones. The caveat to this is SSO will fail.
+You can setup already existing DNS servers to delegate an entire domain +or a subdomain for FreeIPA. This way, you don't overlap with a domain +that's already in use. So for example, if AD owns example.com, you +could have AD delegate ipa.example.com or even forward example.net. If +AD is not the DNS provider for the environment, you can have the +appliance delegate the domain in the same manner.
+Below is a bind example of what example.com would look like when +delegating the IPA domain:
+$ORIGIN example.com.
+@ IN SOA ... ( )
+ NS np-ad01
+ NS np-ad02
+np-ad01 A 10.200.0.232
+np-ad02 A 10.200.0.233
+; Many other records here, pertaining to AD, eg msdcs and SRV records
+
+; IPA records
+$ORIGIN ipa.example.com.
+@ NS np-ipa01
+ NS np-ipa02
+np-ipa01 A 10.200.0.230
+np-ipa02 A 10.200.0.231
+
Note that AD can send nsupdates to a DNS server if given the permissions. As of +this writing, FreeIPA does not do this, which is why DNS delegation is recommended.
+To install the server, make sure the hostname is set to the A records +and NS delegations you've put in DNS (which won't respond to a DNS +lookup). If these are stand-alone, then you can just keep it at the top +level (eg, example.com). You'll also need to modify /etc/hosts, set +static IP addresses, and then run the ipa-server-install command.
+% hostnamectl set-hostname server1.ipa.example.com
+% nmcli con mod ens192 ipv4.address 10.200.0.230/24
+% nmcli con mod ens192 ipv4.gateway 10.200.0.1
+% nmcli con mod ens192 ipv4.method manual
+% nmcli con up ens192
+% vi /etc/hosts
+. . .
+10.200.0.230 server1.ipa.example.com
+10.200.0.231 server2.ipa.example.com
+
+# Fedora
+% dnf install freeipa-server{,-common,-dns,-trust-ad} -y
+
+# Enterprise Linux 8
+% dnf module enable idm:DL1/{dns,adtrust,client,server,common}
+% dnf install ipa-server ipa-server-dns ipa-client sssd sssd-ipa -y
+
+# Enterprise Linux 9 (there appears to be no modules)
+% dnf install ipa-server ipa-server-dns ipa-client sssd sssd-ipa -y
+
+# Setup
+# Enterprise 8 / 9
+% firewall-cmd --permanent --add-service={freeipa-4,ntp,dns,freeipa-trust}
+% firewall-cmd --complete-reload
+% ipa-server-install \
+ --no_hbac_allow \ <-- If you want to have HBAC allow_all disabled initially
+ --no-ntp \ <-- If you want to host NTP from IPA, take off --no-ntp
+ --setup-dns \
+ --realm IPA.EXAMPLE.COM \
+ --domain example.com
+
+. . . (show steps here)
+
While not officially recommended, you could have two accounts. One for +administration of servers and the domain and one for your workstation, +similar to separating domain users and domain administrators in active +directory. You don't have to follow this, but at least there's a form +of separation.
+% kinit admin
+% ipa user-add --first=First --last=Last --cn="First Last Admin" --gecos="First Last Admin" flast2
+% ipa group-add-member --users=flast2 admins
+
On the replica, ensure you repeat the same steps as above.
+% hostnamectl set-hostname server2.ipa.example.com
+% nmcli con mod ens192 ipv4.address 10.200.0.231/24
+% nmcli con mod ens192 ipv4.gateway 10.200.0.1
+% nmcli con mod ens192 ipv4.method manual
+% nmcli con up ens192
+% vi /etc/hosts
+. . .
+10.200.0.230 server1.ipa.example.com
+10.200.0.231 server2.ipa.example.com
+
+% dnf install ipa-server ipa-server-dns ipa-client sssd sssd-ipa -y
+# Enterprise 8 / 9
+% firewall-cmd --permanent --add-service={freeipa-4,ntp,dns,freeipa-trust}
+% firewall-cmd --complete-reload
+% ipa-replica-install --no-forwarders --setup-ca --setup-dns --no-ntp --principal admin --admin-password "ChangePass123" --domain ipa.example.com
+. . . (show steps)
+
You should now be able to see your replicas.
+% ipa-replica-manage list
+server1.ipa.example.com: master
+server2.ipa.example.com: master
+
It is possible to automate the replica installation. To automate the +replica installation, the following requirements would need to be met:
+Once you have a server added as a client and then added to the +ipaservers host group, you would run a command like this:
+% ipa-replica-install --ssh-trust-dns --unattended --setup-ca --mkhomedir --setup-dns --no-forwarders
+
If you have forwarders, use the --forwarders
option instead.
Performing a migration is a multi-step process. Typically you are going +from one major version of Enterprise Linux (such as 7 or 8) to another +(such as 9). Regardless of which version you are migrating from, the +typical beginning steps are:
+ipa server-role-find --status enabled --server ipa.example.com
EL7 to EL9 / Two Major Version Jumps
+When jumping from EL7 to EL9 or two major versions in general, it is +recommended that you have an "in between" machine. This means that you +need to add the in between version first and then you can add the latest +version. See this page +for an example.
+The below is in the case of a single master installation and doesn't +take into account of multiple version jumps. Let's say you have two old +Enterprise Linux replicas instead. There are two approaches you can +take:
+Below is an example, with X being the old version, and Y being the new.
+# Enterprise Linux 8
+% dnf module enable idm:DL1
+
+# Install necessary packages, ie AD trust packages if you need them
+% dnf install ipa-server ipa-server-dns -y
+% ipa-client-install --realm EXAMPLE.COM --domain example.com
+% kinit admin
+
+# Add other switches that you feel are necessary, such as forwarders, kra, ntp...
+% ipa-replica-install --setup-dns --setup-ca --ssh-trust-dns --mkhomedir
+
+# Verify all services are in a RUNNING state
+% ipactl status
+Directory Service: RUNNING
+. . .
+
+% ipa-csreplica-manage list
+elX.example.com: master
+elY.example.com: master
+
+% ipa-csreplica-manage list --verbose elY.example.com
+Directory Manager password:
+
+elX.example.com
+ last init status: None
+ last init ended: 1970-01-01 00:00:00+00:00
+ last update status: Error (0) Replica acquired successfully: Incremental update succeeded
+ last update ended: 2019-11-07 22:46:15+00:00
+
# Change CA master to elY
+% ipa config-mod --ca-renewal-master-server elY.example.com
+
+# Shut down all CRL generation on ELX
+elX% ipa-crlgen-manage status
+CRL generation: enabled
+. . .
+
+elX% ipa-crlgen-manage disable
+Stopping pki-tomcatd
+Editing /var/lib/pki/pki-tomcat/conf/ca/CS.cfg
+Starting pki-tomcatd
+Editing /etc/httpd/conf.d/ipa-pki-proxy.conf
+Restarting httpd
+CRL generation disabled on the local host. Please make sure to configure CRL generation on another master with ipa-crlgen-manage enable.
+The ipa-crlgen-manage command was successful
+
+# Verify that the /etc/httpd/conf.d/ipa-pki-proxy.conf file's RewriteRule is not commented
+# If it is, remove the comment and restart httpd. ipa-crlgen-manage should take care of this.
+% tail -n 1 /etc/httpd/conf.d/ipa-pki-proxy.conf
+RewriteRule ^/ipa/crl/MasterCRL.bin https://elX.example.com/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL [L,R=301,NC]
+
+# Turn it on with ELY
+elY% systemctl stop pki-tomcatd@pki-tomcat.service
+
+# The values should be changed from false to true
+elY% vi /etc/pki/pki-tomcat/ca/CS.cfg
+ca.crl.MasterCRL.enableCRLCache=true
+ca.crl.MasterCRL.enableCRLUpdates=true
+
+elY% systemctl start pki-tomcatd@pki-tomcat.service
+
+# Make sure the rewrite rule has a comment on elY
+elY% vi /etc/httpd/conf.d/ipa-pki-proxy.conf
+. . .
+#RewriteRule ^/ipa/crl/MasterCRL.bin https://elY.example.com/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL [L,R=301,NC]
+
+elY% systemctl restart httpd
+
% ipa user-add --first=testing --last=user testinguser1
+
+# Test on both systems
+elX% ipa user-find testinguser1
+elY% ipa user-find testinguser1
+
# There should be ranges for both replicas
+% ipa-replica-manage dnarange-show
+elX.example.com: ...
+elY.example.com: ...
+
# Stop all elX services
+elX% ipactl stop
+
+# Delete the elX system from the topology
+elY% ipa server-del elX.example.com
+
+# Uninstall and/or power down system
+elX% ipa-server-install --uninstall
+elX% init 0
+
# Enterprise Linux 9
+% dnf install ipa-server ipa-server-dns -y
+% ipa-client-install --realm EXAMPLE.COM --domain example.com
+% kinit admin
+
+# Add other switches that you feel are necessary, such as forwarders, kra, ntp...
+% ipa-replica-install --setup-dns --setup-ca --ssh-trust-dns --mkhomedir
+
+# Verify all services are in a RUNNING state
+% ipactl status
+Directory Service: RUNNING
+. . .
+
+% ipa-csreplica-manage list
+elX.example.com: master
+elY.example.com: master
+
+% ipa-csreplica-manage list --verbose elY.example.com
+Directory Manager password:
+
+elX.example.com
+ last init status: None
+ last init ended: 1970-01-01 00:00:00+00:00
+ last update status: Error (0) Replica acquired successfully: Incremental update succeeded
+ last update ended: 2022-08-12 18:11:11+00:00
+
Set the CA renewal master to the new system and change the CRL settings
+% ipa config-mod --ca-renewal-master-server elY.example.com
+
+# Remove the ca.certStatusUpdateInterval entry or set it to 600 (default) on elY
+elY% vim /etc/pki/pki-tomcat/ca/CS.cfg
+
+# Restart the ipa services
+elY% ipactl restart
+
+# Set the value of ca.certStatusUpdateInterval on elX to 0
+elX% vim /etc/pki/pki-tomcat/ca/CS.cfg
+ca.certStatusUpdateInterval=0
+
+elX% ipactl restart
+
+elX% ipa-crlgen-manage status
+CRL generation: enabled
+. . .
+
+elX% ipa-crlgen-manage disable
+Stopping pki-tomcatd
+Editing /var/lib/pki/pki-tomcat/conf/ca/CS.cfg
+Starting pki-tomcatd
+Editing /etc/httpd/conf.d/ipa-pki-proxy.conf
+Restarting httpd
+CRL generation disabled on the local host. Please make sure to configure CRL generation on another master with ipa-crlgen-manage enable.
+The ipa-crlgen-manage command was successful
+
+elX% ipa-crlgen-manage status
+CRL generation: disabled
+
Create a test user to ensure DNA range is adjusted and replication is +working
+elY% ipa user-add --first=testing --last=user testinguser1
+
+# Test on both systems
+elX% ipa user-find testinguser1
+elY% ipa user-find testinguser1
+
Verify DNA range.
+# There should be ranges for both replicas
+% ipa-replica-manage dnarange-show
+elX.example.com: ...
+elY.example.com: ...
+
Stop old Enterprise Linux IPA services, remove replica, uninstall.
+# Stop all elX services
+elX% ipactl stop
+
+# Delete the elX system from the topology
+elY% ipa server-del elX.example.com
+
+# Uninstall and/or power down system
+elX% ipa-server-install --uninstall
+elX% init 0
+
See this page +for more information.
+To initiate a trust with your active directory domain, ensure the +following requirements are met.
+Requirements
+Package installed: ipa-server-trust-ad
+DNS: Properly configured that FreeIPA can resolve the AD servers A and +SRV records
+This can either be forwarders to AD, a subdomain that IPA manages, or +delegated subdomain from the master DNS servers in your network. This is +completely dependent on your infrastructure.
+DNS: AD forest has sites and SRV records, including priorities, are set +correctly
+When the following requirements are met, you have two choices before +continuning. You can either use POSIX or have the id range generated +automatically.
+POSIX vs Non-POSIX
+If you decide to use POSIX, your AD users are expected to have +uidNumber, gidNumber, loginShell, unixHomeDirectory set. Else, you will +need to setup ID overrides if you already have that information for +current users (assuming this is not a new setup for the environment, ie +you already have UID's for people). If you are not planning a migration +from pure AD over to IPA with a trust, it is recommended to note that +information so you can setup the ID overrides. Afterwards, any new users +will get UID/GID's that you will not have to manage yourself.
+You will need to prep your master(s) for the trust. We will be enabling +compat, adding sids, and adding agents so both masters can provide AD +information.
+% ipa-adtrust-install --add-sids --add-agents --enable-compat
+
This will do what we need. If you do not have legacy clients (Enterprise +Linux 5, Solaris, HP-UX, AIX, SLES 11.4, FreeBSD, the list goes on), then you do +not need to enable compat mode. Though, it could be useful to have it for +certain apps or scenarios.
+You will now need to open the necessary ports. Do this on all masters.
+Ports
+TCP: 135, 138, 139, 389, 445, 1024-1300, 3268 UDP: 138, 139, 389, 445
+% firewall-cmd --add-service=freeipa-trust --permanent
+% firewall-cmd --complete-reload
+
Now you can initiate the trust. The admin account you use should be part +of the domain admins group or at least have permissions to initiate a +trust. The former is path of least resistance.
+# If you are using POSIX ID, use ipa-ad-trust-posix.
+% ipa trust-add --type=ad example.com --range-type=ipa-ad-trust --admin adminaccount --password
+
Once the trust is up, verify it.
+% ipa trust-show example.com
+ Realm name: example.com
+ Domain NetBIOS name: AD
+ Domain Security Identifier: S-X-X-XX-XXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX
+ Trust direction: Trusting forest
+ Trust type: Active Directory domain
+ UPN suffixes: example.com
+
You should be able to test for the users now.
+% id aduser1@example.com
+uid=XXXXX(aduser1@example.com) gid=XXXXX(aduser1@example.com) groups=XXXXX(aduser1@example.com)
+
In some cases, it is a requirement to disable all anonymous binds. If +this is the case, you will need to modify cn=config on each master as it +is not replicated.
+rootdse
+Some applications do anonymous binds to the directory server to +determine its version and it supported controls. While it is possible to +disable anonymous binds completely, it is important to know that if you +disable the rootdse binds, applications that do anonymous lookups to get +server information will fail.
+% ldapmodify -xZZ -D "cn=Directory Manager" -W -h server.ipa.example.com
+Enter LDAP Password:
+dn: cn=config
+changetype: modify
+replace: nsslapd-allow-anonymous-access
+nsslapd-allow-anonymous-access: rootdse
+
+modifying entry "cn=config"
+
Ensure your /etc/resolv.conf (or other dns settings) are set correctly. +Ensure your hostname is also set correctly.
+% dnf install ipa-client -y
+% ipa-client-install --realm EXAMPLE.COM --domain example.com --mkhomedir
+
MacOS Clients are an interesting workstation to setup as a FreeIPA +client. It takes a little bit of fighting and troubleshooting, but it +can work with the right settings. Note that as of Catalina, you may +not be able to login to your account nor will creating a mobile account +function as you would expect. This may have changed in recent macos +releases, so YMMV.
+Other Guides
+There are a couple of guides out there that you may have found before +(if you looked) that help setup IPA for Mac. There's one for much older +(I think Lion) and one for Sierra. This section was made mostly for my +own reference because I found some things in both of those guides +didn't address issues I ran into one way or another and couldn't find +any information on. The FreeIPA users mail list didn't have any +archives with people having similar issues.
+If you are interested in the other guides to compare to, you may see +them here (recent) +and here (older)
+AD Users
+AD Users
+You cannot login as AD users on a Mac when going through FreeIPA. You +can, in theory, point to the cn=compat tree and set the attribute +mapping to rfc2307. In my tests, I have never been able to get this to +work. This section, I am going to assume you are going to be logging in +as a user in IPA. If you are in a mixed environment, add your Mac to +your AD domain instead.
+Anonymous Bind
+There may be cases where if you have disabled anonymous binds in IPA, +this setup may not work, even if you do use a bind account. You will +need to experiment with this if you plan on using a bind account and +plan on or currently have IPA not allowing anonymous binds.
+Check your system's hostname. You want to make sure it has a hostname +defined for it in the domain the mac sits in, even if it's dynamic via +DHCP/DNS.
+% sudo scutil --set HostName mac.example.com
+
Get the IPA certificate. You'll need to double click it after you get +it and import it.
+% cd ~/Desktop && curl -OL http://server1.ipa.example.com/ipa/config/ca.crt
+% sudo mkdir /etc/ipa
+% sudo cp ca.crt /etc/ipa/ca.crt
+% sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /etc/ipa/ca.crt
+
On the IPA server, you will need to create a host and get the keytab.
+% ipa host-add mac.example.com --macaddress="00:00:00:00:00:00"
+% ipa-getkeytab -s server1.ipa.example.com -p host/mac.example.com -k /tmp/krb5.keytab
+
You will need to transfer that keytab to your mac.
+% cd ~
+% scp user@server1.ipa.example.com:/tmp/krb5.keytab .
+% sudo mv krb5.keytab /etc/krb5.keytab
+% sudo chmod 600 /etc/krb5.keytab
+% sudo chown root:wheel /etc/krb5.keytab
+
Configure /etc/krb5.conf
+[domain_realm]
+ .ipa.example.com = IPA.EXAMPLE.COM
+ ipa.example.com = IPA.EXAMPLE.COM
+
+[libdefaults]
+ default_realm = IPA.EXAMPLE.COM
+ allow_weak_crypto = yes
+ dns_lookup_realm = true
+ dns_lookup_kdc = true
+ rdns = false
+ ticket_lifetime = 24h
+ forwardable = yes
+ renewable = true
+
+[realms]
+ IPA.EXAMPLE.COM = {
+ # You don't need to set these when your DNS is setup correctly, but it doesn't hurt to have a reference.
+ # In my opinion, you shouldn't hardcode these values. You have to have a good reason to.
+ #kdc = tcp/server1.ipa.example.com
+ #kdc = tcp/server2.ipa.example.com
+ #admin_server = tcp/server1.ipa.example.com
+ #admin_server = tcp/server2.ipa.example.com
+ pkinit_anchors = FILE:/etc/ipa/ca.crt
+ }
+
You'll want to do a kinit to verify. If it works, you should be able to +go to the FreeIPA webui and check that the host is "enrolled" +(Identity -> Hosts).
+% kinit username@IPA.EXAMPLE.COM
+
You need to modify a couple of pam files. I'll explain why they need to +be changed.
+% sudo vi /etc/pam.d/authorization
+# authorization: auth account
+# Putting krb5 here twice ensures that you can login via kerberos and also get a keytab
+# If "no_ccache" is here, keytabs will not be available on login
+auth optional pam_krb5.so use_first_pass use_kcminit default_principal
+auth sufficient pam_krb5.so use_first_pass default_principal
+auth required pam_opendirectory.so use_first_pass nullok
+account required pam_opendirectory.so
+
+% sudo vi /etc/pam.d/screensaver
+# The krb5 changes do similar to the authorization when on the lock screen after a sleep
+#auth optional pam_krb5.so use_first_pass use_kcminit
+auth optional pam_krb5.so use_first_pass use_kcminit default_principal
+auth sufficient pam_krb5.so use_first_pass default_principal
+auth required pam_opendirectory.so use_first_pass nullok
+account required pam_opendirectory.so
+account sufficient pam_self.so
+account required pam_group.so no_warn group=admin,wheel fail_safe
+account required pam_group.so no_warn deny group=admin,wheel ruser fail_safe
+
+% sudo vi /etc/pam.d/passwd
+# Helps with kerberos logins
+password sufficient pam_krb5.so
+auth required pam_permit.so
+account required pam_opendirectory.so
+password required pam_opendirectory.so
+session required pam_permit.so
+
After these changes, you'll need to go into make some changes with the +directory utility. This depends on your macOS version.
+Automatic login: Off
+Display login window as: Name and Password
+Show fast user switching menu as: Full Name
+
Open/close times out in 5 seconds
+Query times out in 5 seconds
+Connection idles out in 1 minute (this can't be changed)
+Encrypt using SSL (selected)
+
You may either select "rfc2307" from the dropdown or select + custom. It will ask your base DN (eg, dc=ipa,dc=example,dc=com)
+If you select rfc2307, it will ask for your base DN (eg, + dc=ipa,dc=example,dc=com)
+If you select "custom", you will need to do this manually for each + record type. You're better off using rfc2307 and working from + there
+Click the "+" to add a groups record type or scroll and find + "groups".
+Record Type ObjectClasses
+Groups posixGroup
+ ipausergroup
+
+ groupOfNames\*
+
+Note
+"groupOfNames" is optional here, because it seems that the directory +utility doesn't understand this concept.
+Attribute Mapping
+PrimaryGroupID gidNumber
+RecordName cn
+Record Type ObjectClasses
+Users inetOrgPerson
+ posixAccount
+
+ shadowAccount
+
+ apple-user
+
+Attribute Mapping
+AuthenticationAuthority uid
+GeneratedUID GeneratedUID or ipaUniqueID
+HomeDirectory #/Users/\$uid\$
+NFSHomeDirectory #/Users/\$uid\$
+PrimaryGroupID gidNumber
+RealName cn
+RecordName uid
+UniqueID uidNumber
+UserShell loginShell
+AltSecurityIdentities #Kerberos:\$krbPrincipalName\$
+% dscacheutil -flushcache
+% dscacheutil -q user -a name username
+
You should get a return.
+If you want to further verify users and groups after the above succeeds, +open up the directory utility again. Click "Directory Editor", ensure +you are searching for "users" and check that they appear in a list on +the right hand side, optionally doing a search. In a default setup, you +shouldn't need an account to do (some) anonymous lookups. If you +changed that in any way, you will need to create a readonly system +account in cn=sysaccounts,cn=etc.
+Login to the account for the first time from the login screen. Once the +setup has complete, log out and back to a login account. In a terminal, +you will need to make a mobile account.2
+% sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n username -P
+# Press enter and put in the password. sudo may not function if you don't do this step.
+# OPTIONAL: Allow the mobile account to be an administrator
+% sudo dscl . -append /Groups/admin GroupMembership username
+
Go to system preferences, users & groups and ensure the account is a +mobile account.
+Select the "from server" portion under LDAP mappings and clck + RFC2307. You may also leave it as custom.
+If you select rfc2307, it will ask for your base DN (eg, + dc=ipa,dc=example,dc=com)
+If you select "custom", you will need to do this manually for each + record type. You're better off using rfc2307 and working from + there
+Click "edit"
+Record Type ObjectClasses
+Groups posixGroup
+ ipausergroup
+
+ groupOfNames\*
+
+Note
+"groupOfNames" is optional here, because it seems that the directory +utility doesn't understand this concept.
+Attribute Mapping
+PrimaryGroupID gidNumber
+RecordName cn
+Record Type ObjectClasses
+Users inetOrgPerson
+ posixAccount
+
+ shadowAccount
+
+ apple-user
+
+Attribute Mapping
+AuthenticationAuthority uid
+GeneratedUID GeneratedUID or ipaUniqueID
+NFSHomeDirectory #/Users/\$uid\$
+PrimaryGroupID gidNumber
+RealName cn
+RecordName uid
+UniqueID uidNumber
+UserShell loginShell
+AltSecurityIdentities #Kerberos:\$krbPrincipalName\$
+% dscacheutil -flushcache
+% dscacheutil -q user -a name username
+
You should get a return.
+Login to the account for the first time from the login screen. Once the +setup has complete, log out and back to a login account. In a terminal, +you will need to make a mobile account.3
+% sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n username -P
+# Press enter, enter the user's password. sudo may hang if you don't do this.
+# OPTIONAL: Allow the mobile account to be an administrator
+% sudo dscl . -append /Groups/admin GroupMembership username
+
Go to system preferences and ensure the account is a mobile account.
+Group Resolution
+If you want groups from IPA to resolve to the system, you'll need to +enable the compat tree when using this setup (RFC2307).
+Password Notes
+There are a couple of potential issues with this setup that you should +be aware of as it pertains to mobile accounts.
+Below is a script that can be adapted for you. It has not been tested on +Monterey and up. This assumes that you took one mac and set it up +properly and you created a tarball with the proper configuration. You +could optionally setup a temporary NFS or samba mount that gets mounted +as root and then unmounted at the end, if you so wish.
+#!/bin/bash
+serverName=server1.ipa.example.com
+krb5Conf=/etc/krb5.conf
+krb5Tab=/etc/krb5.keytab
+pamDirectory=/etc/pam.d
+
+# Add SSL cert to chain
+mkdir /etc/ipa
+cd /etc/ipa
+curl -OL http://$serverName/ipa/config/ca.crt
+security add-trusted-cert -d -k /Library/Keychains/System.keychain -r trustRoot /etc/ipa/ca.crt
+
+# Stop and flushout the Open Directory
+/usr/sbin/dscacheutil -flushcache
+launchctl unload /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist
+
+# Pull the plist and pam files needed for IPA and deploy them, this assumes you setup one mac and zipped up the configurations
+# You can try your hand at dsconfigldap before pam, but I could never figure it out, honestly.
+# Relevant tar: tar czf /tmp/macconfig.tar.gz /Library/Preferences/OpenDirectory/Configurations /etc/pam.d/authorization \
+# /etc/pam.d/screensaver /etc/pam.d/passwd /etc/krb5.conf
+cd /tmp
+curl -OL http://$serverName/macconfig.tar.gz
+cd /
+tar xzf /tmp/macconfig.tar.gz
+
+# Add steps here for your keytab! Where are you getting it from?
+cp /tmp/mac.keytab /etc/krb5.keytab
+chown root:wheel /etc/krb5.keytab
+chmod 600 /etc/krb5.keytab
+
+# Start directory
+launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist
+sleep 30
+
+# Kill the loginwindow
+killall loginwindow
+
+# If the system doesn't reboot here, reboot now.
+
If you want to move your local files, you will need to tread lightly +here. I personally believe it's always good to start fresh though. Look +into the ditto command. I suppose something like this can work:
+# make sure you're logged in as a different account away from your local account
+% sudo su -
+root# cd /Users
+root# ditto localfolder networkfolder (or maybe an mv?)
+root# chown -R user:user folder
+root# /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n username -P
+
Another issue you may run into, if you have been using your Mac with a +local account for a while, a lot of directories in /Applications will be +owned by localuser:staff or localuser:admin. It's recommended to fix +those too.
+Discovery
+The directory framework in MacOS has the ability to discover settings +for a particular LDAP server that it is being connected to. FreeIPA does +not contain the schema, plugins, nor the infrastructure to provide the +same things (for example, mDNS/Avahi, among other things). There was a +(WIP) plugin created in 2017 by abbra. However, it is unclear if this +works at all, nor is it clear if it ever did and will in python3 (abbra +noted at the time that it "installs" into python 2 directories, which +hints to not being tested or working on python 3). Please see the +following resources for discussion and information.
+ +To setup openSUSE with FreeIPA, we'll need to do some manual work. This +applies to SUSE 12 and up where the freeipa-client packages don't exist +in the main repositories.
+freeipa repos
+There are OpenSUSE repos with the freeipa packages, though they are +considered "experimental". If they show up in the base, then the below +steps will be removed. However, if you are willing to use the +repo, +a lot of the steps below may not be needed. We have not tested this.
+# On an IPA server or client with the IPA utilities...
+% ipa host-add suse.example.com
+% /usr/sbin/ipa-getkeytab -s ipa.example.com -p host/suse.example.com -k /tmp/suse.keytab
+% scp /tmp/suse.keytab suse.example.com:/tmp/krb5.keytab
+
+# On the IPA client...
+% cp /tmp/krb5.keytab /etc
+% chmod 600 /etc/krb5.keytab
+% mkdir /etc/ipa
+% curl -o /etc/ipa/ca.crt http://ipa.example.com/ipa/config/ca.crt
+% curl -o /etc/pki/trust/anchors/ipa.example.com.crt http://ipa.example.com/ipa/config/ca.crt
+% update-ca-certificates
+% zypper install sssd sssd-ipa yast2-auth-client krb5-client openldap2-client cyrus-sasl-gssapi
+
+# Setup SSSD
+% vi /etc/sssd/sssd.conf
+[domain/example.com]
+cache_credentials = True
+krb5_store_password_if_offline = True
+ipa_domain = example.com
+ipa_hostname = suse.example.com
+# Client Specific Settings
+ipa_server = _srv_, ipa.example.com
+dns_discovery_domain = example.com
+# If we have a trust with domain resolution order
+#full_name_format = %1$s
+
+id_provider = ipa
+auth_provider = ipa
+access_provider = ipa
+chpass_provider = ipa
+
+ldap_tls_cacert = /etc/ipa/ca.crt
+
+[sssd]
+services = nss, sudo, pam, ssh
+domains = example.com
+
+[nss]
+filter_users = root,ldap,named,avahi,haldaemon,dbus,radiusd,news,nscd,tomcat,postgres
+homedir_substring = /home
+
+[pam]
+
+[sudo]
+
+[autofs]
+
+[ssh]
+
+# Setup kerberos
+% vi /etc/krb5.conf
+[libdefaults]
+ default_realm = EXAMPLE.COM
+ dns_lookup_realm = true
+ dns_lookup_kdc = true
+ rdns = false
+ dns_canonicalize_hostname = false
+ ticket_lifetime = 24h
+ forwardable = true
+ udp_preference_limit = 0
+ default_ccache_name = KEYRING:persistent:%{uid}
+
+
+[realms]
+ EXAMPLE.COM = {
+ pkinit_anchors = FILE:/var/lib/ipa-client/pki/kdc-ca-bundle.pem
+ pkinit_pool = FILE:/var/lib/ipa-client/pki/ca-bundle.pem
+ }
+
+[domain_realm]
+ .example.com = EXAMPLE.COM
+ example.com = EXAMPLE.COM
+ suse.example.com = EXAMPLE.COM
+
+# Setup pam
+% pam-config -a --sss --mkhomedir --mkhomedir-umask=0077 \
+ --pwhistory --pwhistory-remember=5 --localuser --cracklib \
+ --cracklib-minlen=14 --cracklib-dcredit=-1 --cracklib-ucredit=-1 \
+ --cracklib-lcredit=-1 --cracklib-ocredit=-1 --cracklib-retry=3 --unix-sha512
+
+# Setup nsswitch (you can make it compat sss, but I use files sss)
+% sed -i.bak 's/compat$/files sss/g' /etc/nsswitch.conf
+% echo "sudoers: files sss" >> /etc/nsswitch.conf
+% sed -i '/netgroup/ s/nis/sss/g' /etc/nsswitch.conf
+
+# Depending on your suse version, you may want to set the nisdomainname
+# It does not hurt to set this
+% sed -i.bak '/NETCONFIG_NIS_STATIC_DOMAIN/ s/""/"example.com"/g' /etc/sysconfig/network/config
+% netconfig update -f
+
+# Start sssd
+% systemctl enable sssd --now
+
+# Verify
+% id admin
+
In the case of having an IPA-AD trust, you may need to change a line in +your pam configuration.
+% sed -i 's/use_first_pass/forward_pass/g' /etc/pam.d/common-auth-pc
+
+# The affected line should appear like the below
+auth sufficient pam_sss.so forward_pass
+
When we first setup our IPA servers, we had an option set to make it so +hbac wasn't allowed for everyone. This way we have to create HBAC rules +for our systems. I personally do this out of habit when working with +IPA. What we need to do though is create an "admin" group that can +login to all machines.
+% ipa idrange-show IPA.EXAMPLE.COM_id_range
+ Range name: IPA.EXAMPLE.COM_id_range
+ First Posix ID of the range: 686600000
+ Number of IDs in the range: 200000
+ First RID of the corresponding RID range: 1000
+ First RID of the secondary RID range: 100000000
+ Range type: local domain range
+% ipa group-add --gid=686610000 linuxadm
+% ipa group-add-member --users=flast linuxadm
+
Note for AD Users: In the event that your AD user or group of users +will be an admin, you need to create an "external" group to map the +user or users over. This isn't required if you don't have an AD trust.
+# Create an external group that the AD user/group goes into
+% ipa group-add --external linuxadm_external
+# Add the user (or group) into the external group
+% ipa group-add-member --users=aduser1@example.com linuxadm_external
+% ipa group-add-member --users=adgroup1@example.com linuxadm_external
+# Add the external group as a member of the IPA posix group.
+# aduser1 and adgroup1 are now effectively members of the linuxadm group in IPA.
+% ipa group-add-member --groups=linuxadm_external linuxadm
+
Now, let's create an HBAC for our Linux Administrator account for our +group.
+% ipa hbacrule-add --hostcat=all --servicecat=all --desc='linux admins all access' linuxadm
+% ipa hbacrule-add-user --groups=linuxadm linuxadm
+% ipa hbactest --rules=All_Systems --user=flast --host=server1.ipa.example.com --service=sshd
+% ipa hbactest --rules=All_Systems --user=aduser1@example.com --host=server1.ipa.example.com --service=sshd
+
You might want to create an HBAC rule specifically for your IPA admin +accounts to have ssh access to the IPA servers too. You can follow +something like the above to make it possible. Or you can just add the +IPA admins group into the HBAC rule we just made above.
+Group Types
+Groups in Active Directory have three types. These three types can +actually change the behavior of how SSSD on the IPA domain controllers +resolve them or if they'll even be resolvable at all. The three types +are 'Domain Local', 'Global', and 'Universal'. If at all possible, +avoid groups being 'Global'. Domain Local or Universal is recommended.
+Setting up sudo is relatively easy. SSSD (1.16.x and 2.X) supports IPA +as a provider for sudo. Based on the last section, let's create a +sample rule for our Linux admins that can login to every system, we want +to ensure they can run all commands.
+% ipa sudorule-add --runasusercat=all --hostcat=all --cmdcat=all --desc='linux admins all sudo' all_linux_sudo
+% ipa sudorule-add-user --groups=linuxadm all_linux_sudo
+
You can make this a little more specific, such as /bin/bash as everyone +or otherwise. It's your call here. If you want to create a sudo rule +and add some commands to it, you can do something like this.
+% ipa sudorule-add sudo_rule
+% ipa sudorule-add-allow-command --sudocmds="/usr/bin/less" sudo_rule
+
This applies to Solaris, Omnios, others based on Illumos.
+Setting up Solaris 10 as an IPA client is an interesting feat. However, +it comes with security issues.
+No SSL or TLS Support
+Note that for Solaris 10 to talk to IPA, you must use clear text +communication. Solaris 10 is too old to use new ciphers. However, while +LDAP may be clear text, kerberos should still be secure enough for the +time being.
+If you are using an AD trust, the user's passwords will be passed in +clear text. Highly suggested that you decommission Solaris 10 from your +environment. Solaris 10 will eventually be removed from this page.
+Create an ldif for your service account (optional)
+dn: uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com
+objectclass: account
+objectclass: simplesecurityobject
+uid: solaris
+userPassword: secret123
+passwordExpirationTime: 20380119031407Z
+nsIdleTimeout: 0
+
The solaris system account is required. So now, add it in.
+% ldapadd -xWD 'cn=Directory Manager' -f /tmp/solaris.ldif
+
Now, set the nisdomain.
+% defaultdomain ipa.example.com
+% echo 'ipa.example.com' > /etc/defaultdomain
+
Configure kerberos.
+% vi /etc/krb5/krb5.conf
+[libdefaults]
+default_realm = IPA.EXAMPLE.COM
+dns_lookup_kdc = true
+verify_ap_req_nofail = false
+
+[realms]
+IPA.EXAMPLE.COM = {
+}
+
+[domain_realm]
+ipa.example.com = IPA.EXAMPLE.COM
+.ipa.example.com = IPA.EXAMPLE.COM
+
+[logging]
+default = FILE:/var/krb5/kdc.log
+kdc = FILE:/var/krb5/kdc.log
+kdc_rotate = {
+ period = 1d
+ version = 10
+}
+
+[appdefaults]
+kinit = {
+renewable = true
+forwardable= true
+}
+
Generate a keytab and bring it over.
+# on the ipa server
+% ipa host-add solaris10.example.com
+% ipa-getkeytab -s server1.ipa.example.com -p host/solaris10.example.com -k /tmp/solaris10.keytab
+
+# Transfer the keytab
+% scp /tmp/solaris10.keytab solaris10.example.com:/tmp
+
+# On the solaris 10 machine
+% cp /tmp/solaris10.keytab /etc/krb5/krb5.keytab
+% chmod 600 /etc/krb5/krb5.keytab
+% chmod 644 /etc/krb5/krb5.conf
+% chown root:sys /etc/krb5/*
+% kinit flast2@IPA.EXAMPLE.COM
+
Create the LDAP configurations, bring the certificate, and create an NSS +database.
+% mkdir /etc/ipa /var/ldap
+% cd /etc/ipa
+% wget -O ipa.pem http://server1.ipa.example.com/ipa/config/ca.crt
+% certutil -A -n "ca-cert" -i /etc/ipa/ipa.pem -a -t CT -d .
+% cp * /var/ldap
+% vi /etc/ldap.conf
+base dc=ipa,dc=example,dc=com
+scope sub
+TLS_CACERTDIR /var/ldap
+TLS_CERT /var/ldap/cert8.db
+TLS_CACERT /var/ldap/ipa.pem
+tls_checkpeer no
+ssl off
+bind_timelimit 120
+timelimit 120
+uri ldap://server1.ipa.example.com
+sudoers_base ou=sudoers,dc=ipa,dc=example,dc=com
+pam_lookup_policy yes
+
Now init the ldap client.
+No Secure Connection
+When using this, you are not creating a secure connection. The Solaris +10 SSL libraries are so old that they cannot work with the ciphers that +FreeIPA has turned on.
+AD Trust - Different Trees
+If using an AD trust, you should use the second example, where it looks +at the compat tree for users.
+No Service Account
+If you have configured FreeIPA to not allow any anonymous connections, +you will need to use a proxy account. We have provided the examples for +this configuration.
+Without an AD Trust
+# Without AD Trust (no proxy)
+% ldapclient manual -a authenticationMethod=none \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
+# Without AD Trust (proxy)
+% ldapclient manual -a credentialLevel=proxy \
+ -a authenticationMethod=simple \
+ -a proxyDN="uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com" \
+ -a proxyPassword="secret123" \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
With an AD Trust
+# With AD Trust (no proxy)
+% ldapclient manual -a authenticationMethod=none \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
+# With AD Trust (proxy)
+% ldapclient manual -a credentialLevel=proxy \
+ -a authenticationMethod=simple \
+ -a proxyDN="uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com" \
+ -a proxyPassword="secret123" \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
This should succeed. Once it succeeds, you need to configure pam and +nsswitch.
+AD Trust Information
+In the event you don't have an AD trust, you can change the "binding" +lines to required, remove the pam_ldap lines, and change pam_krb5 +lines to read "required"
+% vi /etc/pam.conf
+
+# Console
+login auth requisite pam_authtok_get.so.1
+login auth sufficient pam_krb5.so.1
+login auth required pam_unix_cred.so.1
+login auth required pam_dial_auth.so.1
+login auth sufficient pam_unix_auth.so.1 server_policy
+login auth sufficient pam_ldap.so.1
+
+rlogin auth sufficient pam_rhosts_auth.so.1
+rlogin auth requisite pam_authtok_get.so.1
+rlogin auth required pam_dhkeys.so.1
+rlogin auth sufficient pam_krb5.so.1
+rlogin auth required pam_unix_cred.so.1
+rlogin auth sufficient pam_unix_auth.so.1 server_policy
+rlogin auth sufficient pam_ldap.so.1
+
+# Needed for krb
+krlogin auth required pam_unix_cred.so.1
+krlogin auth sufficient pam_krb5.so.1
+
+# Needed for krb
+krsh auth required pam_unix_cred.so.1
+krsh auth required pam_krb5.so.1
+
+# ?
+ppp auth requisite pam_authtok_get.so.1
+ppp auth required pam_dhkeys.so.1
+ppp auth sufficient pam_krb5.so.1
+ppp auth required pam_dial_auth.so.1
+ppp auth binding pam_unix_auth.so.1 server_policy
+ppp auth sufficient pam_ldap.so.1
+
+# Other, used by sshd and "others" as a fallback
+other auth requisite pam_authtok_get.so.1
+other auth required pam_dhkeys.so.1
+other auth sufficient pam_krb5.so.1
+other auth required pam_unix_cred.so.1
+other auth sufficient pam_unix_auth.so.1 server_policy
+other auth sufficient pam_ldap.so.1
+other account requisite pam_roles.so.1
+other account required pam_projects.so.1
+other account binding pam_unix_account.so.1 server_policy
+other account sufficient pam_krb5.so.1
+other account sufficient pam_ldap.so.1
+other session required pam_unix_session.so.1
+other password required pam_dhkeys.so.1
+other password requisite pam_authtok_get.so.1
+other password requisite pam_authtok_check.so.1 force_check
+other password required pam_authtok_store.so.1 server_policy
+
+# passwd and cron
+passwd auth binding pam_passwd_auth.so.1 server_policy
+passwd auth sufficient pam_ldap.so.1
+cron account required pam_unix_account.so.1
+
+# SSH Pubkey - Needed for openldap and still probably needed
+sshd-pubkey account required pam_unix_account.so.1
+
% vi /etc/nsswitch.conf
+
+# Below are just the minimum changes
+passwd: files ldap [NOTFOUND=return]
+group: files ldap [NOTFOUND=return]
+sudoers: files ldap
+netgroup: ldap
+# the rest here are just here, up to you if you choose to set them.
+hosts: files dns
+ipnodes: files dns
+ethers: files ldap
+publickey: files ldap
+automount: files ldap
+
You can test now if you'd like.
+bash-3.2# ldaplist -l passwd flast2
+dn: uid=flast2,cn=users,cn=compat,dc=ipa,dc=example,dc=com
+ cn: First Last
+ objectClass: posixAccount
+ objectClass: ipaOverrideTarget
+ objectClass: top
+ gidNumber: 1006800001
+ gecos: First Last
+ uidNumber: 1006800001
+ ipaAnchorUUID: :IPA:ipa.example.com:8babb9a8-5aaf-11e7-9769-00505690319e
+ loginShell: /bin/bash
+ homeDirectory: /home/first.last2
+ uid: first.last2
+
I recommend setting up sudo at least... if you want to use sudo, +install the sudo-ldap from sudo.ws for Solaris 10.
+Solaris 11 shares similar configuration to Solaris 10. There are a +couple of manual things we have to do, but they are trivial. Solaris +11/Omnios will use TLS and sudo should just work.
+AD Groups
+In Solaris 10, users who logged in with AD users (with their short name) +would appear as their full name (name@domain). This allowed their +groups to fully resolve. However, in Solaris 11.4, this was not the +case. Short name logins will work but your groups will not resolve as +the compat tree uses the full name. To avoid running into this problem, +you should be on at least SRU 11.4.7.4.0. Note that on a later SRU, you +may need to setup an ID view (without overrides) for groups and sudo to +work again.
+Below is for the service account like in the previous section, here as a +reference.
+dn: uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com
+objectclass: account
+objectclass: simplesecurityobject
+uid: solaris
+userPassword: secret123
+passwordExpirationTime: 20380119031407Z
+nsIdleTimeout: 0
+
% ldapadd -xWD 'cn=Directory Manager' -f /tmp/solaris.ldif
+
Now, set the nisdomain.
+% defaultdomain ipa.example.com
+% echo 'ipa.example.com' > /etc/defaultdomain
+
Configure kerberos.
+% vi /etc/krb5/krb5.conf
+[libdefaults]
+default_realm = IPA.EXAMPLE.COM
+dns_lookup_kdc = true
+verify_ap_req_nofail = false
+
+[realms]
+IPA.EXAMPLE.COM = {
+}
+
+[domain_realm]
+ipa.example.com = IPA.EXAMPLE.COM
+.ipa.example.com = IPA.EXAMPLE.COM
+
+[logging]
+default = FILE:/var/krb5/kdc.log
+kdc = FILE:/var/krb5/kdc.log
+kdc_rotate = {
+ period = 1d
+ version = 10
+}
+
+[appdefaults]
+kinit = {
+renewable = true
+forwardable= true
+}
+
Generate a keytab and bring it over.
+# on the ipa server
+% ipa host-add solaris11.example.com
+% ipa-getkeytab -s server1.ipa.example.com -p host/solaris11.example.com -k /tmp/solaris11.keytab
+
+# Transfer the keytab
+% scp /tmp/solaris11.keytab solaris11.example.com:/tmp
+
+# On the solaris 11 machine
+% cp /tmp/solaris11.keytab /etc/krb5/krb5.keytab
+% chmod 600 /etc/krb5/krb5.keytab
+% chmod 644 /etc/krb5/krb5.conf
+% chown root:sys /etc/krb5/*
+
+# Check the keytab
+% klist -ket /etc/krb5/krb5.keytab
+
+# Test that you can kinit
+% kinit flast2@IPA.EXAMPLE.COM
+
Create the LDAP configurations, bring the certificate, and create an NSS +database.
+Solaris 11.3 vs 11.4
+Previously we had 11.3 and 11.4 configurations. We have removed 11.3 as +we no longer support it.
+% mkdir /etc/ipa /var/ldap
+% cd /etc/ipa
+% wget -O ipa.pem http://server1.ipa.example.com/ipa/config/ca.crt
+% cp * /var/ldap
+% vi /etc/ldap.conf
+base dc=ipa,dc=example,dc=com
+scope sub
+bind_timelimit 120
+timelimit 120
+uri ldap://server1.ipa.example.com
+sudoers_base ou=sudoers,dc=ipa,dc=example,dc=com
+pam_lookup_policy yes
+TLS_CACERTDIR /var/ldap
+ssl start_tls
+tls_checkpeer no
+
Now init the ldap client. We actually get to use a secure connection +here. Kerberos is hit or miss, could never get sasl/GSSAPI to work.
+Different Trees - Trust or not?
+There are multiple examples of how to setup the trees. If using an AD +trust, you should use the second example, where it looks at the compat +tree for users. However, if you do not have trusts, then it is perfectly +possible to still use the AD Trust example. Try both and see which works +better for your environment.
+No Service Account
+If you have configured FreeIPA to not allow any anonymous connections, +you will need to use a proxy account. We have provided the examples for +this configuration.
+Without AD Trust
+# Without AD Trust (no proxy)
+% ldapclient manual -a authenticationMethod=tls:simple \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
+# Without AD Trust (proxy)
+% ldapclient manual -a authenticationMethod=tls:simple \
+ -a credentialLevel=proxy \
+ -a proxyDN="uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com" \
+ -a proxyPassword="secret123" \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
+# Without AD Trust (Kerberos) - Only works if Solaris is in the same DNS domain as IPA
+% ldapclient manual -a authenticationMethod=sasl/GSSAPI \
+ -a credentialLevel=self \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
With AD Trust
+# With AD Trust (no proxy)
+% ldapclient manual -a authenticationMethod=tls:simple \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
+# With AD Trust (proxy)
+% ldapclient manual -a authenticationMethod=tls:simple \
+ -a credentialLevel=proxy \
+ -a proxyDN="uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com" \
+ -a proxyPassword="secret123" \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
+# With AD Trust (Kerberos) - Only works if Solaris is in the same DNS domain as IPA
+% ldapclient manual -a authenticationMethod=sasl/GSSAPI \
+ -a credentialLevel=self \
+ -a proxyDN="uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com" \
+ -a proxyPassword="secret123" \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.ipa.example.com server2.ipa.example.com" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+
This should succeed. Once it succeeds, you need to configure pam and +nsswitch.
+% /usr/sbin/svccfg -s name-service/switch setprop config/sudoer = astring: "files ldap"
+% /usr/sbin/svccfg -s name-service/switch setprop config/password = astring: "files ldap [NOTFOUND=return]"
+% /usr/sbin/svccfg -s name-service/switch setprop config/group = astring: "files ldap [NOTFOUND=return]"
+
+% /usr/sbin/svcadm refresh svc:/system/name-service/switch
+% /usr/sbin/svcadm restart svc:/system/name-service/switch
+% /usr/sbin/svcadm restart ldap/client
+
AD Trust Information
+In the event you don't have an AD trust, you can change the "binding" +lines to required and remove the pam_ldap lines. Optionally, you can +set pam_krb5 to "required", however sufficient should work just fine.
+Without an AD Trust
+% vi /etc/pam.d/login
+auth definitive pam_user_policy.so.1
+auth requisite pam_authtok_get.so.1
+auth required pam_dhkeys.so.1
+auth sufficient pam_krb5.so.1
+auth required pam_unix_cred.so.1
+auth sufficient pam_unix_auth.so.1 server_policy
+
+% vi /etc/pam.d/other
+auth definitive pam_user_policy.so.1
+auth requisite pam_authtok_get.so.1
+auth required pam_dhkeys.so.1
+auth sufficient pam_krb5.so.1
+auth required pam_unix_cred.so.1
+auth sufficient pam_unix_auth.so.1 server_policy
+
+account requisite pam_roles.so.1
+account definitive pam_user_policy.so.1
+account required pam_unix_account.so.1 server_policy
+account sufficient pam_krb5.so.1
+
+session definitive pam_user_policy.so.1
+session required pam_unix_session.so.1
+
+password definitive pam_user_policy.so.1
+password include pam_authtok_common
+password sufficient pam_krb5.so.1
+password required pam_authtok_store.so.1 server_policy
+
+% vi /etc/pam.d/sshd-pubkey
+account required pam_unix_account.so.1
+
With an AD Trust
+% vi /etc/pam.d/login
+auth definitive pam_user_policy.so.1
+auth requisite pam_authtok_get.so.1
+auth required pam_dhkeys.so.1
+auth sufficient pam_krb5.so.1
+auth required pam_unix_cred.so.1
+auth sufficient pam_unix_auth.so.1 server_policy
+auth sufficient pam_ldap.so.1
+
+% vi /etc/pam.d/other
+auth definitive pam_user_policy.so.1
+auth requisite pam_authtok_get.so.1
+auth required pam_dhkeys.so.1
+auth sufficient pam_krb5.so.1
+auth required pam_unix_cred.so.1
+auth sufficient pam_unix_auth.so.1 server_policy
+auth sufficient pam_ldap.so.1
+
+account requisite pam_roles.so.1
+account definitive pam_user_policy.so.1
+account binding pam_unix_account.so.1 server_policy
+account sufficient pam_krb5.so.1
+account sufficient pam_ldap.so.1
+
+session definitive pam_user_policy.so.1
+session required pam_unix_session.so.1
+
+password definitive pam_user_policy.so.1
+password include pam_authtok_common
+password sufficient pam_krb5.so.1
+password required pam_authtok_store.so.1 server_policy
+
+% vi /etc/pam.d/sshd-pubkey
+account required pam_unix_account.so.1
+
You can test now if you'd like.
+root@solaris11:~# ldaplist -l passwd flast2
+dn: uid=flast2,cn=users,cn=compat,dc=ipa,dc=example,dc=com
+ cn: First Last
+ objectClass: posixAccount
+ objectClass: ipaOverrideTarget
+ objectClass: top
+ gidNumber: 1006800001
+ gecos: First Last
+ uidNumber: 1006800001
+ ipaAnchorUUID: :IPA:ipa.example.com:8babb9a8-5aaf-11e7-9769-00505690319e
+ loginShell: /bin/bash
+ homeDirectory: /home/first.last2
+ uid: first.last2
+
I at one point built a bunch of scripts to automate Solaris servers +talking to IPA +here. +However, it is likely the scripts no longer work or contain outdated +information.
+Solaris 11 once in a while gets random regressions when it comes to +authentication and ID's, among many other things they randomly decide +to break. Big shout out to Oracle.
+In a brief discussion with a user in the #freeipa IRC channel, the user +was trying to find a way to chop off the domain name for logins but also +have sudo still work as there were some random issues in general. We +both discovered that in SRU 11.4.20.4.0, even though both UID's are +present from ldaplist -l passwd, sudo was no longer working properly. +The first thing we tried was to create an ID view and override a user +with a new username. This successfully removed the domain, but did not +solve the sudo problem. He instead got "no account present for that +user". However, I wasn't able to replicate this.
+However, later, one thing he noticed is after creating an ID view with +no overrides and pointing Solaris 11 to the view in the compat tree, +Solaris 10-esque authentication ID reporting started to occur. Running +ldaplist -l passwd user reported back the double UID as expected, but +the FQDN comes first which resolved his group/sudo issues.
+# Create a view... no id overrides required here
+% ipa idview-add solaris
+# On Solaris...
+# Take EXTREME care with the group and passwd base DN's, they need to point
+# to the view properly
+# This example uses kerberos to authenticate.
+% ldapclient manual -a authenticationMethod=self \
+ -a credentialLevel=sasl/GSSAPI \
+ -a defaultSearchBase=dc=ipa,dc=example,dc=com \
+ -a domainName=ipa.example.com \
+ -a defaultServerList="server1.angelsofclockwork.net server2.angelsofclockwork.net" \
+ -a followReferrals=true \
+ -a objectClassMap=shadow:shadowAccount=posixAccount \
+ -a objectClassMap=passwd:posixAccount=posixaccount \
+ -a objectClassMap=group:posixGroup=posixgroup \
+ -a serviceSearchDescriptor=group:cn=groups,cn=solaris,cn=views,cn=compat,dc=angelsofclockwork,dc=net \
+ -a serviceSearchDescriptor=passwd:cn=users,cn=solaris,cn=views,cn=compat,dc=angelsofclockwork,dc=net \
+ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \
+ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \
+ -a bindTimeLimit=5
+# Make sure you set your props...
+% /usr/sbin/svccfg -s name-service/switch setprop config/sudoer = astring: "files ldap"
+% /usr/sbin/svccfg -s name-service/switch setprop config/password = astring: "files ldap [NOTFOUND=return]"
+% /usr/sbin/svccfg -s name-service/switch setprop config/group = astring: "files ldap [NOTFOUND=return]"
+
+% /usr/sbin/svcadm refresh svc:/system/name-service/switch
+% /usr/sbin/svcadm restart svc:/system/name-service/switch
+% /usr/sbin/svcadm restart ldap/client
+# Verify...
+% ldaplist -l passwd adusername
+. . .
+% id -a adusername
+. . .
+
Thank you to "mewho" on libera for finding this interesting workaround.
+Some steps between Solaris 10 and 11 can be followed to make OmniOS +work. However, we have been unable to resolve why sudo will not work +when using an AD trust. If you are using a standalone FreeIPA and no +trust, sudo should work just fine.
+For HBAC to work on Solaris, you will need to compile the pam_hbac +module found here. I would clone +the current master branch or download the master.zip to your Solaris +system. Each OS has their set of instructions for compiling.
+First, create the following system account. We will need this when we +are configuring our legacy clients.
+dn: uid=hbac,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com
+objectClass: account
+objectClass: simplesecurityobject
+objectClass: top
+uid: hbac
+userPassword: password
+
+% /opt/csw/bin/pkgutil -i -y libnet ar binutils gcc4g++ glib2 libglib2_dev gmake
+% /opt/csw/bin/pkgutil -i -y libnet ar binutils gcc4g++ glib2 libglib2_dev gmake
+% PATH=$PATH:/opt/csw/bin
+% export M4=/opt/csw/bin/gm4
+% autoconf -o configure
+% autoreconf -i
+
+# Yes, SSL must be disabled for Solaris 10 to work. The libraries are too old.
+# You may or may not need to set CFLAGS, CXXFLAGS, and LDFLAGS with -m32
+% ./configure AR=/opt/csw/bin/gar --with-pammoddir=/usr/lib/security --sysconfdir=/etc/ --disable-ssl --disable-man-pages
+% make
+% make install
+
% pkg install autoconf libtool pkg-config automake gcc docbook
+% autoreconf -if
+% ./configure --with-pammoddir=/usr/lib/security --mandir=/usr/share/man --sysconfdir=/etc/
+% make
+% make install
+
% pkg install developer/build/autoconf developer/build/libtool \
+ developer/pkg-config developer/build/automake \
+ developer/gcc48 system/header developer/object-file \
+ developer/linker
+% autoreconf -if
+% ./configure --with-pammoddir=/usr/lib/security --mandir=/usr/share/man --sysconfdir=/etc/
+% make
+% make install
+
% vim /etc/pam_hbac.conf
+
+# Replace client with your server's FQDN
+URI = ldap://server.ipa.example.com
+BASE = dc=ipa,dc=example,dc=com
+BIND_DN = uid=hbac,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com
+BIND_PW = password
+SSL_PATH = /var/ldap
+HOST_NAME = client
+
# Solaris 10 - /etc/pam.conf
+# Modify the other account section... It should come at the end of the account blocks.
+. . .
+other account required pam_hbac.so ignore_unknown_user ignore_authinfo_unavail
+
+# Solaris 11 - /etc/pam.d/other
+# Same here, only modify the account section
+. . .
+account required pam_hbac.so ignore_unknown_user ignore_authinfo_unavail
+
In the event you cannot login or things aren't working the way you'd +expect, add 'debug' to the end of the pam_hbac line and watch +/var/log/authlog for errors.
+For AD users to be able to login to legacy clients, you have to enable +system-auth to the IPA servers. Without it, users will be denied access, +regardless of HBAC controls or if you're using the pam_hbac module.
+% ipa hbacsvc-add system-auth
+% ipa hbacrule-add legacy_client_auth
+% ipa hbacrule-add-host --hostgroups=ipaservers legacy_client_auth
+% ipa hbacrule-mod --usercat=all legacy_client_auth
+
Just a section of notes.
+If using domain resolution order, AD users get double uid attributes - +but only if they login with their shortname. If they login with fqdn, +double uid's do not occur. But shortnames do not work anymore. Have to +restart the directory server to make short names work again.
+If using domain resolution order, Solaris 10 gets the group resolution +correct for short named AD users. Solaris 11 does not unless you are on +SRU 11.4.7.4.0 or newer. There is a way to chop off the domain name from +the uid using views.
+This section goes over "situational" scenarios. These scenarios are +reflective of the environment in which IPA is installed and not all will +fit into your environment. These are more or less common situations that +could occur during an IPA deployment or even post-deployment.
+A common scenario is that IPA and AD will have a trust, but there will +not be any IPA users with the exception of the engineering team for +managing IPA itself. The common theme is that because of this, the +engineers and customers would rather not login with username@realm.
+Info
+The following is only applicable in an IPA-AD trust. An IPA-only +scenario would not require any of these steps and most pieces would work +natively (no @realm, sudo, hbac).
+In the event that you are in an IPA-AD scenario, please take note that +this can adversely affect legacy clients. This will cause ldapsearches +that are done in the compat tree to display multiple uid attributes. In +most cases, this is fine and the user can still login without the realm +name. The whoami and id commands will show the domain. There's no +workaround for this.
+On the IPA servers, you will need to set the domain resolution order. +This was introduced in 4.5.0.
+% kinit admin
+% ipa config-mod --domain-resolution-order="example.com:ipa.example.com"
+
After, you will need to clear out your SSSD cache.
+# sss_cache -E is insufficient for this.
+% systemctl stop sssd
+% rm -rf /var/lib/sss/db/*
+% systemctl start sssd
+
The below is optional. It will remove the @realm off the usernames, like +on the prompt or id or whoami commands. Only do this if required. Only +do this on the clients. Do not make this change on an IPA replica.
+# vi /etc/sssd/sssd.conf
+
+[domain/ipa.example.com]
+. . .
+full_name_format = %1$s
+
This will ensure EL7, EL8, EL9 clients resolve the AD domain first when +attempting logins and optionally drop the @realm off the usernames.
+You may notice that your clients have intermittent issues with name +resolution when the following are true:
+You may want to actually search for them to identify the errant groups +and then correct them. You can correct them either on the AD or IPA +side. I would opt for the IPA side.
+% kinit admin@IPA.EXAMPLE.COM
+% vi /tmp/dupecheck.sh
+#!/bin/bash
+for x in ${ARRAY[*]} ; do
+ ldapsearch -x -b "DC=example,DC=com" -h example.com -LLL -w 'PASSWORD' -D 'username@example.com' samaccountname="$x" samaccountname | grep -q $x
+ if [[ $? -eq 0 ]]; then
+ echo "$x: DUPLICATE"
+ fi
+done
+
+% bash /tmp/dupecheck.sh
+
If you run into any duplicates, they should show up in a list for you +address.
+sAMAccountName vs CN
+The "CN" and "sAMAccountName" attributes are not the same in AD, +depending on who made the group or other factors. The sAMAccountName +attribute is the value used to determine names from AD, whether you are +enrolled with AD or the IPA server SSSD is pulling the information. This +is why we are searching for that attribute, and not the CN.
+By creating a subdomain section in /etc/sssd/sssd.conf on an IPA server, +it is possible to set an AD Site or AD server(s) directly in SSSD. By +default, sssd tries to do location based discovery. There may be a case +where this isn't possible (eg, only a set of AD servers may only be +contacted in certain "air gapped" networks).
+[domain/ipa.example.com/example.com]
+# If you want a site
+ad_site = Site_Name
+# If you want a server(s)
+ad_server = dc1.example.com, dc2.example.com
+# A backup?
+ad_backup_server = dc3.example.com, dc4.example.com
+
If you don't have access or a way to find the sites using the Windows +tools, you can run an ldapsearch to find it (or an equivalent ldap +browsing tool).
+% ldapsearch -x -h example.com -s one -WD 'CN=username,CN=Users,DC=example,DC=com' \
+ -b 'CN=Sites,CN=Configuration,DC=example,DC=com' cn
+
This should report back your sites. If you want to know the servers for +those sites (in case you don't want to deal with the sites, but just +the DC's themselves), you use ldapsearch but use the base DN of the +site name.
+% ldapsearch -x -h example.com -WD 'CN=username,CN=Users,DC=example,DC=com' \
+ -b 'CN=Servers,CN=Site_Name,CN=Sites,CN=Configuration,DC=example,DC=com' dnsHostName
+
Hardcoded DC's
+If the DC's change at any time and they are harded in your sssd.conf, +it is up to you to know when new controllers are being added or removed +as to not disrupt the connectivity from IPA to AD when performing user +or group lookups.
+This issue with the above section is that once you do this, sudo rules +will begin failing, they will no longer work for Enterprise Linux 6. +This is because sssd was changed to look for cn=sudo rather than +ou=sudoers. To enable the compatibility fall back, you will need to +install a newer SSSD.
+By default, after a trust has been established, the shell all AD users +get is /bin/sh. To change this, you must change the sssd.conf on the IPA +masters.
+% vi /etc/sssd/sssd.conf
+[domain/ipa.example.com]
+. . .
+default_shell = /bin/bash
+
+% systemctl restart sssd
+
Once in a great while, we run into situations where we need to have an +automated process for creating principals and keytabs. This section +takes a look at some of those examples that we've ran into.
+This assumes you are using Cloudera Manager and not Ambari in any form.
+DNS Information
+It is highly likely that if you are using AWS, your nodes are getting +stupid names like compute.internal. While there is a a way to change +this if +you don't change it, you will need to rely on something like DNSMASQ to +allow the nodes to communicate with FreeIPA. FreeIPA will be upset +about the stupid names because it can't do a rDNS lookup.
+It is likely you have Cloudera/Hadoop, it is also very likely you (or +another team) are deploying and using Cloudera Manager (or Director?). +You may be running into issues that involve direct Active Directory +integration. Maybe you're moving away from a standalone LDAP system +over to Active Directory or even FreeIPA. Maybe you have FreeIPA in an +AD trust but the users or contractors absolutely insist on using AD +against their better judgement, despite the problems they're running +into. Whatever the scenario is, we feel your pain. Here are some things +you should probably know:
+Cloudera Manager (or Director?) supports Active Directory out of the + box and obviously not FreeIPA despite the devs wanting to work + something out back in 2015
+Ambari has support for FreeIPA, but we are focusing on Cloudera + Manager here.
+Hostnames that are longer than 15 characters, regardless of the + cloud provider or onprem setup, will ultimately fail
+FreeIPA does not have the name limitation and using an AD trust, AD +users can freely use Hadoop when the cluster is properly setup. +Enrolling the cluster nodes into FreeIPA and using a custom retrieval +script will solve most (if not all) of the issues you may run into as +well when it comes to keytabs, which Hadoop heavily relies on. The +custom script is simply because Cloudera by default likes having direct +access to the kerberos infrastructure, which is a no-go for FreeIPA.
+To summarize, here is our proposed solution:
+Create a role called "Kerberos Managers" and apply the following + privileges:
+Apply the role to the cdh account
+So let's create the necessary things we need.
+# Create the account
+# Note... you may want to make this account non-expiring since it's just a service account
+% ipa user-add --first="Cloudera" --last="Key Manager" cdh
+
+# Create the Kerberos Managers role
+% ipa role-add "Kerberos Managers"
+
+# Create the kerberos manager privilege
+% ipa privilege-add "Privileges - Kerberos Managers"
+% ipa privilege-add-permission "Privileges - Kerberos Managers" \
+ --privileges="System: Manage Host Keytab" \
+ --privileges="System: Manage Host Keytab Permissions" \
+ --privileges="System: Manage Service Keytab" \
+ --privileges="System: Manage Service Keytab Permissions" \
+ --privileges="System: Manage User Principals"
+
+# Add the privilege to the role
+% ipa role-add-privilege "Kerberos Managers" \
+ --privileges="Privileges - Kerberos Managers"
+
+# Add the user to the role
+% ipa role-add-member --users=cdh "Kerberos Managers"
+
+# Optionally, we can export the keytab for the user with a password
+# You will see why in the next script
+% ipa-getkeytab -p cdh@EXAMPLE.COM -k cdh.keytab -P
+
Now we need our special kerberos keytab retrieval script.
+#!/bin/bash
+# Created by: @nazunalika - Louis Abel
+# Purpose: To retrieve keytabs for Cloudera / Hadoop
+# https://github.com/nazunalika/useful-scripts
+
+# Disclaimer: We do not take responsibilities for breaches or misconfigurations of
+# software. Use at your own risk
+
+# Variables
+# This can be anywhere, but it SHOULD be secure with at least 600 permissions
+CDHKT="/root/.cdh/cdh.keytab"
+CDHUSER="cdh"
+IPAREALM="EXAMPLE.COM"
+# This can be any server. You could make an array and have it randomly selected
+IPASERVER="ipa01.example.com"
+
+# Where is this going?
+DESTINATION="$1"
+# The full principal for the keytab in question
+FULLPRINC="$2"
+# Shortened name
+PRINC=$(echo $FULLPRINC | sed "s/\@$(echo $IPAREALM)//")
+
+00_kinitUser() {
+ # Pick what suits you best, we prefer using a keytab
+ # Password based kinit, based on the keytab we created prior!
+ # You could also have this in a file somewhere, I guess. Just
+ # has to be secured.
+ echo ThisIsAWeakPassword | kinit $CDHUSER@$IPAREALM
+
+ # Keytab based kinit, obviously we created it before right? It just needs to be
+ # on the right system, deployed in some secure manner
+ #kinit -kt $CDHKT $CDHUSER@$IPAREALM
+ if [[ $? == "1" ]]; then
+ echo FAILED TO KINIT
+ exit
+ fi
+}
+
+01_createPrinc() {
+ echo "INFO: Checking for existing principle"
+ if ipa service-find $FULLPRINC; then
+ echo "INFO: Principle found"
+ else
+ echo "INFO: Not found, creating"
+ ipa service-add $FULLPRINC
+ fi
+}
+
+02_createServiceAllows() {
+ # We need to allow the service to create and retrieve keytabs
+ echo "INFO: Ensuring service allows to create and retrieve keytabs"
+ ipa service-allow-create-keytab --users=$CDHUSER $FULLPRINC
+ ipa service-allow-retrieve-keytab --users=$CDHUSER $FULLPRINC
+
+ # Let's retrieve the keytabs
+ if ipa service-show $FULLPRINC | grep 'Keytab' | grep 'False'; then
+ echo "INFO: Creating keytab for $FULLPRINC to $DESTINATION"
+ ipa-getkeytab -s $IPASERVER -p $PRINC -k $DESTINATION
+ else
+ echo "INFO: Retriving keytab for $FULLPRINC to $DESTINATION"
+ ipa-getkeytab -r -s $IPASERVER -p $PRINC -k $DESTINATION
+ fi
+}
+
+00_kinitUser
+01_createPrinc
+02_createServiceAllows
+
+kdestroy
+exit 0
+
Place the above script in a file that is accessible by the cloudera +manager such as /usr/local/bin/getKeytabsCDH.sh and ensure it is owned +by cloudera-scm with a permission set of 775.
+During the kerberos wizard, stop when you are verifying the "cdh" +user. You will need to set the configuration for "Custom Kerberos +Keytab Retrieval Script" to /usr/local/bin/getKeytabsCDH.sh and then +you're almost there.4
+An important tidbit is currently Enterprise Linux 7+ and higher use +memory based keytabs and java doesn't support them.5 Because of +this, the /etc/krb5.conf should be modified.
+% cat /etc/krb5.conf
+. . .
+# Make sure the below is commented
+# default_ccache_name = KEYRING:persistent:%{uid}
+. . .
+
Presently, FreeIPA does not support DoT (DNS over TLS) nor DoH (DNS over +HTTPS) (this appears to be a bind limitation and we can't find +documentation that says otherwise). However, it is possible to setup +unbound to do the forwarding for you, in which you tell your bind +servers (or in this case, the bind DNS servers in your IPA domain) to +forward to that unbound server for all forwarding.
+Keep it Separate
+It is recommended to keep your unbound service separate from the IPA +servers. Spin up another instance in your network that will run unbound +or run it on a standalone bind server that you may have on a separate +port.
+To forward to the unbound service, modify the DNS global configuration +in IPA:
+# Replace 10.100.0.224 with the IP of your unbound instance
+% ipa dnsconfig-mod --forward-policy=only --forwarder='10.100.0.224'
+
+# Add 'port xxxx' if you have set unbound to another port
+% ipa dnsconfig-mod --forward-policy=only --forwarder='10.100.0.224 port 9553'
+
By default, the audit logs in /var/log/dirsrv/slapd-INSTANCE/audit do
+not get populated. And the access logs don't show much in terms of
+modifications and what is being changed. There is also /var/log/httpd/*
+logs, but it may be useful to see ldif style logging for changes against
+FreeIPA.
# Modify the DSE configuration by turning on audit logging
+[label@ipa01 ~]# ldapmodify -D "cn=directory manager" -W -p 389 -h localhost
+Enter LDAP Password:
+dn: cn=config
+changetype: modify
+replace: nsslapd-auditlog-logging-enabled
+nsslapd-auditlog-logging-enabled: on
+# Press CTRL+d here
+modifying entry "cn=config"
+
+# To test, I'll add a user to a group
+[label@ipa01 ~]$ ipa group-add-member --users=jbaskets aocusers
+ Group name: aocusers
+ GID: 686600003
+ Member users: ..., jbaskets
+-------------------------
+Number of members added 1
+-------------------------
+# Let's verify the log
+[label@ipa01 ~]$ sudo su -
+[sudo] password for label:
+Last login: Sun Mar 29 16:42:36 MST 2020 on pts/0
+[root@ipa01 ~]# cd /var/log/dirsrv/slapd-EXAMPLE-NET/
+[root@ipa01 slapd-EXAMPLE-NET]# cat audit
+time: 20200329223754
+dn: cn=config
+result: 0
+changetype: modify
+replace: nsslapd-auditlog-logging-enabled
+nsslapd-auditlog-logging-enabled: on
+-
+replace: modifiersname
+modifiersname: cn=directory manager
+-
+replace: modifytimestamp
+modifytimestamp: 20200330053754Z
+-
+
+ 389-Directory/1.4.1.3 B2019.323.229
+ ipa01.example.net:636 (/etc/dirsrv/slapd-EXAMPLE-NET)
+
+# Looks like right here the modification happened
+time: 20200329224007
+dn: cn=aocusers,cn=groups,cn=accounts,dc=example,dc=net
+result: 0
+changetype: modify
+add: member
+member: uid=jbaskets,cn=users,cn=accounts,dc=example,dc=net
+-
+replace: modifiersname
+modifiersname: uid=label,cn=users,cn=accounts,dc=example,dc=net
+-
+replace: modifytimestamp
+modifytimestamp: 20200330054006Z
+-
+replace: entryusn
+entryusn: 900028
+-
+
These are notes of things I've ran into before while dealing with +certificates.
+This was something I discovered sort of on accident but never really +"noticed" - Though I'm sure I would've noticed sometime in 2021 when +my certificate expired. I was running ipa-healthcheck --failures-only +as I do sometimes, and noticed some weird certmonger things pop up. But +it made me look at my certificate list...
+[root@ipa01 ~]# ipa-getcert list
+Number of certificates and requests being tracked: 9.
+Request ID '20191106025922':
+ status: MONITORING
+ stuck: no
+ key pair storage: type=FILE,location='/var/kerberos/krb5kdc/kdc.key'
+ certificate: type=FILE,location='/var/kerberos/krb5kdc/kdc.crt'
+ CA: IPA
+ issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET
+ subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET
+ expires: 2021-11-05 19:59:27 MST
+ principal name: krbtgt/ANGELSOFCLOCKWORK.NET@ANGELSOFCLOCKWORK.NET
+ key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
+ eku: id-kp-serverAuth,id-pkinit-KPKdc
+ pre-save command:
+ post-save command: /usr/libexec/ipa/certmonger/renew_kdc_cert
+ track: yes
+ auto-renew: yes
+Request ID '20200123075636':
+ status: MONITORING
+ stuck: no
+ key pair storage: type=NSSDB,location='/etc/dirsrv/slapd-ANGELSOFCLOCKWORK-NET',nickname='Server-Cert',token='NSS Certificate DB',pinfile='/etc/dirsrv/slapd-ANGELSOFCLOCKWORK-NET/pwdfile.txt'
+ certificate: type=NSSDB,location='/etc/dirsrv/slapd-ANGELSOFCLOCKWORK-NET',nickname='Server-Cert',token='NSS Certificate DB'
+ CA: IPA
+ issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET
+ subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET
+ expires: 2021-11-05 19:55:33 MST
+ dns: ipa01.angelsofclockwork.net
+ principal name: ldap/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET
+ key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
+ eku: id-kp-serverAuth,id-kp-clientAuth
+ pre-save command:
+ post-save command: /usr/libexec/ipa/certmonger/restart_dirsrv ANGELSOFCLOCKWORK-NET
+ track: yes
+ auto-renew: yes
+Request ID '20200123075639':
+ status: NEWLY_ADDED_NEED_KEYINFO_READ_PIN
+ stuck: yes
+ key pair storage: type=FILE,location='/var/lib/ipa/private/httpd.key'
+ certificate: type=FILE,location='/var/lib/ipa/certs/httpd.crt'
+ CA: IPA
+ issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET
+ subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET
+ expires: 2021-11-05 19:55:48 MST
+ dns: ipa01.angelsofclockwork.net
+ principal name: HTTP/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET
+ key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
+ eku: id-kp-serverAuth,id-kp-clientAuth
+ pre-save command:
+ post-save command: /usr/libexec/ipa/certmonger/restart_httpd
+ track: yes
+ auto-renew: yes
+
Interestingly, I wasn't sure what +NEWLY_ADDED_NEED_KEYINFO_READ_PIN meant and I couldn't really find +much on what would cause this to happen. And I know my certificate +isn't expired, according to the output. In fact, I checked with openssl +just in case.
+[root@ipa01 ~]# openssl x509 -text -noout -in /var/lib/ipa/certs/httpd.crt | grep 'Not After'
+ Not After : Nov 6 02:55:48 2021 GMT
+
I'm not sure if this is just a result of migrating from Enterprise +Linux 7 to 8 at the time, but it seemed easy enough to remove the +tracking and put it back in, which ultimately fixed the monitoring state +and now it was no longer "stuck".
+[root@ipa01 ~]# ipa-getcert stop-tracking -i 20200123075639
+Request "20200123075639" removed.
+[root@ipa01 ~]# ipa-getcert start-tracking -f /var/lib/ipa/certs/httpd.crt -k /var/lib/ipa/private/httpd.key -p /var/lib/ipa/passwds/ipa01.angelsofclockwork.net-443-RSA -C /usr/libexec/ipa/certmonger/restart_httpd -K HTTP/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET
+New tracking request "20200504003758" added.
+[root@ipa01 ~]# ipa-getcert list -i "20200504003758"
+Number of certificates and requests being tracked: 9.
+Request ID '20200504003758':
+ status: MONITORING
+ stuck: no
+ key pair storage: type=FILE,location='/var/lib/ipa/private/httpd.key',pinfile='/var/lib/ipa/passwds/ipa01.angelsofclockwork.net-443-RSA'
+ certificate: type=FILE,location='/var/lib/ipa/certs/httpd.crt'
+ CA: IPA
+ issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET
+ subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET
+ expires: 2021-11-05 19:55:48 MST
+ dns: ipa01.angelsofclockwork.net
+ principal name: HTTP/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET
+ key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
+ eku: id-kp-serverAuth,id-kp-clientAuth
+ pre-save command:
+ post-save command: /usr/libexec/ipa/certmonger/restart_httpd
+ track: yes
+ auto-renew: yes
+
Like with the IPA httpd certificates, I noticed at least 4 certificates +stuck because a PIN was missing. Turns out that it's actually easy to +modify the tracking request and fix the issue entirely. Below is my +example doing this on the auditSigningCert. This seems to only occur on +Enterprise Linux 8.
+[root@ipa01 alias]# getcert list -i 20200615180351
+Number of certificates and requests being tracked: 9.
+Request ID '20200615180351':
+ status: NEWLY_ADDED_NEED_KEYINFO_READ_PIN
+ stuck: yes
+ key pair storage: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca'
+ certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca'
+ CA: dogtag-ipa-ca-renew-agent
+ issuer:
+ subject:
+ expires: unknown
+ pre-save command: /usr/libexec/ipa/certmonger/stop_pkicad
+ post-save command: /usr/libexec/ipa/certmonger/renew_ca_cert "auditSigningCert cert-pki-ca"
+ track: yes
+ auto-renew: yes
+
+[root@ipa01 alias]# getcert start-tracking -i 20200615180351 -p /etc/pki/pki-tomcat/alias/pwdfile.txt
+Request "20200615180351" modified.
+[root@ipa01 alias]# getcert list -i 20200615180351
+Number of certificates and requests being tracked: 9.
+Request ID '20200615180351':
+ status: MONITORING
+ stuck: no
+ key pair storage: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca',token='NSS Certificate DB',pinfile='/etc/pki/pki-tomcat/alias/pwdfile.txt'
+ certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca',token='NSS Certificate DB'
+ CA: dogtag-ipa-ca-renew-agent
+ issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET
+ subject: CN=CA Audit,O=ANGELSOFCLOCKWORK.NET
+ expires: 2021-03-13 23:15:41 MST
+ key usage: digitalSignature,nonRepudiation
+ pre-save command: /usr/libexec/ipa/certmonger/stop_pkicad
+ post-save command: /usr/libexec/ipa/certmonger/renew_ca_cert "auditSigningCert cert-pki-ca"
+ track: yes
+ auto-renew: yes
+
A question that arises now and again is how to setup a load balancer for +FreeIPA's LDAP servers whether it's an actual load balancer (layer 4) +or some sort of DNS record with multiple A records, or perhaps with some +sort of round robin DNS. The issue is that the certificate verification +fails, because the certificate being presented is of the IPA server +itself with no SAN. To address this, you have to create a host that has +the name of the load balancer or DNS record you plan on using and allow +the IPA servers to manage the host.
+This isn't necessarily certificate issue, but more or less an issue as +it pertains to the certificate system itself. There may be cases where +during upgrades, a configuration in /etc/pki/pki-tomcat/server.xml is +not properly reconfigured. In that file, you'll notice Connector lines +that have a secret and a requiredSecret parameter and they both have +different values.
+<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" address="localhost4" secret="AAA" requiredSecret="BBB"/>
+<Connector address="localhost6" port="8009" protocol="AJP/1.3" redirectPort="8443" secret="AAA" requiredSecret="BBB"/>
+
The issue may be that these aren't correct. This generally comes down +to IPA and pki-core conflicting on these attributes. To correct this, +you will need to find the secret in /etc/httpd/conf.d/ipa-pki-proxy.conf +(on the ProxyPass line) and ensure that's the same secret in both +fields.
+ProxyPassMatch ajp://localhost:8009 secret=AAA
+
Make sure they're the same in server.xml
+<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" address="localhost4" secret="AAA" requiredSecret="AAA"/>
+<Connector address="localhost6" port="8009" protocol="AJP/1.3" redirectPort="8443" secret="AAA" requiredSecret="AAA"/>
+
After changing, restart the service with +systemctl restart pki-tomcat@pki-tomcatd.service.
+This section goes over some stuff about kerberos that we've ran into +and might find useful someday.
+When logging into a machine with a password (first factor) and an OTP +token (second factor), this generally works without a problem. You can +easily run klist and you'll see that you have a ticket and everything. +In the cases where you're calling kinit all by itself, this doesn't +work as expected at the time of this writing.
+% kinit account@REALM
+kinit: Pre-authentication failed: Invalid argument while getting initial credentials
+
A bugzilla was +opened about this issue in 2017, a +pagure issue was opened in 2014 +about this exact scenario, where IPA is configured for password+OTP and +a user has an assigned token. There is currently one workaround, which +is using kinit -n to perform anonymous processing.
+For more information on DNS for FreeIPA, please read this page and this page ↩
+The -P asks for the password of the username in question, that way it is cached right away. The directory service on the system then has credentials to compare to. I have found that sometimes if you don't use -P, even if you're logged in as the account, the password does not get cached and you'll get stuck at a background image the next time you login. Again, this is only sometimes. Your mileage may vary here. ↩
+The -P asks for the password of the username in question, that way it is cached right away. The directory service on the system then has credentials to compare to. I have found that sometimes if you don't use -P, even if you're logged in as the account, the password does not get cached and you'll get stuck at a background image the next time you login. Again, this is only sometimes. Your mileage may vary here. ↩
+This may have changed. However it is up to you to test if this is the case. ↩
+This section contains various articles on setups for Enterprise Linux and Fedora systems.
This page goes over setting up a router or a simple NAT service for +Enterprise Linux.
+Here are the list of requirements below.
+To properly setup the system, a few things have to be done.
+ip_forward
must be turned on - optionally if you have ipv6, turn on
+ that forwarding as wellIPv6 and NAT
+If you have an IPv6 prefix, whether it's from your ISP or it's a +brokered prefix from he.net, NAT is generally not needed. Instead of +using NAT for IPv6, you can just do simple forwarding. This is covered +in a later section.
+When using firewalld, Enterprise Linux 7+ and all Fedora\'s can setup a +simple NAT with masquerade without having to know iptables or nftables +syntax. This may be more or less ideal for some users who want to +quickly get a NAT and router going. The drawback is that the syntax and +knowing how the rules work are hidden behind a frontend. To setup a NAT:
+# Tell eth0 to be our WAN
+% nmcli con mod eth0 connection.zone external
+# Tell eth1 to be our LAN (or a bridge if you have one)
+% nmcli con mod eth1 connection.zone internal
+# Doesn't hurt to re-up
+% nmcli con up eth0 ; nmcli con up eth1
+
+# The external zone already has masquerade on, but just in case
+% firewall-cmd --zone=external --add-masquerade --permanent
+% firewall-cmd --complete-reload
+% firewall-cmd --get-active-zones
+external
+ interfaces: eth0
+internal
+ interfaces: eth1
+
This is for Enterprise Linux 8/9 or Fedora where nftables is the default. +While iptables exists for Enterprise Linux 8 still, it is being +superseded by nftables. It is recommended to stick with nftables.
+The syntax for nftables is a little tricky and quite different from what +we may be used to with iptables. This may be an oversimplification and +may or may not work. For ideas, you can view the files in /etc/nftables. +This is a rough example of what I tried on migration to Enterprise Linux +8.
+# Disable firewalld, we'll enable nftables later
+% systemctl disable firewalld --now
+% systemctl mask firewalld
+# Flush all rules
+% nft flush ruleset
+
Rest coming soon.
+Coming soon.
+Optional. Coming soon
Please note that the OpenLDAP server is considered deprecated in RHEL +(and thusly other EL derivatives). This document will stay here as a +reference for those who are still using the server software on +Enterprise Linux 7, potentially using the OpenLDAP LTB version of the +software, or using the openldap-servers package from Rocky Linux 9's +plus repository. It may apply to Fedora users in some contexts, but +there are some differences they may never be documented here. If you see +a need for corrections, please open up an issue on our github.
+Most of this information should be considered out of date. OpenLDAP +2.6.x makes some changes that the below document may or may not cover.
+This tutorial goes over how to install OpenLDAP to a Enterprise Linux +Server and options on configuring and setting up accounts for host +access, etc. This how-to is the method of implementation that I used, +and can be modified/changed to any users preferences if preferred. +Enterprise Linux and Fedora users will have the ability to use SSSD for +SUDO (and it's relatively easy to set it up).
+Simply put, LDAP is a directory service for authentication across a +network. Rather than have local accounts on a bunch of machines, LDAP +can be used to have one account across a bunch of machines. LDAP was +once an easy setup in RHEL 5 but had changed in RHEL 6 and 7, and here +provides the necessary information needed to get a simple LDAP system +running with possible SUDO support and various options of how to support +your LDAP system.
+First and foremost, we have a list of requirements. Keep in mind, if you +do not fulfill these requirements, you may run into some issues down the +road.
+Warning
+Potential Pitfalls!
+Note
+Recommended Information
+~/.vimrc
-- syntax on
~/.vimrc
-- set background=dark
~/.bash_profile
-- export EDITOR=vim
Note
+Database Information
+We will be using lmdb, which is recommended over using hdb or bdb.
+Note
+EL 9 OpenLDAP
+Enterprise Linux 9 has fully dropped OpenLDAP where there are no server +packages normally built. In some EL distributions, openldap-servers is +still built and provided in an extra repository. Rocky Linux 9 has +openldap-servers in their plus repository. EPEL also has it available.
+Below details the process for installing OpenLDAP to our system(s). This +includes installing the packages, setting up certificates, and +configuring the LDAP server via LDIF files.
+You will need the following packages. A couple of them may already be +installed. If you don't plan on migrating local accounts to LDAP, you +can leave out migrationtools.
+# If you are on Rocky Linux 9, you will need to enable the plus repository
+dnf install openldap openldap-servers migrationtools nss-tools -y
+
Enterprise Linux 7 clients and other newer distributions that are non-el +require TLS/SSL for authentication when going toward LDAP. because of +this, we will need to create certificates, regardless if you are in a +lab or not.
+Note
+Certificate Information
+NSS should no longer be required. Anything NSS related has been removed.
+I have two ways of doing it, we can do it manually or through a script. +I prefer using my script to take care of it. First the manual way.
+mkdir /etc/pki/ldap
+cd /etc/pki/ldap
+openssl genrsa -des3 -out ca.key 4096 # Remember the password you put here
+
+openssl genrsa -out ldapserver.key 4096
+
+openssl req -new -x509 -key ca.key -out ca.pem -days 3650
+Country Name (2 letter code) [XX]:US
+State or Province Name (full name) []:Arizona
+Locality Name (eg, city) [Default City]:Phoenix
+Organization Name (eg, company) [Default Company Ltd]:SSN Studio
+Organizational Unit Name (eg, section) []:Channel Maintainers
+Common Name (eg, your name or your server's hostname) []:SSN # If you want to use a server name here, perform this step on another server first
+Email Address []:youremail@mail.com
+
+openssl req -new -key ldapserver.key -out ldapserver.csr
+Country Name (2 letter code) [XX]:US
+State or Province Name (full name) []:Arizona
+Locality Name (eg, city) [Default City]:Phoenix
+Organization Name (eg, company) [Default Company Ltd]:SSN Studio
+Organizational Unit Name (eg, section) []:LDAP Server Maintainer
+Common Name (eg, your name or your server's hostname) []:zera1.angelsofclockwork.net # Set your common name to your server name for this certificate
+Email Address []:youremail@mail.com
+
+openssl x509 -req -in ldapserver.csr -out ldapserver.pem -CA ca.pem -CAkey ca.key -days 3650 -set_serial 01
+
+ln -s ca.pem `openssl x509 -hash -in ca.pem -noout`.0
+# Do an ls on the directory and save the hashed name including the .0 somewhere
+
+certutil -N -d /etc/pki/ldap
+# Do not enter any passwords. When asked, just hit enter beyond this point.
+
+chown root:ldap *
+chmod 640 *
+
The scripted way.
+#!/bin/bash
+# CA Information
+CAcountry="US"
+CAstate="Arizona"
+CAlocale="Phoenix"
+CAorganization="SSN Studio"
+CAorganizationalunit="Channel Maintainers"
+# If you set the below to a hostname, you’re screwed. Don’t do it!
+# Only do it if you have an actual hostname you will do CA signing on!
+CAconicalname="SSN"
+CAemail="tucklesepk@gmail.com"
+# LDAP Server information
+country="US"
+state="Arizona"
+locale="Phoenix"
+organization="SSN Studio"
+organizationalunit="LDAP Server Maintainer"
+conicalname="zera1.angelsofclockwork.net"
+email="pc68xl@gmail.com"
+
+certdir="/etc/pki/ldap"
+
+mkdir $certdir ; cd $certdir
+echo "Enter a password when asked."
+openssl genrsa -des3 -out ca.key 4096
+openssl genrsa -out ldapserver.key 4096
+# Create the self-signed CA cert
+openssl req -new -x509 -key ca.key -out ca.pem -days 3650 -subj /C="$CAcountry"/ST="$CAstate"/L="$CAlocale"/O="$CAorganization"/OU="$CAorganizationalunit"/CN="$CAconicalname"/emailAddress="$CAemail"/
+# Create the LDAP server cert
+openssl req -new -key ldapserver.key -out ldapserver.csr -subj /C="$country"/ST="$state"/L="$locale"/O="$organization"/OU="$organizationalunit"/CN="$conicalname"/emailAddress="$email"/
+# Sign it
+openssl x509 -req -in ldapserver.csr -out ldapserver.pem -CA ca.pem -CAkey ca.key -days 3650 -set_serial 01
+ln -s ca.pem `openssl x509 -hash -in ca.pem -noout`.0
+chown root:ldap *
+chmod 640 *
+
Make sure to obtain your hash. Your hash will be different from mine.
+ls -l /etc/pki/ldap | grep '0'
+39642ab3.0
+
Configurations done in OpenLDAP are done via LDIF. Your passwords should +be hashed as well. Before we begin, let's start by generating a +password for our root DN. This is required.
+slappasswd
+New password:
+Re-enter new password:
+{SSHA}CuaKctEx7rl/+ldG0EjktMzJdrxNc46+
+
Keep this SSHA output for our configuration files. Next, we'll need to +make a couple LDIFs.
+This is our suffix.ldif file. This file helps to create the mdb database +for our LDAP structure. It also sets our DIT suffix, root password, etc. +You should change the olcSuffix, olcRootDN, and olcRootPW to whatever +you plan on using. The olcDbMaxSize is set to 20GB. This is normally +sufficient and can be changed. The olcDbEnvFlags can be changed as well.
+dn: olcDatabase=mdb,cn=config
+objectClass: olcDatabaseConfig
+objectClass: olcMdbConfig
+olcDatabase: mdb
+olcDbDirectory: /var/lib/ldap
+olcSuffix: dc=angelsofclockwork,dc=net
+olcRootDN: cn=manager,dc=angelsofclockwork,dc=net
+olcRootPW: {SSHA}CuaKctEx7rl/+ldG0EjktMzJdrxNc46+
+olcDbIndex: objectClass eq,pres
+olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
+olcLastMod: TRUE
+olcDbEnvFlags: nometasync
+olcDbEnvFlags: writemap
+olcDbMaxSize: 21474836480
+
Now, below we have our primary modification ldif. Comments describe what +each one does.
+# Sets our cert path and information
+# The "CertificateFile" has to be set to the hostname of the LDAP server
+dn: cn=config
+changetype: modify
+replace: olcTLSCACertificatePath
+olcTLSCACertificatePath: /etc/pki/ldap
+-
+replace: olcTLSCertificateFile
+olcTLSCertificateFile: zera1.angelsofclockwork.net
+-
+replace: olcTLSCertificateKeyFile
+olcTLSCertificateKeyFile: /etc/pki/ldap/ldapserver.key
+
+# Adding a rootDN for the config.
+# Note that this isn't fully necessary as you can use -Y EXTERNAL -H ldapi:/// instead
+# So, treat this as an optional thing. If you do want it, consider a different password.
+dn: olcDatabase={0}config,cn=config
+changetype: modify
+replace: olcRootDN
+olcRootDN: cn=config
+-
+replace: olcRootPW
+olcRootPW: {SSHA}CuaKctEx7rl/+ldG0EjktMzJdrxNc46+
+
+# Set the password again in the mdb database
+# This is because sometimes the password set when making the database doesn't 'work' sometimes
+dn: olcDatabase={2}mdb,cn=config
+changetype: modify
+replace: olcRootPW
+olcRootPW: {SSHA}CuaKctEx7rl/+ldG0EjktMzJdrxNc46+
+
+# Sets the default password hash to SSHA -- Refer to the 'bug' information if this does not work
+dn: olcDatabase={-1}frontend,cn=config
+changetype: modify
+replace: olcPasswordHash
+olcPasswordHash: {SSHA}
+
+# Changes the rootdn information in the monitor database
+dn: olcDatabase={1}monitor,cn=config
+changetype: modify
+replace: olcAccess
+olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=manager,dc=angelsofclockwork,dc=net" read by * none
+
Let's make sure we turn on ldaps. It's recommended to use TLS, but +some applications insist on SSL. (Very few, but they are out there.)
+# vi /etc/sysconfig/slapd
+
+. . .
+SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"
+
+# slaptest -u
+Config file testing succeeded
+
+# /etc/openldap/ldap.conf
+. . .
+TLS_CACERTDIR /etc/pki/ldap
+
Now, we need to add our LDIFs into LDAP.
+rm -f /etc/openldap/slapd.d/cn=config/olcDatabase=\{2\}hdb.ldif
+chown -R ldap:ldap /var/lib/ldap
+systemctl enable slapd
+systemctl start slapd
+ldapadd -Y EXTERNAL -H ldapi:/// -f suffix.ldif
+ldapmodify -Y EXTERNAL -H ldapi:/// -f info.ldif
+
You may end up getting a checksum error in your logs. To solve this, you +need to do a simple operation against the configuration.
+ldapmodify -h localhost -xWD "cn=config"
+Enter LDAP Password:
+dn: olcDatabase={0}config,cn=config
+changetype: modify
+replace: olcRootDN
+olcRootDN: cn=config
+modifying entry "olcDatabase={0}config,cn=config"
+slaptest -u
+config file testing succeeded
+
That should do it. You can do a -Y EXTERNAL -H ldapi:/// instead if you +wanted to. I did the above to show passwords will work for config.
+The next piece is to get our backend structure built. In EL7, core is +the only schema that is there. In EL6, it's a good chunk of these. I +like to put them in a file so I can loop through them.
+Note
+ppolicy schema
+As of OpenLDAP 2.6.x, the ppolicy schema no longer applies as it is +built-in to the slapo-ppolicy module. See the upgrade +document +for information.
+/etc/openldap/schema/corba.ldif
+/etc/openldap/schema/cosine.ldif
+/etc/openldap/schema/duaconf.ldif
+/etc/openldap/schema/dyngroup.ldif
+/etc/openldap/schema/inetorgperson.ldif
+/etc/openldap/schema/java.ldif
+/etc/openldap/schema/misc.ldif
+/etc/openldap/schema/nis.ldif
+/etc/openldap/schema/openldap.ldif
+/etc/openldap/schema/collective.ldif
+
Note
+rfc2307
+If you want to be able to combine groupOfNames and posixGroup together +(similar to Active Directory, other open source, and commercial +offerings), don't use nis. Use the +rfc2307bis +schema instead.
+Once you have your list of schema to put in, we can loop through them.
+for x in $(cat schemaorder) ; do ldapadd -Y EXTERNAL -H ldapi:/// -f $x ; done
+adding new entry "cn=corba,cn=schema,cn=config"
+adding new entry "cn=cosine,cn=schema,cn=config"
+adding new entry "cn=duaconf,cn=schema,cn=config"
+adding new entry "cn=dyngroup,cn=schema,cn=config"
+adding new entry "cn=inetorgperson,cn=schema,cn=config"
+adding new entry "cn=java,cn=schema,cn=config"
+adding new entry "cn=misc,cn=schema,cn=config"
+adding new entry "cn=nis,cn=schema,cn=config"
+adding new entry "cn=openldap,cn=schema,cn=config"
+adding new entry "cn=collective,cn=schema,cn=config"
+
I normally like to keep all LDIFs in a folder by themselves to avoid +clutter (non-configuration LDIF).
+mkdir ldif ; cd ldif
+
Let's get our base created. Make sure to replace my DN with your DN +that you chose earlier. Call this base.ldif.
+dn: dc=angelsofclockwork,dc=net
+dc: angelsofclockwork
+objectClass: top
+objectClass: domain
+
+dn: ou=People,dc=angelsofclockwork,dc=net
+ou: People
+objectClass: top
+objectClass: organizationalUnit
+
+dn: ou=Group,dc=angelsofclockwork,dc=net
+ou: Group
+objectClass: top
+objectClass: organizationalUnit
+
ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f base.ldif
+Enter LDAP Password:
+adding new entry "dc=angelsofclockwork,dc=net"
+adding new entry "ou=People,dc=angelsofclockwork,dc=net"
+adding new entry "ou=Group,dc=angelsofclockwork,dc=net"
+
If this doesn't add, make sure your LDAP server is running, check +/var/log/messages, and ensure you've completed all steps before this.
+ldapsearch -x -LLL -b 'dc=angelsofclockwork,dc=net'
+dn: dc=angelsofclockwork,dc=net
+dc: angelsofclockwork
+objectClass: top
+objectClass: domain
+
+dn: ou=People,dc=angelsofclockwork,dc=net
+ou: People
+objectClass: top
+objectClass: organizationalUnit
+
+dn: ou=Group,dc=angelsofclockwork,dc=net
+ou: Group
+objectClass: top
+objectClass: organizationalUnit
+
Note
+But... I don't want to add my users locally
+You don't have to add your users locally to the system. This just aids +in the creation of users. Go to the next section if you want to add +users and do permissions by hand.
+This is the fun part. We'll need to add some users, set some passwords +and migrate them into the LDAP system. I'll make three users as an +example, give them an ID starting at 10000, home directories in /lhome, +set a password, and proceed to migrate them. If you don't want to use +/lhome, keep them set to /home and their home directories should get +created automatically when logging into another machine.
+# mkdir /lhome
+# mkdir ldif/user
+# semanage fcontext -a -t home_root_t "/lhome(/.*)?"
+# restorecon -v /lhome \
+ restorecon reset /lhome context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:home_root_t:s0
+# groupadd -g 10000 sokel
+# groupadd -g 10001 suree
+# groupadd -g 10002 ranos
+# useradd -u 10000 -g 10000 -d /lhome/sokel sokel
+# useradd -u 10001 -g 10001 -d /lhome/suree suree
+# useradd -u 10002 -g 10002 -d /lhome/ranos ranos
+# passwd sokel ; passwd suree ; passwd ranos
+# cat /etc/passwd | grep sokel > ldif/user/passwd.sokel
+# cat /etc/passwd | grep suree > ldif/user/passwd.suree
+# cat /etc/passwd | grep ranos > ldif/user/passwd.ranos
+# cat /etc/group | grep sokel > ldif/user/group.sokel
+# cat /etc/group | grep suree > ldif/user/group.suree
+# cat /etc/group | grep ranos > ldif/user/group.ranos
+
We'll set some aliases for our migration scripts too
+# alias miguser='/usr/share/migrationtools/migrate_passwd.pl'
+# alias miggroup='/usr/share/migrationtools/migrate_group.pl'
+
Before we continue, we need to modify our migration scripts. This is +extremely important, otherwise our LDIFs will come out incorrect. Change +them to your DN.
+# sed -i.bak "s/padl.com/angelsofclockwork.net/g" /usr/share/migrationtools/migrate_common.ph
+# sed -i.bak "s/padl,dc=com/angelsofclockwork,dc=net/g" /usr/share/migrationtools/migrate_common.ph
+
Now we can use a loop to convert them. You can do it by hand also, but +that's up to you.
+# for x in sokel suree ranos ; do miguser ldif/user/passwd.$x > ldif/user/$x.ldif ; done
+# for x in sokel suree ranos ; do miggroup ldif/user/group.$x >> ldif/user/$x.ldif ; done
+# cd ldif/user/
+# cat *.ldif >> /tmp/ourusers.ldif
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f /tmp/ourusers.ldif
+Enter LDAP Password:
+adding new entry "uid=ranos,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=ranos,ou=Group,dc=angelsofclockwork,dc=net"
+
+adding new entry "uid=sokel,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=sokel,ou=Group,dc=angelsofclockwork,dc=net"
+
+adding new entry "uid=suree,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=suree,ou=Group,dc=angelsofclockwork,dc=net"
+
The manual way.
+# /usr/share/migrationtools/migrate_passwd.pl ldif/user/passwd.sokel > ldif/user/sokel.ldif
+# /usr/share/migrationtools/migrate_group.pl ldif/user/group.sokel >> ldif/user/sokel.ldif
+# /usr/share/migrationtools/migrate_passwd.pl ldif/user/passwd.suree > ldif/user/suree.ldif
+# /usr/share/migrationtools/migrate_group.pl ldif/user/group.suree >> ldif/user/suree.ldif
+# /usr/share/migrationtools/migrate_passwd.pl ldif/user/passwd.ranos > ldif/user/ranos.ldif
+# /usr/share/migrationtools/migrate_group.pl ldif/user/group.ranos >> ldif/user/ranos.ldif
+
+# cd ldif/user/
+# ls
+group.ranos group.suree passwd.sokel ranos.ldif suree.ldif
+group.sokel passwd.ranos passwd.suree sokel.ldif
+
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f sokel.ldif
+Enter LDAP Password:
+adding new entry "uid=sokel,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=sokel,ou=Group,dc=angelsofclockwork,dc=net"
+
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f suree.ldif
+Enter LDAP Password:
+adding new entry "uid=suree,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=suree,ou=Group,dc=angelsofclockwork,dc=net"
+
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f ranos.ldif
+Enter LDAP Password:
+adding new entry "uid=ranos,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=ranos,ou=Group,dc=angelsofclockwork,dc=net"
+
This is for those who don't want to create the account locally. For +each user, you need to create an LDIF that satisfies their account +information such as UID, GID and their group information. If you plan on +having NFS exports to /lhome, make sure homeDirectory is correctly +pointing as such. Otherwise, keep it as /home/username.
+dn: uid=zera,ou=People,dc=angelsofclockwork,dc=net
+objectClass: posixAccount
+objectClass: top
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+cn: Zera Nalika
+gidNumber: 11000
+sn: Nalika
+uidNumber: 11000
+givenName: Zera
+uid: zera
+loginShell: /bin/bash
+homeDirectory: /home/zera
+displayName: Zera Nalika
+userPassword: changeme2
+
+dn: cn=zera,ou=Group,dc=angelsofclockwork,dc=net
+objectClass: posixGroup
+objectClass: top
+cn: zera
+gidNumber: 11000
+
That's about it for that. You create these for each user as needed and +then add them into ldap.
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f zera.ldif
+adding new entry "uid=zera,ou=People,dc=angelsofclockwork,dc=net"
+
+adding new entry "cn=zera,ou=Group,dc=angelsofclockwork,dc=net"
+
For users who are doing the /lhome thing, make their directories. When +you are changing ownership, do it by UID and GID number.
+# mkdir /lhome
+# semanage fcontext -a -t home_root_t "/lhome(/.*)?"
+# mkdir /lhome/zera
+# cp /etc/skel/.* /lhome/zera
+# chown -R 11000:11000 /lhome/zera
+# restorecon -Rv /lhome
+
Warning
+/home vs /lhome
+If you used /lhome and you want to use NFS mounts, you may continue +here. Otherwise, skip this section entirely. If you use /home and still +want to do NFS, you will need to do persistent NFS to say /export/home, +and then setup AutoFS to use /export/home as a way to automount into +/home.
+Warning
+Potential Pitfall
+Do NOT use NFSv3. The steps below show how to prevent user squashing to +allow the user to have access to their home directories. Typically, in +an NFSv4 fashion, it tends to mount it with permissions set to nobody. +Other solutions have been to force NFSv3. This is NOT recommended. +YOU HAVE BEEN WARNED.
+First, we'll need to install nfs-utils, set up our exports, and modify +our id map file.
+# dnf install nfs-utils libnfsidmap -y
+
+# vi /etc/exports
+/lhome *(rw,sync,root_squash,no_all_squash)
+
+# vi /etc/idmapd.conf
+
+# Comment out the first Domain line and make your own
+Domain = zera1.angelsofclockwork.net
+
+# systemctl start nfs-server
+# systemctl enable nfs-server
+
Sometimes you'll still run into the nobody problem. Sometimes this +helps.
+# vi /etc/sysconfig/nfs
+NEED_IDMAPD=yes
+NFSMAPID_DOMAIN=library.angelsofclockwork.net
+
Warning
+Keep your firewall on
+It is bad practice to turn your firewall off. Don't do it.
+We need to open up our firewall.
+Note
+Port Reference
+If using firewalld, you can add these ports by service.
+# firewall-cmd --add-service=ldap --zone=public --permanent
+# firewall-cmd --add-service=ldaps --zone=public --permanent
+# firewall-cmd --add-service=nfs --zone=public --permanent
+# firewall-cmd --reload
+
Setting up the client can be straight-forward or troubling, depending on +the distribution you're using. We'll be going over EL7+. Fedora also +works here as well.
+Warning
+Third-party Repositories
+If you use third-party repositories, you may want to disable them, at +least temporarily. Depending on the repository, there may be conflicts +when installing the appropriate packages. You may want to consider on +setting up priorities, and ensure your base and updates are higher than +the rest.
+We'll be using SSSD for this. We need to install some key packages +first. Some of these packages may not install because they were either +superceded or obsoleted.
+# yum install pki-{ca,common,silent} openldap-clients nss-pam-ldapd policycoreutils-python sssd sssd-common sssd-client sssd-ldap
+
Use authselect to configure pam and nss. You'll need to configure +/etc/sssd/sssd.conf by hand after.
+# authselect select sssd with-mkhomedir with-sudo
+
+# vi /etc/sssd/sssd.conf
+[domain/default]
+
+cache_credentials = True
+krb5_realm = #
+ldap_search_base = dc=angelsofclockwork,dc=net
+id_provider = ldap
+auth_provider = ldap
+chpass_provider = ldap
+sudo_provider = ldap
+ldap_uri = ldap://zera1.angelsofclockwork.net
+ldap_id_use_start_tls = True
+ldap_tls_cacertdir = /etc/openldap/certs
+ldap_tls_cacert = /etc/openldap/certs/ca.pem
+# Add the below
+ldap_sudo_search_base = ou=SUDOers,dc=angelsofclockwork,dc=net
+
+[sssd]
+# Modify this line and add sudo to the list
+services = nss, pam, autofs, sudo
+
+[sudo]
+
Now, let's get our CA cert that we made way long ago and download it. +If you used a real CA to sign your certificate, obtain their +certificate.
+Note
+Hash
+Remember your hash from when you were making your certificates? You need +to obtain it. In both examples, we created it while using a symbolic +link.
+# scp zera1.angelsofclockwork.net:/etc/pki/ldap/ca.pem /etc/openldap/certs/ca.pem
+# cd /etc/openldap/certs
+# ln -s ca.pem 39642ab3.0
+
Now, modify /etc/openldap/ldap.conf and add the following to the bottom, +ensuring your BASE is set correctly.
+URI ldap://library.angelsofclockwork.net
+BASE dc=angelsofclockwork,dc=net
+ssl start_tls
+
You can attempt an ldapsearch and it should work. Search for one of your +users.
+# ldapsearch -x -LLL uid=zera
+
+dn: uid=zera,ou=People,dc=angelsofclockwork,dc=net
+cn: Zera Nalika
+gidNumber: 11000
+uidNumber: 11000
+givenName: Zera
+objectClass: posixAccount
+objectClass: top
+objectClass: shadowAccount
+objectClass: hostObject
+objectClass: radiusprofile
+objectClass: inetOrgPerson
+objectClass: ldapPublicKey
+uid: zera
+loginShell: /bin/bash
+homeDirectory: /lhome/zera
+displayName: Zera Nalika
+
If you chose to do /lhome NFS mounting, proceed here.
+# mkdir /lhome
+# semanage fcontext -a -t autofs_t "/lhome(/.*)?"
+# restorecon -v /lhome
+# setsebool use_nfs_home_dirs 1
+
Now, let's get our automounting setup.
+# vi /etc/auto.master
+. . .
+/lhome /etc/auto.lhome # Add this under the /misc line
+
Let's copy the misc template and make a change to it.
+# cp /etc/auto.misc /etc/auto.lhome
+# vi /etc/auto.lhome
+
+# Comment the cd line, and add our mount under it.
+#cd -fstype=iso9660,ro,nosuid,nodev :/dev/cdrom
+* -rw,soft,intr zera1.angelsofclockwork.net:/lhome/&
+
+# restorecon -v /etc/auto.lhome
+# systemctl enable autofs
+# systemctl start autofs
+
Let's make our change to the idmapd configuration.
+# vi /etc/idmapd.conf
+
+#Domain = local.domain.edu
+Domain = zera1.angelsofclockwork.net
+
+# systemctl restart sssd autofs
+
Here you'll find my value-added portions of getting LDAP going further +than what the above presented.
+Getting SUDO to work in LDAP can be a real pain. It doesn't have to be.
+The default sudo schema provided by the LDAP packages, which I have +taken and converted into the proper olc format.
+dn: cn=sudo,cn=schema,cn=config
+objectClass: olcSchemaConfig
+cn: sudo
+olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s)
+ who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMa
+ tch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s)
+ who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMat
+ ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Comma
+ nd(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1
+ 466.115.121.1.26 )
+olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s)
+ impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1
+ .4.1.1466.115.121.1.26 )
+olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Option
+ s(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115
+ .121.1.26 )
+olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'Use
+ r(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466
+ .115.121.1.26 )
+olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Gr
+ oup(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.14
+ 66.115.121.1.26 )
+olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Sta
+ rt of time interval for which the entry is valid' EQUALITY generalizedTimeMat
+ ch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ )
+olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End
+ of time interval for which the entry is valid' EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an int
+ eger to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrd
+ eringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer En
+ tries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ s
+ udoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotB
+ efore $ sudoNotAfter $ description ) )
+
Save this as sudoschema.ldif and add it in.
+# ldapadd -Y EXTERNAL -H ldapi:/// -f sudoschema.ldif
+
Let's create our defaults. This will start our sudo OU and give it some +defaults. You may change these if you so desire.
+# vi sudo.ldif
+
+dn: ou=SUDOers,dc=angelsofclockwork,dc=net
+objectClass: top
+objectClass: organizationalUnit
+ou: SUDOers
+
+dn: cn=defaults,ou=SUDOers,dc=angelsofclockwork,dc=net
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: SUDOers Default values
+sudoOption: requiretty
+sudoOption: env_reset
+sudoOption: env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
+sudoOption: env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
+sudoOption: env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
+sudoOption: env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
+sudoOption: env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
+
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f sudo.ldif
+
Now, let's create our first SUDO container. It will be for our +\"admins\". We could specify \"sudoHost: ALL\" if we wanted. But for the +example, I chose a couple of hosts.
+# vi admins.ldif
+
+dn: cn=ADMINS,ou=SUDOers,dc=angelsofclockwork,dc=net
+objectClass: sudoRole
+cn: ADMINS
+description: Administration Role
+sudoCommand: ALL
+sudoHost: zera2.angelsofclockwork.net
+sudoHost: zera3.angelsofclockwork.net
+sudoRunAs: ALL
+sudoRunAsGroup: ALL
+sudoRunAsUser: ALL
+sudoUser: zera
+
+# ldapadd -xWD "cn=manager,dc=angelsofclockwork,dc=net" -f admins.ldif
+
If you used authselect with the with-sudo option, this should have +turned on sss for sudoers. You may want to verify /etc/nsswitch.conf +just to be sure.
+Note
+SSSD Cache
+Sometimes SSSD likes to cache things or never update things for whatever +reason or another. To get around this, stop sssd, delete everything +under /var/lib/sss/db/ and then start sssd again.
+Now, let's test.
+[root@zera3 ~]# su - zera
+[zera@zera3 ~]$ sudo -l
+[sudo] password for zera:
+Matching Defaults entries for zera on this host:
+ requiretty, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL
+ PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT
+ LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
+ LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin, env_reset, requiretty
+
+User sokel may run the following commands on this host:
+ (ALL : ALL) ALL
+
Member groups are extremely useful, especially for when you're granting +permissions to external applications (and SSSD if you wish).
+# vi modules.ldif
+
+dn: cn=module,cn=config
+objectClass: olcModuleList
+cn: module
+olcModulePath: /usr/lib64/openldap
+olcModuleLoad: memberof.la
+
+# vi memberof.ldif
+
+dn: olcOverlay=memberof,olcDatabase={2}mdb,cn=config
+objectClass: olcMemberOf
+objectClass: olcOverlayConfig
+objectClass: olcConfig
+objectClass: top
+olcOverlay: memberof
+olcMemberOfDangling: ignore
+olcMemberOfRefInt: TRUE
+olcMemberOfGroupOC: groupOfNames
+olcMemberOfMemberAD: member
+olcMemberOfMemberOfAD: memberOf
+
+# ldapadd -Y EXTERNAL -H ldapi:/// -f modules.ldif
+# ldapadd -Y EXTERNAL -H ldapI:/// -f memberof.ldif
+
After that, we can now create our groups. Example.
+dn: cn=Admins,ou=Group,dc=angelsofclockwork,dc=net
+objectClass: groupOfNames
+cn: Admins
+member: uid=chris,ou=People,dc=angelsofclockwork,dc=net
+member: uid=zera,ou=People,dc=angelsofclockwork,dc=net
+member: uid=sithlord,ou=People,dc=angelsofclockwork,dc=net
+
In SSSD, we can make some minor changes.
+ldap_search_base = dc=angelsofclockwork,dc=net?sub?|(memberOf=cn=Admins,ou=Group,dc=angelsofclockwork,dc=net)
+ldap_access_filter = (|(memberOf=cn=Admins,ou=Group,dc=angelsofclockwork,dc=net))
+# Change this to rfc2307 if you are using nis
+ldap_schema = rfc2307bis
+enumerate = True
+
+# systemctl stop sssd ; rm -rf /var/lib/sss/db/* ; systemctl start sssd
+
If we were to do an ldapsearch, we can see the groups show up.
+# ldapsearch -x -LLL uid=zera memberOf
+dn: uid=zera,ou=People,dc=angelsofclockwork,dc=net
+memberOf: cn=Admins,ou=Group,dc=angelsofclockwork,dc=net
+
Make sure you turn on referential integrity!
+Having referential integrity is absolutely important. It basically means +that if a user gets deleted, their group membership disappears also. +This prevents you from having to clean up manually.
+# vi module.ldif
+
+dn: cn=module,cn=config
+changetype: modify
+replace: olcModuleLoad
+olcModuleLoad: refint.la
+olcModuleLoad: memberof.la
+
+# ldapmodify -Y EXTERNAL -H ldapi:/// -f module.ldif
+
You also need the overlay. An overlay allows certain plugins to work on +a DIT.
+# vi overlay.ldif
+dn: olcOverlay=refint,olcDatabase={2}mdb,cn=config
+objectClass: olcOverlayConfig
+objectClass: olcConfig
+objectClass: olcRefintConfig
+objectClass: top
+olcOverlay: refint
+olcRefintAttribute: memberOf member manager
+
+# ldapmodify -Y EXTERNAL -H ldapi:/// -f overlay.ldif
+
An ACL (Access Control List) allows permissions to be given to those in +the LDAP tree. The problem with a default LDAP setup is that, attributes +like userPassword show up in an ldapsearch. This gives little +protection. So, to get around this issue, we have to create ACLs.
+Note
+The Manager's Rights
+The manager has all rights to the DIT. In previous implementations, I +have put him in access controls as a reference and would put \"write\" +as his access. This isn't needed, but it doesn't hurt to have it.
+This ldif creates an ACL that allows the Admins group to do anything +they want on the DIT (similar to manager). This also prevents anonymous +searches from pulling up a user's password.
+# vi acl.ldif
+
+dn: olcDatabase={2}mdb,cn=config
+changetype: modify
+replace: olcAccess
+olcAccess: {0}to attrs=userPassword,shadowLastChange by group.exact="cn=Admins,ou=Group,dc=angelsofclockwork,dc=net" write by anonymous auth by self write by * none break
+olcAccess: {2}to * by group.exact="cn=Admins,ou=Group,dc=angelsofclockwork,dc=net" write by * read
+olcAccess: {3}to dn.base="" by * read
+
+# ldapmodify -Y EXTERNAL -H ldapi:/// -f acl.ldif
+
It's highly recommended, however, to disable anonymous searching, +especially if you go production with LDAP. A lot of LDAP implementations +disallow anonymous searching by default. You can do this with ACLs, but +it's not recommended. We cover this in the search.
+It's recommended to disable anonymous searching. This can be handled by +making a modification to the global configuration and the DIT +configuration.
+dn: cn=config
+changetype: modify
+add: olcDisallows
+olcDisallows: bind_anon
+
+dn: olcDatabase={2}mdb,cn=config
+changetype: modify
+add: olcRequires
+olcRequires: authc
+
Once you add this in, all anonymous searching will cease.
+# ldapsearch -x -LLL uid=zera
+ldap_bind: Inappropriate authentication (48)
+ additional info: anonymous bind disallowed
+
Logging is of course, very important for an LDAP server. There are a few +types of logs we can do. There are the standard logs and then there are +also audit logs. Audit logs allow an administrator to view changes being +done to LDAP in an LDIF form. We can setup both.
+Let's create our modification LDIF. This will turn on standard logging +and enable the audit module. Run an ldapmodify against this LDIF.
+dn: cn=config
+changetype: modify
+replace: olcLogFile
+olcLogFile: /var/log/ldap-standard.log
+-
+replace: olcLogLevel
+olcLogLevel: 256
+
+# Keep in mind, if you have other modules being loaded,
+# add them to the list
+dn: cn=module,cn=config
+changetype: modify
+replace: olcModuleLoad
+olcModuleLoad: refint.la
+olcModuleLoad: memberof.la
+olcModuleLoad: auditlog.la
+
Now, we need to make sure audit logging is done on our database.
+dn: olcOverlay=auditlog,olcDatabase={2}mdb,cn=config
+objectClass: olcAuditlogConfig
+objectClass: olcOverlayConfig
+olcOverlay: auditlog
+olcAuditlogFile: /var/log/ldap-audit.log
+
It's recommended to have logrotate working for our logs. Here is a file +I've dropped into /etc/logrotate.d. Experiment with these options. +Since I work in an environment that has tons of transactions going all +the time, and thus, my rotations are at 100M and 250M respectively.
+/var/log/ldap-standard.log {
+missingok
+compress
+notifempty
+daily
+rotate 10
+size=100M
+}
+
+/var/log/ldap-audit.log {
+missingok
+compress
+notifempty
+daily
+rotate 10
+size=250M
+}
+
In /etc/rsyslog.conf, optionally, you can create this. If you find that +logs are not appearing after the changes above, use this.
+local4.* /var/log/ldap.log
+
Password policies are a great asset, especially when working in an +environment that have or require security policies. First, let's load +our module and then add our overlay. This LDIF will do both. You may +want to remove the comments before adding.
+dn: cn=module,cn=config
+changetype: modify
+replace: olcModuleLoad
+olcModuleLoad: refint.la
+olcModuleLoad: memberof.la
+olcModuleLoad: auditlog.la
+olcModuleLoad: ppolicy.la
+
+dn: olcOverlay=ppolicy,olcDatabase={2}mdb,cn=config
+objectClass: olcOverlayConfig
+objectClass: olcPPolicyConfig
+olcOverlay: ppolicy
+olcPPolicyDefault: cn=default,ou=policies,dc=angelsofclockwork,dc=net
+# Set the below to TRUE if you want users to get locked out after failed attempted
+olcPPolicyUseLockout: TRUE
+# Set the below to TRUE if you want passwords to be hashed.
+# HIGHLY RECOMMENDED YOU SET THIS TO TRUE
+olcPPolicyHashCleartext: TRUE
+
Now, we need an LDIF to create our standard password policy. It's +important to have a default password policy and then create separate +ones as needed. Make sure to read the comments. You may want to remove +the comments before adding.
+dn: cn=default,ou=policies,dc=angelsofclockwork,dc=net
+objectClass: pwdPolicy
+objectClass: person
+objectClass: top
+cn: passwordDefault
+sn: passwordDefault
+pwdAttribute: userPassword
+# If set to 0, quality is not checked.
+# If set to 1, quality is checked by an internal module which you setup.
+# If set to 2, the system used to change the password must have a checking mechanism.
+# Pick your poison.
+pwdCheckQuality: 0
+# Password lives for 84 days
+pwdMinAge: 0
+pwdMaxAge: 7257600
+# Minimum length is 7
+pwdMinLength: 7
+# Password history of 10, cannot use a password that's in history
+pwdInHistory: 10
+# 5 Failures till a lockout, 10 minutes for it to reset, 30 minute lockout.
+pwdMaxFailure: 5
+pwdFailureCountInterval: 600
+pwdLockout: TRUE
+pwdLockoutDuration: 1800
+# A user can change their own password.
+pwdAllowUserChange: TRUE
+# Systems that authenticate to LDAP can warn 14 days before an expiration
+pwdExpireWarning: 1209600
+# Allowed binds on an expired password.
+pwdGraceAuthNLimit: 5
+pwdMustChange: TRUE
+pwdSafeModify: FALSE
+
In the instance you want to use the built-in module for password +checking, your LDIF would have these lines.
+pwdCheckQuality: 1
+pwdCheckModule: check_password.so
+
This page goes over setting up a pxeboot system using tftp on Enterprise +Linux or Fedora
+Here are the list of requirements below.
+next_server
directive or setup the tftp server locationhttpd
or nginx
installed. (This guide assumes httpd
)In some environments, it may be better (or easier, depending on your +perspective) to setup a PXE server and roll out systems in a lab or +otherwise in that fashion. It's one of the most straight forward ways +to build out systems easily and consistently. The difference between a +typical PXE setup and this is we're using grub2 menus, rather than the +classic menu style. This makes it simpler to keep all configurations +consistent between classic boot and EFI boot.
+If you plan on using supporting other architectures, it will be easier +to use that architecture to run the grub2-mknetdir command and brings +those to your tftp server.
+While cobbler is a perfectly viable solution to setting up a pxeboot +system for various distros and configurations, it is out of scope for +this article. It is unknown if it sets up or directly supports grub2.
+This section goes over the server setup portion for the tftp server.
+Let's install the tftpserver package plus some additional grub +packages. If you are wanting other architectures, you can obtain the +other grub2 module packages from your distribution's BaseOS or +equivalent repository for that architecture and install it manually.
+# x86_64
+% dnf install \
+ grub2-efi-x64-modules \
+ grub2-tools-extra \
+ grub2-pc-modules \
+ shim-ia32 \ # this does not exist on el9+
+ tftp-server
+
+# aarch64
+% dnf install \
+ grub2-efi-aa64-modules \
+ grub2-tools-extra \
+ tftp-server
+
Let's make our initial net directories and ensure the selinux contexts +are correct.
+% grub2-mknetdir --net-directory /var/lib/tftpboot/
+Netboot directory for i386-pc created. Configure your DHCP server to point to /srv/tftp/boot/grub2/i386-pc/core.0
+Netboot directory for x86_64-efi created. Configure your DHCP server to point to /srv/tftp/boot/grub2/x86_64-efi/core.efi
+
+% restorecon -R /var/lib/tftpboot
+
Now you'll need to enable the tftp socket and open the port. +Traditionally, you would use xinetd. It's no longer required for the +tftp service.
+# Note: This is port 69 with the UDP protocol
+% firewall-cmd --add-service=tftp --permanent
+% systemctl enable tftp.socket --now
+
On your DHCP server configuration (typically /etc/dhcp/dhcpd.conf if +running on Fedora or EL), you should set the following options:
+option pxe-system-type code 93 = unsigned integer 16;
+option rfc3442-classless-static-routes code 121 = array of integer 8;
+option ms-classless-static-routes code 249 = array of integer 8;
+
+option space pxelinux;
+option pxelinux.magic code 208 = string;
+option pxelinux.configfile code 209 = text;
+option pxelinux.pathprefix code 210 = text;
+option pxelinux.reboottime code 211 = unsigned integer 32;
+option architecture-type code 93 = unsigned integer 16;
+option pxelinux.mtftp-ip code 1 = ip-address;
+option pxelinux.mtftp-cport code 2 = unsigned integer 16;
+option pxelinux.mtftp-sport code 3 = unsigned integer 16;
+option pxelinux.mtftp-tmout code 4 = unsigned integer 8;
+option pxelinux.mtftp-delay code 5 = unsigned integer 8;
+
Whether this section is within a subnet block or not, it is needed to +ensure the right bootloader is called. Note that we're only loading +x86. If you are loading armhfp, use 00:0a. If you are loading aarch64, +use 00:0b.
+class "pxeclients" {
+ match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
+ # x86_64 EFI
+ if option pxe-system-type = 00:07 {
+ filename "boot/grub2/x86_64-efi/core.efi";
+ } else if option pxe-system-type = 00:08 {
+ filename "boot/grub2/x86_64-efi/core.efi";
+ } else if option pxe-system-type = 00:09 {
+ filename "boot/grub2/x86_64-efi/core.efi";
+ } else {
+ # BIOS boot only
+ filename "boot/grub2/i386-pc/core.0";
+ }
+}
+
Note that in your subnet blocks, you should also mention next_server
,
+which should point to your TFTP server. The DHCP and TFTP server can be
+on the same machine and there's nothing stopping you from doing that;
+next_server
needs to be set regardless here. See an example below of a
+full work dhcpd.conf.
ddns-update-style interim;
+
+allow booting;
+allow bootp;
+authoritative;
+log-facility local6;
+
+ignore client-updates;
+set vendorclass = option vendor-class-identifier;
+
+## Allowing EFI Clients
+option pxe-system-type code 93 = unsigned integer 16;
+option rfc3442-classless-static-routes code 121 = array of integer 8;
+option ms-classless-static-routes code 249 = array of integer 8;
+
+option space pxelinux;
+option pxelinux.magic code 208 = string;
+option pxelinux.configfile code 209 = text;
+option pxelinux.pathprefix code 210 = text;
+option pxelinux.reboottime code 211 = unsigned integer 32;
+option architecture-type code 93 = unsigned integer 16;
+
+option pxelinux.mtftp-ip code 1 = ip-address;
+option pxelinux.mtftp-cport code 2 = unsigned integer 16;
+option pxelinux.mtftp-sport code 3 = unsigned integer 16;
+option pxelinux.mtftp-tmout code 4 = unsigned integer 8;
+option pxelinux.mtftp-delay code 5 = unsigned integer 8;
+
+subnet 10.100.0.0 netmask 255.255.255.0 {
+ interface br1000;
+ option routers 10.100.0.1;
+ option domain-name-servers 10.100.0.1, 10.100.0.231;
+ option domain-name "angelsofclockwork.net";
+ option subnet-mask 255.255.255.0;
+ range 10.100.0.110 10.100.0.199;
+ ## EFI Client Catch
+ class "pxeclients" {
+ match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
+ if option pxe-system-type = 00:07 {
+ filename "boot/grub2/x86_64-efi/core.efi";
+ } else if option pxe-system-type = 00:08 {
+ filename "boot/grub2/x86_64-efi/core.efi";
+ } else if option pxe-system-type = 00:09 {
+ filename "boot/grub2/x86_64-efi/core.efi";
+ } else if option pxe-system-type = 00:0a {
+ filename "boot/grub2/armv7a-efi/core.efi";
+ } else if option pxe-system-type = 00:0b {
+ filename "boot/grub2/aarch64-efi/core.efi";
+ } else {
+ filename "boot/grub2/i386-pc/core.0";
+ }
+ }
+ default-lease-time 21600;
+ max-lease-time 43200;
+ next-server 10.100.0.1;
+}
+
Ensure that the dhcpd service is restarted after making the necessary +changes.
+Kea is a different configuration style from ISC. At this time, we do not +have a full working example.
+If we plan on hosting the installation mirror in your environment, it's +recommended to stand up a simple web server. It does not require any +kind of special configuration. We'll use the default /var/www/html/ +path. If you wish to use another such as /srv/www, you will need to +setup a virtual host (this is outside the scope of this page).
+% dnf install httpd -y
+% systemctl enable httpd --now
+% firewall-cmd --add-service=http --permanent
+% firewall-cmd --complete-reload
+
+# create the directories for our distributions
+% mkdir -p /var/www/html/os/{fedora,centos,rocky}
+
When you run grub2-mknetdir, it created a core.* set of files. An +accompanying grub.cfg must sit next to them. To prevent a duplication of +work, it can be simplified by making all grub configurations at +/var/lib/tftpboot and then symlink them next to each directory +containing core.*. Let's make a very, very simple one.
+set default=0
+set timeout=60
+menuentry 'EFI Firmware System Setup' $menuentry_id_option 'uefi-firmware' {
+ fwsetup
+}
+
+menuentry 'Reboot' {
+ reboot
+}
+
+menuentry 'Shutdown' {
+ halt
+}
+
Now let's just symlink it.
+% cd /var/lib/tftpboot/boot/grub2/x86_64-efi
+% ln -s ../../../grub.cfg
+% cd /var/lib/tftpboot/boot/grub2/i386-pc
+% ln -s ../../../grub.cfg
+
This should produce a grub menu for both EFI and BIOS systems that +contain three bootable options.
+Now that grub is sort of setup, we should add a distribution to it at +least. Below are a couple examples using Fedora, Rocky Linux, and CentOS +Stream.
+Setting up Rocky Linux (or any other Enterprise Linux distribution) +should be straight forward. We'll download both Rocky Linux 8 and Rocky +Linux 9 and setup the menus.
+Note
+If you plan on not hosting a mirror of the base repositories, ensure +that your inst.repo/inst.stage2 commands are accurate to a mirror of +your choice.
+The below assumes we are hosting a mirror of the downloaded ISO, which +will make installations quicker as it'll be confined to your network.
+% cd /var/tmp
+# Rocky Linux 8
+% wget https://dl.rockylinux.org/pub/rocky/8/isos/x86_64/Rocky-8-latest-x86_64-dvd.iso
+# Rocky Linux 9
+% wget https://dl.rockylinux.org/pub/rocky/9/isos/x86_64/Rocky-9-latest-x86_64-dvd.iso
+
+# Optionally, if you plan on supporting ARM...
+% wget https://dl.rockylinux.org/pub/rocky/8/isos/aarch64/Rocky-8-latest-aarch64-dvd.iso
+% wget https://dl.rockylinux.org/pub/rocky/9/isos/aarch64/Rocky-9-latest-aarch64-dvd.iso
+
Here we'll copy the data we want into the necessary directories. Any +pxeboot related images will go to /var/lib/tftpboot/rocky-X-ARCH (X +being the major version, ARCH being the architecture). If we are keeping +a local mirror of the DVD, we'll put it into +/var/www/html/os/rocky/X/ARCH. Below is for x86_64, but the same steps +can be repeated for aarch64 without any issues. Just replace x86_64 +with aarch64.
+## Rocky 8
+% mount -o loop Rocky-8-latest-x86_64-dvd.iso /mnt
+% mkdir /var/lib/tftpboot/rocky-8-x86_64
+% cp /mnt/images/pxeboot/* /var/lib/tftpboot/rocky-8-x86_64
+% mkdir -p /var/www/html/os/rocky/8/x86_64
+% rsync -vrlptDSH --delete /mnt/ /var/www/html/os/rocky/8/x86_64
+% umount /mnt
+
+## Rocky 9
+% mount -o loop Rocky-9-latest-x86_64-dvd.iso /mnt
+% mkdir /var/lib/tftpboot/rocky-9-x86_64
+% cp /mnt/images/pxeboot/* /var/lib/tftpboot/rocky-9-x86_64
+% mkdir -p /var/www/html/os/rocky/9/x86_64
+% rsync -vrlptDSH --delete /mnt/ /var/www/html/os/rocky/9/x86_64
+% umount /mnt
+
+% restorecon -R /var/www/html/os/rocky
+
At this point, we'll need to setup the grub menus. We'll setup +non-kickstart examples for BIOS and UEFI.
+. . .
+# Rocky 8
+menuentry 'Install Rocky Linux 8 (No KS) (UEFI)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading Rocky Linux 8 kernel..."
+ linuxefi rocky-8-x86_64/vmlinuz inst.repo=http://10.100.0.1/os/rocky/8/x86_64 inst.stage2=http://10.100.0.1/os/rocky/8/x86_64 ip=dhcp
+ initrdefi rocky-8-x86_64/initrd.img
+}
+menuentry 'Install Rocky Linux 8 (No KS) (BIOS)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading Rocky Linux 8 kernel..."
+ linux16 rocky-8-x86_64/vmlinuz inst.repo=http://10.100.0.1/os/rocky/8/x86_64 inst.stage2=http://10.100.0.1/os/rocky/8/x86_64 ip=dhcp
+ initrd16 rocky-8-x86_64/initrd.img
+}
+
+# if you are setting up arm...
+menuentry 'Install Rocky Linux 8 (No KS) (aarch64)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading Rocky Linux 8 kernel..."
+ linux rocky-9-aarch64/vmlinuz inst.repo=http://10.100.0.1/os/rocky/8/aarch64 inst.stage2=http://10.100.0.1/os/rocky/8/aarch64 ip=dhcp
+ initrd rocky-9-aarch64/initrd.img
+}
+
. . .
+# Rocky 9
+menuentry 'Install Rocky Linux 9 (No KS) (UEFI)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading Rocky Linux 9 kernel..."
+ linuxefi rocky-9-x86_64/vmlinuz inst.repo=http://10.100.0.1/os/rocky/9/x86_64 inst.stage2=http://10.100.0.1/os/rocky/9/x86_64 ip=dhcp
+ initrdefi rocky-9-x86_64/initrd.img
+}
+menuentry 'Install Rocky Linux 9 (No KS) (BIOS)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading Rocky Linux 9 kernel..."
+ linux16 rocky-9-x86_64/vmlinuz inst.repo=http://10.100.0.1/os/rocky/9/x86_64 inst.stage2=http://10.100.0.1/os/rocky/9/x86_64 ip=dhcp
+ initrd16 rocky-9-x86_64/initrd.img
+}
+
+# if you are setting up arm...
+menuentry 'Install Rocky Linux 9 (No KS) (aarch64)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading Rocky Linux 9 kernel..."
+ linux rocky-9-aarch64/vmlinuz inst.repo=http://10.100.0.1/os/rocky/9/aarch64 inst.stage2=http://10.100.0.1/os/rocky/9/aarch64 ip=dhcp
+ initrd rocky-9-aarch64/initrd.img
+}
+
The Rocky Linuxinstallation should now be bootable.
+Much like Rocky Linux (or other derivatives), the path is the same for +setting it up.
+Using upstream mirror path
+If you plan on not hosting a mirror of the base repositories, ensure +that your inst.repo/inst.stage2 commands are accurate to a mirror of +your choice.
+% cd /var/tmp
+# CentOS Stream 9
+% wget -O CentOS-Stream-9-latest-x86_64-dvd1.iso \
+ 'https://mirrors.centos.org/mirrorlist?path=/9-stream/BaseOS/x86_64/iso/CentOS-Stream-9-latest-x86_64-dvd1.iso&redirect=1&protocol=https'
+
+# Optionally, if you plan on supporting ARM...
+% wget -O CentOS-Stream-9-latest-aarch64-dvd1.iso \
+ 'https://mirrors.centos.org/mirrorlist?path=/9-stream/BaseOS/aarch64/iso/CentOS-Stream-9-latest-aarch64-dvd1.iso&redirect=1&protocol=https'
+
Here we'll copy the data we want into the necessary directories. Any +pxeboot related images will go to /var/lib/tftpboot/rocky-X-ARCH (X +being the major version, ARCH being the architecture). If we are keeping +a local mirror of the DVD, we'll put it into +/var/www/html/os/rocky/X/ARCH. Below is for x86_64, but the same steps +can be repeated for aarch64 without any issues. Just replace x86_64 +with aarch64.
+## CentOS Stream 9
+% mount -o loop CentOS-Stream-9-latest-x86_64-dvd1.iso /mnt
+% mkdir /var/lib/tftpboot/centos-9-x86_64
+% cp /mnt/images/pxeboot/* /var/lib/tftpboot/centos-9-x86_64
+% mkdir -p /var/www/html/os/centos/9/x86_64
+% rsync -vrlptDSH --delete /mnt/ /var/www/html/os/centos/9/x86_64
+% restorecon -R /var/www/html/os/centos/9
+% umount /mnt}
+
At this point, we'll need to setup the grub menus. We'll setup +non-kickstart examples for BIOS and UEFI.
+. . .
+# CentOS Stream 9
+menuentry 'Install CentOS Stream 9 (No KS) (UEFI)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading CentOS Stream 9 kernel..."
+ linuxefi centos-9-x86_64/vmlinuz inst.repo=http://10.100.0.1/os/centos/9/x86_64 inst.stage2=http://10.100.0.1/os/centos/9/x86_64 ip=dhcp
+ initrdefi centos-9-x86_64/initrd.img
+}
+menuentry 'Install CentOS Stream 9 (No KS) (BIOS)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading CentOS Stream 9 kernel..."
+ linux16 centos-9-x86_64/vmlinuz inst.repo=http://10.100.0.1/os/centos/9/x86_64 inst.stage2=http://10.100.0.1/os/centos/9/x86_64 ip=dhcp
+ initrd16 centos-9-x86_64/initrd.img
+}
+
+# if you are setting up arm...
+menuentry 'Install CentOS Stream 9 (No KS) (aarch64)' --class fedora --class gnu-linux --class gnu --class os {
+ echo "Loading CentOS Stream 9 kernel..."
+ linux centos-9-aarch64/vmlinuz inst.repo=http://10.100.0.1/os/centos/9/aarch64 inst.stage2=http://10.100.0.1/os/centos/9/aarch64 ip=dhcp
+ initrd centos-9-aarch64/initrd.img
+}
+
The CentOS Stream installation should now be bootable.
+Let's put up a regular installer with no kickstart for Fedora. This +does not involve pulling down any ISO's and will rely entirely on using +upstream repositories.
+% cd /var/lib/tftpboot
+% mkdir fedora-x86_64
+% cd fedora-x86_64
+# Replace XX with the current fedora version
+% wget https://dl.fedoraproject.org/pub/fedora/linux/releases/XX/Everything/x86_64/os/images/pxeboot/initrd.img
+% wget https://dl.fedoraproject.org/pub/fedora/linux/releases/XX/Everything/x86_64/os/images/pxeboot/vmlinuz
+
+# If you want arm systems... aarch64
+% cd ..
+% mkdir fedora-aarch64
+# Replace XX with the current fedora version
+% wget https://dl.fedoraproject.org/pub/fedora/linux/releases/XX/Everything/aarch64/os/images/pxeboot/initrd.img
+% wget https://dl.fedoraproject.org/pub/fedora/linux/releases/XX/Everything/aarch64/os/images/pxeboot/vmlinuz
+
Now we can add a couple menu entry items for Fedora. I'm making both +EFI and Classic entries to ensure we can boot both EFI and BIOS systems +from the same menu.
+. . .
+menuentry 'Install Fedora Linux (EFI)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os ip=dhcp
+ initrdefi fedora-x86_64/initrd.img
+}
+menuentry 'Install Fedora Linux (Classic)' --class fedora --class gnu-linux --class gnu --class os {
+ linux16 fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ ip=dhcp
+ initrd16 fedora-x86_64/initrd.img
+}
+# Add the below for ARM systems
+menuentry 'Install Fedora Linux (ARM)' --class fedora --class gnu-linux --class gnu --class os {
+ linux fedora-aarch64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os/ ip=dhcp
+ initrd fedora-aarch64/initrd.img
+}
+
Now the Fedora installation should be bootable.
+Grub is customizable. It is possible to setup background images, choose +menu colors, setup themes, and so on.
+Colors and backgrounds are perfectly possible, even in an EFI setup. +We'll need to load a few modules and then set the colors and background +we want. Note that if you're using a background, it should live in +/var/lib/tftpboot to make things easier.
+. . .
+insmod all_video
+insmod gfxterm
+insmod gfxterm_menu
+insmod gfxmenu
+insmod gfxterm_background
+insmod png
+terminal_output gfxterm
+background_image -m stretch /bg.png
+
+set menu_color_highlight=cyan/black
+set menu_color_normal=white/black
+set color_normal=white/black
+. . .
+
The background would be /var/lib/tftpboot/bg.png in this example. +Selected items will appear to be cyan and the typical gray selection box +is now transparent, which is done by setting it to black. Everything +else should appear as white text with a transparent background. Example +below.
+Submenus are easily created using submenu in the grub configuration. For +example:
+submenu 'Fedora Linux' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+
+ menuentry 'Install Fedora Linux (EFI)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os ip=dhcp
+ initrdefi fedora-x86_64/initrd.img
+ }
+ menuentry 'Install Fedora Linux (Classic)' --class fedora --class gnu-linux --class gnu --class os {
+ linux16 fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ ip=dhcp
+ initrd16 fedora-x86_64/initrd.img
+ }
+ menuentry 'Install Fedora Linux (ARM)' --class fedora --class gnu-linux --class gnu --class os {
+ linux fedora-aarch64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os/ ip=dhcp
+ initrd fedora-aarch64/initrd.img
+ }
+}
+
This now means "Fedora Linux" will show up as a menu option and it +will take you to a brand new menu with the two listed items, and another +color scheme. Note that we created color items because submenus will +reset the theme options. Example of how it looks is below.
+It is also possible to place everything into separate source-able files. +Note that when you do this, you will need to symlink those files just +like you did with grub.cfg.
+submenu 'Fedora Linux' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+ source fedora.cfg
+}
+
menuentry 'Install Fedora Linux (EFI)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os ip=dhcp
+ initrdefi fedora-x86_64/initrd.img
+}
+menuentry 'Install Fedora Linux (Classic)' --class fedora --class gnu-linux --class gnu --class os {
+ linux16 fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ ip=dhcp
+ initrd16 fedora-x86_64/initrd.img
+}
+menuentry 'Install Fedora Linux (ARM)' --class fedora --class gnu-linux --class gnu --class os {
+ linux fedora-aarch64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os/ ip=dhcp
+ initrd fedora-aarch64/initrd.img
+}
+
Submenus can be nested too. Here's a deeper, working example of my own +setup using Fedora 35.
+# grub.cfg
+set default=0
+set timeout=60
+insmod all_video
+insmod gfxterm
+insmod gfxterm_menu
+insmod gfxmenu
+insmod gfxterm_background
+insmod png
+terminal_output gfxterm
+loadfont /unicode.pf2
+background_image -m stretch /bg.png
+
+set menu_color_highlight=cyan/black
+set menu_color_normal=white/black
+set color_normal=white/black
+
+submenu 'Fedora Linux' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+ source fedora.cfg
+}
+
+menuentry 'EFI System Setup' $menuentry_id_option 'uefi-firmware' {
+ fwsetup
+}
+
+menuentry 'Reboot' {
+ reboot
+}
+
+menuentry 'Shutdown' {
+ halt
+}
+
+# fedora.cfg
+submenu 'Fedora Linux (latest stable)' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+
+ # EFI Only
+ submenu 'EFI Mode' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+
+ menuentry 'Install Fedora Linux (No KS)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os ip=dhcp
+ initrdefi fedora-x86_64/initrd.img
+ }
+
+ menuentry 'Install Fedora Linux' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os ip=dhcp
+ initrdefi fedora-x86_64/initrd.img
+ }
+
+ menuentry 'Fedora Linux (Rescue Mode)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-x86_64/vmlinuz inst.rescue inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os
+ initrdefi fedora-x86_64/initrd.img
+ }
+ }
+
+ # Classic Only
+ submenu 'Classic Mode' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+
+ menuentry 'Install Fedora Linux (No KS)' --class fedora --class gnu-linux --class gnu --class os {
+ linux16 fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ ip=dhcp
+ initrd16 fedora-x86_64/initrd.img
+ }
+
+ menuentry 'Install Fedora Linux' --class fedora --class gnu-linux --class gnu --class os {
+ linux16 fedora-x86_64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/ ip=dhcp
+ initrd16 fedora-x86_64/initrd.img
+ }
+
+ menuentry 'Fedora Linux (Rescue Mode)' --class fedora --class gnu-linux --class gnu --class os {
+ linux16 fedora-x86_64/vmlinuz inst.rescue inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/x86_64/os/
+ initrd16 fedora-x86_64/initrd.img
+ }
+ }
+
+ # EFI mode for ARM
+ submenu 'EFI Mode (aarch64)' --class fedora --class gnu-linux --class gnu --class os {
+ set menu_color_highlight=black/light-cyan
+ set menu_color_normal=white/black
+ set color_normal=white/black
+
+ menuentry 'Install Fedora Linux (No KS)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-aarch64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os ip=dhcp
+ initrdefi fedora-aarch64/initrd.img
+ }
+
+ menuentry 'Install Fedora Linux' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-aarch64/vmlinuz inst.repo=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os ip=dhcp
+ initrdefi fedora-aarch64/initrd.img
+ }
+
+ menuentry 'Fedora Linux (Rescue Mode)' --class fedora --class gnu-linux --class gnu --class os {
+ linuxefi fedora-aarch64/vmlinuz inst.rescue inst.stage2=http://dl.fedoraproject.org/pub/fedora/linux/releases/39/Everything/aarch64/os
+ initrdefi fedora-aarch64/initrd.img
+ }
+ }
+}
+
This write up provides steps on the System Administrator experience. +This is not an end-all, be-all, and has many variables to keep in mind. +But can provide a baseline for you.
+Please keep in mind, this is for Red Hat based distributions, mainly +Enterprise Linux 8 and 9. CentOS Stream works within reason.
+Also note that it will be recommended that you do things in ansible. The +RHCE for RHEL 9 will require you to be able to use ansible. As such, we +will be focusing on RHEL 9.
+Note
+Software Replacements
+Note
+General Notes
+~/.vimrc
with syntax on
~/.vimrc
with set background=dark
~/.bash_profile
with export EDITOR=vim
Note
+Hardware Requirements
+Please consider on building an actual lab machine that you can do this +on.
+Certification guidelines will be updated later.
+Note
+Post Experience Notes
+While this write up uses KVM exclusively, you may want to enhance your +learning after the fact by setting up another virtualization platform +on your virtual host. It may require you to redesign everything or +even start over, but it is something you can consider which you like +best overall.
+Date | +Changes | +
---|---|
January 07, 2024 | +Restructure with markdown | +
We'll now begin the system administrator experience. We will provide +from beginning to end, what to do, without giving away what has to be +done or has to be configured. This is on you to perform. At the end, +there is a "wiki" that you create where you will have a chance to +document everything you did. I recommend writing down or putting in a +word document what you are doing or have done throughout so it'll make +your wiki documentation much, much better.
+Now you'll need to setup a KVM Hypervisor. You can do this on Fedora +39+ or Enterprise Linux 9. Because EL9 is a stable platform for libvirt, +I recommend using going that route. If you want the latest features for +the cost of some stability, Fedora will work for you.
+You may want to make sure your hardware supports virtualization.
+egrep --color 'vmx|svm' /proc/cpuinfo
+
Create multiple datastores (storage pools where the VM images will + sit)
+Attempt to use LVM as the backing for the store.
+Destroy the "built in" network that libvirt already provides and + make your own
+Most of your commands will be from the following:
+To get the most performance out of your VM's disk wise, consider + these options:
+You'll need to setup a DHCP and DNS server. You have a few choices.
+It would be sensible to do "1", if you do "2", you at least get more +exposure to how zone files are created and the like. For ease of use, +we recommend choosing option 1.
+Also, it is possible to allow cobbler handle DHCP and DNS or integrate +directly into DNS such as making changes, but this is outside the scope +of this write up.
+Warning
+Do NOT run DHCP from the FreeIPA replicas. The FreeIPA servers should +have STATIC addresses set.
+Note
+When you are setting up DHCP and DNS on separate servers (such as +FreeIPA replicas), the DHCP server needs to be configured to tell all +the clients the true gateway (this is either a VM in on KVM or a +hypervisor of your choice if you are doing straight KVM) and the DNS servers.
+Setup a VM or your hypervisor as the gateway to the internet.
+When setting up DHCP and DNS:
+From this point forward, you are to ensure each of your VM's that you +create have DNS entries. If you have Dynamic DNS running, you will NOT +need to do any manual changes. If using FreeIPA, you may not need to +make these changes. You can use nsupdate or the ipa equivalent to add +additional entries as needed if you are implementing static A records or +CNAME records.
+At this point, you'll need to setup Foreman/Katello, Pulp, or Uyuni on +a VM. I recommend using Pulp if you want something smaller and simpler. +If you want something close to Red Hat Satellite, go through +katello. It is a combination of pulp, candlepin, foreman. This +recommendation is primarily because of Satellite 6 existing in a large +amount of Red Hat shops.
+Katello, go here.
+Note
+Heads up
+Kickstart examples can be found at my +github.
+Next you will need to connect your Content Management to your +hypervisor. View their documentation to get an idea of how it works.
+You will need to spin up two EL8 or EL9 VM's via Katello or PXE. Do not spin +them up using virt-install, virt-manager, or anything else. This will require +you to connect Katello to the hypervisor. Ensure they are registered +properly to your content management server.
+If you find the clients aren't registering on Katello, click +here.
+If you find that you do not want to use Katello to perform this task, +then you can setup cobbler and work it out from there. I currently do +not have a tutorial for this, but there is plenty of documentation +online. There are also ansible playbooks you could look at for +examples if you wanted to go that route, but it may be time consuming +and something to setup at the very end.
+Setup FreeIPA with two replicas, using CA and DNS built in +configuration. This is recommended if you do not want to setup BIND by +hand. FreeIPA also provides authentication to your systems without +having to go through the hassle of setting up OpenLDAP by hand nor +having Windows AD.
+I recommend against setting up OpenLDAP for the case of UNIX +authentication. For anything else, go for it.
+Once FreeIPA is available, all systems should be using FreeIPA as your +DNS servers and they should all be enrolled to your domain.
+Create two new VM's from your Content Management or PXE system that are +EL9 and install the default postgresql on them.
+Attempt to install and configure pgpool-II for master-master +replication. Note that this may not be default in Enterprise Linux and +you can safely skip this.
+While Katello has some form of ansible built in, it may be +better to create a solitary configuration management VM and hook it in. +Spin up a VM that is EL9 and install a master for configuration +management.
+It is HIGHLY recommended that you use ansible. Ansible is the supported +and recommended system by Red Hat and is utilized in the certification +exams for EL9. At some point, you could spin up a docker container for +AWX if you wanted, but this is not a strict requirement.
+This VM should be EL9. Ensure it has an extra 20GB disk attached to it. +Install the following:
+You are to:
+Bacula is a backup service. It is actually confusing to setup. It's not +easy. There are plenty of write-ups for bacula and RHEL/Enterprise Linux. +The digital ocean write-ups are complete, but do NOT give you everything +you need to know to do it "correct" or to succeed completing this portion.
+Your server will need the following:
+This is a typical "web/app" configuration. Some shops use apache +frontends to weblogic backends. Sometimes it's tomcat backends. Some +shops opt for other methods and software too.
+If wish to setup Wildfly and host a wiki, you will need to do the +following:
+If you wish to setup a Git
+This will be considered a "VIP" of sorts for your wiki and other +applications. This VM can either use iptables round-robin or HAProxy. I +highly recommend trying both to see what's easier for you. HAProxy is +recommended, because it's an actual load balancer application.
+You will need the following:
+Warning
+Dynamic DNS
+If you are using Dynamic DNS, you may need to run rndc sync before +making changes in the case of standalone BIND. You will want to use the +nsupdate command to make changes to your Dynamic Zones. If you are using +FreeIPA DNS this is not required.
+You will need to do the following:
+Create a CNAME for "mailhost.domain.tld" for your load balancer, + forwarding port 25 to both servers
+This will be a monitoring server on EL9. You will need to set it up to +use snmp to monitor the communication state of every service above. This +means:
+If you are planning to use full on SNMP, all servers will need the +appropriate SNMP ports open and they will need the snmpd clients +installed (with a monitor snmpd account)
+Setup this server as a syslog server. It can be EL8 or higher. Ensure +that it is listening on port 514 UDP and TCP in the configuration and +that those ports are open.
+You will need to go to your servers and setup /etc/rsyslog.conf to send +ALL logs to this syslog server
+Optionally, setup an all inclusive logging solution, like graylog, +elastic search, mongodb, fluentd. The sky is the limit here!
+On your new wiki, document everything you did, right now, on your new +wiki.
+For fun, you can setup a new server that is your designated RPM building +machine. You will need to install mock to do this. Optionally, you +can setup koji, bodhi, the things that the Fedora project uses. This is +not for the faint of heart.
+Also for fun, you can setup a git server. There are many options out +there. A popular opensource one is Gitea.
+Consider setting up ansible and the open source tower. Automate +everything via ansible.
% yum install unbound -y
+% systemctl enable unbound
+
Setting up DoT with unbound is straight forward, whether you already have a DNS server already or not. Let's go over the most basic configuration.
+% vi /etc/unbound/unbound.conf
+server:
+ . . .
+ # Set the below to an IP address if you wish - as I have multiple VLAN's
+ # it is just easier for me to listen everywhere
+ interface: 0.0.0.0
+ interface: ::
+ # Optionally set a port - I have bind already running, so port 9053 works
+ interface-automatic: no
+ port: 9053
+ . . .
+ # Set access control rules here. I'll show a few examples with just two of
+ # my networks
+ # REFUSE everything
+ access-control: 0.0.0.0/0 refuse
+ access-control: ::0/0 refuse
+ # Allow localhost to snoop
+ access-control: 127.0.0.1/32 allow_snoop
+ access-control: ::1 allow_snoop
+ # Allow the entire localhost subnet
+ access-control: 127.0.0.0/8 allow
+ access-control: ::ffff:127.0.0.1 allow
+ # Allow my main network and sandbox network
+ access-control: 10.100.0.0/24 allow
+ access-control: 10.100.1.0/24 allow
+ . . .
+ # Ensure tls-cert-bundle is set
+ tls-cert-bundle: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
+ . . .
+# Create the forward zone for DoT queries
+forward-zone:
+ name: "."
+ forward-tls-upstream: yes
+ # Cloudflare
+ forward-addr: 1.1.1.1@853#cloudflare-dns.com
+ forward-addr: 1.0.0.1@853#cloudflare-dns.com
+ forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
+ forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
+ # Quad9
+ forward-addr: 9.9.9.9@853#dns.quad9.net
+ forward-addr: 149.112.112.112@853#dns.quad9.net
+
+% systemctl enable unbound --now
+# If you are using bind already with forwarders, you should edit it. Example.
+% vi /etc/named.conf
+options {
+ . . .
+ forwarders {
+ # This assumes your bind server and unbound server are on
+ # the same server like I did.
+ 127.0.0.1 port 9053;
+ };
+ forward only;
+ . . .
+
The source code for this page can be found on github. This page contains tutorials and generally useful information regarding packages and system administration in Fedora and Enterprise Linux (Rocky Linux, CentOS Stream).
+Here are some quick links to solid documentation:
+ +Due to the number of articles out there about disabling SELinux, we felt this note was important.
+Disabling SELinux is and almost always will be a terrible idea. See our antipatterns page as well as the Red Hat Enterprise Linux documentation, Fedora Docs, and Rocky Linux documentation.
' + escapeHtml(summary) +'
' + noResultsText + '
'); + } +} + +function doSearch () { + var query = document.getElementById('mkdocs-search-query').value; + if (query.length > min_search_length) { + if (!window.Worker) { + displayResults(search(query)); + } else { + searchWorker.postMessage({query: query}); + } + } else { + // Clear results for short queries + displayResults([]); + } +} + +function initSearch () { + var search_input = document.getElementById('mkdocs-search-query'); + if (search_input) { + search_input.addEventListener("keyup", doSearch); + } + var term = getSearchTermFromLocation(); + if (term) { + search_input.value = term; + doSearch(); + } +} + +function onWorkerMessage (e) { + if (e.data.allowSearch) { + initSearch(); + } else if (e.data.results) { + var results = e.data.results; + displayResults(results); + } else if (e.data.config) { + min_search_length = e.data.config.min_search_length-1; + } +} + +if (!window.Worker) { + console.log('Web Worker API not supported'); + // load index in main thread + $.getScript(joinUrl(base_url, "search/worker.js")).done(function () { + console.log('Loaded worker'); + init(); + window.postMessage = function (msg) { + onWorkerMessage({data: msg}); + }; + }).fail(function (jqxhr, settings, exception) { + console.error('Could not load worker.js'); + }); +} else { + // Wrap search in a web worker + var searchWorker = new Worker(joinUrl(base_url, "search/worker.js")); + searchWorker.postMessage({init: true}); + searchWorker.onmessage = onWorkerMessage; +} diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000..ebf1d438 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"The source code for this page can be found on github . This page contains tutorials and generally useful information regarding packages and system administration in Fedora and Enterprise Linux (Rocky Linux, CentOS Stream). Quick Links \u00b6 Here are some quick links to solid documentation: Fedora Quick Docs Fedora Latest Release Docs Notes \u00b6 Due to the number of articles out there about disabling SELinux, we felt this note was important. Disabling SELinux is and almost always will be a terrible idea. See our antipatterns page as well as the Red Hat Enterprise Linux documentation, Fedora Docs, and Rocky Linux documentation.","title":"Linux Guide and Hints"},{"location":"#quick-links","text":"Here are some quick links to solid documentation: Fedora Quick Docs Fedora Latest Release Docs","title":"Quick Links"},{"location":"#notes","text":"Due to the number of articles out there about disabling SELinux, we felt this note was important. Disabling SELinux is and almost always will be a terrible idea. See our antipatterns page as well as the Red Hat Enterprise Linux documentation, Fedora Docs, and Rocky Linux documentation.","title":"Notes"},{"location":"archive/","text":"This section is for archives. Most of these pages were created by one of our late contributors and have not been updated since his passing. As such, we have moved most of them here as clean up.","title":"Archives"},{"location":"el/","text":"This section contains various articles on setups for Enterprise Linux and Fedora systems.","title":"Enterprise Linux"},{"location":"el/builds/","text":"This page goes over various ways that installs can be automated without the use of PXE. Instead, we can use templated scripts with pre-configured commands, boot images, and mirrors for builds. We cover the following here: CentOS Stream 9 Enterprise Linux 8, 9 Fedora openSUSE 15+ Windows Server","title":"Auto-Provisioning"},{"location":"el/freeipa/","text":"This page is a series of notes and information that goes over how to install and configure FreeIPA on Enterprise Linux 8/9 servers with replicas, as well as configuring client machines to connect and utilize FreeIPA resources, policies (eg sudo), and host based access control methods. We will also go over a scenario of configuring a trust with an Active Directory domain. The client setup will work for Fedora users as the packages are the same, just newer versions. Overview \u00b6 FreeIPA is an integrated security information management system combining Linux, a Directory Server (389), Kerberos, NTP, DNS, DogTag. It's a system that can be loosely compared to Active Directory in what it attempts to solve for Linux and UNIX clients and even mixed environments. While it is not an active directory, it is an integrated Identity and Authentication solution for Linux/UNIX environments, which means it does not support Windows clients. One problem that FreeIPA attempts to solve is giving back control to the Linux/UNIX administration teams of access, authentication, and authorization rather than trying to integrate directly into Active Directory, where the controls do not work the same or do not work at all. And because of this, no third party software is required to be installed. Requirements \u00b6 Here are the list of requirements below. Enterprise Linux 8+ or Fedora Linux An active internet connection to install the packages required or available internal mirrors 2 core, 4GB system with at least 10GB+ disk for /var/lib/dirsrv DNS domain delegation (if a DNS appliance or server already exists) Tutorial Preface, Notes, and Recommendations \u00b6 Potential Pitfalls! Leave SELinux enabled at all times. You will not run into SELinux issues FreeIPA runs better when it controls the DNS domain that it is given - It is recommended DNS is delegated or that FreeIPA run DNS entirely FreeIPA does not run DHCP. ISC DHCP can be configured to do dynamic DNS updates to FreeIPA or hosts can be configured to perform dynamic DNS updates Recommended Information Keep selinux set to enforcing DNS - You must be careful when using DNS. Here are recommendations. 1 Recommendation 1: FreeIPA runs your entire DNS for your network - This requires the DHCP servers to set the DNS servers to the IPA servers. This will be useful in the case that your clients will have their SSH keys added as SSHFP records to DNS when enrolled as clients. This also gives you the added benefit of a client updating its own DNS entries (A and PTR records) if the client is DHCP enabled and the IP changes if you so choose. Recommendation 2: FreeIPA is delegated a subdomain of a domain used already in the network - It's not required for hosts to live in the subdomain to be a member of the IPA domain, but you will lose out on kerberos SSO. Do not try to hijack a domain. Consider setting up a trust with Active Directory if you are in a mixed environment, eg Active Directory already exists - winsync is available, but deprecated and not recommended. IPA servers should have static assigned addresses - Configured via nmcli or directly in /etc/sysconfig/network-scripts/ifcfg-* Try to avoid running FreeIPA without DNS - while possible, you are creating higher maintenance Trust Information If you are in a mixed environment (both Windows and Linux/UNIX), it is recommended to setup a trust between FreeIPA and Active Directory. Because of this, they will need to be in different domains (eg, example.com and ipa.example.com, or example.com and example.net). This way, you do not have to create duplicate users if a windows user logs into Linux resources nor use winsync. DNS \u00b6 As noted in the previous section, you must try not to hijack a domain. You can migrate records over to FreeIPA's DNS if you'd like, but care must be taken with that approach. While FreeIPA can do the typical DNS server work such as forward/reverse zones and various types of records, it should not be considered a full solution. It does not support views (eg, you can't have internal and external views, assuming you have domains that are publically facing). In the event you need to have views, that's when you need a different DNS server or service to provide this to you. There are two ways you can have DNS entries updated dynamically: --enable-dns-updates for ipa-client-install and DHCP dynamic DNS updates. Both are sufficient. The latter requires additional work and is outside the scope of this write up. Delegation \u00b6 Throughout this guide, you may find or see examples of domain delegation where there is an AD trust, as it would be a more real world example of bringing in FreeIPA to an environment that is already in place, working, with a DNS hosted by AD or by an appliance. Majority of the examples assume both IPA and AD is delegated (when it's normally IPA that's just delegated while AD hosts the actual parent zone). Using this type of setup, it is not required for clients to have entries in the IPA domain. In fact, they can be in other domains as long as they have A/AAAA/PTR records associated with them. This assumes that there could be dynamic dns associated with DHCP or everything is static and lives in the parent zones. The caveat to this is SSO will fail . You can setup already existing DNS servers to delegate an entire domain or a subdomain for FreeIPA. This way, you don't overlap with a domain that's already in use. So for example, if AD owns example.com, you could have AD delegate ipa.example.com or even forward example.net. If AD is not the DNS provider for the environment, you can have the appliance delegate the domain in the same manner. Below is a bind example of what example.com would look like when delegating the IPA domain: $ORIGIN example.com. @ IN SOA ... ( ) NS np-ad01 NS np-ad02 np-ad01 A 10.200.0.232 np-ad02 A 10.200.0.233 ; Many other records here, pertaining to AD, eg msdcs and SRV records ; IPA records $ORIGIN ipa.example.com. @ NS np-ipa01 NS np-ipa02 np-ipa01 A 10.200.0.230 np-ipa02 A 10.200.0.231 Note that AD can send nsupdates to a DNS server if given the permissions. As of this writing, FreeIPA does not do this, which is why DNS delegation is recommended. Server Setup \u00b6 Required Packages \u00b6 ipa-server ipa-client (required as an IPA server is technically a client of the domain) ipa-server-dns (required for using the internal DNS) sssd/sssd-ipa (pulled in as dependencies) Optional Packages \u00b6 ipa-server-trust-ad if using an AD trust Installation \u00b6 To install the server, make sure the hostname is set to the A records and NS delegations you've put in DNS (which won't respond to a DNS lookup). If these are stand-alone, then you can just keep it at the top level (eg, example.com). You'll also need to modify /etc/hosts, set static IP addresses, and then run the ipa-server-install command. % hostnamectl set-hostname server1.ipa.example.com % nmcli con mod ens192 ipv4.address 10.200.0.230/24 % nmcli con mod ens192 ipv4.gateway 10.200.0.1 % nmcli con mod ens192 ipv4.method manual % nmcli con up ens192 % vi /etc/hosts . . . 10.200.0.230 server1.ipa.example.com 10.200.0.231 server2.ipa.example.com # Fedora % dnf install freeipa-server{,-common,-dns,-trust-ad} -y # Enterprise Linux 8 % dnf module enable idm:DL1/{dns,adtrust,client,server,common} % dnf install ipa-server ipa-server-dns ipa-client sssd sssd-ipa -y # Enterprise Linux 9 (there appears to be no modules) % dnf install ipa-server ipa-server-dns ipa-client sssd sssd-ipa -y # Setup # Enterprise 8 / 9 % firewall-cmd --permanent --add-service={freeipa-4,ntp,dns,freeipa-trust} % firewall-cmd --complete-reload % ipa-server-install \\ --no_hbac_allow \\ <-- If you want to have HBAC allow_all disabled initially --no-ntp \\ <-- If you want to host NTP from IPA, take off --no-ntp --setup-dns \\ --realm IPA.EXAMPLE.COM \\ --domain example.com . . . (show steps here) While not officially recommended, you could have two accounts. One for administration of servers and the domain and one for your workstation, similar to separating domain users and domain administrators in active directory. You don't have to follow this, but at least there's a form of separation. % kinit admin % ipa user-add --first=First --last=Last --cn=\"First Last Admin\" --gecos=\"First Last Admin\" flast2 % ipa group-add-member --users=flast2 admins Replica \u00b6 On the replica, ensure you repeat the same steps as above. % hostnamectl set-hostname server2.ipa.example.com % nmcli con mod ens192 ipv4.address 10.200.0.231/24 % nmcli con mod ens192 ipv4.gateway 10.200.0.1 % nmcli con mod ens192 ipv4.method manual % nmcli con up ens192 % vi /etc/hosts . . . 10.200.0.230 server1.ipa.example.com 10.200.0.231 server2.ipa.example.com % dnf install ipa-server ipa-server-dns ipa-client sssd sssd-ipa -y # Enterprise 8 / 9 % firewall-cmd --permanent --add-service={freeipa-4,ntp,dns,freeipa-trust} % firewall-cmd --complete-reload % ipa-replica-install --no-forwarders --setup-ca --setup-dns --no-ntp --principal admin --admin-password \"ChangePass123\" --domain ipa.example.com . . . (show steps) You should now be able to see your replicas. % ipa-replica-manage list server1.ipa.example.com: master server2.ipa.example.com: master Replica Automation \u00b6 It is possible to automate the replica installation. To automate the replica installation, the following requirements would need to be met: Server must be added as a client (ipa-client-install) with an IP address on the commandline Server must be added to the ipaservers host group ipa-replica-install ran without principal and passwords Once you have a server added as a client and then added to the ipaservers host group, you would run a command like this: % ipa-replica-install --ssh-trust-dns --unattended --setup-ca --mkhomedir --setup-dns --no-forwarders If you have forwarders, use the --forwarders option instead. Server Migration/Upgrade \u00b6 Performing a migration is a multi-step process. Typically you are going from one major version of Enterprise Linux (such as 7 or 8) to another (such as 9). Regardless of which version you are migrating from, the typical beginning steps are: System's time is verified for time synchronization like using ntpstat or equivalent Server roles are verified in the current environment using ipa server-role-find --status enabled --server ipa.example.com New system is installed and enrolled as a client New system is added as a replica with required server roles EL7 to EL9 / Two Major Version Jumps When jumping from EL7 to EL9 or two major versions in general, it is recommended that you have an \"in between\" machine. This means that you need to add the in between version first and then you can add the latest version. See this page for an example. The below is in the case of a single master installation and doesn't take into account of multiple version jumps. Let's say you have two old Enterprise Linux replicas instead. There are two approaches you can take: Install a new Enterprise Linux system, add it, reinstall old system to the new version, add it back. Install two new Enterprise Linux systems, add them as needed, power off old systems. Below is an example, with X being the old version, and Y being the new. Enterprise Linux Y system is installed and enrolled as a client Enterprise Linux Y system is added as a replica Change CRL to Enterprise Linux Y system and adjust settings on Enterprise Linux X CA master and new Enterprise Linux Y replica for pki-tomcatd and httpd Test user is created to ensure DNA range is adjusted Verify DNA range Stop first Enterprise Linux X IPA services, remove replica, uninstall, power off. Second Enterprise Linux Y system is installed and enrolled as a client Second Enterprise Linux Y system is added as a replica Test user is created again to ensure DNA range is adjusted Verify DNA range Stop second Enterprise Linux X IPA services, remove replica, uninstall, power off. EL7 to EL8 \u00b6 # Enterprise Linux 8 % dnf module enable idm:DL1 # Install necessary packages, ie AD trust packages if you need them % dnf install ipa-server ipa-server-dns -y % ipa-client-install --realm EXAMPLE.COM --domain example.com % kinit admin # Add other switches that you feel are necessary, such as forwarders, kra, ntp... % ipa-replica-install --setup-dns --setup-ca --ssh-trust-dns --mkhomedir # Verify all services are in a RUNNING state % ipactl status Directory Service: RUNNING . . . % ipa-csreplica-manage list elX.example.com: master elY.example.com: master % ipa-csreplica-manage list --verbose elY.example.com Directory Manager password: elX.example.com last init status: None last init ended: 1970-01-01 00:00:00+00:00 last update status: Error (0) Replica acquired successfully: Incremental update succeeded last update ended: 2019-11-07 22:46:15+00:00 Change CRL to new Enterprise Linux system and adjust settings on both replicas for pki-tomcatd and httpd # Change CA master to elY % ipa config-mod --ca-renewal-master-server elY.example.com # Shut down all CRL generation on ELX elX% ipa-crlgen-manage status CRL generation: enabled . . . elX% ipa-crlgen-manage disable Stopping pki-tomcatd Editing /var/lib/pki/pki-tomcat/conf/ca/CS.cfg Starting pki-tomcatd Editing /etc/httpd/conf.d/ipa-pki-proxy.conf Restarting httpd CRL generation disabled on the local host. Please make sure to configure CRL generation on another master with ipa-crlgen-manage enable. The ipa-crlgen-manage command was successful # Verify that the /etc/httpd/conf.d/ipa-pki-proxy.conf file's RewriteRule is not commented # If it is, remove the comment and restart httpd. ipa-crlgen-manage should take care of this. % tail -n 1 /etc/httpd/conf.d/ipa-pki-proxy.conf RewriteRule ^/ipa/crl/MasterCRL.bin https://elX.example.com/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL [L,R=301,NC] # Turn it on with ELY elY% systemctl stop pki-tomcatd@pki-tomcat.service # The values should be changed from false to true elY% vi /etc/pki/pki-tomcat/ca/CS.cfg ca.crl.MasterCRL.enableCRLCache=true ca.crl.MasterCRL.enableCRLUpdates=true elY% systemctl start pki-tomcatd@pki-tomcat.service # Make sure the rewrite rule has a comment on elY elY% vi /etc/httpd/conf.d/ipa-pki-proxy.conf . . . #RewriteRule ^/ipa/crl/MasterCRL.bin https://elY.example.com/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL [L,R=301,NC] elY% systemctl restart httpd Test user is created to ensure DNA range is adjusted and replication is working % ipa user-add --first=testing --last=user testinguser1 # Test on both systems elX% ipa user-find testinguser1 elY% ipa user-find testinguser1 Verify DNA range # There should be ranges for both replicas % ipa-replica-manage dnarange-show elX.example.com: ... elY.example.com: ... Stop old Enterprise Linux IPA services, remove replica, uninstall # Stop all elX services elX% ipactl stop # Delete the elX system from the topology elY% ipa server-del elX.example.com # Uninstall and/or power down system elX% ipa-server-install --uninstall elX% init 0 EL8 to EL9 \u00b6 # Enterprise Linux 9 % dnf install ipa-server ipa-server-dns -y % ipa-client-install --realm EXAMPLE.COM --domain example.com % kinit admin # Add other switches that you feel are necessary, such as forwarders, kra, ntp... % ipa-replica-install --setup-dns --setup-ca --ssh-trust-dns --mkhomedir # Verify all services are in a RUNNING state % ipactl status Directory Service: RUNNING . . . % ipa-csreplica-manage list elX.example.com: master elY.example.com: master % ipa-csreplica-manage list --verbose elY.example.com Directory Manager password: elX.example.com last init status: None last init ended: 1970-01-01 00:00:00+00:00 last update status: Error (0) Replica acquired successfully: Incremental update succeeded last update ended: 2022-08-12 18:11:11+00:00 Set the CA renewal master to the new system and change the CRL settings % ipa config-mod --ca-renewal-master-server elY.example.com # Remove the ca.certStatusUpdateInterval entry or set it to 600 (default) on elY elY% vim /etc/pki/pki-tomcat/ca/CS.cfg # Restart the ipa services elY% ipactl restart # Set the value of ca.certStatusUpdateInterval on elX to 0 elX% vim /etc/pki/pki-tomcat/ca/CS.cfg ca.certStatusUpdateInterval=0 elX% ipactl restart elX% ipa-crlgen-manage status CRL generation: enabled . . . elX% ipa-crlgen-manage disable Stopping pki-tomcatd Editing /var/lib/pki/pki-tomcat/conf/ca/CS.cfg Starting pki-tomcatd Editing /etc/httpd/conf.d/ipa-pki-proxy.conf Restarting httpd CRL generation disabled on the local host. Please make sure to configure CRL generation on another master with ipa-crlgen-manage enable. The ipa-crlgen-manage command was successful elX% ipa-crlgen-manage status CRL generation: disabled Create a test user to ensure DNA range is adjusted and replication is working elY% ipa user-add --first=testing --last=user testinguser1 # Test on both systems elX% ipa user-find testinguser1 elY% ipa user-find testinguser1 Verify DNA range. # There should be ranges for both replicas % ipa-replica-manage dnarange-show elX.example.com: ... elY.example.com: ... Stop old Enterprise Linux IPA services, remove replica, uninstall. # Stop all elX services elX% ipactl stop # Delete the elX system from the topology elY% ipa server-del elX.example.com # Uninstall and/or power down system elX% ipa-server-install --uninstall elX% init 0 See this page for more information. Active Directory Trust \u00b6 To initiate a trust with your active directory domain, ensure the following requirements are met. Requirements Package installed: ipa-server-trust-ad DNS: Properly configured that FreeIPA can resolve the AD servers A and SRV records This can either be forwarders to AD, a subdomain that IPA manages, or delegated subdomain from the master DNS servers in your network. This is completely dependent on your infrastructure. DNS: AD forest has sites and SRV records, including priorities, are set correctly When the following requirements are met, you have two choices before continuning. You can either use POSIX or have the id range generated automatically. POSIX vs Non-POSIX If you decide to use POSIX, your AD users are expected to have uidNumber, gidNumber, loginShell, unixHomeDirectory set. Else, you will need to setup ID overrides if you already have that information for current users (assuming this is not a new setup for the environment, ie you already have UID's for people). If you are not planning a migration from pure AD over to IPA with a trust, it is recommended to note that information so you can setup the ID overrides. Afterwards, any new users will get UID/GID's that you will not have to manage yourself. You will need to prep your master(s) for the trust. We will be enabling compat, adding sids, and adding agents so both masters can provide AD information. % ipa-adtrust-install --add-sids --add-agents --enable-compat This will do what we need. If you do not have legacy clients (Enterprise Linux 5, Solaris, HP-UX, AIX, SLES 11.4, FreeBSD, the list goes on), then you do not need to enable compat mode. Though, it could be useful to have it for certain apps or scenarios. You will now need to open the necessary ports. Do this on all masters. Ports TCP: 135, 138, 139, 389, 445, 1024-1300, 3268 UDP: 138, 139, 389, 445 % firewall-cmd --add-service=freeipa-trust --permanent % firewall-cmd --complete-reload Now you can initiate the trust. The admin account you use should be part of the domain admins group or at least have permissions to initiate a trust. The former is path of least resistance. # If you are using POSIX ID, use ipa-ad-trust-posix. % ipa trust-add --type=ad example.com --range-type=ipa-ad-trust --admin adminaccount --password Once the trust is up, verify it. % ipa trust-show example.com Realm name: example.com Domain NetBIOS name: AD Domain Security Identifier: S-X-X-XX-XXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX Trust direction: Trusting forest Trust type: Active Directory domain UPN suffixes: example.com You should be able to test for the users now. % id aduser1@example.com uid=XXXXX(aduser1@example.com) gid=XXXXX(aduser1@example.com) groups=XXXXX(aduser1@example.com) Disable Anonymous Bind \u00b6 In some cases, it is a requirement to disable all anonymous binds. If this is the case, you will need to modify cn=config on each master as it is not replicated. rootdse Some applications do anonymous binds to the directory server to determine its version and it supported controls. While it is possible to disable anonymous binds completely, it is important to know that if you disable the rootdse binds, applications that do anonymous lookups to get server information will fail. % ldapmodify -xZZ -D \"cn=Directory Manager\" -W -h server.ipa.example.com Enter LDAP Password: dn: cn=config changetype: modify replace: nsslapd-allow-anonymous-access nsslapd-allow-anonymous-access: rootdse modifying entry \"cn=config\" Client Setup \u00b6 Enterprise Linux & Fedora \u00b6 Ensure your /etc/resolv.conf (or other dns settings) are set correctly. Ensure your hostname is also set correctly. % dnf install ipa-client -y % ipa-client-install --realm EXAMPLE.COM --domain example.com --mkhomedir Mac Clients \u00b6 MacOS Clients are an interesting workstation to setup as a FreeIPA client. It takes a little bit of fighting and troubleshooting, but it can work with the right settings. Note that as of Catalina, you may not be able to login to your account nor will creating a mobile account function as you would expect. This may have changed in recent macos releases, so YMMV. Other Guides There are a couple of guides out there that you may have found before (if you looked) that help setup IPA for Mac. There's one for much older (I think Lion) and one for Sierra. This section was made mostly for my own reference because I found some things in both of those guides didn't address issues I ran into one way or another and couldn't find any information on. The FreeIPA users mail list didn't have any archives with people having similar issues. If you are interested in the other guides to compare to, you may see them here (recent) and here (older) AD Users AD Users You cannot login as AD users on a Mac when going through FreeIPA. You can, in theory, point to the cn=compat tree and set the attribute mapping to rfc2307. In my tests, I have never been able to get this to work. This section, I am going to assume you are going to be logging in as a user in IPA. If you are in a mixed environment, add your Mac to your AD domain instead. Anonymous Bind There may be cases where if you have disabled anonymous binds in IPA, this setup may not work, even if you do use a bind account. You will need to experiment with this if you plan on using a bind account and plan on or currently have IPA not allowing anonymous binds. Check your system's hostname. You want to make sure it has a hostname defined for it in the domain the mac sits in, even if it's dynamic via DHCP/DNS. % sudo scutil --set HostName mac.example.com Get the IPA certificate. You'll need to double click it after you get it and import it. % cd ~/Desktop && curl -OL http://server1.ipa.example.com/ipa/config/ca.crt % sudo mkdir /etc/ipa % sudo cp ca.crt /etc/ipa/ca.crt % sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /etc/ipa/ca.crt On the IPA server, you will need to create a host and get the keytab. % ipa host-add mac.example.com --macaddress=\"00:00:00:00:00:00\" % ipa-getkeytab -s server1.ipa.example.com -p host/mac.example.com -k /tmp/krb5.keytab You will need to transfer that keytab to your mac. % cd ~ % scp user@server1.ipa.example.com:/tmp/krb5.keytab . % sudo mv krb5.keytab /etc/krb5.keytab % sudo chmod 600 /etc/krb5.keytab % sudo chown root:wheel /etc/krb5.keytab Configure /etc/krb5.conf [domain_realm] .ipa.example.com = IPA.EXAMPLE.COM ipa.example.com = IPA.EXAMPLE.COM [libdefaults] default_realm = IPA.EXAMPLE.COM allow_weak_crypto = yes dns_lookup_realm = true dns_lookup_kdc = true rdns = false ticket_lifetime = 24h forwardable = yes renewable = true [realms] IPA.EXAMPLE.COM = { # You don't need to set these when your DNS is setup correctly, but it doesn't hurt to have a reference. # In my opinion, you shouldn't hardcode these values. You have to have a good reason to. #kdc = tcp/server1.ipa.example.com #kdc = tcp/server2.ipa.example.com #admin_server = tcp/server1.ipa.example.com #admin_server = tcp/server2.ipa.example.com pkinit_anchors = FILE:/etc/ipa/ca.crt } You'll want to do a kinit to verify. If it works, you should be able to go to the FreeIPA webui and check that the host is \"enrolled\" (Identity -> Hosts). % kinit username@IPA.EXAMPLE.COM You need to modify a couple of pam files. I'll explain why they need to be changed. % sudo vi /etc/pam.d/authorization # authorization: auth account # Putting krb5 here twice ensures that you can login via kerberos and also get a keytab # If \"no_ccache\" is here, keytabs will not be available on login auth optional pam_krb5.so use_first_pass use_kcminit default_principal auth sufficient pam_krb5.so use_first_pass default_principal auth required pam_opendirectory.so use_first_pass nullok account required pam_opendirectory.so % sudo vi /etc/pam.d/screensaver # The krb5 changes do similar to the authorization when on the lock screen after a sleep #auth optional pam_krb5.so use_first_pass use_kcminit auth optional pam_krb5.so use_first_pass use_kcminit default_principal auth sufficient pam_krb5.so use_first_pass default_principal auth required pam_opendirectory.so use_first_pass nullok account required pam_opendirectory.so account sufficient pam_self.so account required pam_group.so no_warn group=admin,wheel fail_safe account required pam_group.so no_warn deny group=admin,wheel ruser fail_safe % sudo vi /etc/pam.d/passwd # Helps with kerberos logins password sufficient pam_krb5.so auth required pam_permit.so account required pam_opendirectory.so password required pam_opendirectory.so session required pam_permit.so After these changes, you'll need to go into make some changes with the directory utility. This depends on your macOS version. Monterey and older \u00b6 Go to system preferences -> users & groups -> login options - Click the 'lock' to make changes Set the following: Automatic login: Off Display login window as: Name and Password Show fast user switching menu as: Full Name Click \"Join\" next to \"Network Account Server\" Enter one of your IPA servers (you can duplicate it later for backup purposes) and click Continue. Ensure \"Allow network users to log in at login window\" is checked - Make sure it's set to all users Click \"edit\" next to the \"Network Account Server\" Click \"Open Directory Utility\" Click the lock, edit LDAPv3 Select your server and click \"edit\" Set the following options: Open/close times out in 5 seconds Query times out in 5 seconds Connection idles out in 1 minute (this can't be changed) Encrypt using SSL (selected) Click \"Search & Mappings\" You may either select \"rfc2307\" from the dropdown or select custom. It will ask your base DN (eg, dc=ipa,dc=example,dc=com) If you select rfc2307, it will ask for your base DN (eg, dc=ipa,dc=example,dc=com) If you select \"custom\", you will need to do this manually for each record type. You're better off using rfc2307 and working from there Click the \"+\" to add a groups record type or scroll and find \"groups\". Select \"groups\", and ensure the following object classes exist. You can click the \"+\" to add them when needed. Record Type ObjectClasses Groups posixGroup ipausergroup groupOfNames\\* Note \"groupOfNames\" is optional here, because it seems that the directory utility doesn't understand this concept. Expand \"groups\" and ensure the following for each record type. You can click the \"+\" to add the attribute types as needed. Attribute Mapping PrimaryGroupID gidNumber RecordName cn Click the \"+\" to add a users record type or scroll and find \"users\". Select \"users\" and ensure the following object classes exist. You can click the \"+\" to add them when needed. Record Type ObjectClasses Users inetOrgPerson posixAccount shadowAccount apple-user Expand \"users\" and ensure the following for each record type. You can click the \"+\" to add the attribute types as needed. Do not set homeDirectory otherwise you will fail to login. Attribute Mapping AuthenticationAuthority uid GeneratedUID GeneratedUID or ipaUniqueID HomeDirectory #/Users/\\$uid\\$ NFSHomeDirectory #/Users/\\$uid\\$ PrimaryGroupID gidNumber RealName cn RecordName uid UniqueID uidNumber UserShell loginShell AltSecurityIdentities #Kerberos:\\$krbPrincipalName\\$ If using custom mapping, click reach record type you created and ensure the base DN is set. Make sure each record type is set to all subtrees. Click \"security\" and set an authentication bind DN if needed Click OK Click OK Click on Search Policy. Double check that \"/LDAPV3/server1.ipa.example.com\" is listed beneath \"/Local/Default\" Close everything until you're back to the users & groups section of preferences Open a terminal. % dscacheutil -flushcache % dscacheutil -q user -a name username You should get a return. If you want to further verify users and groups after the above succeeds, open up the directory utility again. Click \"Directory Editor\", ensure you are searching for \"users\" and check that they appear in a list on the right hand side, optionally doing a search. In a default setup, you shouldn't need an account to do (some) anonymous lookups. If you changed that in any way, you will need to create a readonly system account in cn=sysaccounts,cn=etc. Login to the account for the first time from the login screen. Once the setup has complete, log out and back to a login account. In a terminal, you will need to make a mobile account. 2 % sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n username -P # Press enter and put in the password. sudo may not function if you don't do this step. # OPTIONAL: Allow the mobile account to be an administrator % sudo dscl . -append /Groups/admin GroupMembership username Go to system preferences, users & groups and ensure the account is a mobile account. Ventura and likely newer \u00b6 Go to system preferences -> users & groups Set \"automatic login\" to \"off\" Click \"edit\" next to \"Network account server\" Type in one of your IPA servers (you can duplicate it later for backup purposes). Press enter and wait for it to be \"green\". Click \"Open Directory Utility\" Click the \"lock\" to unlock the utility Click \"LDAPv3\" and click the pencil at the bottom left corner Select the \"from server\" portion under LDAP mappings and clck RFC2307. You may also leave it as custom. If you select rfc2307, it will ask for your base DN (eg, dc=ipa,dc=example,dc=com) If you select \"custom\", you will need to do this manually for each record type. You're better off using rfc2307 and working from there Click \"edit\" Click the \"+\" to add a groups record type or scroll and find \"groups\" and select it. Add the following object classes Record Type ObjectClasses Groups posixGroup ipausergroup groupOfNames\\* Note \"groupOfNames\" is optional here, because it seems that the directory utility doesn't understand this concept. Expand \"groups\" and ensure the following for each record type. You can click the \"+\" to add the attribute types as needed. Attribute Mapping PrimaryGroupID gidNumber RecordName cn Click the \"+\" to add a users record type or scroll and find \"users\". Select \"users\" and ensure the following object classes exist. You can click the \"+\" to add them when needed. Record Type ObjectClasses Users inetOrgPerson posixAccount shadowAccount apple-user Expand \"users\" and ensure the following for each record type. You can click the \"+\" to add the attribute types as needed. Do not set homeDirectory otherwise you will fail to login. Attribute Mapping AuthenticationAuthority uid GeneratedUID GeneratedUID or ipaUniqueID NFSHomeDirectory #/Users/\\$uid\\$ PrimaryGroupID gidNumber RealName cn RecordName uid UniqueID uidNumber UserShell loginShell AltSecurityIdentities #Kerberos:\\$krbPrincipalName\\$ If using custom mapping, click reach record type you created and ensure the base DN is set. Make sure each record type is set to all subtrees if needed. Click \"security\" and set an authentication bind DN if needed Click OK. Click Search Policy Double check that \"/LDAPV3/server1.ipa.example.com\" is listed beneath \"/Local/Default\". If it is not, select \"search patch\" and set it to custom and add it. Click Apply after. Close everything until you're back to the users & groups section of preferences Go to Lock Screen. Set \"login window shows\" to \"name and password\" Open a terminal. % dscacheutil -flushcache % dscacheutil -q user -a name username You should get a return. Login to the account for the first time from the login screen. Once the setup has complete, log out and back to a login account. In a terminal, you will need to make a mobile account. 3 % sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n username -P # Press enter, enter the user's password. sudo may hang if you don't do this. # OPTIONAL: Allow the mobile account to be an administrator % sudo dscl . -append /Groups/admin GroupMembership username Go to system preferences and ensure the account is a mobile account. General macOS Notes \u00b6 Group Resolution If you want groups from IPA to resolve to the system, you'll need to enable the compat tree when using this setup (RFC2307). Password Notes There are a couple of potential issues with this setup that you should be aware of as it pertains to mobile accounts. If you do a mobile account, changing your password through the FreeIPA gui does not change your passwords on your system. If your account does not have any keytabs (eg, you haven't had your mac on or haven't logged in in over 24 hours), you can login with the new password and it will suceed. The system will cache the new password right away. However, your keychain the first time will ask for the old passwords and this is normal. So you can change them by hand or you can log out and back in and the system will ask you if you want to update the password and it will just update automatically. There have been reports in a github issue that states you can change the password in the system preferences but I've been unable to confirm this. Below is a script that can be adapted for you. It has not been tested on Monterey and up. This assumes that you took one mac and set it up properly and you created a tarball with the proper configuration. You could optionally setup a temporary NFS or samba mount that gets mounted as root and then unmounted at the end, if you so wish. #!/bin/bash serverName=server1.ipa.example.com krb5Conf=/etc/krb5.conf krb5Tab=/etc/krb5.keytab pamDirectory=/etc/pam.d # Add SSL cert to chain mkdir /etc/ipa cd /etc/ipa curl -OL http://$serverName/ipa/config/ca.crt security add-trusted-cert -d -k /Library/Keychains/System.keychain -r trustRoot /etc/ipa/ca.crt # Stop and flushout the Open Directory /usr/sbin/dscacheutil -flushcache launchctl unload /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist # Pull the plist and pam files needed for IPA and deploy them, this assumes you setup one mac and zipped up the configurations # You can try your hand at dsconfigldap before pam, but I could never figure it out, honestly. # Relevant tar: tar czf /tmp/macconfig.tar.gz /Library/Preferences/OpenDirectory/Configurations /etc/pam.d/authorization \\ # /etc/pam.d/screensaver /etc/pam.d/passwd /etc/krb5.conf cd /tmp curl -OL http://$serverName/macconfig.tar.gz cd / tar xzf /tmp/macconfig.tar.gz # Add steps here for your keytab! Where are you getting it from? cp /tmp/mac.keytab /etc/krb5.keytab chown root:wheel /etc/krb5.keytab chmod 600 /etc/krb5.keytab # Start directory launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist sleep 30 # Kill the loginwindow killall loginwindow # If the system doesn't reboot here, reboot now. If you want to move your local files, you will need to tread lightly here. I personally believe it's always good to start fresh though. Look into the ditto command. I suppose something like this can work: # make sure you're logged in as a different account away from your local account % sudo su - root# cd /Users root# ditto localfolder networkfolder (or maybe an mv?) root# chown -R user:user folder root# /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n username -P Another issue you may run into, if you have been using your Mac with a local account for a while, a lot of directories in /Applications will be owned by localuser:staff or localuser:admin. It's recommended to fix those too. Discovery The directory framework in MacOS has the ability to discover settings for a particular LDAP server that it is being connected to. FreeIPA does not contain the schema, plugins, nor the infrastructure to provide the same things (for example, mDNS/Avahi, among other things). There was a (WIP) plugin created in 2017 by abbra. However, it is unclear if this works at all, nor is it clear if it ever did and will in python3 (abbra noted at the time that it \"installs\" into python 2 directories, which hints to not being tested or working on python 3). Please see the following resources for discussion and information. Pagure freeipa-macosx-support SUSE \u00b6 To setup openSUSE with FreeIPA, we'll need to do some manual work. This applies to SUSE 12 and up where the freeipa-client packages don't exist in the main repositories. freeipa repos There are OpenSUSE repos with the freeipa packages, though they are considered \"experimental\". If they show up in the base, then the below steps will be removed. However, if you are willing to use the repo , a lot of the steps below may not be needed. We have not tested this. # On an IPA server or client with the IPA utilities... % ipa host-add suse.example.com % /usr/sbin/ipa-getkeytab -s ipa.example.com -p host/suse.example.com -k /tmp/suse.keytab % scp /tmp/suse.keytab suse.example.com:/tmp/krb5.keytab # On the IPA client... % cp /tmp/krb5.keytab /etc % chmod 600 /etc/krb5.keytab % mkdir /etc/ipa % curl -o /etc/ipa/ca.crt http://ipa.example.com/ipa/config/ca.crt % curl -o /etc/pki/trust/anchors/ipa.example.com.crt http://ipa.example.com/ipa/config/ca.crt % update-ca-certificates % zypper install sssd sssd-ipa yast2-auth-client krb5-client openldap2-client cyrus-sasl-gssapi # Setup SSSD % vi /etc/sssd/sssd.conf [domain/example.com] cache_credentials = True krb5_store_password_if_offline = True ipa_domain = example.com ipa_hostname = suse.example.com # Client Specific Settings ipa_server = _srv_, ipa.example.com dns_discovery_domain = example.com # If we have a trust with domain resolution order #full_name_format = %1$s id_provider = ipa auth_provider = ipa access_provider = ipa chpass_provider = ipa ldap_tls_cacert = /etc/ipa/ca.crt [sssd] services = nss, sudo, pam, ssh domains = example.com [nss] filter_users = root,ldap,named,avahi,haldaemon,dbus,radiusd,news,nscd,tomcat,postgres homedir_substring = /home [pam] [sudo] [autofs] [ssh] # Setup kerberos % vi /etc/krb5.conf [libdefaults] default_realm = EXAMPLE.COM dns_lookup_realm = true dns_lookup_kdc = true rdns = false dns_canonicalize_hostname = false ticket_lifetime = 24h forwardable = true udp_preference_limit = 0 default_ccache_name = KEYRING:persistent:%{uid} [realms] EXAMPLE.COM = { pkinit_anchors = FILE:/var/lib/ipa-client/pki/kdc-ca-bundle.pem pkinit_pool = FILE:/var/lib/ipa-client/pki/ca-bundle.pem } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM suse.example.com = EXAMPLE.COM # Setup pam % pam-config -a --sss --mkhomedir --mkhomedir-umask=0077 \\ --pwhistory --pwhistory-remember=5 --localuser --cracklib \\ --cracklib-minlen=14 --cracklib-dcredit=-1 --cracklib-ucredit=-1 \\ --cracklib-lcredit=-1 --cracklib-ocredit=-1 --cracklib-retry=3 --unix-sha512 # Setup nsswitch (you can make it compat sss, but I use files sss) % sed -i.bak 's/compat$/files sss/g' /etc/nsswitch.conf % echo \"sudoers: files sss\" >> /etc/nsswitch.conf % sed -i '/netgroup/ s/nis/sss/g' /etc/nsswitch.conf # Depending on your suse version, you may want to set the nisdomainname # It does not hurt to set this % sed -i.bak '/NETCONFIG_NIS_STATIC_DOMAIN/ s/\"\"/\"example.com\"/g' /etc/sysconfig/network/config % netconfig update -f # Start sssd % systemctl enable sssd --now # Verify % id admin In the case of having an IPA-AD trust, you may need to change a line in your pam configuration. % sed -i 's/use_first_pass/forward_pass/g' /etc/pam.d/common-auth-pc # The affected line should appear like the below auth sufficient pam_sss.so forward_pass HBAC \u00b6 When we first setup our IPA servers, we had an option set to make it so hbac wasn't allowed for everyone. This way we have to create HBAC rules for our systems. I personally do this out of habit when working with IPA. What we need to do though is create an \"admin\" group that can login to all machines. % ipa idrange-show IPA.EXAMPLE.COM_id_range Range name: IPA.EXAMPLE.COM_id_range First Posix ID of the range: 686600000 Number of IDs in the range: 200000 First RID of the corresponding RID range: 1000 First RID of the secondary RID range: 100000000 Range type: local domain range % ipa group-add --gid=686610000 linuxadm % ipa group-add-member --users=flast linuxadm Note for AD Users : In the event that your AD user or group of users will be an admin, you need to create an \"external\" group to map the user or users over. This isn't required if you don't have an AD trust. # Create an external group that the AD user/group goes into % ipa group-add --external linuxadm_external # Add the user (or group) into the external group % ipa group-add-member --users=aduser1@example.com linuxadm_external % ipa group-add-member --users=adgroup1@example.com linuxadm_external # Add the external group as a member of the IPA posix group. # aduser1 and adgroup1 are now effectively members of the linuxadm group in IPA. % ipa group-add-member --groups=linuxadm_external linuxadm Now, let's create an HBAC for our Linux Administrator account for our group. % ipa hbacrule-add --hostcat=all --servicecat=all --desc='linux admins all access' linuxadm % ipa hbacrule-add-user --groups=linuxadm linuxadm % ipa hbactest --rules=All_Systems --user=flast --host=server1.ipa.example.com --service=sshd % ipa hbactest --rules=All_Systems --user=aduser1@example.com --host=server1.ipa.example.com --service=sshd You might want to create an HBAC rule specifically for your IPA admin accounts to have ssh access to the IPA servers too. You can follow something like the above to make it possible. Or you can just add the IPA admins group into the HBAC rule we just made above. Group Types Groups in Active Directory have three types. These three types can actually change the behavior of how SSSD on the IPA domain controllers resolve them or if they'll even be resolvable at all. The three types are 'Domain Local', 'Global', and 'Universal'. If at all possible, avoid groups being 'Global'. Domain Local or Universal is recommended. SUDO \u00b6 Setting up sudo is relatively easy. SSSD (1.16.x and 2.X) supports IPA as a provider for sudo. Based on the last section, let's create a sample rule for our Linux admins that can login to every system, we want to ensure they can run all commands. % ipa sudorule-add --runasusercat=all --hostcat=all --cmdcat=all --desc='linux admins all sudo' all_linux_sudo % ipa sudorule-add-user --groups=linuxadm all_linux_sudo You can make this a little more specific, such as /bin/bash as everyone or otherwise. It's your call here. If you want to create a sudo rule and add some commands to it, you can do something like this. % ipa sudorule-add sudo_rule % ipa sudorule-add-allow-command --sudocmds=\"/usr/bin/less\" sudo_rule Legacy Client Setup \u00b6 This applies to Solaris, Omnios, others based on Illumos. Solaris 10 \u00b6 Setting up Solaris 10 as an IPA client is an interesting feat. However, it comes with security issues. No SSL or TLS Support Note that for Solaris 10 to talk to IPA, you must use clear text communication. Solaris 10 is too old to use new ciphers. However, while LDAP may be clear text, kerberos should still be secure enough for the time being. If you are using an AD trust, the user's passwords will be passed in clear text. Highly suggested that you decommission Solaris 10 from your environment. Solaris 10 will eventually be removed from this page. Create an ldif for your service account (optional) dn: uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com objectclass: account objectclass: simplesecurityobject uid: solaris userPassword: secret123 passwordExpirationTime: 20380119031407Z nsIdleTimeout: 0 The solaris system account is required. So now, add it in. % ldapadd -xWD 'cn=Directory Manager' -f /tmp/solaris.ldif Now, set the nisdomain. % defaultdomain ipa.example.com % echo 'ipa.example.com' > /etc/defaultdomain Configure kerberos. % vi /etc/krb5/krb5.conf [libdefaults] default_realm = IPA.EXAMPLE.COM dns_lookup_kdc = true verify_ap_req_nofail = false [realms] IPA.EXAMPLE.COM = { } [domain_realm] ipa.example.com = IPA.EXAMPLE.COM .ipa.example.com = IPA.EXAMPLE.COM [logging] default = FILE:/var/krb5/kdc.log kdc = FILE:/var/krb5/kdc.log kdc_rotate = { period = 1d version = 10 } [appdefaults] kinit = { renewable = true forwardable= true } Generate a keytab and bring it over. # on the ipa server % ipa host-add solaris10.example.com % ipa-getkeytab -s server1.ipa.example.com -p host/solaris10.example.com -k /tmp/solaris10.keytab # Transfer the keytab % scp /tmp/solaris10.keytab solaris10.example.com:/tmp # On the solaris 10 machine % cp /tmp/solaris10.keytab /etc/krb5/krb5.keytab % chmod 600 /etc/krb5/krb5.keytab % chmod 644 /etc/krb5/krb5.conf % chown root:sys /etc/krb5/* % kinit flast2@IPA.EXAMPLE.COM Create the LDAP configurations, bring the certificate, and create an NSS database. % mkdir /etc/ipa /var/ldap % cd /etc/ipa % wget -O ipa.pem http://server1.ipa.example.com/ipa/config/ca.crt % certutil -A -n \"ca-cert\" -i /etc/ipa/ipa.pem -a -t CT -d . % cp * /var/ldap % vi /etc/ldap.conf base dc=ipa,dc=example,dc=com scope sub TLS_CACERTDIR /var/ldap TLS_CERT /var/ldap/cert8.db TLS_CACERT /var/ldap/ipa.pem tls_checkpeer no ssl off bind_timelimit 120 timelimit 120 uri ldap://server1.ipa.example.com sudoers_base ou=sudoers,dc=ipa,dc=example,dc=com pam_lookup_policy yes Now init the ldap client. No Secure Connection When using this, you are not creating a secure connection. The Solaris 10 SSL libraries are so old that they cannot work with the ciphers that FreeIPA has turned on. AD Trust - Different Trees If using an AD trust, you should use the second example, where it looks at the compat tree for users. No Service Account If you have configured FreeIPA to not allow any anonymous connections, you will need to use a proxy account. We have provided the examples for this configuration. Without an AD Trust # Without AD Trust (no proxy) % ldapclient manual -a authenticationMethod=none \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # Without AD Trust (proxy) % ldapclient manual -a credentialLevel=proxy \\ -a authenticationMethod=simple \\ -a proxyDN=\"uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com\" \\ -a proxyPassword=\"secret123\" \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 With an AD Trust # With AD Trust (no proxy) % ldapclient manual -a authenticationMethod=none \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # With AD Trust (proxy) % ldapclient manual -a credentialLevel=proxy \\ -a authenticationMethod=simple \\ -a proxyDN=\"uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com\" \\ -a proxyPassword=\"secret123\" \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 This should succeed. Once it succeeds, you need to configure pam and nsswitch. AD Trust Information In the event you don't have an AD trust, you can change the \"binding\" lines to required, remove the pam_ldap lines, and change pam_krb5 lines to read \"required\" % vi /etc/pam.conf # Console login auth requisite pam_authtok_get.so.1 login auth sufficient pam_krb5.so.1 login auth required pam_unix_cred.so.1 login auth required pam_dial_auth.so.1 login auth sufficient pam_unix_auth.so.1 server_policy login auth sufficient pam_ldap.so.1 rlogin auth sufficient pam_rhosts_auth.so.1 rlogin auth requisite pam_authtok_get.so.1 rlogin auth required pam_dhkeys.so.1 rlogin auth sufficient pam_krb5.so.1 rlogin auth required pam_unix_cred.so.1 rlogin auth sufficient pam_unix_auth.so.1 server_policy rlogin auth sufficient pam_ldap.so.1 # Needed for krb krlogin auth required pam_unix_cred.so.1 krlogin auth sufficient pam_krb5.so.1 # Needed for krb krsh auth required pam_unix_cred.so.1 krsh auth required pam_krb5.so.1 # ? ppp auth requisite pam_authtok_get.so.1 ppp auth required pam_dhkeys.so.1 ppp auth sufficient pam_krb5.so.1 ppp auth required pam_dial_auth.so.1 ppp auth binding pam_unix_auth.so.1 server_policy ppp auth sufficient pam_ldap.so.1 # Other, used by sshd and \"others\" as a fallback other auth requisite pam_authtok_get.so.1 other auth required pam_dhkeys.so.1 other auth sufficient pam_krb5.so.1 other auth required pam_unix_cred.so.1 other auth sufficient pam_unix_auth.so.1 server_policy other auth sufficient pam_ldap.so.1 other account requisite pam_roles.so.1 other account required pam_projects.so.1 other account binding pam_unix_account.so.1 server_policy other account sufficient pam_krb5.so.1 other account sufficient pam_ldap.so.1 other session required pam_unix_session.so.1 other password required pam_dhkeys.so.1 other password requisite pam_authtok_get.so.1 other password requisite pam_authtok_check.so.1 force_check other password required pam_authtok_store.so.1 server_policy # passwd and cron passwd auth binding pam_passwd_auth.so.1 server_policy passwd auth sufficient pam_ldap.so.1 cron account required pam_unix_account.so.1 # SSH Pubkey - Needed for openldap and still probably needed sshd-pubkey account required pam_unix_account.so.1 % vi /etc/nsswitch.conf # Below are just the minimum changes passwd: files ldap [NOTFOUND=return] group: files ldap [NOTFOUND=return] sudoers: files ldap netgroup: ldap # the rest here are just here, up to you if you choose to set them. hosts: files dns ipnodes: files dns ethers: files ldap publickey: files ldap automount: files ldap You can test now if you'd like. bash-3.2# ldaplist -l passwd flast2 dn: uid=flast2,cn=users,cn=compat,dc=ipa,dc=example,dc=com cn: First Last objectClass: posixAccount objectClass: ipaOverrideTarget objectClass: top gidNumber: 1006800001 gecos: First Last uidNumber: 1006800001 ipaAnchorUUID: :IPA:ipa.example.com:8babb9a8-5aaf-11e7-9769-00505690319e loginShell: /bin/bash homeDirectory: /home/first.last2 uid: first.last2 I recommend setting up sudo at least... if you want to use sudo, install the sudo-ldap from sudo.ws for Solaris 10. Solaris 11 \u00b6 Solaris 11 shares similar configuration to Solaris 10. There are a couple of manual things we have to do, but they are trivial. Solaris 11/Omnios will use TLS and sudo should just work. AD Groups In Solaris 10, users who logged in with AD users (with their short name) would appear as their full name ( name@domain ). This allowed their groups to fully resolve. However, in Solaris 11.4, this was not the case. Short name logins will work but your groups will not resolve as the compat tree uses the full name. To avoid running into this problem, you should be on at least SRU 11.4.7.4.0. Note that on a later SRU, you may need to setup an ID view (without overrides) for groups and sudo to work again. Below is for the service account like in the previous section, here as a reference. dn: uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com objectclass: account objectclass: simplesecurityobject uid: solaris userPassword: secret123 passwordExpirationTime: 20380119031407Z nsIdleTimeout: 0 % ldapadd -xWD 'cn=Directory Manager' -f /tmp/solaris.ldif Now, set the nisdomain. % defaultdomain ipa.example.com % echo 'ipa.example.com' > /etc/defaultdomain Configure kerberos. % vi /etc/krb5/krb5.conf [libdefaults] default_realm = IPA.EXAMPLE.COM dns_lookup_kdc = true verify_ap_req_nofail = false [realms] IPA.EXAMPLE.COM = { } [domain_realm] ipa.example.com = IPA.EXAMPLE.COM .ipa.example.com = IPA.EXAMPLE.COM [logging] default = FILE:/var/krb5/kdc.log kdc = FILE:/var/krb5/kdc.log kdc_rotate = { period = 1d version = 10 } [appdefaults] kinit = { renewable = true forwardable= true } Generate a keytab and bring it over. # on the ipa server % ipa host-add solaris11.example.com % ipa-getkeytab -s server1.ipa.example.com -p host/solaris11.example.com -k /tmp/solaris11.keytab # Transfer the keytab % scp /tmp/solaris11.keytab solaris11.example.com:/tmp # On the solaris 11 machine % cp /tmp/solaris11.keytab /etc/krb5/krb5.keytab % chmod 600 /etc/krb5/krb5.keytab % chmod 644 /etc/krb5/krb5.conf % chown root:sys /etc/krb5/* # Check the keytab % klist -ket /etc/krb5/krb5.keytab # Test that you can kinit % kinit flast2@IPA.EXAMPLE.COM Create the LDAP configurations, bring the certificate, and create an NSS database. Solaris 11.3 vs 11.4 Previously we had 11.3 and 11.4 configurations. We have removed 11.3 as we no longer support it. % mkdir /etc/ipa /var/ldap % cd /etc/ipa % wget -O ipa.pem http://server1.ipa.example.com/ipa/config/ca.crt % cp * /var/ldap % vi /etc/ldap.conf base dc=ipa,dc=example,dc=com scope sub bind_timelimit 120 timelimit 120 uri ldap://server1.ipa.example.com sudoers_base ou=sudoers,dc=ipa,dc=example,dc=com pam_lookup_policy yes TLS_CACERTDIR /var/ldap ssl start_tls tls_checkpeer no Now init the ldap client. We actually get to use a secure connection here. Kerberos is hit or miss, could never get sasl/GSSAPI to work. Different Trees - Trust or not? There are multiple examples of how to setup the trees. If using an AD trust, you should use the second example, where it looks at the compat tree for users. However, if you do not have trusts, then it is perfectly possible to still use the AD Trust example. Try both and see which works better for your environment. No Service Account If you have configured FreeIPA to not allow any anonymous connections, you will need to use a proxy account. We have provided the examples for this configuration. Without AD Trust # Without AD Trust (no proxy) % ldapclient manual -a authenticationMethod=tls:simple \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # Without AD Trust (proxy) % ldapclient manual -a authenticationMethod=tls:simple \\ -a credentialLevel=proxy \\ -a proxyDN=\"uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com\" \\ -a proxyPassword=\"secret123\" \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # Without AD Trust (Kerberos) - Only works if Solaris is in the same DNS domain as IPA % ldapclient manual -a authenticationMethod=sasl/GSSAPI \\ -a credentialLevel=self \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 With AD Trust # With AD Trust (no proxy) % ldapclient manual -a authenticationMethod=tls:simple \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # With AD Trust (proxy) % ldapclient manual -a authenticationMethod=tls:simple \\ -a credentialLevel=proxy \\ -a proxyDN=\"uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com\" \\ -a proxyPassword=\"secret123\" \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # With AD Trust (Kerberos) - Only works if Solaris is in the same DNS domain as IPA % ldapclient manual -a authenticationMethod=sasl/GSSAPI \\ -a credentialLevel=self \\ -a proxyDN=\"uid=solaris,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com\" \\ -a proxyPassword=\"secret123\" \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.ipa.example.com server2.ipa.example.com\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=passwd:cn=users,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 This should succeed. Once it succeeds, you need to configure pam and nsswitch. % /usr/sbin/svccfg -s name-service/switch setprop config/sudoer = astring: \"files ldap\" % /usr/sbin/svccfg -s name-service/switch setprop config/password = astring: \"files ldap [NOTFOUND=return]\" % /usr/sbin/svccfg -s name-service/switch setprop config/group = astring: \"files ldap [NOTFOUND=return]\" % /usr/sbin/svcadm refresh svc:/system/name-service/switch % /usr/sbin/svcadm restart svc:/system/name-service/switch % /usr/sbin/svcadm restart ldap/client AD Trust Information In the event you don't have an AD trust, you can change the \"binding\" lines to required and remove the pam_ldap lines. Optionally, you can set pam_krb5 to \"required\", however sufficient should work just fine. Without an AD Trust % vi /etc/pam.d/login auth definitive pam_user_policy.so.1 auth requisite pam_authtok_get.so.1 auth required pam_dhkeys.so.1 auth sufficient pam_krb5.so.1 auth required pam_unix_cred.so.1 auth sufficient pam_unix_auth.so.1 server_policy % vi /etc/pam.d/other auth definitive pam_user_policy.so.1 auth requisite pam_authtok_get.so.1 auth required pam_dhkeys.so.1 auth sufficient pam_krb5.so.1 auth required pam_unix_cred.so.1 auth sufficient pam_unix_auth.so.1 server_policy account requisite pam_roles.so.1 account definitive pam_user_policy.so.1 account required pam_unix_account.so.1 server_policy account sufficient pam_krb5.so.1 session definitive pam_user_policy.so.1 session required pam_unix_session.so.1 password definitive pam_user_policy.so.1 password include pam_authtok_common password sufficient pam_krb5.so.1 password required pam_authtok_store.so.1 server_policy % vi /etc/pam.d/sshd-pubkey account required pam_unix_account.so.1 With an AD Trust % vi /etc/pam.d/login auth definitive pam_user_policy.so.1 auth requisite pam_authtok_get.so.1 auth required pam_dhkeys.so.1 auth sufficient pam_krb5.so.1 auth required pam_unix_cred.so.1 auth sufficient pam_unix_auth.so.1 server_policy auth sufficient pam_ldap.so.1 % vi /etc/pam.d/other auth definitive pam_user_policy.so.1 auth requisite pam_authtok_get.so.1 auth required pam_dhkeys.so.1 auth sufficient pam_krb5.so.1 auth required pam_unix_cred.so.1 auth sufficient pam_unix_auth.so.1 server_policy auth sufficient pam_ldap.so.1 account requisite pam_roles.so.1 account definitive pam_user_policy.so.1 account binding pam_unix_account.so.1 server_policy account sufficient pam_krb5.so.1 account sufficient pam_ldap.so.1 session definitive pam_user_policy.so.1 session required pam_unix_session.so.1 password definitive pam_user_policy.so.1 password include pam_authtok_common password sufficient pam_krb5.so.1 password required pam_authtok_store.so.1 server_policy % vi /etc/pam.d/sshd-pubkey account required pam_unix_account.so.1 You can test now if you'd like. root@solaris11:~# ldaplist -l passwd flast2 dn: uid=flast2,cn=users,cn=compat,dc=ipa,dc=example,dc=com cn: First Last objectClass: posixAccount objectClass: ipaOverrideTarget objectClass: top gidNumber: 1006800001 gecos: First Last uidNumber: 1006800001 ipaAnchorUUID: :IPA:ipa.example.com:8babb9a8-5aaf-11e7-9769-00505690319e loginShell: /bin/bash homeDirectory: /home/first.last2 uid: first.last2 Automated Scripts \u00b6 I at one point built a bunch of scripts to automate Solaris servers talking to IPA here . However, it is likely the scripts no longer work or contain outdated information. AD Trust Double UID \u00b6 Solaris 11 once in a while gets random regressions when it comes to authentication and ID's, among many other things they randomly decide to break. Big shout out to Oracle. In a brief discussion with a user in the #freeipa IRC channel, the user was trying to find a way to chop off the domain name for logins but also have sudo still work as there were some random issues in general. We both discovered that in SRU 11.4.20.4.0, even though both UID's are present from ldaplist -l passwd, sudo was no longer working properly. The first thing we tried was to create an ID view and override a user with a new username. This successfully removed the domain, but did not solve the sudo problem. He instead got \"no account present for that user\". However, I wasn't able to replicate this. However, later, one thing he noticed is after creating an ID view with no overrides and pointing Solaris 11 to the view in the compat tree, Solaris 10-esque authentication ID reporting started to occur. Running ldaplist -l passwd user reported back the double UID as expected, but the FQDN comes first which resolved his group/sudo issues. # Create a view... no id overrides required here % ipa idview-add solaris # On Solaris... # Take EXTREME care with the group and passwd base DN's, they need to point # to the view properly # This example uses kerberos to authenticate. % ldapclient manual -a authenticationMethod=self \\ -a credentialLevel=sasl/GSSAPI \\ -a defaultSearchBase=dc=ipa,dc=example,dc=com \\ -a domainName=ipa.example.com \\ -a defaultServerList=\"server1.angelsofclockwork.net server2.angelsofclockwork.net\" \\ -a followReferrals=true \\ -a objectClassMap=shadow:shadowAccount=posixAccount \\ -a objectClassMap=passwd:posixAccount=posixaccount \\ -a objectClassMap=group:posixGroup=posixgroup \\ -a serviceSearchDescriptor=group:cn=groups,cn=solaris,cn=views,cn=compat,dc=angelsofclockwork,dc=net \\ -a serviceSearchDescriptor=passwd:cn=users,cn=solaris,cn=views,cn=compat,dc=angelsofclockwork,dc=net \\ -a serviceSearchDescriptor=netgroup:cn=ng,cn=compat,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=ethers:cn=computers,cn=accounts,dc=ipa,dc=example,dc=com \\ -a serviceSearchDescriptor=sudoers:ou=sudoers,dc=ipa,dc=example,dc=com \\ -a bindTimeLimit=5 # Make sure you set your props... % /usr/sbin/svccfg -s name-service/switch setprop config/sudoer = astring: \"files ldap\" % /usr/sbin/svccfg -s name-service/switch setprop config/password = astring: \"files ldap [NOTFOUND=return]\" % /usr/sbin/svccfg -s name-service/switch setprop config/group = astring: \"files ldap [NOTFOUND=return]\" % /usr/sbin/svcadm refresh svc:/system/name-service/switch % /usr/sbin/svcadm restart svc:/system/name-service/switch % /usr/sbin/svcadm restart ldap/client # Verify... % ldaplist -l passwd adusername . . . % id -a adusername . . . Thank you to \"mewho\" on libera for finding this interesting workaround. OmniOS/Illumos \u00b6 Some steps between Solaris 10 and 11 can be followed to make OmniOS work. However, we have been unable to resolve why sudo will not work when using an AD trust. If you are using a standalone FreeIPA and no trust, sudo should work just fine. Legacy HBAC \u00b6 For HBAC to work on Solaris, you will need to compile the pam_hbac module found here . I would clone the current master branch or download the master.zip to your Solaris system. Each OS has their set of instructions for compiling. First, create the following system account. We will need this when we are configuring our legacy clients. dn: uid=hbac,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com objectClass: account objectClass: simplesecurityobject objectClass: top uid: hbac userPassword: password Solaris 10 \u00b6 % /opt/csw/bin/pkgutil -i -y libnet ar binutils gcc4g++ glib2 libglib2_dev gmake % /opt/csw/bin/pkgutil -i -y libnet ar binutils gcc4g++ glib2 libglib2_dev gmake % PATH=$PATH:/opt/csw/bin % export M4=/opt/csw/bin/gm4 % autoconf -o configure % autoreconf -i # Yes, SSL must be disabled for Solaris 10 to work. The libraries are too old. # You may or may not need to set CFLAGS, CXXFLAGS, and LDFLAGS with -m32 % ./configure AR=/opt/csw/bin/gar --with-pammoddir=/usr/lib/security --sysconfdir=/etc/ --disable-ssl --disable-man-pages % make % make install Solaris 11 \u00b6 % pkg install autoconf libtool pkg-config automake gcc docbook % autoreconf -if % ./configure --with-pammoddir=/usr/lib/security --mandir=/usr/share/man --sysconfdir=/etc/ % make % make install Omnios \u00b6 % pkg install developer/build/autoconf developer/build/libtool \\ developer/pkg-config developer/build/automake \\ developer/gcc48 system/header developer/object-file \\ developer/linker % autoreconf -if % ./configure --with-pammoddir=/usr/lib/security --mandir=/usr/share/man --sysconfdir=/etc/ % make % make install pam_hbac.conf \u00b6 % vim /etc/pam_hbac.conf # Replace client with your server's FQDN URI = ldap://server.ipa.example.com BASE = dc=ipa,dc=example,dc=com BIND_DN = uid=hbac,cn=sysaccounts,cn=etc,dc=ipa,dc=example,dc=com BIND_PW = password SSL_PATH = /var/ldap HOST_NAME = client PAM Configuration \u00b6 # Solaris 10 - /etc/pam.conf # Modify the other account section... It should come at the end of the account blocks. . . . other account required pam_hbac.so ignore_unknown_user ignore_authinfo_unavail # Solaris 11 - /etc/pam.d/other # Same here, only modify the account section . . . account required pam_hbac.so ignore_unknown_user ignore_authinfo_unavail In the event you cannot login or things aren't working the way you'd expect, add 'debug' to the end of the pam_hbac line and watch /var/log/authlog for errors. Login with AD Users to Legacy Clients \u00b6 For AD users to be able to login to legacy clients, you have to enable system-auth to the IPA servers. Without it, users will be denied access, regardless of HBAC controls or if you're using the pam_hbac module. % ipa hbacsvc-add system-auth % ipa hbacrule-add legacy_client_auth % ipa hbacrule-add-host --hostgroups=ipaservers legacy_client_auth % ipa hbacrule-mod --usercat=all legacy_client_auth Legacy Active Directory Trust Notes \u00b6 Just a section of notes. Domain Resolution Order Oddness \u00b6 If using domain resolution order, AD users get double uid attributes - but only if they login with their shortname. If they login with fqdn, double uid's do not occur. But shortnames do not work anymore. Have to restart the directory server to make short names work again. Solaris Weirdness \u00b6 If using domain resolution order, Solaris 10 gets the group resolution correct for short named AD users. Solaris 11 does not unless you are on SRU 11.4.7.4.0 or newer. There is a way to chop off the domain name from the uid using views. Domain Options \u00b6 This section goes over \"situational\" scenarios. These scenarios are reflective of the environment in which IPA is installed and not all will fit into your environment. These are more or less common situations that could occur during an IPA deployment or even post-deployment. Remove @realm for AD users \u00b6 A common scenario is that IPA and AD will have a trust, but there will not be any IPA users with the exception of the engineering team for managing IPA itself. The common theme is that because of this, the engineers and customers would rather not login with username@realm . Info The following is only applicable in an IPA-AD trust. An IPA-only scenario would not require any of these steps and most pieces would work natively (no @realm, sudo, hbac). In the event that you are in an IPA-AD scenario, please take note that this can adversely affect legacy clients. This will cause ldapsearches that are done in the compat tree to display multiple uid attributes. In most cases, this is fine and the user can still login without the realm name. The whoami and id commands will show the domain. There's no workaround for this. On the IPA servers, you will need to set the domain resolution order. This was introduced in 4.5.0. % kinit admin % ipa config-mod --domain-resolution-order=\"example.com:ipa.example.com\" After, you will need to clear out your SSSD cache. # sss_cache -E is insufficient for this. % systemctl stop sssd % rm -rf /var/lib/sss/db/* % systemctl start sssd The below is optional. It will remove the @realm off the usernames, like on the prompt or id or whoami commands. Only do this if required. Only do this on the clients. Do not make this change on an IPA replica. # vi /etc/sssd/sssd.conf [domain/ipa.example.com] . . . full_name_format = %1$s This will ensure EL7, EL8, EL9 clients resolve the AD domain first when attempting logins and optionally drop the @realm off the usernames. AD and IPA group names with short names \u00b6 You may notice that your clients have intermittent issues with name resolution when the following are true: Groups (or users) have the same names in both IPA and AD You are using domain resolution order You are shortening names on the clients You may want to actually search for them to identify the errant groups and then correct them. You can correct them either on the AD or IPA side. I would opt for the IPA side. % kinit admin@IPA.EXAMPLE.COM % vi /tmp/dupecheck.sh #!/bin/bash for x in ${ARRAY[*]} ; do ldapsearch -x -b \"DC=example,DC=com\" -h example.com -LLL -w 'PASSWORD' -D 'username@example.com' samaccountname=\"$x\" samaccountname | grep -q $x if [[ $? -eq 0 ]]; then echo \"$x: DUPLICATE\" fi done % bash /tmp/dupecheck.sh If you run into any duplicates, they should show up in a list for you address. sAMAccountName vs CN The \"CN\" and \"sAMAccountName\" attributes are not the same in AD, depending on who made the group or other factors. The sAMAccountName attribute is the value used to determine names from AD, whether you are enrolled with AD or the IPA server SSSD is pulling the information. This is why we are searching for that attribute, and not the CN. Sites and AD DC's \u00b6 By creating a subdomain section in /etc/sssd/sssd.conf on an IPA server, it is possible to set an AD Site or AD server(s) directly in SSSD. By default, sssd tries to do location based discovery. There may be a case where this isn't possible (eg, only a set of AD servers may only be contacted in certain \"air gapped\" networks). [domain/ipa.example.com/example.com] # If you want a site ad_site = Site_Name # If you want a server(s) ad_server = dc1.example.com, dc2.example.com # A backup? ad_backup_server = dc3.example.com, dc4.example.com If you don't have access or a way to find the sites using the Windows tools, you can run an ldapsearch to find it (or an equivalent ldap browsing tool). % ldapsearch -x -h example.com -s one -WD 'CN=username,CN=Users,DC=example,DC=com' \\ -b 'CN=Sites,CN=Configuration,DC=example,DC=com' cn This should report back your sites. If you want to know the servers for those sites (in case you don't want to deal with the sites, but just the DC's themselves), you use ldapsearch but use the base DN of the site name. % ldapsearch -x -h example.com -WD 'CN=username,CN=Users,DC=example,DC=com' \\ -b 'CN=Servers,CN=Site_Name,CN=Sites,CN=Configuration,DC=example,DC=com' dnsHostName Hardcoded DC's If the DC's change at any time and they are harded in your sssd.conf, it is up to you to know when new controllers are being added or removed as to not disrupt the connectivity from IPA to AD when performing user or group lookups. Enterprise Linux 6 SUDO and Default Domain Suffix \u00b6 This issue with the above section is that once you do this, sudo rules will begin failing, they will no longer work for Enterprise Linux 6. This is because sssd was changed to look for cn=sudo rather than ou=sudoers. To enable the compatibility fall back, you will need to install a newer SSSD. Set Default Shell for AD Users \u00b6 By default, after a trust has been established, the shell all AD users get is /bin/sh. To change this, you must change the sssd.conf on the IPA masters. % vi /etc/sssd/sssd.conf [domain/ipa.example.com] . . . default_shell = /bin/bash % systemctl restart sssd Automated Kerberos Principals \u00b6 Once in a great while, we run into situations where we need to have an automated process for creating principals and keytabs. This section takes a look at some of those examples that we've ran into. Hadoop/Cloudera \u00b6 This assumes you are using Cloudera Manager and not Ambari in any form. DNS Information It is highly likely that if you are using AWS, your nodes are getting stupid names like compute.internal. While there is a a way to change this if you don't change it, you will need to rely on something like DNSMASQ to allow the nodes to communicate with FreeIPA. FreeIPA will be upset about the stupid names because it can't do a rDNS lookup. Cloudera Manager Woes \u00b6 It is likely you have Cloudera/Hadoop, it is also very likely you (or another team) are deploying and using Cloudera Manager (or Director?). You may be running into issues that involve direct Active Directory integration. Maybe you're moving away from a standalone LDAP system over to Active Directory or even FreeIPA. Maybe you have FreeIPA in an AD trust but the users or contractors absolutely insist on using AD against their better judgement, despite the problems they're running into. Whatever the scenario is, we feel your pain. Here are some things you should probably know: Cloudera Manager (or Director?) supports Active Directory out of the box and obviously not FreeIPA despite the devs wanting to work something out back in 2015 Ambari has support for FreeIPA, but we are focusing on Cloudera Manager here. Cloudera Manager supports custom keytab retrieval scripts Hostnames that are longer than 15 characters, regardless of the cloud provider or onprem setup, will ultimately fail The NETBIOS limit in AD is 16 characters, which is 15 + $ at the end - This means hosts will enroll on top of themselves and your cluster will be broken FreeIPA does not have the name limitation and using an AD trust, AD users can freely use Hadoop when the cluster is properly setup. Enrolling the cluster nodes into FreeIPA and using a custom retrieval script will solve most (if not all) of the issues you may run into as well when it comes to keytabs, which Hadoop heavily relies on. The custom script is simply because Cloudera by default likes having direct access to the kerberos infrastructure, which is a no-go for FreeIPA. The Solution \u00b6 To summarize, here is our proposed solution: Create an account called cdh Create a role called \"Kerberos Managers\" and apply the following privileges: System: Manage Host Keytab System: Manage Host Keytab Permissions System: Manage Service Keytab System: Manage Service Keytab Permissions System: Manage User Principals (was not actually used, but who knows what we could use the role for later) Apply the role to the cdh account Create a custom script they could use to enroll the servers into FreeIPA (out of scope here) Create a custom script that utilizes the cdh account to create services So let's create the necessary things we need. # Create the account # Note... you may want to make this account non-expiring since it's just a service account % ipa user-add --first=\"Cloudera\" --last=\"Key Manager\" cdh # Create the Kerberos Managers role % ipa role-add \"Kerberos Managers\" # Create the kerberos manager privilege % ipa privilege-add \"Privileges - Kerberos Managers\" % ipa privilege-add-permission \"Privileges - Kerberos Managers\" \\ --privileges=\"System: Manage Host Keytab\" \\ --privileges=\"System: Manage Host Keytab Permissions\" \\ --privileges=\"System: Manage Service Keytab\" \\ --privileges=\"System: Manage Service Keytab Permissions\" \\ --privileges=\"System: Manage User Principals\" # Add the privilege to the role % ipa role-add-privilege \"Kerberos Managers\" \\ --privileges=\"Privileges - Kerberos Managers\" # Add the user to the role % ipa role-add-member --users=cdh \"Kerberos Managers\" # Optionally, we can export the keytab for the user with a password # You will see why in the next script % ipa-getkeytab -p cdh@EXAMPLE.COM -k cdh.keytab -P Now we need our special kerberos keytab retrieval script. #!/bin/bash # Created by: @nazunalika - Louis Abel # Purpose: To retrieve keytabs for Cloudera / Hadoop # https://github.com/nazunalika/useful-scripts # Disclaimer: We do not take responsibilities for breaches or misconfigurations of # software. Use at your own risk # Variables # This can be anywhere, but it SHOULD be secure with at least 600 permissions CDHKT=\"/root/.cdh/cdh.keytab\" CDHUSER=\"cdh\" IPAREALM=\"EXAMPLE.COM\" # This can be any server. You could make an array and have it randomly selected IPASERVER=\"ipa01.example.com\" # Where is this going? DESTINATION=\"$1\" # The full principal for the keytab in question FULLPRINC=\"$2\" # Shortened name PRINC=$(echo $FULLPRINC | sed \"s/\\@$(echo $IPAREALM)//\") 00_kinitUser() { # Pick what suits you best, we prefer using a keytab # Password based kinit, based on the keytab we created prior! # You could also have this in a file somewhere, I guess. Just # has to be secured. echo ThisIsAWeakPassword | kinit $CDHUSER@$IPAREALM # Keytab based kinit, obviously we created it before right? It just needs to be # on the right system, deployed in some secure manner #kinit -kt $CDHKT $CDHUSER@$IPAREALM if [[ $? == \"1\" ]]; then echo FAILED TO KINIT exit fi } 01_createPrinc() { echo \"INFO: Checking for existing principle\" if ipa service-find $FULLPRINC; then echo \"INFO: Principle found\" else echo \"INFO: Not found, creating\" ipa service-add $FULLPRINC fi } 02_createServiceAllows() { # We need to allow the service to create and retrieve keytabs echo \"INFO: Ensuring service allows to create and retrieve keytabs\" ipa service-allow-create-keytab --users=$CDHUSER $FULLPRINC ipa service-allow-retrieve-keytab --users=$CDHUSER $FULLPRINC # Let's retrieve the keytabs if ipa service-show $FULLPRINC | grep 'Keytab' | grep 'False'; then echo \"INFO: Creating keytab for $FULLPRINC to $DESTINATION\" ipa-getkeytab -s $IPASERVER -p $PRINC -k $DESTINATION else echo \"INFO: Retriving keytab for $FULLPRINC to $DESTINATION\" ipa-getkeytab -r -s $IPASERVER -p $PRINC -k $DESTINATION fi } 00_kinitUser 01_createPrinc 02_createServiceAllows kdestroy exit 0 Place the above script in a file that is accessible by the cloudera manager such as /usr/local/bin/getKeytabsCDH.sh and ensure it is owned by cloudera-scm with a permission set of 775. During the kerberos wizard, stop when you are verifying the \"cdh\" user. You will need to set the configuration for \"Custom Kerberos Keytab Retrieval Script\" to /usr/local/bin/getKeytabsCDH.sh and then you're almost there. 4 An important tidbit is currently Enterprise Linux 7+ and higher use memory based keytabs and java doesn't support them. 5 Because of this, the /etc/krb5.conf should be modified. % cat /etc/krb5.conf . . . # Make sure the below is commented # default_ccache_name = KEYRING:persistent:%{uid} . . . DNS Forwarding \u00b6 DNS Forwarding to DoT \u00b6 Presently, FreeIPA does not support DoT (DNS over TLS) nor DoH (DNS over HTTPS) (this appears to be a bind limitation and we can't find documentation that says otherwise). However, it is possible to setup unbound to do the forwarding for you, in which you tell your bind servers (or in this case, the bind DNS servers in your IPA domain) to forward to that unbound server for all forwarding. Keep it Separate It is recommended to keep your unbound service separate from the IPA servers. Spin up another instance in your network that will run unbound or run it on a standalone bind server that you may have on a separate port. To forward to the unbound service, modify the DNS global configuration in IPA: # Replace 10.100.0.224 with the IP of your unbound instance % ipa dnsconfig-mod --forward-policy=only --forwarder='10.100.0.224' # Add 'port xxxx' if you have set unbound to another port % ipa dnsconfig-mod --forward-policy=only --forwarder='10.100.0.224 port 9553' Logging \u00b6 Audit Logs \u00b6 By default, the audit logs in /var/log/dirsrv/slapd-INSTANCE/audit do not get populated. And the access logs don't show much in terms of modifications and what is being changed. There is also /var/log/httpd/* logs, but it may be useful to see ldif style logging for changes against FreeIPA. # Modify the DSE configuration by turning on audit logging [label@ipa01 ~]# ldapmodify -D \"cn=directory manager\" -W -p 389 -h localhost Enter LDAP Password: dn: cn=config changetype: modify replace: nsslapd-auditlog-logging-enabled nsslapd-auditlog-logging-enabled: on # Press CTRL+d here modifying entry \"cn=config\" # To test, I'll add a user to a group [label@ipa01 ~]$ ipa group-add-member --users=jbaskets aocusers Group name: aocusers GID: 686600003 Member users: ..., jbaskets ------------------------- Number of members added 1 ------------------------- # Let's verify the log [label@ipa01 ~]$ sudo su - [sudo] password for label: Last login: Sun Mar 29 16:42:36 MST 2020 on pts/0 [root@ipa01 ~]# cd /var/log/dirsrv/slapd-EXAMPLE-NET/ [root@ipa01 slapd-EXAMPLE-NET]# cat audit time: 20200329223754 dn: cn=config result: 0 changetype: modify replace: nsslapd-auditlog-logging-enabled nsslapd-auditlog-logging-enabled: on - replace: modifiersname modifiersname: cn=directory manager - replace: modifytimestamp modifytimestamp: 20200330053754Z - 389-Directory/1.4.1.3 B2019.323.229 ipa01.example.net:636 (/etc/dirsrv/slapd-EXAMPLE-NET) # Looks like right here the modification happened time: 20200329224007 dn: cn=aocusers,cn=groups,cn=accounts,dc=example,dc=net result: 0 changetype: modify add: member member: uid=jbaskets,cn=users,cn=accounts,dc=example,dc=net - replace: modifiersname modifiersname: uid=label,cn=users,cn=accounts,dc=example,dc=net - replace: modifytimestamp modifytimestamp: 20200330054006Z - replace: entryusn entryusn: 900028 - Certificates \u00b6 These are notes of things I've ran into before while dealing with certificates. Renewed IPA HTTP Certificate Stuck \u00b6 This was something I discovered sort of on accident but never really \"noticed\" - Though I'm sure I would've noticed sometime in 2021 when my certificate expired. I was running ipa-healthcheck --failures-only as I do sometimes, and noticed some weird certmonger things pop up. But it made me look at my certificate list... [root@ipa01 ~]# ipa-getcert list Number of certificates and requests being tracked: 9. Request ID '20191106025922': status: MONITORING stuck: no key pair storage: type=FILE,location='/var/kerberos/krb5kdc/kdc.key' certificate: type=FILE,location='/var/kerberos/krb5kdc/kdc.crt' CA: IPA issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET expires: 2021-11-05 19:59:27 MST principal name: krbtgt/ANGELSOFCLOCKWORK.NET@ANGELSOFCLOCKWORK.NET key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment eku: id-kp-serverAuth,id-pkinit-KPKdc pre-save command: post-save command: /usr/libexec/ipa/certmonger/renew_kdc_cert track: yes auto-renew: yes Request ID '20200123075636': status: MONITORING stuck: no key pair storage: type=NSSDB,location='/etc/dirsrv/slapd-ANGELSOFCLOCKWORK-NET',nickname='Server-Cert',token='NSS Certificate DB',pinfile='/etc/dirsrv/slapd-ANGELSOFCLOCKWORK-NET/pwdfile.txt' certificate: type=NSSDB,location='/etc/dirsrv/slapd-ANGELSOFCLOCKWORK-NET',nickname='Server-Cert',token='NSS Certificate DB' CA: IPA issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET expires: 2021-11-05 19:55:33 MST dns: ipa01.angelsofclockwork.net principal name: ldap/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment eku: id-kp-serverAuth,id-kp-clientAuth pre-save command: post-save command: /usr/libexec/ipa/certmonger/restart_dirsrv ANGELSOFCLOCKWORK-NET track: yes auto-renew: yes Request ID '20200123075639': status: NEWLY_ADDED_NEED_KEYINFO_READ_PIN stuck: yes key pair storage: type=FILE,location='/var/lib/ipa/private/httpd.key' certificate: type=FILE,location='/var/lib/ipa/certs/httpd.crt' CA: IPA issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET expires: 2021-11-05 19:55:48 MST dns: ipa01.angelsofclockwork.net principal name: HTTP/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment eku: id-kp-serverAuth,id-kp-clientAuth pre-save command: post-save command: /usr/libexec/ipa/certmonger/restart_httpd track: yes auto-renew: yes Interestingly, I wasn't sure what NEWLY_ADDED_NEED_KEYINFO_READ_PIN meant and I couldn't really find much on what would cause this to happen. And I know my certificate isn't expired, according to the output. In fact, I checked with openssl just in case. [root@ipa01 ~]# openssl x509 -text -noout -in /var/lib/ipa/certs/httpd.crt | grep 'Not After' Not After : Nov 6 02:55:48 2021 GMT I'm not sure if this is just a result of migrating from Enterprise Linux 7 to 8 at the time, but it seemed easy enough to remove the tracking and put it back in, which ultimately fixed the monitoring state and now it was no longer \"stuck\". [root@ipa01 ~]# ipa-getcert stop-tracking -i 20200123075639 Request \"20200123075639\" removed. [root@ipa01 ~]# ipa-getcert start-tracking -f /var/lib/ipa/certs/httpd.crt -k /var/lib/ipa/private/httpd.key -p /var/lib/ipa/passwds/ipa01.angelsofclockwork.net-443-RSA -C /usr/libexec/ipa/certmonger/restart_httpd -K HTTP/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET New tracking request \"20200504003758\" added. [root@ipa01 ~]# ipa-getcert list -i \"20200504003758\" Number of certificates and requests being tracked: 9. Request ID '20200504003758': status: MONITORING stuck: no key pair storage: type=FILE,location='/var/lib/ipa/private/httpd.key',pinfile='/var/lib/ipa/passwds/ipa01.angelsofclockwork.net-443-RSA' certificate: type=FILE,location='/var/lib/ipa/certs/httpd.crt' CA: IPA issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET subject: CN=ipa01.angelsofclockwork.net,O=ANGELSOFCLOCKWORK.NET expires: 2021-11-05 19:55:48 MST dns: ipa01.angelsofclockwork.net principal name: HTTP/ipa01.angelsofclockwork.net@ANGELSOFCLOCKWORK.NET key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment eku: id-kp-serverAuth,id-kp-clientAuth pre-save command: post-save command: /usr/libexec/ipa/certmonger/restart_httpd track: yes auto-renew: yes CA Related Certificates Stuck \u00b6 Like with the IPA httpd certificates, I noticed at least 4 certificates stuck because a PIN was missing. Turns out that it's actually easy to modify the tracking request and fix the issue entirely. Below is my example doing this on the auditSigningCert. This seems to only occur on Enterprise Linux 8. [root@ipa01 alias]# getcert list -i 20200615180351 Number of certificates and requests being tracked: 9. Request ID '20200615180351': status: NEWLY_ADDED_NEED_KEYINFO_READ_PIN stuck: yes key pair storage: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca' certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca' CA: dogtag-ipa-ca-renew-agent issuer: subject: expires: unknown pre-save command: /usr/libexec/ipa/certmonger/stop_pkicad post-save command: /usr/libexec/ipa/certmonger/renew_ca_cert \"auditSigningCert cert-pki-ca\" track: yes auto-renew: yes [root@ipa01 alias]# getcert start-tracking -i 20200615180351 -p /etc/pki/pki-tomcat/alias/pwdfile.txt Request \"20200615180351\" modified. [root@ipa01 alias]# getcert list -i 20200615180351 Number of certificates and requests being tracked: 9. Request ID '20200615180351': status: MONITORING stuck: no key pair storage: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca',token='NSS Certificate DB',pinfile='/etc/pki/pki-tomcat/alias/pwdfile.txt' certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca',token='NSS Certificate DB' CA: dogtag-ipa-ca-renew-agent issuer: CN=Certificate Authority,O=ANGELSOFCLOCKWORK.NET subject: CN=CA Audit,O=ANGELSOFCLOCKWORK.NET expires: 2021-03-13 23:15:41 MST key usage: digitalSignature,nonRepudiation pre-save command: /usr/libexec/ipa/certmonger/stop_pkicad post-save command: /usr/libexec/ipa/certmonger/renew_ca_cert \"auditSigningCert cert-pki-ca\" track: yes auto-renew: yes Default Certificates with SAN \u00b6 A question that arises now and again is how to setup a load balancer for FreeIPA's LDAP servers whether it's an actual load balancer (layer 4) or some sort of DNS record with multiple A records, or perhaps with some sort of round robin DNS. The issue is that the certificate verification fails, because the certificate being presented is of the IPA server itself with no SAN. To address this, you have to create a host that has the name of the load balancer or DNS record you plan on using and allow the IPA servers to manage the host. CMS Communication Issues (403) \u00b6 This isn't necessarily certificate issue, but more or less an issue as it pertains to the certificate system itself. There may be cases where during upgrades, a configuration in /etc/pki/pki-tomcat/server.xml is not properly reconfigured. In that file, you'll notice Connector lines that have a secret and a requiredSecret parameter and they both have different values.This page contains the necessary resources to help you prepare for the Red Hat Certified Specialist in Identity Management exam, EX362. This follows the youtube playlist as much as possible with various examples and ideas. Soon to come, you will also find our own example practice exam for you to try your hand at to test your knowledge.
+The list of objectives can be found here. Note that the exam objectives can change at any time. It is the responsibility of the reader to always review the objectives prior to studying and taking the exam to ensure success.
+Note
+Affiliation and Exam Information
+Please note that we are not affiliated with Red Hat. The materials and examples used are our own and do not reflect the training programs provided by Red Hat and are educational only. We do not disclose any of the tasks, questions, or material on the exam as it would violate the NDA. Any questions sent to us about anything directly related to the exam will not be answered. We also do not provide any one-on-one tutoring or online teaching courses.
+If exam objectives have changed to where the videos and this material are missing information, we can add on at any time upon request. If exam objectives have not changed but operational tasks have, we will note them as we find them. If there are things about FreeIPA that you'd like to see in the videos that may fit into objective, we can add it also upon request. However, it is likely those extra things would be better suited in the separate FreeIPA section on this site.
+The video series goes over setting up FreeIPA in a lab/VM environment by following the objectives as outlined by Red Hat. The list of objectives can be found here.
+The EX362 exam tests your knowledge in a real world format style test - Meaning just like any Red Hat exam, it is performance-based and you perform tasks as if you were on the job. You are evaluated on the tasks you perform and if they meet the objective criteria. The EX362 is related to FreeIPA or Red Hat Identity Management and counts toward the RHCA (Red Hat Certified Architect).
+To take the exam, you must have at least an RHCSA. If you are attempting to become a Red Hat Certified Architect, you must have an RHCE.
+The minimum requirements for IdM are fairly low. 2GB of RAM, 1 core, and a 10GB disk. However, we believe that's too low, especially if we plan on scaling out. And during upgrades, you would need at least 4GB of RAM for the operations to be successful. Below are our minimum recommendations:
+Per the Red Hat documentation, consider that with at least 10k users and 100 groups, you would need at least 3GB of RAM and 1GB swap. If you end up having 100k users and 50k groups, then 16GB of RAM and 4GB of swap is recommended. In fact, in larger deployments, it's more effective to increase RAM than disk, as most data is stored in cache.
+View the resources above in the previous section for directory server tuning information.
+Server Name | +IP Address | +
---|---|
idm1.example.com | +192.168.15.2 | +
idm2.example.com | +192.168.15.3 | +
!!! note:: + IPA Servers should either have a DHCP reservation or a static address. In the event that you have either, DNS should always be pointing at 127.0.0.1, especially if your replica serves DNS. Both of our replicas serve DNS, so loopback is sufficient and recommended for our name server.
+In later versions of FreeIPA, there is support to force network manager to ensure resolv.conf is loopback without the need to set it by hand with nmcli.
+
+# Set a static address - It's important for your IdM servers
+# to have static addresses or a DHCP reservation.
+% nmcli con mod eth0 ipv4.address 192.168.15.2/24
+% nmcli con mod eth0 ipv4.gateway 192.168.15.1
+% nmcli con mod eth0 ipv4.method manual
+% nmcli con mod eth0 ipv4.dns-search example.com
+
+# You should set this if your replica serves DNS! If not, set it to
+# one or more of your IdM replicas that do.
+% nmcli con mod eth0 ipv4.dns 127.0.0.1
+% nmcli con up eth0
+
# Examples of using ipa-server-install
+# RHEL 9
+% yum install ipa-server ipa-server-dns ipa-client sssd sssd-ipa
+# Installation, interactive, does not setup specific components
+% ipa-server-install
+
+# Installation, mostly automatic (recommended)
+# This will setup DNS and the necessary pieces for an AD trust
+# Optionally, you can use the --netbios-name switch to set your forest netbios name
+% ipa-server-install --domain example.com --realm EXAMPLE.COM \
+ --reverse-zone=15.168.192.in-addr.arpa. \
+ --no-forwarders \
+ --no-ntp \
+ --setup-dns \
+ --setup-adtrust \
+ -p Passw0rd! \
+ -a Passw0rd!
+
# Configure the firewall for RHEL 7
+% firewall-cmd --permanent --add-service={ntp,http,https,freeipa-ldap,freeipa-ldaps,kerberos,freeipa-replication,kpasswd,dns}
+# RHEL 8
+% firewall-cmd --permanent --add-service={freeipa-4,ntp,dns}
+
% kinit admin
+# We need to make sure that any A records get a corresponding PTR record, otherwise you're making them manually.
+% ipa dnsconfig-mod --allow-sync-ptr=True
+
# Adding a replica
+% ipa-replica-install --setup-dns \
+ --setup-ca \
+ --no-forwarders
+
+# Adding a replica unattended without forwarders
+% ipa-client-install --realm EXAMPLE.COM
+% kinit admin
+% ipa hostgroup-add-member --hosts=ipa02.example.com ipaservers
+% ipa-replica-install --setup-dns \
+ --setup-ca \
+ --no-forwarders \
+ --unattended
+
Users | +Login Name | +Type | +Group | +Role | +UID/GID | +
---|---|---|---|---|---|
John Smith | +jsmith | +Normal | +admins | ++ | Auto | +
Bob Rufus | +brufus | +Normal | +corp | ++ | Auto | +
Larry Dufus | +ldufus | +Normal | +helpdesk | ++ | Auto | +
Robert Cole | +rcole | +Staged | ++ | + | Auto | +
Thomas Snyder | +tsnyder | +Preserved | ++ | + | Auto | +
SysHost Management | +syshostmgt | +Normal | ++ | Host Manager | +10000 | +
Groups | +Policy | +
---|---|
HelpDesk | +helpdesk | +
corp | ++ |
enrollers | +Enrollment Administrator | +
Roles | +Privilege | +
---|---|
Host Manager | +Host administrators | +
+ | Host group administrators | +
+ | Netgroups administrators | +
+ | Host enrollment | +
Note
+Custom UID/GID
+It is possible to create the users with a custom uid/gid with the switches --uid and --gidnumber which you will see below. It is also possible to set random passwords with --random.
+See ipa user-add --help for more switches.
+Note
+Password Expiration
+When you make a user with the --password switch or use ipa passwd to set a password, it is automatically expired and must be changed on next login. If you want to avoid this from happening, you will need to set a random password via --password or --random, and then use kpasswd username to change it to the desired password. This does not make the account non-expiring.
+# Creating users with a password, create all the accounts from the table (except from syshost)
+% ipa user-add --first="John" --last="Smith" --password jsmith
+
+# Create the system account with a password of Sup3R$ecre7! and a UID of 10000
+% ipa user-add --first="SysHost" --last="Management" --uid=10000 --gidnumber=10000 --password syshostmgt
+
+# Stage a user
+% ipa stageuser-add --first="Robert" --last="Cole" rcole
+
+# Preserve a user
+% ipa user-del tsynder --preserve
+
+# Create a regular (POSIX) group
+% ipa group-add corp
+
+# Create a member only group
+% ipa group-add --nonposix HelpDesk
+% ipa group-add --nonposix enrollers
+
+# Add the HelpDesk group to the helpdesk policy
+# Add the enrollers group to the Enrollment Administrator role
+% ipa role-add-member "helpdesk" --groups=HelpDesk
+% ipa role-add-member "Enrollment Administrator" --groups=enrollers
+
+# Create a role with privileges
+% ipa role-add "Host Manager"
+% ipa role-add-privilege "Host Manager" \
+ --privileges="Host administrators" \
+ --privileges="Host group administrators" \
+ --privileges="Netgroups administrators" \
+ --privileges="Host enrollment"
+
+# Add the syshostmgt user as a member of the role
+% ipa role-add-member "Host Manager" --users="syshostmgt"
+
+# Set our user passwords to CentOS123!$ so that way we don't have to change them later
+% kpasswd jsmith
+
+# If we already set the password we want but we don't want it to expire without making a policy or prompt for a password change (NOT RECOMMENDED)
+% ldapmodify -x -w 'Passw0rd!' -D 'cn=Directory Manager'
+dn: uid=syshostmgt,cn=users,cn=accounts,dc=example,dc=com
+changetype: modify
+delete: krbLastPwdChange
+
+(Press CTRL+D)
+
The common question we receive (and even the #freeipa IRC receive) is "Why can't we just set the password to not be expired right away?" See this page for information on why this is. You may also look at the pagure page and the Red Hat bugzilla related bug.
+To setup a very, very simple SSO, you can setup a simple location that requires a login.
+% ipa-getkeytab -s idm1.example.com -p http/http.example.com -k /etc/httpd/conf/http.keytab
+% vi /etc/httpd/conf.d/location.conf
+<Location "/">
+ AuthType Kerberos
+ AuthName "IPA Kerberos Auth"
+ # Keytab
+ Krb5Keytab /etc/httpd/conf/http.keytab
+ # Kerb settings
+ KrbMethodNegotiate on
+ KrbMethodK5Passwd on
+ KrbServiceName HTTP
+ KrbAuthRealms EXAMPLE.COM
+ KrbSaveCredentials off
+ Require valid-user
+</Location>
+
Client Name | +IP Address | +
---|---|
client.example.com | +192.168.15.10 | +
nfs.example.com | +192.168.15.11 | +
utility.example.com | +192.168.15.12 | +
Note
+Depending on your architecture and setup, IdM clients should either be pointing directly at the IdM servers for DNS (at least two of them) or pointing at the DNS server in the environment that is delegating that domain to the IdM domain controllers.
+In our lab, our IdM servers are our only DNS servers, thus it makes sense that our clients should point to them. In that scenario, you would configure your DHCP server to use the IdM servers as the name servers and/or configure them in a static manner depending on your environment.
+# If your client is not pointing at the IdM DNS and you
+# don't have another DNS server that's performing delegation,
+# change your name servers.
+% nmcli con mod eth0 ipv4.dns 192.168.15.2
+% nmcli con mod eth0 +ipv4.dns 192.168.15.3
+% nmcli con mod eth0 ipv4.dns-search example.com
+
+# Optionally, if your clients don't have DHCP
+# reservations, set a static address.
+% nmcli con mod eth0 ipv4.address 192.168.15.10/24
+% nmcli con mod eth0 ipv4.gateway 192.168.15.1
+% nmcli con mod eth0 ipv4.method manual
+
+# It might be a good idea to set your hostname if you haven't already
+% hostnamectl set-hostname client.example.com
+% hostname client.example.com
+
+# Install the ipa-client packages
+% yum install ipa-client -y
+% ipa-client-install --realm EXAMPLE.COM --domain example.com
+. . .
+% id admin
+uid=686600000(admin) gid=686600000(admins) groups=686600000(admins)
+
One of the things that you may end up doing, whether by hand or in an automated fashion, is creating kerberized services. In a previous section, we addressed creating an NFS service for both a server and a client for the purpose of automating home directory mounts on a client when a user logs in. So you already have the idea of what this entails.
+# Create kerberos service
+% ipa service-add HTTP/http.example.com
+
Not only that, it's probably a good idea to actually get the keytab.
+% kinit admin
+% ipa-getkeytab -s idm1.example.com -p HTTP/http.example.com -k /etc/krb5.keytab
+
For an example of automating keytab creation and retrieval, see the CentOS/FreeIPA page on this site.
+By default FreeIPA stands up its own CA. And because of this, this allows you or your workplace to be able to issue certificates, that can be used in a wide variety of services, the most common or obvious one would be for Apache httpd.
+There's a couple of ways you can get a certificate signed by FreeIPA. One method is to generate your own CSR and request it to be signed by FreeIPA. Another way is you can do it all from one command, ipa-getcert
, and optionally, either have the certificate in PEM format or an NSS database. We'll address these examples.
# Creating an SSL certificate in the PEM format
+% ipa service-add HTTP/http.example.com
+% ipa-getcert request -f /etc/pki/tls/certs/http.pem -k /etc/pki/tls/private/http.key -K HTTP/http.example.com -D http.example.com
+New signing request "20190902000318" added.
+# Verify
+% ipa-getcert list
+Number of certificates and requests being tracked: 1.
+Request ID '20190902000318':
+ status: MONITORING
+ stuck: no
+ key pair storage: type=FILE,location='/etc/pki/tls/private/http.key'
+ certificate: type=FILE,location='/etc/pki/tls/certs/http.pem'
+ CA: IPA
+ issuer: CN=Certificate Authority,O=EXAMPLE.COM
+ subject: CN=http.example.com,O=EXAMPLE.COM
+ expires: 2021-09-02 00:03:19 UTC
+ dns: http.example.com
+ principal name: HTTP/http.example.com@EXAMPLE.COM
+ key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
+ eku: id-kp-serverAuth,id-kp-clientAuth
+ pre-save command:
+ post-save command:
+ track: yes
+ auto-renew: yes
+
+# Create an SSL certificate in the NSS format
+% ipa-getcert request -d /etc/pki/tls/certs/nss -n 'Test' -K HTTP/http.example.com -D http.example.com
+New signing request "20190902000756" added.
+# Verify
+% ipa-getcert list
+. . .
+Request ID '20190902000756':
+ status: MONITORING
+ stuck: no
+ key pair storage: type=NSSDB,location='/etc/pki/tls/certs/nss',nickname='Test',token='NSS Certificate DB'
+ certificate: type=NSSDB,location='/etc/pki/tls/certs/nss',nickname='Test',token='NSS Certificate DB'
+ CA: IPA
+ issuer: CN=Certificate Authority,O=EXAMPLE.COM
+ subject: CN=http.example.com,O=EXAMPLE.COM
+ expires: 2021-09-02 00:07:57 UTC
+ dns: http.example.com
+ principal name: HTTP/http.example.com@EXAMPLE.COM
+ key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
+ eku: id-kp-serverAuth,id-kp-clientAuth
+ pre-save command:
+ post-save command:
+ track: yes
+ auto-renew: yes
+
By default, when a certificate request is performed (and succeeds to be signed by the IPA CA), it is typically tracked and auto-renewed by default. This is done by the certmonger service, which eliminates the need to have to renew anything by hand.
+When a domain supports the KRA role, it can hold password vaults or anything that's considered "secret". You can add the KRA role by simply running on each relevant domain controller:
+% ipa-kra-install
+
(more to come)
+In FreeIPA, there are two sets of policies:
+HBAC, or Host Based Access Controls, are permissions that grant user or users access to systems via any number of services. The services are PAM services. No doubt you have looked in /etc/pam.d
before and have seen quite a few files or even modified them by hand at some point.
% ls -l /etc/pam.d/
+total 80
+-rw-r--r--. 1 root root 272 May 11 2019 atd
+-rw-r--r--. 1 root root 232 Apr 15 15:28 config-util
+-rw-r--r--. 1 root root 328 Nov 8 2019 crond
+lrwxrwxrwx. 1 root root 32 Jan 14 2020 fingerprint-auth -> /etc/authselect/fingerprint-auth
+-rw-r--r--. 1 root root 70 Apr 24 06:35 ksu
+-rw-r--r--. 1 root root 715 Apr 24 05:38 login
+-rw-r--r--. 1 root root 154 Apr 15 15:28 other
+-rw-r--r--. 1 root root 168 Apr 6 20:08 passwd
+lrwxrwxrwx. 1 root root 29 Jan 14 2020 password-auth -> /etc/authselect/password-auth
+-rw-r--r--. 1 root root 155 Apr 8 22:00 polkit-1
+lrwxrwxrwx. 1 root root 25 Jan 14 2020 postlogin -> /etc/authselect/postlogin
+-rw-r--r--. 1 root root 640 Apr 24 05:38 remote
+-rw-r--r--. 1 root root 143 Apr 24 05:38 runuser
+-rw-r--r--. 1 root root 138 Apr 24 05:38 runuser-l
+lrwxrwxrwx. 1 root root 30 Jan 14 2020 smartcard-auth -> /etc/authselect/smartcard-auth
+lrwxrwxrwx. 1 root root 25 Jun 15 10:18 smtp -> /etc/alternatives/mta-pam
+-rw-r--r--. 1 root root 76 Apr 6 20:11 smtp.postfix
+-rw-r--r--. 1 root root 727 Feb 4 2020 sshd
+-rw-r--r--. 1 root root 214 Apr 23 20:48 sssd-shadowutils
+-rw-r--r--. 1 root root 566 Apr 24 05:38 su
+-rw-r--r--. 1 root root 154 Apr 23 19:40 sudo
+-rw-r--r--. 1 root root 178 Apr 23 19:40 sudo-i
+-rw-r--r--. 1 root root 137 Apr 24 05:38 su-l
+lrwxrwxrwx. 1 root root 27 Jan 14 2020 system-auth -> /etc/authselect/system-auth
+-rw-r--r--. 1 root root 248 Jul 21 07:57 systemd-user
+-rw-r--r--. 1 root root 84 May 11 2019 vlock
+
On a typical Red Hat system, the most common ones (such as su
, sshd
, sudo
) imports the system-auth
file, so the login request is processed through those means. When defining HBAC rules, you either must allow "all" services or be selective. For example, if an HBAC rule allows "sshd", a user is allowed to ssh into a system, but wouldn't allow them to login locally, as that goes through login
. If you want the user to be able to run the su
and sudo
commands, you would also need to allow those services. Otherwise, the user is denied, despite sudo policies being available.
[label@mgt ~]$ sudo -i
+[sudo] password for label:
+sudo: PAM account management error: Permission denied
+
In FreeIPA, there is typically a rule already predefined that allows everyone to access all systems and all services. This can be removed or disabled and this removes host access to everything immediately. This is typically recommended in most environments where there are security standards and procedures in place.
+# To disable
+% ipa hbacrule-disable allow_all
+# To delete instead
+% ipa hbacrule-del allow_all
+
When performing a FreeIPA installation, it is possible to add --no-hbac-allow
that will disable the allow_all rule.
Below are some examples of adding access.
+# Allow all admins to access all systems
+% ipa hbacrule-add --hostcat=all --servicecat=all --desc='Allow all admins to access all systems' All_Admins
+% ipa hbacrule-add-user --groups=admins All_Admins
+
+# And then test...
+% ipa hbactest --rules=All_Admins --user=jsmith --host=client.example.com --service=login
+
# Allow the corp users to access the client system only using the sshd pam services
+% ipa hbacrule-add --desc='Allow corp users to access client on ssh' corp_access
+% ipa hbacrule-add-user --groups=corp corp_access
+% ipa hbacrule-add-host --hosts=client.example.com corp_access
+% ipa hbacrule-add-service --hbacsvcs=sshd corp_access
+
+# And then test...
+% ipa hbactest --rules=corp_access --user=brufus --host=client.example.com --service=sshd
+
You will need to configure your NFS server to serve up roaming home directories for users and then your client should have automouting enabled.
+Note
+Client Kerberos Service
+It may not be required to create an nfs kerberos service for the client. The ipa-client-automount command may already handle this but it does not hurt to create one. In fact, the host keytab is used on the client side anyway. Creating an NFS client keytab may have been required back in the EL6 days.
+# IDM Steps
+% kinit admin
+% ipa service-add nfs/nfs.example.com
+% ipa service-add nfs/client.example.com
+
+# Setup the automounting locations
+% ipa automountmap-add default auto.home
+% ipa automountkey-add default --key "/home" --info auto.home auto.master
+% ipa automountkey-add default --key "*" --info "-fstype=nfs4,rw,sec=krb5,soft nfs.example.com:/exports/home/&" auto.home
+
+# NFS Server Steps
+% yum install nfs-utils -y
+% mkdir /exports/home
+% vi /etc/exports
+/exports/home *(rw,sec=sys:krb5:krb5i:krb5p)
+
+# Make the home directories for all users and move them to /export/home
+% mkhomedir_helper jsmith
+% mv /home/jsmith /export/home/
+
+# Create the necessary keytabs
+% kinit admin
+% ipa-getkeytab -s idm1.example.com -p nfs/nfs.example.com -k /etc/krb5.keytab
+
+# Verify keytab
+% klist -ket /etc/krb5.keytab
+
+# Enable and start nfs
+% systemctl enable nfs-server --now
+
+# Open the necessary firewall ports
+% firewall-cmd --add-service=nfs --permanent
+% firewall-cmd --complete-reload
+
+# Client steps
+% kinit admin
+% ipa-getkeytab -s idm1.example.com -p nfs/client.example.com -k /etc/krb5.keytab
+% ipa-client-automount --location=default
+
+# Verify keytab
+% klist -ket /etc/krb5.keytab
+
To test, login to the system via ssh or console and verify the home directory has mounted. /var/log/messages and secure will display errors in case of failure.
+Most services and applications that authenticate users do typically have LDAP support. IdM can be used as an LDAP backend. You typically need only a few things to authenticate users from IdM to an application.
+Below is a table of common DN's you may specify in an application:
+DN's | +Path | +Filter (if applicable) | +
---|---|---|
Base DN | +dc=example,dc=com | ++ |
User DN | +cn=users,cn=accounts,dc=example,dc=com | +uid=... | +
Group DN | +cn=groups,cn=accounts,dc=example,dc=com | +(objectClass=groupOfNames) | +
Bind DN | +uid=account,cn=sysaccounts,cn=etc,dc=example,dc=com | ++ |
% ipa user-show admin --all | grep '^dn'
+ dn: uid=admin,cn=users,cn=accounts,dc=example,dc=com
+
Below is a table of common attributes that may be used to map user information in the application.
+Type | +Attribute | +
---|---|
Login Name | +uid | +
First Name | +givenName | +
Surname | +sn | +
Groups | +memberOf | +
Full Name | +cn | +
Below are two ways to create a bind account (bind DN). The first way is the LDAP way. The second way is the ipa-ldap-updater.
+% kinit admin
+% ldapadd -Y GSSAPI
+. . .
+dn: uid=binder,cn=sysaccounts,cn=etc,dc=example,dc=com
+objectclass: account
+objectclass: simplesecurityobject
+uid: binder
+userPassword: password123
+passwordExpirationTime: 20380119031407Z
+nsIdleTimeout: 0
+# Press CTRL+d
+adding new entry "uid=binder,cn=sysaccounts,cn=etc,dc=example,dc=com"
+
% kinit admin
+% cat << EOF > binder.update
+dn: uid=binder,cn=sysaccounts,cn=etc,dc=example,dc=com
+add:objectclass:account
+add:objectclass:simplesecurityobject
+add:uid:binder
+add:userPassword:password123
+add:passwordExpirationTime:20380119031407Z
+add:nsIdleTimeout:0
+EOF
+% ipa-ldap-updater binder.update
+
When this account is created, you can then specify the full DN for that object into a bind DN field, along with it's password into an accompanying bind password field.
+If you'd like an example of setting up Ansible Tower (or AWX, the open source version of tower) against IdM, you can click here.
+Note
+Kerberos
+On some applications, it is possible to use kerberos authentication rather than a straight bind account. The general idea is the same when picking out the base dn, attributes, and the like. However, instead you would create an account with an accompanying LDAP/... service principal to do the authentication.
+Note
+AD Setup
+We do not cover setting up an AD forest here. This is out of scope for this series. If you are using Server 2016 or higher and you are using "core", look up the commands:
+Install-WindowsFeature AD-domain-services +Import-Module ADDSDeployment +Install-ADDSForest
+Server Name | +IP Address | +
---|---|
ad.example.net | +192.168.15.15 | +
For our trust, the AD server will need to be configured to be the example.net domain with the hostname of ad.example.net. This way, we are not colliding in DNS and both AD and IdM should be able to communicate with each other as two separate forests. It is recommended to use Windows Server 2016 (with the same domain functional level) for this setup, as experience with that product is a recommended prerequisite for the exam.
+% yum install ipa-server-trust-ad -y
+% firewall-cmd --add-service=freeipa-trust --permanent
+success
+% firewall-cmd --reload
+success
+% ipa-adtrust-install
+. . .
+# This is the admin@REALM IPA account
+admin password:
+
+WARNING: The smb.conf already exists. Running ipa-adtrust-install will break your existing samba configuration.
+
+# Type 'yes' here
+Do you wish to continue? [no]: yes
+
+Do you want to enable support for trusted domains in Schema Compatibility plugin?
+This will allow clients older than SSSD 1.9 and non-Linux clients to work with trusted users.
+
+# You can press enter here to accept the default. If you have BSD, Solaris, Omnios, HP-UX, AIX, or RHEL 5 and older clients
+# you may want to enable this. Some apps may benefit from this also.
+Enable trusted domains support in slapi-nis? [no]:
+
+Enter the NetBIOS name for the IPA domain.
+Only up to 15 uppercase ASCII letters, digits and dashes are allowed.
+Example: EXAMPLE.
+
+# You can accept the default or put your own.
+NetBIOS domain name [IPA]: IPA0
+
+WARNING: 4 existing users or groups do not have a SID identifier assigned.
+Installer can run a task to have ipa-sidgen Directory Server plugin generate
+the SID identifier for all these users. Please note, in case of a high
+number of users and groups, the operation might lead to high replication
+traffic and performance degradation. Refer to ipa-adtrust-install(1) man page
+for details.
+
+# You should always say yes.
+Do you want to run the ipa-sidgen task? [no]: yes
+
+. . .
+
+# This will complete and list ports to open and such. We did this earlier.
+
Now that the AD trust components are prepped, depending on the setup, we'll need to do some DNS zone forwards. It is likely you have IPA and AD running their own DNS. Note: This may not be the case in a real world scenario.
+# We need to create a forward zone here for the example.net zone
+% ipa dnsforwardzone-add example.net --forwarder=192.168.15.15 --forward-policy=only
+Server will check DNS forwarder(s).
+This may take some time, please wait ...
+ Zone name: example.net.
+ Active zone: TRUE
+ Zone forwarders: 192.168.15.15
+ Forward policy: only
+
+# We should probably create a few dns records...
+# Assuming the AD netbios name is EXAMPLEAD, use the syntax hostname.NETBIOS here
+% ipa dnsrecord-add example.com ad.EXAMPLEAD --a-ip-address=192.168.15.15
+# Same idea here, but we're only doing the netbios name and saying the name server record is the AD server
+% ipa dnsrecord-add example.com EXAMPLEAD --ns-hostname=ad.EXAMPLEAD
+
+# We need to allow the zones to be transferable to the AD domain
+% ipa dnszone-mod example.com --allow-transfer=192.168.15.15
+
On the AD side, we need to create the IPA zone. It's absolutely required.
+C:\Windows\System32>dnscmd 127.0.0.1 /ZoneAdd example.com /Secondary 192.168.15.2
+
% dig _ldap._tcp.example.com SRV
+; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> SRV _ldap._tcp.example.com
+;; global options: +cmd
+;; Got answer:
+;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14793
+;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2
+
+;; OPT PSEUDOSECTION:
+; EDNS: version: 0, flags:; udp: 4096
+;; QUESTION SECTION:
+;_ldap._tcp.example.com. IN SRV
+
+;; ANSWER SECTION:
+_ldap._tcp.example.com. 86400 IN SRV 0 100 389 idm1.example.com.
+_ldap._tcp.example.com. 86400 IN SRV 0 100 389 idm2.example.com.
+
+;; AUTHORITY SECTION:
+example.com. 86400 IN NS idm1.example.com.
+example.com. 86400 IN NS idm2.example.com.
+
+;; ADDITIONAL SECTION:
+idm1.example.com. 1200 IN A 192.168.15.2
+idm2.example.com. 1200 IN A 192.168.15.3
+
+# Same with the AD records
+% dig _ldap._tcp.example.net SRV
+; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> SRV _ldap._tcp.example.net
+;; global options: +cmd
+;; Got answer:
+;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12195
+;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 9
+
+;; OPT PSEUDOSECTION:
+; EDNS: version: 0, flags:; udp: 4096
+;; QUESTION SECTION:
+;_ldap._tcp.example.net. IN SRV
+
+;; ANSWER SECTION:
+_ldap._tcp.example.net. 600 IN SRV 0 100 389 ad.example.net.
+
+. . .
+
Now that they are returning, intiate the trust.
+% ipa trust-add --type=ad example.net --admin Administrator --password
+Active Directiron domain administrator's password: (type password here)
+-----------------------------------------------------
+Added Active Directory trust for realm "example.net"
+-----------------------------------------------------
+ Realm name: example.net
+ Domain NetBIOS name: EXAMPLEAD
+ Domain Security Identifier: S-1-5-21-XXXXXXXXXX-YYYYYYYYY-ZZZZZZZZZZ
+ Trust direction: Trusting forest
+ Trust type: Active Directory domain
+ Trust status: Established and verified
+
+# Check that an AD user is resolvable. You can do this with DOMAIN\name or name@DOMAIN
+% id EXAMPLEAD\\administrator
+% id administrator@example.net
+
As we disabled the allow_all rule, let's create a set of groups first and then the HBAC rule.
+# Create the starting AD group
+% ipa group-add adusers
+# Create an external group. This is required for AD users.
+% ipa group-add --external adgroup_external
+# Add an AD user into the external group
+% ipa group-add-member --users=administrator@example.net adgroup_external
+# Make the external group a member of ad users
+% ipa group-add-member --groups=adgroup_external adusers
+
As we've made an HBAC rule before, this should be simple.
+% ipa hbacrule-add --hostcat=all --servicecat=all --desc='ad users all access' adusers_access
+% ipa hbacrule-add-user --groups=adusers adusers_access
+% ipa hbactest --rules=adusers_access --user=administrator@example.net --host=client.example.com --service=sshd
+
The test should pass without any issues.
+Note
+Group Types
+While this may not be required information while working on the exam, it's important to understand that there are different group types in AD and the behavior changes based on the group type.
+Groups in Active Directory have three types. These three types can actually change the behavior of how SSSD on the IPA domain controllers resolve them or if they'll even be resolvable at all. The three types are 'Domain Local', 'Global', and 'Universal'. If at all possible, avoid groups being 'Global'. Domain Local or Universal is recommended.
+There are multiple ways you can backup IPA.
+# Turns off IPA completely and perform a backup
+% ipa-backup
+# Backs up and gpg encrypts
+% ipa-backup --gpg --gpg-keyring=/root/keys
+
To restore a backup, the ipa-restore command is available.
+% ipa-restore /var/lib/ipa/backup/
+
The backup command allows you to pass an online flag to ensure a backup taken doesn't down the IPA services. Note that not everything can be backed up online.
+# Backs up data only and doesn't take down IPA
+% ipa-backup --data --online
+# Backs up data only and gpg encrypts
+% ipa-backup --gpg --gpg-keyring=/root/keys --data --online
+
When you invoke the ipa
command, you are actually communicating with the API that runs on the IdM replicas. Operations done are sent via a POST with JSON data. The return data is also in JSON and translated to be readable in the terminal. Because it's JSON, custom scripts can be made with say perl or python that communicates with the API to send the calls, perhaps for specific tasks, jobs, or other operations that could be automated. You can also use curl
to do this also if you so choose.
The question becomes, "well, how do I know the right data to send?" You can issue the -vv switch to see the request being sent.
+% ipa -vv ping
+ipa: INFO: trying https://idm1.example.com/ipa/json
+ipa: INFO: [try 1]: Forwarding 'schema' to json server 'https://idm1.example.com/ipa/json'
+ipa: INFO: trying https://idm1.example.com/ipa/session/json
+ipa: INFO: [try 1]: Forwarding 'ping/1' to json server 'https://idm1.example.com/ipa/session/json'
+ipa: INFO: Request: {
+ "id": 0,
+ "method": "ping/1",
+ "params": [
+ [],
+ {
+ "version": "2.251"
+ }
+ ]
+}
+ipa: INFO: Response: {
+ "error": null,
+ "id": 0,
+ "principal": "admin@EXAMPLE.COM",
+ "result": {
+ "summary": "IPA server version 4.10.2. API version 2.251"
+ },
+ "version": "4.10.2"
+}
+--------------------------------------------
+IPA server version 4.10.2. API version 2.251
+--------------------------------------------
+
If you look at the 'request' section, you can see the data that is sent. Each request has a method
and params
, where method is a command to be excuted and params is simply an array that contains positional arguments and a dictionary of options. If you take a look at say, group-show, you would see a different request.
% ipa -vv group-show admins
+ipa: INFO: trying https://idm1.example.com/ipa/session/json
+ipa: INFO: [try 1]: Forwarding 'group_show/1' to json server 'https://idm1.example.com/ipa/session/json'
+ipa: INFO: Request: {
+ "id": 0,
+ "method": "group_show/1",
+ "params": [
+ [
+ "admins"
+ ],
+ {
+ "version": "2.230"
+ }
+ ]
+}
+### Lots of output ###
+
Let's say I wanted to perform that in a simple bash script that uses curl. I would perform a kinit
and then run the script below to have it login for me via kerberos and do the work.
#!/bin/bash
+ipaReplica=idm1.example.com
+cookieJar=my.cookie.jar
+
+# Login with Kerberos
+curl -v \
+ -H referer:https://$ipaReplica/ipa \
+ -c $cookieJar -b $cookieJar \
+ --cacert /etc/ipa/ca.crt \
+ --negotiate -u : \
+ -X POST \
+ https://$ipaReplica/ipa/session/login_kerberos
+
+# Send user_find method request
+curl -v \
+ -H referer:https://$ipaReplica/ipa \
+ -H "Content-Type:application/json" \
+ -H "Accept:applicaton/json"\
+ -c $cookieJar -b $cookieJar \
+ --cacert /etc/ipa/ca.crt \
+ -d '{"method":"group_show/1","params":[["admins"],{}],"id":0}' \
+ -X POST \
+ https://$ipaReplica/ipa/session/json
+
Any of the commands ran via ipa
can be reviewed with the -vv switch so you can see what kind of call it's making and how it's making it. Thus, making it easier to tie into your own scripts. On the Web UI, you can go to IPA Server -> API Browser to find more information on the specific API calls.
While not strictly a certification objective at this present time, there may be a chance it could be. FreeIPA 4.10+ have the ability to implement authentication to external identity providers. FreeIPA allows you to use RADIUS proxy authentication for example, but using this same method, an OAuth 2.0 authorization server could be used as well. When it comes to an IdP, you can instead configure IdP clients using ipa idp-add
and use software like Keycloak or otherwise that supports OAuth 2.0 workflows. We recommend checking out the FreeIPA Workshop Unit 12 for more details.