FreeIPA

From Leo's Notes
Last edited on 14 January 2024, at 07:40.

Installation

Here are my notes as I fumble my way setting up FreeIPA.

Docker

There is an official Docker container that has a complete FreeIPA installation. This container uses systemd to start up FreeIPA along with the other related services such as OpenLDAP, Bind, and Kerberos. See more at: https://github.com/freeipa/freeipa-container

If you are using Docker, you must disable cgroup v2 (this is enabled by default on RHEL9 and above). More about this in the Troubleshooting section below.

Use the following docker-compose.yml stack to quickly get started with FreeIPA:

version: '3.3'

services:

  freeipa:
    image: freeipa/freeipa-server:rocky-8
    restart: unless-stopped
    tty: true
    stdin_open: true
    hostname: ipa
    domainname: home.steamr.com
    extra_hosts:
      - "ipa.home.steamr.com:10.1.2.12"
    environment:
      - IPA_SERVER_HOSTNAME=ipa.home.steamr.com
      - IPA_SERVER_IP=10.1.2.12
      - DNS=10.1.0.8
      - TZ=America/Edmonton
    command:
      - ipa-server-install
      - --realm=home.steamr.com
      - --domain=home.steamr.com
      - --ds-password=xxxxxxxxxx
      - --admin-password=xxxxxxxxxx
      - --no-host-dns
      - --setup-dns
      - --auto-forwarders
      - --allow-zone-overlap
      - --no-dnssec-validation
      - --unattended
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=0
    volumes:
      - ./data:/data
      - ./logs:/var/logs
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    tmpfs:
      - /run
      - /var/cache
      - /tmp
    cap_add:
      - SYS_TIME
    ports:
      - "10.1.2.12:80:80/tcp"
      - "10.1.2.12:443:443/tcp"
      # DNS
      - "10.1.2.12:53:53/tcp"
      - "10.1.2.12:53:53/udp"
      # LDAP(S)
      - "10.1.2.12:389:389/tcp"
      - "10.1.2.12:636:636/tcp"
      # Kerberos
      - "10.1.2.12:88:88/tcp"
      - "10.1.2.12:464:464/tcp"
      - "10.1.2.12:88:88/udp"
      - "10.1.2.12:464:464/udp"

Samba integration

There are 3 methods to using FreeIPA with Samba. I eventually settled on method #2.

  1. Configure Samba to use FreeIPA as a simple LDAP server, using ldapsam as the passdb backend. This requires a schema change to include the sambaSAMAccount and sambaGroupMapping, and sambaSID object classes. There is a DNA (distributed numeric assignment) plugin that can be used to update these fields.
  2. Configure Samba to use FreeIPA using ipasam as the passdb backend. This requires the ipasam.so module installed on the samba servers.
  3. Configure Samba to use Kerberos. Does not seem to allow users to use password authentication.

Method 1: ldapsam

I didn't get this to work
I wasn't able to fully get this method to work. If you are using OpenLDAP only, this way of integrating Samba does work. The issue I had was getting the DNA plugin to work as advertised.

I eventually settled on the ipasam method in the section below.

To use ldapsam, we need to make some changes to the FreeIPA LDAP server by adding sambaSAMAccount and sambaGroupMapping as a default user object class and group object class.

You can either set this in the FreeIPA web interface under configuration, or run:

# ldapmodify <<EOF
dn: cn=ipaConfig,cn=etc,dc=home,dc=steamr,dc=com
changetype: modify
add: ipaUserObjectClasses
ipaUserObjectClasses: sambaSAMAccount
-
add: ipaGroupObjectClasses
ipaGroupObjectClasses: sambaGroupMapping
EOF

We will then need to make a custom DNA (distributed numeric assignment) plugin to update these attributes whenever something related to the object (such as the password) is changed. This can be done by adding a DNA object into LDAP.

ldapadd <<EOF
dn: cn=SambaSid,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
objectClass: top
objectClass: extensibleObject
dnatype: sambaSID
dnaprefix: S-1-5-21-2049073866-1371207509-1214748462
dnainterval: 1
dnamagicregen: assign
dnafilter: (|(objectclass=sambasamaccount)(objectclass=sambagroupmapping))
dnascope: dc=home,dc=steamr,dc=com
cn: SambaSid
dnanextvalue: 2

dn: cn=sambaGroupType,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
objectClass: top
objectClass: extensibleObject
cn: sambaGroupType
dnatype: sambaGroupType
dnainterval: 1
dnamagicregen: assign
dnafilter: (objectClass=sambagroupmapping)
dnascope: dc=home,dc=steamr,dc=com
dnanextvalue: 2
EOF

A ldapsam user entry should have these fields. I don't see these though.

dn: uid=guest2, ou=People,dc=quenya,dc=org
sambaLMPassword: 878D8014606CDA29677A44EFA1353FC7
sambaPwdMustChange: 2147483647
sambaPrimaryGroupSID: S-1-5-21-2447931902-1787058256-3961074038-513
sambaNTPassword: 552902031BEDE9EFAAD3B435B51404EE
sambaPwdLastSet: 1010179124
sambaLogonTime: 0
objectClass: sambaSamAccount
uid: guest2
sambaKickoffTime: 2147483647
sambaAcctFlags: [UX         ]
sambaLogoffTime: 2147483647
sambaSID: S-1-5-21-2447931902-1787058256-3961074038-5006
sambaPwdCanChange: 0

Configure the Samba server

You can either use a specific binding credential that's shared across all your samba servers, or use the machine's cifs service account to authenticate to the LDAP server.

I tried to do the following using the admin account as the bind DN: (using the admin account like this is probably a bad idea, I'm just testing)

[global]
	# freeipa configurations
	passdb backend = ipasam:ldap://home.steamr.com
	ldap admin dn = uid=admin,cn=users,cn=accounts,dc=home,dc=steamr,dc=com
	ldapsam:trusted = yes
	ldap suffix = cn=accounts,dc=home,dc=steamr,dc=com
	ldap user suffix = cn=users,cn=accounts
	ldap machine suffix = cn=computers,cn=accounts
	ldap group suffix = cn=groups,cn=accounts
	ldap passwd sync = only
	ldap ssl = no

Run smbpasswd -w password to set your bind credential passwords.

Method 2: ipasam

See: https://bgstack15.wordpress.com/2017/05/10/samba-share-with-freeipa-auth/

Install the adtrust components on the FreeIPA server. Install ipa-server-trust-ad and run ipa-adtrust-install --add-sids. This will add the additional IPASAM attributes such as ipaNtPassword in user objects.

# ipa-adtrust-install --add-sids
## Answer yes to overwrite smb.conf
## Answer yes to install slapi-nis

Ensure that your hostname is set to the FQDN of the hostname otherwise this process will fail. If you are using an external DNS server, ensure that the additional service records are present. If you are using a Docker container, set the hostname to the full FQDN (eg. ipa.example.com, rather than just 'ipa').

Next, create a new user and then change the user's password. This should populate the ipaNTPassword attribute.

# ipa user-add leo --first=Leo --last=Leung
# ipa group-add-member smbgrp --users=leo

When modifying smb.conf, the service account or bind DN must have access to these new ipasam attributes. You need to create a new set of privilege and role and grant the account access. Create the role and permissions in the web interface or run:

# ipa permission-add "CIFS server can read user passwords"  --attrs={ipaNTHash,ipaNTSecurityIdentifier} --type=user --right={read,search,compare} --bindtype=permission
# ipa privilege-add "CIFS server privilege"
# ipa privilege-add-permission "CIFS server privilege" --permission="CIFS server can read user passwords"
# ipa role-add "CIFS server"
# ipa role-add-privilege "CIFS server" --privilege="CIFS server privilege"

Then, add your service account or bind DN to the 'CIFS server' role. For example:

# ipa service-add cifs/dnas.home.steamr.com
# ipa role-add-member "CIFS server" --services=cifs/dnas.home.steamr.com

Configure the Samba server

Generate a keytab file for samba.

# kinit -kt /etc/krb5.keytab
## Note: we ran this in the previous step.
## ipa service-add cifs/dnas.home.steamr.com
# ipa-getkeytab -s ipa.home.steamr.com -p cifs/dnas.home.steamr.com -k /etc/samba/samba.keytab

Then, tweak smb.conf.

[global]
passdb backend = ipasam:ldap://ipa.home.steamr.com
ldapsam:trusted = yes
ldap suffix = dc=home,dc=steamr,dc=com
ldap user suffix = cn=users,cn=accounts
ldap machine suffix = cn=computers,cn=accounts
ldap group suffix = cn=groups,cn=accounts
ldap ssl = no
idmap config * : backend = tdb  
create krb5 conf = No 
dedicated keytab file = FILE:/etc/samba/samba.keytab
kerberos method = dedicated keytab

If you get: NT_STATUS_BAD_TOKEN_TYPE, you need to disable MS-POC in the FreeIPA settings or disable it specifically for this cifs service account.

The ipasam passdb provider is available from the ipa-server-trust-ad package. However, this package also pulls in a ton of other IPA dependencies which aren't needed if you just want to run Samba that talks to IPA and not the entire FreeIPA server. If you just want the provider to work on a bare minimal samba server, you can simply just copy (or extract from the ipa-server-trust-ad package) the ipasam.so file to /usr/lib64/samba/pdb/ipasam.so with this set of commands:

# yum download ipa-server-trust-ad
# mkdir x && cd x
# rpm2cpio ../ipa-server-trust-ad*rpm | cpio -id ./usr/lib64/samba/pdb/ipasam.so
# cp ./usr/lib64/samba/pdb/ipasam.so /usr/lib64/samba/pdb/ipasam.so

Method 3: Kerberos

This method is similar to the ipasam method above and you will need to set up the server in the same way. However, the way you configure Samba is different.

On the Samba server

## Join the samba server to FreeIPA
# ipa-client-install

## Then add the client to samba.
# ipa-client-samba

Note that when you try adding the samba client, the IPA server has to be able to resolve the A record for the Samba server you're adding or else it will fail.

This should automatically set up the cifs service accounts for this particular samba server, get the samba keytab file in /etc/samba/samba.keytab, and then tweak the smb.conf file to use this keytab file.

The smb.conf file now looks like:

[global]
    # Limit number of forked processes to avoid SMBLoris attack
    max smbd processes = 1000
    # Use dedicated Samba keytab. The key there must be synchronized
    # with Samba tdb databases or nothing will work
    dedicated keytab file = FILE:/etc/samba/samba.keytab
    kerberos method = dedicated keytab
    # Set up logging per machine and Samba process
    log file = /var/log/samba/log.%m
    log level = 1
    # We force 'member server' role to allow winbind automatically
    # discover what is supported by the domain controller side
    server role = member server
    realm = HOME.STEAMR.COM
    netbios name = DNAS
    workgroup = HOME
    # Local writable range for IDs not coming from IPA or trusted domains
    idmap config * : range = 0 - 0
    idmap config * : backend = tdb


    idmap config HOME : range = 100000 - 299999
    idmap config HOME : backend = sss


# Default homes share
[homes]
    read only = no

You need to then start winbind and smb. For some reason, this method doesn't seem to work as winbind is stuck with "wb_parent_idmap_setup_lookupname_done: Lookup domain name 'home' failed 'NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND'"

Debug samba issues

Use smbclient to help debug issues. This utility is provided by the samba-client package. You can then test authentication by running: smbclient -d 10 -U leo //dnas/home

Tasks

Join a computer to a FreeIPA

Use the ipa-client-install command to add a computer to a FreeIPA server. This should also automatically add a computer account, generate a keytab file, and tweak sssd to use FreeIPA as an authentication mechanism.

# ipa-client-install -U -p admin -w $Password --server ipa.home.steamr.com --domain home.steamr.com --force-join --no-ntp --fixed-primary

Troubleshooting

Error: did not receive Kerberos credentials

Tools such as 'ipa' uses your session's Kerberos tickets for authentication. If you don't have any tickets or if your tickets expired, you may get an ipa: ERROR: did not receive Kerberos credentials error. Fix this by running:

## Renew/obtain Kerberos tickets for 'admin'
# kinit admin
Password for admin@HOME.STEAMR.COM:  ****

Verify if your tickets are available with klist:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin@STEAMR.COM

Valid starting     Expires            Service principal
03/06/22 14:44:35  03/07/22 14:39:47  krbtgt/STEAMR.COM@STEAMR.COM

Container issues

  • Don't mount /var/log because the container image symlinks everything into /data. If you do mount /var/log, make sure you make the expected directories or else the installer will fail.
  • Error with AssertionError: Another instance named 'HOME-STEAMR-COM' may already exist. I can't figure out what's causing lib389 to think there's another instance. I built a container image on top of this image with the assertion patched out. This seemed to have fixed the issue.
  • FROM freeipa/freeipa-server:rocky-8
    RUN sed 's/assert_c(len(insts)/# assert_c(len(insts)/' -i /usr/lib/python3.6/site-packages/lib389/instance/setup.py
    

Can't find the ipa-adtrust-install package

The FreeIPA packages are under a different app stream repo. Enable it by running dnf -y module enable idm:DL1.

sssd: Decrypt integrity check failed

After recreating the FreeIPA server, I uninstalled and reinstalled the FreeIPA client on a machine. Kinit works as expected, but sssd authentication fails with the following error in /var/log/sssd/.

[krb5_child[29691]] [get_and_save_tgt] (0x0020): [RID#6] 1725: [-1765328353][Decrypt integrity check failed]

The fix here is to wipe out all the caches. sss_cache -E isn't sufficient. You have to stop sssd and delete all the databases:

# systemctl stop sssd
# rm -rf /var/lib/sss/db/*
# systemctl start sssd

File permission issues

I ran into issues starting FreeIPA in a Docker container. Symptoms include the following issues in the subsections below.

Bind / named doesn't start:

ipa named-pkcs11[5407]: LDAP error: Invalid credentials: bind to LDAP server failed
ipa named-pkcs11[5407]: couldn't establish connection in LDAP connection pool: permission denied
ipa named-pkcs11[5407]: dynamic database 'ipa' configuration failed: permission denied
ipa named-pkcs11[5407]: loading configuration: permission denied
ipa named-pkcs11[5407]: exiting (due to fatal error)

Ignore this for now. You have other issues, likely.

Samba doesn't start: Error: Invalid credentials

When trying to start smb, I get the following:

[2023/01/24 05:17:46.170883,  0, pid=5124] ipa_sam.c:4945(bind_callback)
  bind_callback: cannot perform interactive SASL bind with GSSAPI. LDAP security error is 49
[2023/01/24 05:17:46.171155,  0, pid=5124] ../../source3/lib/smbldap.c:1059(smbldap_connect_system)
  failed to bind to server ldapi://%2fvar%2frun%2fslapd-HOME-STEAMR-COM.socket with dn="[Anonymous bind]" Error: Invalid credentials
        (unknown)
[2023/01/24 05:17:46.171419,  1, pid=5124] ../../source3/lib/smbldap.c:1272(get_cached_ldap_connect)
  Connection to LDAP server failed for the 1 try!

The fix was to stop FreeIPA with ipactl stop, then rm /run/samba/krb5cc_samba, and restarting FreeIPA with ipactl start. If the error recurrs after restarting FreeIPA, then you have other issues that's preventing Samba from starting.

Tomcat doesn't start: status=5/NOTINSTALLED

When trying to start Tomcat, you get a 5 exit code, as reported by systemd:

pki-tomcatd@pki-tomcat.service: Control process exited, code=exited, status=5/NOTINSTALLED
pki-tomcatd@pki-tomcat.service: Failed with result 'exit-code'.
Failed to start PKI Tomcat Server pki-tomcat.

The exit code 5 being 'NOTINSTALLED' is a red herring. You likely have permission issues that's preventing the user running tomcat (pkiuser) from accessing some certs or configs. Go through your Docker volumes and chown anything directory called 'pki' to the pkiuser.

# chown -R 17:17 etc/pki etc/sysconfig/pki var/lib/pki var/lib/ipa/pki-ca

Tomcat still doesn't start: start-post operation timed out. Terminating.

Tomcat doesn't start as it times out.

pki-tomcatd@pki-tomcat.service: start-post operation timed out. Terminating.
pki-tomcatd@pki-tomcat.service: Control process exited, code=killed, status=15/TERM
pki-tomcatd@pki-tomcat.service: Failed with result 'timeout'.

There's likely still something tomcat can't write to.

It seemed to get better when made the ownerships for /data/var/lib/pki/pki-tomcat/logs/ and /var/log/pki/pki-tomcat to pkiuser.

To help troubleshoot, su as pkiuser and try running tomcat as per the service file and see if you get any stack traces.

IPA Web GUI reports "Your session has expired. Please re-login"

Review the logs for dirsrv and see if there are any errors.

# tail -f /var/log/dirsrv/slapd-*/access

For this instance, this was caused when I accidentally removed /etc/dirsrv/ds.keytab.

Configuring Samba issues

When running # ipa-adtrust-install --add-sids, you get:

# ipa-adtrust-install --add-sids
...
Configuring CIFS
  [1/25]: validate server hostname
  [error] ValueError: Host reports different name than configured: 'ipa' versus 'ipa.home.steamr.com'. Samba requires to have the same hostname or Kerberos principal 'cifs/ipa.home.steamr.com' will not be found in Samba keytab.
Unexpected error - see /var/log/ipaserver-adtrust-install.log for details:
ValueError: Host reports different name than configured: 'ipa' versus 'ipa.home.steamr.com'. Samba requires to have the same hostname or Kerberos principal 'cifs/ipa.home.steamr.com' will not be found in Samba keytab.

Ensure that your hostname is the full FQDN.

# hostname
ipa
# hostname -f
ipa.home.steamr.com

## You need to fix the hostname so that this is what you get:
# hostname ipa.home.steamr.com
# hostname
ipa.home.steamr.com

Once the hostname is fixed, try the command again.

DNS is missing A/AAAA entries for hosts

When trying to add a new host, the DNS silently gets ignored. Possible issues:

  • I think this is related to this error when running ipa-client-install: Could not update DNS SSHFP records..
  • Possibly bad DNS entries during install was detected and it skipped the DNS tasks?
    Hostname (fc37.home.steamr.com) does not have A/AAAA record.
    Failed to update DNS records.
    Missing A/AAAA record(s) for host fc37.home.steamr.com: 10.1.2.32.
    Incorrect reverse record(s):
    10.1.2.32 is pointing to fc35.home.steamr.com. instead of fc37.home.steamr.com.
    

Without this DNS entry set, other issues will crop up later on:

[root@ipa /]# ipa service-add cifs/dnas.home.steamr.com
ipa: ERROR: Host 'dnas.home.steamr.com' does not have corresponding DNS A/AAAA record

The quick work-around would be to add the DNS entry manually and try again.

FreeIPA doesn't start under Docker: Failed to allocate manager object

When trying to run FreeIPA under Docker, you get the following message almost immediately on startup:

Detected virtualization docker.
Detected architecture x86-64.
Failed to create /init.scope control group: Read-only file system
Failed to allocate manager object: Read-only file system
[!!!!!!] Failed to allocate manager object.
Exiting PID 1...

You're likely running this under a Docker host that has cgroup v2 enabled.

Possible workaround (though I couldn't get it to work before I reverted to Rocky Linux 8, but I realized after downgrading FreeIPA takes a ton of time before it appears to be functional): You will have to disable this by adding systemd.unified_cgroup_hierarchy=0 as a kernel arguments to /etc/default/grub: . Rebuild grub configs grub2-mkconfig -o /boot/grub2/grub.cfg and reboot. Bring the container up as usual.

Alternatively, use Podman (except that I can't because I use docker-compose for all my setups).

See also