1 | Preparation for the Kerberos lab |
---|
2 | ================================ |
---|
3 | |
---|
4 | To get the "wow" factor for the initial exercises, showing how easy it is to |
---|
5 | add clients and servers to a Kerberised network, we need to have a |
---|
6 | Kerberos/LDAP environment already up and running. |
---|
7 | |
---|
8 | Prepare the DNS |
---|
9 | --------------- |
---|
10 | |
---|
11 | Build the NOC machine and ensure forward and reverse DNS is fully working, |
---|
12 | if not already done. |
---|
13 | |
---|
14 | Create kdc1 as an alias to whatever machine will be running the primary KDC |
---|
15 | (probably also the NOC), and add the Kerberos service records. |
---|
16 | |
---|
17 | # apt-get install bind9 bind9-utils |
---|
18 | # editor /etc/bind/named.conf.local |
---|
19 | zone "ws.nsrc.org" { type master; file "/etc/bind/ws.nsrc.org"; }; |
---|
20 | zone "10.in-addr.arpa" { type master; file "/etc/bind/10.in-addr.arpa"; }; |
---|
21 | |
---|
22 | # editor /etc/bind/ws.nsrc.org |
---|
23 | $TTL 600 |
---|
24 | @ IN SOA noc.ws.nsrc.org. root.noc.ws.nsrc.org. ( |
---|
25 | 1 ; Serial |
---|
26 | 604800 ; Refresh |
---|
27 | 600 ; Retry |
---|
28 | 2419200 ; Expire |
---|
29 | 600 ) ; Negative Cache TTL |
---|
30 | @ IN NS noc.ws.nsrc.org. |
---|
31 | |
---|
32 | _kerberos IN TXT "WS.NSRC.ORG" |
---|
33 | _kerberos-master._udp IN SRV 0 0 88 kdc1 |
---|
34 | _kerberos-adm._tcp IN SRV 0 0 749 kdc1 |
---|
35 | _kpasswd._udp IN SRV 0 0 464 kdc1 |
---|
36 | ; List all active Kerberos servers here |
---|
37 | _kerberos._udp IN SRV 0 0 88 kdc1 |
---|
38 | ldap IN A 10.10.254.250 |
---|
39 | |
---|
40 | noc IN A 10.10.254.250 |
---|
41 | kdc1 IN A 10.10.254.250 |
---|
42 | $GENERATE 1-20 $ IN PTR pc$.ws.nsrc.org. |
---|
43 | |
---|
44 | # editor /etc/bind/10.in-addr.arpa |
---|
45 | $TTL 600 |
---|
46 | @ IN SOA noc.ws.nsrc.org. root.noc.ws.nsrc.org. ( |
---|
47 | 1 ; Serial |
---|
48 | 604800 ; Refresh |
---|
49 | 600 ; Retry |
---|
50 | 2419200 ; Expire |
---|
51 | 600 ) ; Negative Cache TTL |
---|
52 | @ IN NS noc.ws.nsrc.org. |
---|
53 | |
---|
54 | $GENERATE 1-20 $.1.10 IN PTR pc$.ws.nsrc.org. |
---|
55 | 250.254.10 IN PTR noc.ws.nsrc.org. |
---|
56 | |
---|
57 | # editor /etc/resolv.conf |
---|
58 | search ws.nsrc.org |
---|
59 | nameserver 127.0.0.1 |
---|
60 | |
---|
61 | Test it: |
---|
62 | |
---|
63 | # dig pc1 |
---|
64 | # dig -x 10.10.1.1 |
---|
65 | # dig _kerberos._udp.ws.nsrc.org. srv |
---|
66 | |
---|
67 | If the NOC machine also has an entry for itself in /etc/hosts, make sure its |
---|
68 | FQDN is the first one listed. |
---|
69 | |
---|
70 | # editor /etc/hosts |
---|
71 | ... |
---|
72 | 10.10.254.250 noc.ws.nsrc.org noc |
---|
73 | |
---|
74 | Build slave DNS if desired |
---|
75 | -------------------------- |
---|
76 | |
---|
77 | You like resilience don't you? :-) And it sets a good example! |
---|
78 | |
---|
79 | Build primary KDC |
---|
80 | ----------------- |
---|
81 | |
---|
82 | See also the MIT Kerberos docs (esp. install guide) at |
---|
83 | http://web.mit.edu/kerberos/krb5-1.8/#documentation |
---|
84 | |
---|
85 | Install ntp: |
---|
86 | |
---|
87 | # apt-get install ntp |
---|
88 | |
---|
89 | Install kdc packages: |
---|
90 | |
---|
91 | # apt-get install krb5-kdc krb5-admin-server |
---|
92 | |
---|
93 | Answer the annoying debconf questions: |
---|
94 | |
---|
95 | Default Kerberos 5 realm: [WS.NSRC.ORG] |
---|
96 | Kerberos servers for your realm: [kdc1.ws.nsrc.org] |
---|
97 | Administrative server: [kdc1.ws.nsrc.org] |
---|
98 | |
---|
99 | Create the client library config: |
---|
100 | |
---|
101 | # mv /etc/krb5.conf /etc/krb5.conf.example |
---|
102 | # editor /etc/krb5.conf |
---|
103 | [libdefaults] |
---|
104 | default_realm = WS.NSRC.ORG |
---|
105 | dns_lookup_realm = true |
---|
106 | dns_lookup_kdc = true |
---|
107 | |
---|
108 | [realms] |
---|
109 | WS.NSRC.ORG = { |
---|
110 | admin_server = kdc1.ws.nsrc.org |
---|
111 | } |
---|
112 | |
---|
113 | (note that kadmin doesn't yet support looking up the admin server via DNS; |
---|
114 | hence we have to list it in krb5.conf) |
---|
115 | |
---|
116 | Create Kerberos database: |
---|
117 | |
---|
118 | kdb5_util create -r WS.NSRC.ORG -s |
---|
119 | # You will be asked to choose a database master password. We use "abcd" |
---|
120 | |
---|
121 | Create the ACL file and grant admin rights to all */admin principals: |
---|
122 | |
---|
123 | # editor /etc/krb5kdc/kadm5.acl |
---|
124 | */admin@WS.NSRC.ORG * |
---|
125 | |
---|
126 | Now create some principals: a host principal for the host itself, putting |
---|
127 | the random key into its own keytab file; an instructor principal ("nsrc"); |
---|
128 | and an instructor KDC admin principal ("nsrc/admin") |
---|
129 | |
---|
130 | # kadmin.local |
---|
131 | addprinc -randkey host/noc.ws.nsrc.org |
---|
132 | ktadd host/noc.ws.nsrc.org |
---|
133 | addprinc nsrc |
---|
134 | -- you'll be prompted to choose a password |
---|
135 | addprinc nsrc/admin |
---|
136 | -- you'll be prompted to choose a password |
---|
137 | ^D |
---|
138 | |
---|
139 | Now start the daemons: |
---|
140 | |
---|
141 | # /etc/init.d/krb5-kdc start |
---|
142 | # /etc/init.d/krb5-admin-server start |
---|
143 | |
---|
144 | At this point, you should be able to `kinit nsrc` and get a ticket. If you |
---|
145 | get "Cannot resolve network address for KDC" then check the DNS. |
---|
146 | |
---|
147 | Note: new principals can now be added using `kadmin` instead of |
---|
148 | `kadmin.local`, and you can use it from any remote machine where you can |
---|
149 | kinit. (So you never need to do a local login to the KDC) |
---|
150 | |
---|
151 | Build slave KDC if desired |
---|
152 | -------------------------- |
---|
153 | |
---|
154 | If you want to build a slave KDC, see the instructions at |
---|
155 | http://web.mit.edu/kerberos/krb5-1.8/krb5-1.8.3/doc/krb5-install.html#Install%20the%20Slave%20KDCs |
---|
156 | |
---|
157 | Add another `_kerberos._udp` srv entry in the DNS pointing to kdc2 so that |
---|
158 | clients know about both of them. |
---|
159 | |
---|
160 | Enable Kerberized ssh |
---|
161 | --------------------- |
---|
162 | |
---|
163 | The first exercise requires students to make a single-signon ssh login. |
---|
164 | |
---|
165 | Create a 'testuser' kerberos principal in the KDC, which the students will |
---|
166 | login as. |
---|
167 | |
---|
168 | $ kadmin -p nsrc/admin |
---|
169 | addprinc testuser |
---|
170 | ... choose a password which will be given to the students, e.g. nsrc2020 |
---|
171 | ^D |
---|
172 | |
---|
173 | On the machine(s) where the students will be allowed to login via kerberos, |
---|
174 | create a 'testuser' account (but don't set any local password) and enable |
---|
175 | Kerberos authentication for sshd. Note we're not doing LDAP yet. |
---|
176 | |
---|
177 | # useradd -m -s /bin/bash testuser |
---|
178 | # editor /etc/ssh/sshd_config |
---|
179 | ... |
---|
180 | GSSAPIAuthentication yes |
---|
181 | GSSAPIKeyExchange yes |
---|
182 | ... |
---|
183 | # service ssh restart |
---|
184 | |
---|
185 | Now we'll test it. You can either do this from the noc to itself, or you can |
---|
186 | use a separate throw-away client VM, or your own laptop. If using a |
---|
187 | separate machine you'll first have to make it a Kerberos client like this: |
---|
188 | |
---|
189 | # apt-get install krb5-user |
---|
190 | # mv /etc/krb5.conf /etc/krb5.conf.example |
---|
191 | # editor /etc/krb5.conf |
---|
192 | [libdefaults] |
---|
193 | default_realm = WS.NSRC.ORG |
---|
194 | dns_lookup_realm = true |
---|
195 | dns_lookup_kdc = true |
---|
196 | |
---|
197 | Check that `/etc/ssh/ssh_config` has `GSSAPIAuthentication yes` and |
---|
198 | if supported `GSSAPIKeyExchange yes` (On Mac OSX: `/etc/ssh_config`) |
---|
199 | |
---|
200 | Now it should work: |
---|
201 | |
---|
202 | $ kinit testuser |
---|
203 | $ ssh testuser@noc |
---|
204 | |
---|
205 | If it still doesn't work after this, Kerberos problems can be tricky to |
---|
206 | debug. First check both machines have accurately synced clocks, and that |
---|
207 | forward and reverse DNS is working. Then you can try starting another sshd |
---|
208 | in debug mode on another port: |
---|
209 | |
---|
210 | # /usr/sbin/sshd -d -p99 |
---|
211 | |
---|
212 | Then on the client: |
---|
213 | |
---|
214 | $ ssh -v -p99 nsrc@noc |
---|
215 | |
---|
216 | Test with Kerberized Apache |
---|
217 | --------------------------- |
---|
218 | |
---|
219 | If Apache isn't already installed on the noc, install it, and also curl for |
---|
220 | testing. |
---|
221 | |
---|
222 | # apt-get install apache2 curl |
---|
223 | |
---|
224 | Create a test directory and test page: |
---|
225 | |
---|
226 | # mkdir /var/www/secure |
---|
227 | # editor /var/www/secure/index.html |
---|
228 | ... whatever you like |
---|
229 | |
---|
230 | -- check it works and is not yet protected |
---|
231 | # curl http://noc.ws.nsrc.org/secure/ |
---|
232 | |
---|
233 | Now we're going to kerberize it. |
---|
234 | |
---|
235 | # apt-get install libapache2-mod-auth-kerb |
---|
236 | # editor /etc/apache2/conf.d/topsecret |
---|
237 | <Location /secure> |
---|
238 | AuthName "Hello Kerberos World" |
---|
239 | AuthType Kerberos |
---|
240 | # Allow fallback to Basic Auth? |
---|
241 | KrbMethodK5Passwd Off |
---|
242 | KrbAuthRealms WS.NSRC.ORG |
---|
243 | Krb5Keytab /etc/apache2/krb5/krb5.keytab |
---|
244 | # require user nsrc@WS.NSRC.ORG |
---|
245 | require valid-user |
---|
246 | </Location> |
---|
247 | |
---|
248 | # service apache2 restart |
---|
249 | |
---|
250 | Check that the page is no longer visible (curl gives a 403 error) |
---|
251 | |
---|
252 | We now have to create a service principal, and extract its key into the |
---|
253 | keytab specified in the config above, readable to the apache daemon. |
---|
254 | |
---|
255 | # mkdir /etc/apache2/krb5 |
---|
256 | # kadmin -p nsrc/admin |
---|
257 | addprinc -randkey HTTP/noc.ws.nsrc.org |
---|
258 | ktadd -k /etc/apache2/krb5/krb5.keytab HTTP/noc.ws.nsrc.org |
---|
259 | ^D |
---|
260 | # chown -R www-data:www-data /etc/apache2/krb5 |
---|
261 | # chmod 550 /etc/apache2/krb5 |
---|
262 | # chmod 440 /etc/apache2/krb5/krb5.keytab |
---|
263 | |
---|
264 | Check that the page is visible while you have a ticket with a client which |
---|
265 | supports HTTP Negotiate (and also check it isn't after `kdestroy`) |
---|
266 | |
---|
267 | # curl --negotiate -u: http://noc.ws.nsrc.org/secure/ |
---|
268 | |
---|
269 | If you want to test from Firefox or Chrome, see the presentation. |
---|
270 | |
---|
271 | NOTE: testing suggests that mod_authnz_ldap only does anonymous binds or |
---|
272 | fixed simple binds (i.e. I couldn't get it to use SASL, even if the www-data |
---|
273 | user has a ticket). We can gloss over this for now. |
---|
274 | |
---|
275 | |
---|
276 | Configure master LDAP server |
---|
277 | ---------------------------- |
---|
278 | |
---|
279 | This is by far the hardest part of the operation, due to the cryptic way |
---|
280 | OpenLDAP 2.4 now stores its configs within LDAP instead of in a config file. |
---|
281 | See `man slapd-config` |
---|
282 | |
---|
283 | There is a good series of articles here: |
---|
284 | http://www.opinsys.fi/en/setting-up-openldap-on-ubuntu-10-04-alpha2 |
---|
285 | But there are many others which user openldap <2.4 and slapd.conf |
---|
286 | |
---|
287 | Install the slapd server and Kerberos bits: |
---|
288 | |
---|
289 | # apt-get install slapd ldap-utils libsasl2-modules-gssapi-mit |
---|
290 | |
---|
291 | Set up the service principal with keytab readable by slapd: |
---|
292 | |
---|
293 | # mkdir /etc/ldap/krb5 |
---|
294 | # kadmin -p nsrc/admin |
---|
295 | addprinc -randkey ldap/noc.ws.nsrc.org |
---|
296 | ktadd -k /etc/ldap/krb5/krb5.keytab ldap/noc.ws.nsrc.org |
---|
297 | ^D |
---|
298 | # chown -R openldap:openldap /etc/ldap/krb5 |
---|
299 | # chmod 550 /etc/ldap/krb5 |
---|
300 | # chmod 440 /etc/ldap/krb5/krb5.keytab |
---|
301 | # editor /etc/default/slapd |
---|
302 | ... |
---|
303 | export KRB5_KTNAME=/etc/ldap/krb5/krb5.keytab |
---|
304 | |
---|
305 | # service slapd restart |
---|
306 | |
---|
307 | Install the schemas we need: |
---|
308 | |
---|
309 | # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif |
---|
310 | # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif |
---|
311 | # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif |
---|
312 | # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/misc.ldif |
---|
313 | |
---|
314 | NOTE: For a real production LDAP server, read the files in |
---|
315 | `/usr/share/doc/slapd` carefully, especially README.Debian.gz |
---|
316 | and README.DB_CONFIG.gz |
---|
317 | |
---|
318 | Now we need to run some scripts. First is `create_database.sh` |
---|
319 | |
---|
320 | ldapadd -Y EXTERNAL -H ldapi:/// <<EOS |
---|
321 | # Load hdb backend module |
---|
322 | dn: cn=module{0},cn=config |
---|
323 | objectClass: olcModuleList |
---|
324 | cn: module |
---|
325 | olcModulepath: /usr/lib/ldap |
---|
326 | olcModuleload: {0}back_hdb |
---|
327 | EOS |
---|
328 | |
---|
329 | ldapadd -Y EXTERNAL -H ldapi:/// <<EOS |
---|
330 | # Create the hdb database and place the files under /var/lib/ldap |
---|
331 | dn: olcDatabase={1}hdb,cn=config |
---|
332 | objectClass: olcDatabaseConfig |
---|
333 | objectClass: olcHdbConfig |
---|
334 | olcDatabase: {1}hdb |
---|
335 | olcDbDirectory: /var/lib/ldap |
---|
336 | olcSuffix: dc=ws,dc=nsrc,dc=org |
---|
337 | olcDbConfig: {0}set_cachesize 0 2097152 0 |
---|
338 | olcDbConfig: {1}set_lk_max_objects 1500 |
---|
339 | olcDbConfig: {2}set_lk_max_locks 1500 |
---|
340 | olcDbConfig: {3}set_lk_max_lockers 1500 |
---|
341 | olcLastMod: TRUE |
---|
342 | olcDbCheckpoint: 512 30 |
---|
343 | olcDbIndex: uid pres,eq |
---|
344 | olcDbIndex: cn,sn,mail pres,eq,approx,sub |
---|
345 | olcDbIndex: objectClass eq |
---|
346 | EOS |
---|
347 | |
---|
348 | (Note: we have no olcRootDN or olcRootPW. This is a pure Kerberos config) |
---|
349 | |
---|
350 | Next is `init_database.sh` |
---|
351 | |
---|
352 | ldapadd -Y EXTERNAL -H ldapi:/// <<EOS |
---|
353 | dn: dc=ws,dc=nsrc,dc=org |
---|
354 | objectClass: dcObject |
---|
355 | objectclass: organization |
---|
356 | o: ws.nsrc.org |
---|
357 | dc: ws |
---|
358 | description: LDAP root |
---|
359 | |
---|
360 | dn: ou=People,dc=ws,dc=nsrc,dc=org |
---|
361 | objectClass: top |
---|
362 | objectClass: organizationalUnit |
---|
363 | ou: People |
---|
364 | |
---|
365 | dn: ou=Groups,dc=ws,dc=nsrc,dc=org |
---|
366 | objectClass: top |
---|
367 | objectClass: organizationalUnit |
---|
368 | ou: Groups |
---|
369 | EOS |
---|
370 | |
---|
371 | And finally `config.sh` |
---|
372 | |
---|
373 | # Because these are 'replace' operations it's safe to modify this script |
---|
374 | # and re-run it |
---|
375 | ldapmodify -Y EXTERNAL -H ldapi:/// <<EOS |
---|
376 | dn: cn=config |
---|
377 | replace: olcSaslSecProps |
---|
378 | olcSaslSecProps: noanonymous,noplain,minssf=56 |
---|
379 | |
---|
380 | dn: olcDatabase={1}hdb,cn=config |
---|
381 | replace: olcAccess |
---|
382 | olcAccess: {0}to * by dn.regex="^uid=([^@,]+)/admin,cn=gssapi,cn=auth$" manage by users read |
---|
383 | - |
---|
384 | replace: olcRequires |
---|
385 | olcRequires: SASL |
---|
386 | EOS |
---|
387 | |
---|
388 | The following tweak disables unused sasl mechanisms, and means that |
---|
389 | `-Y GSSAPI` can be omitted form the ldapsearch command line. |
---|
390 | |
---|
391 | # editor /etc/ldap/sasl2/slapd.conf |
---|
392 | mech_list: gssapi external |
---|
393 | |
---|
394 | Test LDAP |
---|
395 | --------- |
---|
396 | |
---|
397 | (On the same machine, or on a separate client) |
---|
398 | |
---|
399 | # apt-get install ldap-utils libsasl2-modules-gssapi-mit |
---|
400 | # editor /etc/ldap/ldap.conf |
---|
401 | BASE dc=ws,dc=nsrc,dc=org |
---|
402 | URI ldap://ldap.ws.nsrc.org |
---|
403 | |
---|
404 | $ kinit nsrc |
---|
405 | $ ldapsearch [-Y GSSAPI] [-b "dc=ws,dc=nsrc,dc=org"] |
---|
406 | |
---|
407 | This should dump back the (mostly empty) LDAP database, as long as you have |
---|
408 | a Kerberos ticket |
---|
409 | |
---|
410 | Create user |
---|
411 | ----------- |
---|
412 | |
---|
413 | We are going to create a central user called "ldapuser" |
---|
414 | |
---|
415 | Firstly in Kerberos: |
---|
416 | |
---|
417 | $ kadmin -p nsrc/admin |
---|
418 | addprinc ldapuser |
---|
419 | ... password: foo123bar |
---|
420 | ^D |
---|
421 | |
---|
422 | And now in LDAP: |
---|
423 | |
---|
424 | $ kinit nsrc/admin |
---|
425 | $ ldapadd <<EOS |
---|
426 | dn: uid=ldapuser,ou=People,dc=ws,dc=nsrc,dc=org |
---|
427 | objectClass: account |
---|
428 | objectClass: posixAccount |
---|
429 | cn: ldapuser |
---|
430 | uid: ldapuser |
---|
431 | uidNumber: 10004 |
---|
432 | gidNumber: 100 |
---|
433 | homeDirectory: /home/ldapuser |
---|
434 | loginShell: /bin/bash |
---|
435 | gecos: ldapuser |
---|
436 | description: User account |
---|
437 | EOS |
---|
438 | $ kdestroy |
---|
439 | |
---|
440 | Test NSS |
---|
441 | -------- |
---|
442 | |
---|
443 | Now configure LDAP nscd/nsswitch, as per part 2 of exercise 2. |
---|
444 | |
---|
445 | To verify all is working: |
---|
446 | |
---|
447 | $ id ldapuser |
---|
448 | |
---|
449 | You should see a result with the uid and gid. Repeated operations should be |
---|
450 | quick as nscd will be caching them. |
---|
451 | |
---|
452 | Troubleshooting: |
---|
453 | |
---|
454 | * Make sure clock is synced |
---|
455 | * Make sure you have a kerberos ticket for root. Re-run |
---|
456 | `/etc/cron.hourly/kerberos` if necessary. |
---|
457 | * Restart nscd |
---|
458 | * If you stop nscd, then 'id <username>' will make an LDAP query as the |
---|
459 | current user. Make sure that the current user has a kerberos ticket. |
---|
460 | |
---|
461 | For easier management you can install the `ldapscripts` package, but see |
---|
462 | the patches at the end of exercise 4. |
---|
463 | |
---|
464 | Configure backup LDAP |
---|
465 | --------------------- |
---|
466 | |
---|
467 | OpenLDAP replication is left as an exercise to the reader. You can |
---|
468 | configure round-robin DNS for ldap.ws.nsrc.org and it should work. |
---|