Advertisement
US | EN
Mad Beats
Industry

Native FreeBSD Kerberos/LDAP with FreeIPA/IDM

Native FreeBSD Kerberos/LDAP with FreeIPA/IDM

I want to make this clear in the first sentence because its biggest chance that people will read it – this article is entirely based on work done by Christian Hofstede-Kuhn (Larvitz) that wrote Integrating FreeBSD 15 with FreeIPA: Native Kerberos and LDAP Authentication recently. Credit goes to him. Besides that I like to share everything that could be useful – I also treat my blog as a place where I keep and maintain my FreeBSD documentation … and I have seen many blogs and sources of knowledge disappear from the Internet over time … and as I use free WordPress tear I am sure this blog (and knowledge) should be here long after I am gone.

So as You see there are several motivations for this:

– Keep and maintain personal version with more code snippets that I can copy/paste fast.

– More detailed commands and outputs.

– Some additional improvements that may be useful – like local console login.

I just hope Christian will not be mad at me for this 🙂

… and I will directly notify him about this article.

First of all – this new method is possible to work because FreeBSD switched from Heimdal Kerberos implementation to MIT Kerberos in FreeBSD 15.0-RELEASE … and I am really glad that FreeBSD finally did it.

As You know I already messed with that topic several times in the past:

All of these previous attempts had many downsides:

  • You needed to (re)compile multiple custom packages from FreeBSD Ports.

  • Sometimes it was needed to use custom code by Mariusz Zaborski (oshogbo) for example.

  • Complex sssd(8) daemon with many deps/reqs including D-Bus or Python and more.

  • Setup was complicated/fragile and prune to errors – especially during upgrades.

  • This new way is using MIT Kerberos from FreeBSD 15.0-RELEASE and small lightweight nslcd(8) daemon from net/nss-pam-ldapd package. The only (non technical) downside is that it uses LGPL21/LGPL3 license … but as we connect to entire Linux domain with FreeIPA/IDM it does not matter much, does it? :)Now – we first need FreeIPA/IDM server … use instructions from older Connect FreeBSD 14.0-STABLE to FreeIPA/IDM article.Now for the new way … lets start by switching the pkg(8) repository from quarterly to latest.

    **FreeBSD # mkdir -p /usr/local/etc/pkg/repos

    FreeBSD # sed s/quarterly/latest/g /etc/pkg/FreeBSD.conf > /usr/local/etc/pkg/repos/FreeBSD.conf**

    Next we will install needed packages.

    FreeBSD # pkg install -y nss-pam-ldapd pam_mkhomedir sudo doas

    If your DNS configured at /etc/resolv.conf does not resolve FreeIPA/IDM use /etc/hosts instead.

    FreeBSD # cat << __EOF >> /etc/hosts 172.27.33.200 rhidm.lab.org rhidm 172.27.33.215 fbsd15.lab.org fbsd15 __EOF

    Add our new FreeBSD host and its IP on FreeIPA/IDM server.

    [root@idm ~]# kinit admin Password for admin@LAB.ORG: [root@idm ~]# ipa dnsrecord-add lab.org fbsd15 --a-rec=172.27.33.215 --a-create-reverse Record name: fbsd15 A record: 172.27.33.215

    [root@idm ~]# ipa host-add fbsd15.lab.org

    Added host "fbsd15.lab.org"

    Host name: fbsd15.lab.org Principal name: host/fbsd15.lab.org@LAB.ORG Principal alias: host/fbsd15.lab.org@LAB.ORG Password: False Keytab: False Managed by: fbsd15.lab.org

    [root@idm ~]# ipa-getkeytab -s rhidm.lab.org -p host/fbsd15.lab.org@LAB.ORG -k /root/fbsd15.keytab Keytab successfully retrieved and stored in: /root/fbsd15.keytab

    **[root@idm ~]# cp /root/fbsd15.keytab /usr/share/ipa/html/

    [root@idm ~]# chmod 644 /usr/share/ipa/html/fbsd15.keytab**

    On FreeBSD host copy the keytab from FreeIPA/IDM server and put it into right place with proper permissions.

    FreeBSD # fetch -o /etc/krb5.keytab http://rhidm.lab.org/ipa/config/fbsd15.keytab /root/fbsd15.keytab 314 B 804 kBps 00s

    FreeBSD # chmod 640 /etc/krb5.keytab

    Verify FreeBSD keytab.

    FreeBSD # klist -k Keytab name: FILE:/etc/krb5.keytab KVNO Principal


    1 host/fbsd15.lab.org@LAB.ORG 1 host/fbsd15.lab.org@LAB.ORG 1 host/fbsd15.lab.org@LAB.ORG 1 host/fbsd15.lab.org@LAB.ORG

    The nslcd(8) daemon will need /etc/krb5.keytab keytab read access to work – to achieve that we will add sshd user to its nslcd group.

    FreeBSD # groups sshd sshd

    **FreeBSD # pw groupmod nslcd -m sshd

    FreeBSD # groups sshd** sshd nslcd

    Prepare /etc/krb5.conf config.

    FreeBSD # cat << __EOF > /etc/krb5.conf [libdefaults] default_realm = LAB.ORG dns_lookup_kdc = false dns_lookup_realm = false

    [realms] LAB.ORG = { kdc = rhidm.lab.org admin_server = rhidm.lab.org }

    [domain_realm] .lab.org = LAB.ORG lab.org = LAB.ORG __EOF

    Create /usr/local/etc/nslcd.conf config for nslcd(8) daemon.

    FreeBSD # cat << __EOF > /usr/local/etc/nslcd.conf # RUN AS nslcd USER uid nslcd gid nslcd

    # LDAP CONNECTION DETAILS uri ldap://rhidm.lab.org base dc=lab,dc=org

    # USE SYSTEM KEYTAB FOR AUTH sasl_mech GSSAPI sasl_realm LAB.ORG

    # FORCE /bin/sh SHELL map passwd loginShell "/bin/sh" __EOF

    Enable and start the nslcd(8) daemon.

    FreeBSD # service nslcd enable nslcd enabled in /etc/rc.conf

    FreeBSD # service nslcd start Starting nslcd.

    Modify /etc/nsswitch.conf config the following way with simple sed(1) one liner.

    FreeBSD # sed -i '.OLD' -E \ -e 's/^group:.*/group: files ldap/g' \ -e 's/^passwd:.*/passwd: files ldap/g' \ /etc/nsswitch.conf

    This is what we changed.

    FreeBSD # diff -u /etc/nsswitch.conf.OLD /etc/nsswitch.conf --- /etc/nsswitch.conf.OLD 2026-02-18 04:54:41.487608000 +0000 +++ /etc/nsswitch.conf 2026-02-18 04:59:00.234662000 +0000 @@ -1,9 +1,9 @@ -group: compat +group: files ldap group_compat: nis hosts: files dns netgroup: compat networks: files -passwd: compat +passwd: files ldap passwd_compat: nis shells: files services: compat

    One can use even more compact /etc/nsswitch.conf as shown by Christian Hofstede-Kuhn (Larvitz) below.

    FreeBSD # cat << __EOF > /etc/nsswitch.conf group: files ldap passwd: files ldap hosts: files dns networks: files shells: files services: compat protocols: files rpc: files __EOF

    Now lets test how it works.

    FreeBSD # id vermaden uid=854800003(vermaden) gid=854800003(vermaden) groups=854800003(vermaden)

    Now the sshd(8) part.

    FreeBSD # cat << __EOF >> /etc/ssh/sshd_config # KRB5/GSSAPI AUTH GSSAPIAuthentication yes GSSAPICleanupCredentials yes GSSAPIStrictAcceptorCheck no __EOF

    Time to restart sshd(8) daemon.

    FreeBSD # service sshd restart Performing sanity check on sshd configuration. Stopping sshd. Waiting for PIDS: 1089. Performing sanity check on sshd configuration. Starting sshd.

    Now lets test how it works over SSH.

    [root@rhidm ~]# kinit vermaden Password for vermaden@LAB.ORG:

    [root@rhidm ~]# ssh fbsd15 -l vermaden FreeBSD 15.0-RELEASE-p2 (GENERIC) releng/15.0-n281005-5fb0f8e9e61d

    Welcome to FreeBSD!

    Release Notes, Errata: https://www.FreeBSD.org/releases/ Security Advisories: https://www.FreeBSD.org/security/ FreeBSD Handbook: https://www.FreeBSD.org/handbook/ FreeBSD FAQ: https://www.FreeBSD.org/faq/ Questions List: https://www.FreeBSD.org/lists/questions/ FreeBSD Forums: https://forums.FreeBSD.org/

    Documents installed with the system are in the /usr/local/share/doc/freebsd/ directory, or can be installed later with: pkg install en-freebsd-doc For other languages, replace "en" with a language code like de or fr.

    Show the version of FreeBSD installed: freebsd-version ; uname -a Please include that output and any error messages when posting questions. Introduction to manual pages: man man FreeBSD directory layout: man hier

    To change this login announcement, see motd(5).

    Could not chdir to home directory /home/vermaden: No such file or directory

    vermaden@fbsd15:/ $ id admin uid=854800000(admin) gid=854800000(admins) groups=854800000(admins)

    vermaden@fbsd15:/ $ id uid=854800003(vermaden) gid=854800003(vermaden) groups=0(wheel),854800003(vermaden)

    Works but … the ${HOME} directory is not automatically created because we did not configured it yet.

    Lets use sed(1) again … and yes it has to be spread over two lines.

    FreeBSD # sed -i '.OLD' '/^session.*/i\ session optional pam_mkhomedir.so mode=0700' /etc/pam.d/sshd

    FreeBSD # ls -l /etc/pam.d/sshd* -rw-r--r-- 1 root wheel 608 Feb 18 05:18 /etc/pam.d/sshd -rw-r--r-- 1 root wheel 564 Feb 18 05:18 /etc/pam.d/sshd.OLD

    FreeBSD # diff -u /etc/pam.d/sshd.OLD /etc/pam.d/sshd --- /etc/pam.d/sshd.OLD 2026-02-18 05:20:50.344139000 +0000 +++ /etc/pam.d/sshd 2026-02-18 05:20:53.552277000 +0000 @@ -16,6 +16,7 @@

    session

    #session optional pam_ssh.so want_agent +session optional pam_mkhomedir.so mode=0700 session required pam_permit.so

    password

    We use optional instead of required if for some reason pam_mkhomedir.so fails or is not available.

    For the record the entire /etc/pam.d/sshd PAM config looks like that.

    FreeBSD # cat /etc/pam.d/sshd # auth auth required pam_unix.so no_warn try_first_pass

    # account account required pam_nologin.so account required pam_login_access.so account required pam_unix.so

    # session session optional pam_mkhomedir.so mode=0700 session required pam_permit.so

    # password password required pam_unix.so no_warn try_first_pass

    We will now configure sudo(8) for more permissions.

    **FreeBSD # pw groupmod wheel -m vermaden

    FreeBSD # cat << __EOF >> /usr/local/etc/sudoers** %wheel ALL=(ALL:ALL) NOPASSWD: ALL __EOF

    We will also do doas(1) here as its simpler and more secure.

    FreeBSD # cat << __EOF > /usr/local/etc/doas.conf permit nopass keepenv root as root permit nopass keepenv :wheel as root __EOF

    Now lets try to login again.

    [root@rhidm ~]# kinit vermaden Password for vermaden@LAB.ORG:

    **[root@rhidm ~]# ssh fbsd15 -l vermaden

    vermaden@fbsd15:~ $ pwd** /home/vermaden

    vermaden@fbsd15:~ $ sudo -i root@fbsd15:~ #

    Better.

    I also ‘silenced’ the login a little by creating empty ~/.hushlogin file and by removing /usr/bin/fortune from the ~/.profile file.

    **vermaden@fbsd15~/ $ :> ~/.hushlogin

    vermaden@fbsd15:~ $ sed -i '.OLD' '/fortune/d' ~/.profile**

    … and this is the part I added – using FreeIPA/IDM user for console access – because right now – it does not work.

    FreeBSD/amd64 (fbsd15.lab.org) (ttyu0)

    login: vermaden Password: Login incorrect

    To allow that we will uncomment all lines matching the pam_krb5.so module within /etc/pam.d/system config.

    FreeBSD # sed -i '.OLD' '/pam_krb5.so/s/^#//g' /etc/pam.d/system

    FreeBSD # ls -l /etc/pam.d/system* -rw-r--r-- 1 root wheel 568 Feb 18 05:34 /etc/pam.d/system -rw-r--r-- 1 root wheel 571 Feb 18 05:33 /etc/pam.d/system.OLD

    FreeBSD # diff -u /etc/pam.d/system.OLD /etc/pam.d/system --- /etc/pam.d/system.OLD 2026-02-18 05:33:48.171585000 +0000 +++ /etc/pam.d/system 2026-02-18 05:34:24.444767000 +0000 @@ -4,12 +4,12 @@

    auth

    -#auth sufficient pam_krb5.so no_warn try_first_pass +auth sufficient pam_krb5.so no_warn try_first_pass #auth sufficient pam_ssh.so no_warn try_first_pass auth required pam_unix.so no_warn try_first_pass nullok

    account

    -#account required pam_krb5.so +account required pam_krb5.so account required pam_login_access.so account required pam_unix.so

    @@ -19,5 +19,5 @@ session required pam_xdg.so

    password

    -#password sufficient pam_krb5.so no_warn try_first_pass +password sufficient pam_krb5.so no_warn try_first_pass password required pam_unix.so no_warn try_first_pass

    Lets try again.

    FreeBSD/amd64 (fbsd15.lab.org) (ttyu0)

    login: vermaden Password:

    vermaden@fbsd15:~ $ klist klist: No credentials cache found (filename: /tmp/krb5cc_854800003_AeF9er)

    vermaden@fbsd15:~ $ kinit Password for vermaden@LAB.ORG:

    vermaden@fbsd15:~ $ klist Ticket cache: FILE:/tmp/krb5cc_854800003_AeF9er Default principal: vermaden@LAB.ORG

    Valid starting Expires Service principal 02/18/26 05:27:47 02/19/26 05:07:21 krbtgt/LAB.ORG@LAB.ORG

    You have reached the end of this article – see you in the next one 🙂

    EOF