Over the years I've watched [Kerberos][] and related tools from afar, interested in the idea, but not interested enough to figure out the installation, configuration, etc. Well, in an attempt to secure assorted [[NFS]] mounts around my home, I decided to take the plunge today and install NFSv4 + Kerberos. Here are my notes for my [[Gentoo]] systems, mostly following the [Kerberos install guide][install]. I'll use the following settings for my examples: * Domain: `d.net` * Kerberos realm: `R.EDU` * Server: `server.d.net` * Client: `client.d.net` * User: `jdoe` (on both the client and server) Setup the Kerberos server ------------------------- Emerge the Kerberos server (`app-crypt/mit-krb5`) and [[PAM]] module: # USE=-openldap emerge -av pam_krb5 `-openldap` breaks an OpenLDAP <-> Kerberos dependency loop. Setup [[DNS]] to centralize service location management ([krb manual][DNS]): # emacs /etc/bind/pri/d.net.zone # /etc/init.d/named restart I added the following entries to the `$ORIGIN d.net.` section of my zone file: _kerberos TXT "R.EDU" kerberos A 192.168.0.2 krb5 A 192.168.0.2 _kerberos-adm._tcp SRV 0 0 749 krb5 _kerberos._udp SRV 0 0 88 krb5 _kerberos-master._udp SRV 0 0 88 krb5 _kpasswd._udp SRV 0 0 464 krb5 Configure Kerberos and the KDC ([krb manual][config]): # cp /etc/krb5.conf{.example,} # emacs /etc/krb5.conf # cat /etc/krb5.conf [libdefaults] default_realm = R.EDU dns_fallback = yes kdc_ports = 88 [realms] R.EDU = { kdc = "server.d.net" # HACK? admin_server = "server.d.net" # DNS support not yet complete } [domain_realm] .d.net = R.EDU d.net = R.EDU [logging] kdc = FILE:/var/log/krb5/kdc.log admin_server = FILE:/var/log/krb5/kadmind.log default = FILE:/var/log/krb5/krblib.log # cp /var/lib/krb5kdc/kdc.conf{.example,} # emacs /var/lib/krb5kdc/kdc.conf # cat /var/lib/krb5kdc/kdc.conf [realms] R.EDU = { admin_server = server.d.net # DNS support not yet complete database_name = /var/lib/krb5kdc/principal admin_keytab = FILE:/etc/krb5.keytab acl_file = /var/lib/krb5kdc/kadm5.acl key_stash_file = /var/lib/krb5kdc/.k5.R.EDU kdc_ports = 88 max_life = 10h 0m 0s max_renewable_life = 7d 0h 0m 0s } Create the database and stash file ([krb manual][database]): # kdb5_util create -r R.EDU -s Add administrators to the access control list ([krb manual][acl]): # emacs /var/lib/krb5kdc/kadm5.acl # cat /var/lib/krb5kdc/kadm5.acl jdoe/admin@R.EDU x # kadmin.local kadmin.local: add_principal jdoe/admin@R.EDU WARNING: no policy specified for jdoe/admin@R.EDU; defaulting to no policy Enter password for principal "jdoe/admin@R.EDU": Re-enter password for principal "jdoe/admin@R.EDU": Principal "jdoe/admin@R.EDU" created. kadmin.local: quit Start the Kerberos daemons: # /etc/init.d/mit-krb5kdc start # /etc/init.d/mit-krb5kadmind start Add them to your default runlevel with: # eselect rc add /etc/init.d/mit-krb5kadmin default # eselect rc add /etc/init.d/mit-krb5kadmind default Add new principals ([krb manual][principal]): $ kadmin -p jdoe/admin Authenticating as principal jdoe/admin with password. Password for jdoe/admin@R.EDU: kadmin: list_principals ... kadmin: add_principal jdoe WARNING: no policy specified for jdoe@R.EDU; defaulting to no policy Enter password for principal "jdoe@R.EDU": Re-enter password for principal "jdoe@R.EDU": Principal "jdoe@R.EDU" created. kadmin: quit Now you can get your ticket granting ticket (TGT) with $ kinit and do all the other standard Kerberos stuff. Setup the Kerberos client ------------------------- Not much to do here, just # emerge -av pam_krb5 and `scp` `/etc/krb5.conf` from your Kerberos server onto the client. Check that everything works by running $ kinit Password for jdoe@R.EDU: $ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: jdoe@R.EDU Valid starting Expires Service principal 06/02/11 10:32:30 06/02/11 20:32:30 krbtgt/R.EDU@R.EDU renew until 06/03/11 10:32:30 Setup the NFS server -------------------- Now we'll setup [[NFSv4|NFS]] using Kerberos authentication. There don't seem to be authoritative docs, but there are a number of good tutorials ([1][nfs-tut1], [2][nfs-tut2], [3][nfs-tut3], [4][nfs-tut4]). Emerge `nfs-utils` with the `kerberos` USE flag set ([homepage][nfs-utils]). You may also want `app-crypt/kstart` ([homepage][kstart]) to automatically renew your server and client tickets. Now is also a good time to check your kernel config. I was missing [CRYPTO_CTS][CTS], which lead to error writing to downcall channel /proc/net/rpc/auth.rpcsec.context/channel: Invalid argument If your realm is not your uppercased domain name, you probably also want a version of [libnfsidmap][] >0.21 to avoid the get_ids: failed to map name 'nfs/@REALM' to uid/gid: Invalid argument bug ([discussion][lr-bug]). Since we'll be running the NFS service, we'll need a `nfs/@REALM` principal for the service. Because we want that service to start automatically at boot, we neek to keep its key in a keytab file ([krb manual][keytab]). # kadmin.local -p jdoe/admin Authenticating as principal jdoe/admin with password. Password for jdoe/admin@R.EDU: kadmin.local: add_principal -randkey nfs/server.d.net WARNING: no policy specified for nfs/server.d.net@R.EDU; defaulting to no policy Principal "nfs/server.d.net@R.EDU" created. kadmin.local: ktadd nfs/server.d.net Entry for principal nfs/server.d.net... ... kadmin.local: quit You need use `kadmin.local` here (instead of `kadmin`) so the process has premission to create and edit the keytab file. Read through `/etc/idmapd.conf` to see if you need to make any changes for your setup. I set `Domain = d.net` and `Local-Realms = R.EDU`. You probably also want to look through `/etc/conf.d/nfs`. I added `-vvv` to `OPTS_RPC_GSSD`, `OPTS_RPC_IDMAPD`, and `OPTS_RPC_SVCGSSD` to aid in debugging. Setup your export filesystem. NFSv4 wants all its exports to live under a single root, so do something like: # mkdir /export # mkdir /export/home # mount --bind /home /export/home And then setup `/etc/exports`: # cat /etc/exports /export *(rw,fsid=0,insecure,sec=krb5p,root_squash,no_subtree_check,crossmnt) /export/a/ *(rw,insecure,sec=krb5p,root_squash,no_subtree_check) Note that the syntax has changed somewhat, and there seem to have been a few versions of the NFSv4 syntax. `exports(5)` should contain good documentation for whatever version of `nfs-utils` you have installed on your system. If you used `mount --bind` to populate `/export`, make sure you add appropriate entries to `/etc/fstab` so the mounts come up when you reboot. # cat /etc/fstab ... /home /export/home none rw,bind 0 0 Start the NFS server: # /etc/init.d/nfs start Add it to your default runlevel with: # eselect rc add /etc/init.d/nfs default Setup the NFS client -------------------- In order to use private (`sec=krb5p`) mounts, you'll need to enable [RPCSEC_GSS_KRB5][]. Without it, [you'll get error messages][gss_error] such as gss_create: Pseudoflavor 390005 not found! You'll also need `nfs-utils` here # USE="kerberos" emerge -av nfs-utils You'll need a client principal for secured mounts, so head back over to the server and run server.d.net# kadmin.local kadmin.local: add_principal -randkey nfs/client.d.net kadmin.local: ktadd -k /tmp/krb5.keytab nfs/client.d.net Entry for principal nfs/client.d.net ... ... kadmin.local: quit Then `scp` the new keyfile over to `/etc/krb5.keytab` on the client and remove the temporary version from the host. You can list the keys in a keytab with `klist -e -k /path/to/keytab` if you find a keytab lying around but forget what's inside it. On the client, you'll need `gssd` and `idmapd` running (both part of `nfs-utils`). # /etc/init.d/rpc.gssd start # /etc/init.d/rpc.idmapd start There's no need to add these to your default runlevel, since they should be started automatically if you have NFSv4 entries in your `/etc/fstab` (I have no idea how that works). Now test your mount: $ sudo mkdir /tmp/mnt $ sudo mount -v -t nfs4 -o sec=krb5p server:/ /tmp/mnt mount.nfs4: timeout set for Thu Jun 2 10:44:46 2011 mount.nfs4: trying text-based options '...' server:/ on /tmp/mnt type nfs4 (rw,sec=krb5p) $ ls /tmp/mnt ls: cannot access /tmp/mnt: Permission denied $ klist klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1000) $ kinit Password for jdoe@R.EDU: $ ls /tmp/mnt/ home Note that if you `kestroy` your key, you can still access the files: $ kdestroy $ klist klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1000) $ ls /tmp/mnt/ home This is because your credentials have been cached in the client's kernel. On AIX there seems to be an [nfsauthreset][] command to manually flush cached GSSAPI information. Linux support is [waiting on a new key ring implementation][keyring]. Other stuff ----------- If you hadn't had the `kerberos` USE flag set before, you should consider adding it to your `/etc/make.conf` and running $ sudo emerge -av --deep --newuse --update @world to get Kerberized versions of any packages you have installed (e.g. `cups`, `curl`, `cvs`, `emacs`, `openssh`, most SASL libraries, ...). For details on using Kerberos with [[SSH]], check out the excellent description in [the SSH definative guide][ssh]. The key elements are `host/@REALM` principals for each host (with keyfiles on each server) and appropriate enabling of the `GSSAPI*` options in `sshd_config` and `ssh_config`. There's also [suite of Kerberos-aware utilities][apps] in `app-crypt/mit-krb5-appl` (`krcp`, `krlogin`, `krsh`, `ktelnet`, and `kftp`). I don't use the non-Kerberized versions, so I haven't tried any of these. If you're using [[MPD]] on an NFS-mounted music repository, you might be interested in my [[kinit-mpd.sh]] script for granting the `mpd` user access to the NFS-mounted music as the `nobody` principal. For debugging, check out the [KRB5_TRACE][] environment variable. I sent some patches [upstream][7151] to integrate reverse DNS debugging into the `KRB5_TRACE` framework. The patches will go live with the next major krb5 release after the 1.10 series. If you end up compiling from source, you can run the [unit tests][test] and [check coverage][gcov] with something like: $ git clone git://github.com/krb5/krb5.git $ cd krb5/src $ util/reconf $ mkdir ../build $ cd ../build $ ../src/configure --disable-rpath CFLAGS="-fprofile-arcs -ftest-coverage -O0" LIBS=-lgcov $ make $ make check $ cd lib/krb5/os $ gcov -o sn2princ.so.gcno ../../../lib/krb5/os/sn2princ.c $ gcov -o sn2princ.so.gcno sn2princ.c $ less sn2princ.c.gcov Running `configure` from a separate directory creates a [VPATH][] build, which avoids polluting the source directory with generated files. [Kerberos]: http://web.mit.edu/kerberos/ [install]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html [DNS]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-admin.html#Using%20DNS [config]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Edit%20the%20Configuration%20Files [database]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Create%20the%20Database [acl]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Add%20Administrators%20to%20the%20Acl%20File [principal]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-admin.html#Adding%20or%20Modifying%20Principals [keytab]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Create%20a%20kadmind%20Keytab%20%28optional%29 [RPCSEC_GSS_KRB5]: http://www.kernel.org/doc/menuconfig/net-sunrpc-Kconfig.html [gss_error]: http://osdir.com/ml/linux.nfsv4/2006-01/msg00014.html [nfs-tut1]: http://wiki.linux-nfs.org/wiki/index.php/Enduser_doc_kerberos [nfs-tut2]: http://bernard.nexusinternational.jp/2008/03/nfs-and-kerberos-bernie-howto.html [nfs-tut3]: http://www.techrepublic.com/blog/opensource/kerberos-authentication-with-nfsv4/1965 [nfs-tut4]: http://www.itp.uzh.ch/~dpotter/howto/kerberos [kstart]: http://www.eyrie.org/~eagle/software/kstart/ [nfs-utils]: http://linux-nfs.org/ [CTS]: http://permalink.gmane.org/gmane.linux.nfs/39963 [libnfsidmap]: http://www.citi.umich.edu/projects/nfsv4/linux/ [lr-bug]: http://linux-nfs.org/pipermail/nfsv4/2008-October/009558.html [nfsauthreset]: http://publib.boulder.ibm.com/infocenter/aix/v7r1/index.jsp?topic=/com.ibm.aix.cmds/doc/aixcmds4/nfsauthreset.htm [keyring]: http://www.citi.umich.edu/projects/nfsv4/linux/faq/#krb5_006 [ssh]: http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch11_04.htm [apps]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-user.html#Kerberos%20V5%20Applications [KRB5_TRACE]: http://web.mit.edu/kerberos/krb5-current/doc/krb_admins/env_variables.html [7151]: http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=7151 [test]: http://web.mit.edu/kerberos/krb5-current/doc/krb_build/doing_build.html#testing-the-build [gcov]: http://web.mit.edu/kerberos/krb5-current/doc/krb_build/test_cov.html [VPATH]: http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Make-Target-Lookup.html [[!tag tags/linux]] [[!tag tags/tools]]