mkogg.py: Fix 'self.get_mp4_metadata(self, source)'
[blog.git] / posts / Kerberos.mdwn
1 Over the years I've watched [Kerberos][] and related tools from afar,
2 interested in the idea, but not interested enough to figure out the
3 installation, configuration, etc.  Well, in an attempt to secure
4 assorted [[NFS]] mounts around my home, I decided to take the plunge
5 today and install NFSv4 + Kerberos.  Here are my notes for my
6 [[Gentoo]] systems, mostly following the [Kerberos install
7 guide][install].  I'll use the following settings for my examples:
8
9 * Domain: `d.net`
10 * Kerberos realm: `R.EDU`
11 * Server: `server.d.net`
12 * Client: `client.d.net`
13 * User: `jdoe` (on both the client and server)
14
15 Setup the Kerberos server
16 -------------------------
17
18 Emerge the Kerberos server (`app-crypt/mit-krb5`) and [[PAM]] module:
19
20     # USE=-openldap emerge -av pam_krb5
21
22 `-openldap` breaks an OpenLDAP <-> Kerberos dependency loop.
23
24 Setup [[DNS]] to centralize service location management ([krb
25 manual][DNS]):
26
27     # emacs /etc/bind/pri/d.net.zone
28     # /etc/init.d/named restart
29
30 I added the following entries to the `$ORIGIN d.net.` section of my
31 zone file:
32
33     _kerberos TXT   "R.EDU"
34     kerberos  A     192.168.0.2
35     krb5      A     192.168.0.2
36     _kerberos-adm._tcp     SRV  0 0 749 krb5
37     _kerberos._udp         SRV  0 0 88  krb5
38     _kerberos-master._udp  SRV  0 0 88  krb5
39     _kpasswd._udp          SRV  0 0 464 krb5
40
41 Configure Kerberos and the KDC ([krb manual][config]):
42
43     # cp /etc/krb5.conf{.example,}
44     # emacs /etc/krb5.conf
45     # cat /etc/krb5.conf
46     [libdefaults]
47             default_realm = R.EDU
48             dns_fallback = yes
49             kdc_ports = 88
50     
51     [realms]
52             R.EDU = {
53                     kdc = "server.d.net"  # HACK?
54                     admin_server = "server.d.net"  # DNS support not yet complete
55             }
56     
57     [domain_realm]
58             .d.net = R.EDU
59             d.net = R.EDU
60     
61     [logging]
62             kdc = FILE:/var/log/krb5/kdc.log
63             admin_server = FILE:/var/log/krb5/kadmind.log
64             default = FILE:/var/log/krb5/krblib.log
65     # cp /var/lib/krb5kdc/kdc.conf{.example,}
66     # emacs /var/lib/krb5kdc/kdc.conf
67     # cat /var/lib/krb5kdc/kdc.conf
68     [realms]
69             R.EDU = {
70                     admin_server = server.d.net  # DNS support not yet complete
71                     database_name = /var/lib/krb5kdc/principal
72                     admin_keytab = FILE:/etc/krb5.keytab
73                     acl_file = /var/lib/krb5kdc/kadm5.acl
74                     key_stash_file = /var/lib/krb5kdc/.k5.R.EDU
75                     kdc_ports = 88
76                     max_life = 10h 0m 0s
77                     max_renewable_life = 7d 0h 0m 0s
78             }
79
80 Create the database and stash file ([krb manual][database]):
81
82     # kdb5_util create -r R.EDU -s
83
84 Add administrators to the access control list ([krb manual][acl]):
85
86     # emacs /var/lib/krb5kdc/kadm5.acl
87     # cat /var/lib/krb5kdc/kadm5.acl
88     jdoe/admin@R.EDU  x
89     # kadmin.local
90     kadmin.local:  add_principal jdoe/admin@R.EDU
91     WARNING: no policy specified for jdoe/admin@R.EDU; defaulting to no policy
92     Enter password for principal "jdoe/admin@R.EDU": 
93     Re-enter password for principal "jdoe/admin@R.EDU": 
94     Principal "jdoe/admin@R.EDU" created.
95     kadmin.local:  quit
96
97 Start the Kerberos daemons:
98
99     # /etc/init.d/mit-krb5kdc start
100     # /etc/init.d/mit-krb5kadmind start
101
102 Add them to your default runlevel with:
103
104     # eselect rc add /etc/init.d/mit-krb5kadmin default
105     # eselect rc add /etc/init.d/mit-krb5kadmind default
106
107 Add new principals ([krb manual][principal]):
108
109     $ kadmin -p jdoe/admin
110     Authenticating as principal jdoe/admin with password.
111     Password for jdoe/admin@R.EDU: 
112     kadmin:  list_principals
113     ...
114     kadmin:  add_principal jdoe
115     WARNING: no policy specified for jdoe@R.EDU; defaulting to no policy
116     Enter password for principal "jdoe@R.EDU": 
117     Re-enter password for principal "jdoe@R.EDU": 
118     Principal "jdoe@R.EDU" created.
119     kadmin:  quit
120
121 Now you can get your ticket granting ticket (TGT) with
122
123     $ kinit
124
125 and do all the other standard Kerberos stuff.
126
127 Setup the Kerberos client
128 -------------------------
129
130 Not much to do here, just
131
132     # emerge -av pam_krb5
133
134 and `scp` `/etc/krb5.conf` from your Kerberos server onto the client.
135
136 Check that everything works by running
137
138     $ kinit
139     Password for jdoe@R.EDU: 
140     $ klist 
141     Ticket cache: FILE:/tmp/krb5cc_1000
142     Default principal: jdoe@R.EDU
143     
144     Valid starting     Expires            Service principal
145     06/02/11 10:32:30  06/02/11 20:32:30  krbtgt/R.EDU@R.EDU
146             renew until 06/03/11 10:32:30
147
148 Setup the NFS server
149 --------------------
150
151 Now we'll setup [[NFSv4|NFS]] using Kerberos authentication.  There
152 don't seem to be authoritative docs, but there are a number of good
153 tutorials ([1][nfs-tut1], [2][nfs-tut2], [3][nfs-tut3],
154 [4][nfs-tut4]).
155
156 Emerge `nfs-utils` with the `kerberos` USE flag set
157 ([homepage][nfs-utils]).  You may also want `app-crypt/kstart`
158 ([homepage][kstart]) to automatically renew your server and client
159 tickets.  Now is also a good time to check your kernel config.  I was
160 missing [CRYPTO_CTS][CTS], which lead to
161
162     error writing to downcall channel /proc/net/rpc/auth.rpcsec.context/channel: Invalid argument
163
164 If your realm is not your uppercased domain name, you probably also
165 want a version of [libnfsidmap][] >0.21 to avoid the
166
167     get_ids: failed to map name 'nfs/<fqdn>@REALM' to uid/gid: Invalid argument
168
169 bug ([discussion][lr-bug]).
170
171 Since we'll be running the NFS service, we'll need a
172 `nfs/<fqdn>@REALM` principal for the service.  Because we want that
173 service to start automatically at boot, we neek to keep its key in a
174 keytab file ([krb manual][keytab]).
175
176     # kadmin.local -p jdoe/admin
177     Authenticating as principal jdoe/admin with password.
178     Password for jdoe/admin@R.EDU: 
179     kadmin.local:  add_principal -randkey nfs/server.d.net
180     WARNING: no policy specified for nfs/server.d.net@R.EDU; defaulting to no policy
181     Principal "nfs/server.d.net@R.EDU" created.
182     kadmin.local:  ktadd nfs/server.d.net
183     Entry for principal nfs/server.d.net...
184     ...
185     kadmin.local:  quit
186
187 You need use `kadmin.local` here (instead of `kadmin`) so the process
188 has premission to create and edit the keytab file.
189
190 Read through `/etc/idmapd.conf` to see if you need to make any changes
191 for your setup.  I set `Domain = d.net` and `Local-Realms = R.EDU`.
192 You probably also want to look through `/etc/conf.d/nfs`.  I added
193 `-vvv` to `OPTS_RPC_GSSD`, `OPTS_RPC_IDMAPD`, and `OPTS_RPC_SVCGSSD`
194 to aid in debugging.
195
196 Setup your export filesystem.  NFSv4 wants all its exports to live
197 under a single root, so do something like:
198
199     # mkdir /export
200     # mkdir /export/home
201     # mount --bind /home /export/home
202
203 And then setup `/etc/exports`:
204
205     # cat /etc/exports
206     /export  *(rw,fsid=0,insecure,sec=krb5p,root_squash,no_subtree_check,crossmnt)
207     /export/a/ *(rw,insecure,sec=krb5p,root_squash,no_subtree_check)
208
209 Note that the syntax has changed somewhat, and there seem to have been
210 a few versions of the NFSv4 syntax.  `exports(5)` should contain good
211 documentation for whatever version of `nfs-utils` you have installed
212 on your system.
213
214 If you used `mount --bind` to populate `/export`, make sure you add
215 appropriate entries to `/etc/fstab` so the mounts come up when you
216 reboot.
217
218     # cat /etc/fstab
219     ...
220     /home /export/home none rw,bind 0 0
221
222 Start the NFS server:
223
224     # /etc/init.d/nfs start
225
226 Add it to your default runlevel with:
227
228     # eselect rc add /etc/init.d/nfs default
229
230 Setup the NFS client
231 --------------------
232
233 In order to use private (`sec=krb5p`) mounts, you'll need to enable
234 [RPCSEC_GSS_KRB5][].  Without it, [you'll get error
235 messages][gss_error] such as
236
237     gss_create: Pseudoflavor 390005 not found!
238
239 You'll also need `nfs-utils` here
240
241     # USE="kerberos" emerge -av nfs-utils
242
243 You'll need a client principal for secured mounts, so head back over
244 to the server and run
245
246     server.d.net# kadmin.local
247     kadmin.local:  add_principal -randkey nfs/client.d.net
248     kadmin.local:  ktadd -k /tmp/krb5.keytab nfs/client.d.net
249     Entry for principal nfs/client.d.net ...
250     ...
251     kadmin.local:  quit
252
253 Then `scp` the new keyfile over to `/etc/krb5.keytab` on the client
254 and remove the temporary version from the host.  You can list the keys
255 in a keytab with `klist -e -k /path/to/keytab` if you find a keytab
256 lying around but forget what's inside it.
257
258 On the client, you'll need `gssd` and `idmapd` running (both part of
259 `nfs-utils`).
260
261     # /etc/init.d/rpc.gssd start
262     # /etc/init.d/rpc.idmapd start
263
264 There's no need to add these to your default runlevel, since they
265 should be started automatically if you have NFSv4 entries in your
266 `/etc/fstab` (I have no idea how that works).
267
268 Now test your mount:
269
270     $ sudo mkdir /tmp/mnt
271     $ sudo mount -v -t nfs4 -o sec=krb5p server:/ /tmp/mnt
272     mount.nfs4: timeout set for Thu Jun  2 10:44:46 2011
273     mount.nfs4: trying text-based options '...'
274     server:/ on /tmp/mnt type nfs4 (rw,sec=krb5p)
275     $ ls /tmp/mnt 
276     ls: cannot access /tmp/mnt: Permission denied
277     $ klist 
278     klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1000)
279     $ kinit 
280     Password for jdoe@R.EDU: 
281     $ ls /tmp/mnt/
282     home
283
284 Note that if you `kestroy` your key, you can still access the files:
285
286     $ kdestroy 
287     $ klist 
288     klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1000)
289     $ ls /tmp/mnt/
290     home
291
292 This is because your credentials have been cached in the client's
293 kernel.  On AIX there seems to be an [nfsauthreset][] command to
294 manually flush cached GSSAPI information.  Linux support is [waiting
295 on a new key ring implementation][keyring].
296
297 Other stuff
298 -----------
299
300 If you hadn't had the `kerberos` USE flag set before, you should
301 consider adding it to your `/etc/make.conf` and running
302
303     $ sudo emerge -av --deep --newuse --update @world
304
305 to get Kerberized versions of any packages you have installed
306 (e.g. `cups`, `curl`, `cvs`, `emacs`, `openssh`, most SASL libraries,
307 ...).
308
309 For details on using Kerberos with [[SSH]], check out the excellent
310 description in [the SSH definative guide][ssh].  The key elements are
311 `host/<fqdn>@REALM` principals for each host (with keyfiles on each
312 server) and appropriate enabling of the `GSSAPI*` options in
313 `sshd_config` and `ssh_config`.
314
315 There's also [suite of Kerberos-aware utilities][apps] in
316 `app-crypt/mit-krb5-appl` (`krcp`, `krlogin`, `krsh`, `ktelnet`, and
317 `kftp`).  I don't use the non-Kerberized versions, so I haven't tried
318 any of these.
319
320 If you're using [[MPD]] on an NFS-mounted music repository, you might
321 be interested in my [[kinit-mpd.sh]] script for granting the `mpd`
322 user access to the NFS-mounted music as the `nobody` principal.
323
324 For debugging, check out the [KRB5_TRACE][] environment variable.  I
325 sent some patches [upstream][7151] to integrate reverse DNS debugging
326 into the `KRB5_TRACE` framework.  The patches will go live with the
327 next major krb5 release after the 1.10 series.
328
329 If you end up compiling from source, you can run the [unit
330 tests][test] and [check coverage][gcov] with something like:
331
332     $ git clone git://github.com/krb5/krb5.git
333     $ cd krb5/src
334     $ util/reconf
335     $ mkdir ../build
336     $ cd ../build
337     $ ../src/configure --disable-rpath CFLAGS="-fprofile-arcs -ftest-coverage -O0" LIBS=-lgcov
338     $ make
339     $ make check
340     $ cd lib/krb5/os
341     $ gcov -o sn2princ.so.gcno ../../../lib/krb5/os/sn2princ.c
342     $ gcov -o sn2princ.so.gcno sn2princ.c
343     $ less sn2princ.c.gcov
344
345 Running `configure` from a separate directory creates a [VPATH][]
346 build, which avoids polluting the source directory with generated
347 files.
348
349 [Kerberos]: http://web.mit.edu/kerberos/
350 [install]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html
351 [DNS]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-admin.html#Using%20DNS
352 [config]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Edit%20the%20Configuration%20Files
353 [database]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Create%20the%20Database
354 [acl]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Add%20Administrators%20to%20the%20Acl%20File
355 [principal]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-admin.html#Adding%20or%20Modifying%20Principals
356 [keytab]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-install.html#Create%20a%20kadmind%20Keytab%20%28optional%29
357 [RPCSEC_GSS_KRB5]: http://www.kernel.org/doc/menuconfig/net-sunrpc-Kconfig.html
358 [gss_error]: http://osdir.com/ml/linux.nfsv4/2006-01/msg00014.html
359 [nfs-tut1]: http://wiki.linux-nfs.org/wiki/index.php/Enduser_doc_kerberos
360 [nfs-tut2]: http://bernard.nexusinternational.jp/2008/03/nfs-and-kerberos-bernie-howto.html
361 [nfs-tut3]: http://www.techrepublic.com/blog/opensource/kerberos-authentication-with-nfsv4/1965
362 [nfs-tut4]: http://www.itp.uzh.ch/~dpotter/howto/kerberos
363 [kstart]: http://www.eyrie.org/~eagle/software/kstart/
364 [nfs-utils]: http://linux-nfs.org/
365 [CTS]: http://permalink.gmane.org/gmane.linux.nfs/39963
366 [libnfsidmap]: http://www.citi.umich.edu/projects/nfsv4/linux/
367 [lr-bug]: http://linux-nfs.org/pipermail/nfsv4/2008-October/009558.html
368 [nfsauthreset]: http://publib.boulder.ibm.com/infocenter/aix/v7r1/index.jsp?topic=/com.ibm.aix.cmds/doc/aixcmds4/nfsauthreset.htm
369 [keyring]: http://www.citi.umich.edu/projects/nfsv4/linux/faq/#krb5_006
370 [ssh]: http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch11_04.htm
371 [apps]: http://web.mit.edu/kerberos/krb5-1.9/krb5-1.9.1/doc/krb5-user.html#Kerberos%20V5%20Applications
372 [KRB5_TRACE]: http://web.mit.edu/kerberos/krb5-current/doc/krb_admins/env_variables.html
373 [7151]: http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=7151
374 [test]: http://web.mit.edu/kerberos/krb5-current/doc/krb_build/doing_build.html#testing-the-build
375 [gcov]: http://web.mit.edu/kerberos/krb5-current/doc/krb_build/test_cov.html
376 [VPATH]: http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Make-Target-Lookup.html
377
378 [[!tag tags/linux]]
379 [[!tag tags/tools]]