I recently started setting up Kerberos and LDAP for my home network. While I don’t have a ton of users, it’s handy to be able to centralize account information and do single sign-on. So far all I really have for clients are a server computer, laptop, and Raspberry Pi, but I find it quite handy even if it was kind of a pain to set up.
I have an older PC in the basement I use mostly when I need to work on the network or some other project and just need to quickly grab a web page or SSH into something. I had been running Ubuntu Mate on this, since I like the Mate desktop and wanted to give this distro a try. It ran, but not well. The desktop was slow, and it would take a minute to start something like Firefox. This machine is 3 GHz Pentium 4 dual core with 1 GB of RAM.
I also use OpenBSD on and off, and like it a lot. Since I was curious about how it does on the desktop I decided to give it a try, using the Lumina desktop environment. It works well, and it feels noticeably faster than Ubuntu did on this hardware. Initially I got it going just to get a quick desktop, but then I started thinking about getting it into my Kerberos realm.
This turned out to be a little tricky. For one thing, OpenBSD uses Heimdal Kerberos, as opposed to MIT Kerberos, which the rest of my setup uses. For another, doesn’t use PAM, like all (most?) GNU/Linux distros do, as well as FreeBSD. RedHat’s SSSD is also not present, which has been a godsend on the other platforms. OpenBSD can authenticate to sources such as Kerberos and LDAP, however, though there isn’t a whole lot floating around online about it (though of course the man pages help out a lot). There’s also no support for authorization (eg, group information, UID number) for anything besides local files and NIS, which presents a further challenge.
A Quick Little Guide
I thought I’d post this here in cases it helps someone down the line, or in case I have to do this again myself. 🙂 I’ve pieced this together from information found online, as well as man pages. Note that this doesn’t cover setting up the Kerberos/LDAP server(s), which is another topic on which there are other guides. I used a combination of this guide for Debian, and this one for Ubuntu (even though my KDC runs Debian). At the moment the exact details of the setup aren’t terribly important, but you should have some kind of Kerberos/LDAP implementation that authenticates users.
I just want to point out here, that although Active Directory is in fact one Kerberos/LDAP implementation, I don’t really have much experience with it, and this guide will not directly concern it or any peculiarities it may have. In theory a lot of what you see here should be applicable, and hopefully it will be helpful. In my travels I found this, which may be helpful if that’s what you’re trying to do.
Aside from the server, you should obviously have an OpenBSD system you want to have as your authentication/authorization client. Have some test users kicking around helps too, both some local users on your OpenBSD system as well as a couple configured in Kerberos/LDAP to test authentication there.
I’m using OpenBSD 6.2, i386, but I think this should work on other platforms as well(?), particularly amd64. Now a word of caution: this guide requires modifying some system files. I myself screwed up at one point, causing my system to boot but not allow anyone to log in. I recommend not only making backups of relevant files, but also reading a bit about single user mode. Take a look at the root password reset guide in the OpenBSD handbook; you can also use single user mode to fix system files. For running an editor, you may also want to take a look at this if you get any errors in single user mode.
Kerberos
First, we’ll install Kerberos, which will handle authentication. That is, this will check a user’s password and verify they are who they say they are. I assume that you have a realm, EXAMPLE.COM, with a KDC/admin server kerberos.example.com.
Note that in this guide, in a code snippet meant to be run at the command line, # indicates the root prompt. However, in a file, # will indicate a comment.
To start, we’ll need to install some packages. From the command prompt:
# pkg_add heimdal heimdal-libs login_krb5
Next, you’ll want to modify your path so that you actually have access to the different Kerberos tools. In .profile, look for that PATH line and add /usr/local/heimdal/bin like this:
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin:/usr/local/heimdal/bin
You may want to make the same modification in /etc/skel/.profile, so that it’s propagated to new users. Next, modify /etc/rc.conf.local and add teh shlib_dirs line. I had made other modifications in setting up my desktop, so for me that file now looks like this:
portmap=YES portmap_flags= shlib_dirs=/usr/local/heimdal/lib xenodm_flags=
The reason for that is that Heimdal is installed under /usr/local/heimdal, which is also where its shared libraries are. This tells the rest of the system where they are. (You may have to reboot after saving this change.)
Next, we’ll start putting in some Kerberos details. In the file /etc/kerberos/krb5.conf, modify it to reflect your situation (ie, your own realm and kdc/admin server):
# $OpenBSD: krb5.conf,v 1.1 2014/07/13 14:10:13 ajacoutot Exp $ # # See krb5.conf(5) and the heimdal info(1) page for more information. [libdefaults] # local realm(s) default_realm = EXAMPLE.COM [realms] EXAMPLE.COM = { # list of KDC(s) for this realm kdc = kerberos.example.com # admin server for this realm admin_server = kerberos.example.com default_domain = EXAMPLE.COM } [domain_realm] .EXAMPLE.COM = EXAMPLE.COM [kadmin] # default salt string default_keys = v5 [logging] # log to syslog(3) kdc = SYSLOG:INFO:DAEMON kpasswdd = SYSLOG:INFO:AUTH default = SYSLOG:INFO:DAEMON
By this point you should be able to use tools like kinit, klist, etc. on the OpenBSD client. What we want to do now is set up a host principal for this machine, and a keytab for it. At this point, I would like to mention that I had a problem with this on OpenBSD: normally I create the principal by logging into my KDC, then creating the principal in kadmin, then logging into the client and running kadmin as root. Because of the krb5.conf configuration, you basically use kadmin to copy the principal from the KDC to the local keytab. Unfortunately, when I tried to do this from my OpenBSD machine it hung. I’m not sure what was going on, or if it was some kind of Heimdal vs MIT Kerberos issue, but I ended up having to copy the keytab over manually.
Log in to your KDC, and run the following. Note that in the addprinc command I have the -x dn=”uid..” line – this is because my KDC uses LDAP as its backend (not just for authorization), and I keep the principal with other information about that computer. (See the Ubuntu guide I linked earlier for more information.) You can leave that out if you don’t do this.
The session should look something like this (again, my KDC is running MIT Kerberos):
root@kerberos:~/kdc# kadmin -p kerberosadminuser Authenticating as principal kerberosadminuser with password. Password for kerberosadminuser@EXAMPLE.COM: kadmin: addprinc -randkey -x dn="uid=openbsdclienthostname$,ou=computers,dc=example,dc=com" host/openbsdclienthostname.example.com WARNING: no policy specified for host/openbsdclienthostname.example.com@EXAMPLE.COM; defaulting to no policy Principal "host/openbsdclienthostname.example.com@EXAMPLE.COM" created. ktadd -k /path/to/some/file.keytab host/openbsdclienthostname.example.com@EXAMPLE.COM quit
The above copies the host principal to /path/to/some/file.keytab, which you need to then transfer to the client – rename it to /etc/heimdal/krb5.keytab. Transfer it using a secure method, like SSH or a thumb drive. Assuming you put it in /root:
# mv /root/file.keytab /etc/heimdal/krb5.keytab # chown root:wheel /etc/heimdal/krb5.keytab # chmod 600 /etc/heimdal/krb5.keytab
At this point, you should be able to get a Kerberos principal yourself:
# klist klist: No ticket file: /tmp/krb5cc_0 # kinit krbuser krbuser@EXAMPLE.COM's Password: # klist Credentials cache: FILE:/tmp/krb5cc_0 Principal: krbuser@EXAMPLE.COM Issued Expires Principal Mar 4 15:48:38 2018 Mar 5 15:48:38 2018 krbtgt/EXAMPLE.COM@EXAMPLE.COM
Next, we want to be able get that principal when we log in. Earlier, we installed login_krb5, which will do this (along with of course letting us log into the system without a passwd entry).
Edit /etc/login.conf, and look for the default:\ section as shown below:
default:\ :path=/usr/bin /bin /usr/sbin /sbin /usr/X11R6/bin /usr/local/bin /usr/local/sbin:\ :umask=022:\ :datasize-max=512M:\ :datasize-cur=512M:\ :maxproc-max=256:\ :maxproc-cur=128:\ :openfiles-max=1024:\ :openfiles-cur=512:\ :stacksize-cur=4M:\ :localcipher=blowfish,a:\ :auth=-krb5-or-pwd:\ :tc=auth-defaults:\ :tc=auth-ftp-defaults:
The line to add is “:auth=-krb5-or-pwd:\” just above “:tc=auth-defaults:\”. This line allows you to use Kerberos as a login mechanism, but falls back to checking local files if that fails.
This should be about it – you can test authentication to a Kerberos account, but note that we don’t have authorization. In other words, the system still has to look to local files for things like user and group information. To test now, create a local account with a home directory, group, etc. in OpenBSD (as root):
# useradd krbuser
Follow the prompts that come up. The password doesn’t really matter, just use something different than what you set up for the Kerberos principal. Then, log in to the console as that user using the Kerberos principal’s password. After logging in, you should be able to run klist and see that user’s principal. (If you get a “Command not found” or similar error, make sure that /usr/local/heimdal/bin is in your path, see above.)
LDAP
Assuming you got the Kerberos part working, now might be a good time to take a break, get a fresh coffee, etc.
As I mentioned before, LDAP is used for authorization, that is user info like groups, login shells, etc. Unfortunately, OpenBSD doesn’t actually support using LDAP for authorization, only Network Information System (NIS, aka YellowPages or yp, which most of the tools are named for). Luckily, there’s a translator we can use that comes with the base system, ypldap. This basically makes the LDAP directory look like a YP (NIS) server.
I couldn’t find much online about using this with OpenBSD 6.2, but I think I got it working. I found two pages on this, both of which are older. Both of these start by talking about login_ldap, which I ended up installing, but which isn’t really needed. That’s if you want to authenticate to LDAP (ie, if that’s where you’re storing your passwords). In our case, that’s already taken care of by login_krb5.
To start, create /etc/ypldap.conf. I recommend copying the example:
# cp /etc/examples/ypldap.conf /etc/ypldap.conf
There is another caveat – on my Linux clients, I use GSSAPI with the host principal to authenticate to the LDAP database. On OpenBSD, ypldap does not support this (that I could tell). This means you’ll need a user that can just bind to LDAP by itself, for instance using the userPassword attribute. This user needs to be able to read through your directory to get user/group information. Also, while I don’t have it set up here, you should probably be using SSL/TLS with your LDAP server.
Now, edit this file like the following (I’ve added some of my own comments) to reflect your own setup:
# $OpenBSD: ypldap.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $ domain "example.com" #This is just the name of your realm interval 120 #How often to pull data from the LDAP database, in seconds provide map "passwd.byname" provide map "passwd.byuid" provide map "group.byname" provide map "group.bygid" provide map "netid.byname" directory "kerberos.example.com" { #This is the machine hosting your LDAP directory # directory options binddn "uid=openbsdclienthostname$,ou=computers,dc=example,dc=com" #User to bind to LDAP as bindcred "mypassword" #Password for above user basedn "dc=example,dc=com" # starting point for groups directory search, default to basedn groupdn "ou=groups,dc=example,dc=com" #Change to reflect your setup # passwd maps configuration (RFC 2307 posixAccount object class) passwd filter "(objectClass=posixAccount)" attribute name maps to "uid" fixed attribute passwd "*" #Can leave this as is, we check passwords with Kerberos attribute uid maps to "uidNumber" attribute gid maps to "gidNumber" attribute gecos maps to "cn" attribute home maps to "homeDirectory" attribute shell maps to "loginShell" fixed attribute change "0" fixed attribute expire "0" fixed attribute class "" # group maps configuration (RFC 2307 posixGroup object class) group filter "(objectClass=posixGroup)" attribute groupname maps to "cn" fixed attribute grouppasswd "*" attribute groupgid maps to "gidNumber" # memberUid returns multiple group members list groupmembers maps to "memberUid" }
Next, we configure the YP client. I recommend taking a look at the relevant page in the FAQ, for reference. Since we basically just set up an YP server, we want to tell the client where to find it:
# echo 'example.com' > /etc/defaultdomain # echo '127.0.0.1' > /etc/yp/example.com
To have the system use the YP client, make the following changes to /etc/master.passwd and /etc/group:
# echo '+:*::::::::' >> /etc/master.passwd # pwd_mkdb -p /etc/master.passwd # echo '+:*::' >> /etc/group
The first line sets the YP domain, while the second tells the YP client to look to our own host for the server (ypldap). Next, enable some services:
# rcctl enable portmap # rcctl start portmap # rcctl enable ypldap # rcctl start ypldap # rcctl enable ypbind # rcctl start ypbind
In some of the other guides online, it was said that you had to edit /etc/rc.local to make sure that ypldap starts before ypbind. For 6.2, I didn’t have to do this.
Now, you can reboot and check to make sure you have the above running:
# ps aux | grep yp _ypldap 3982 0.0 0.1 540 1488 ?? Ip 4:55PM 0:00.01 ypldap: dns engine (ypldap) _ypldap 85354 0.0 0.2 584 1608 ?? Ssp 4:55PM 0:00.01 ypldap: parent (ypldap) _ypldap 56536 0.0 0.2 628 1600 ?? Ip 4:55PM 0:00.01 ypldap: ldap client (ypldap) root 23124 0.0 0.1 384 960 ?? Ss 4:55PM 0:00.00 /usr/sbin/ypbind
You can also test lookup up user information using the id command:
# id krbuser uid=5555(krbuser) gid=5555(krbuser) groups=5555(krbuser)
In the above, 5555 would be whatever uid/gid you set it up for. (If you have the user from before, the one which was using the local OpenBSD files, you may want to use a different one to make sure you’re actually pulling from LDAP.)
Next test logging in with a Kerberos/LDAP user from the console. Note that I did not look into creating users’s home directories automatically, so you’ll have to do that yourself. (If I figure this out, I’ll post it, or if someone else knows, feel free to comment.)
Final Remarks
I like OpenBSD a lot, but this was kind of a pain. Actually, it was a good learning experience, and it’s good to know that it’s possible. I got to learn a little more about the internals, and once I started looking into it it wasn’t too bad, just different from what I’d been used to on Linux. Let me know if you have any trouble with this, or if I missed anything (I’m putting this down partly from memory, after working on it on and off over a couple weeks.).
I did not manage to get Kerberized SSH working, that is being able to SSH to/from the OpenBSD client without entering a password. I think this is because the builtin sshd doesn’t support it. This might be something that could be changed by recompiling it, I’ll have to look into it in the future.