Exercise2 : enable Kerberos logins to a host ============================================ This is to connect a server to an existing Kerberos/LDAP infrastructure. In part 1 we'll just enable Kerberos authentication, and in part 2 we'll enable LDAP authorization for uid/gid mapping. Part 1: Kerberos authentication =============================== Your machine must already be working as a Kerberos client (i.e. `/etc/krb5.conf` is setup correctly) Sync your clock --------------- Kerberos only works if your clocks are in close sync (certainly within 5 minutes). You can do a one-off clock sync like this: # ntpdate ntp.ubuntu.com But it's better to install the ntp daemon, which will continuously keep your clock in accurate sync. # apt-get install ntp Enable kerberos for sshd ------------------------ In the `sshd_config` file, uncomment the `GSSAPIAuthentication` line and set it to `yes`; also add `GSSAPIKeyExchange yes`. Then restart sshd. # editor /etc/ssh/sshd_config ... # GSSAPI options GSSAPIAuthentication yes GSSAPIKeyExchange yes .... # service ssh restart You're also going to add some extra lines to the end of krb5.conf, because of a current limitation in the kadmin utility. # editor /etc/krb5.conf ... [realms] WS.NSRC.ORG = { admin_server = kdc1.ws.nsrc.org } Now you need to set up a shared key between the KDC and the host's keytab. Call over an instructor to do this for you (because we're not letting you have admin access to the workshop Kerberos server :-) Here's what they will do: # kadmin -p nsrc/admin ... enter secret instructor password addprinc -randkey host/pcN.ws.nsrc.org ktadd host/pcN.ws.nsrc.org ^D This has (1) created the principal on the KDC, and (2) has copied the key into a local keytab file. You can examine your own keytab using either `klist -k` for a summary, or `ktutil` for more detailled information. Inside `ktutil` use '?' for help and ^D (ctrl-D) to exit. # ktutil rkt /etc/krb5.keytab list -e ^D (The key will be listed multiple times, for use with different encryption algorithms) Now you're going to allow ssh logins for 'testuser'. Because we don't have LDAP configured yet, we'll have to create a local account - but there's no need to set a password. # useradd -m -s /bin/bash testuser Now you're ready to test it. You can try logging in from your own machine to yourself, and you can get someone else to login to your machine. $ kinit testuser # use password from exercise 1 $ ssh testuser@pcN.ws.nsrc.org If instead of logging straight in you see a password prompt from ssh, then there's a problem which needs investigating. Debugging --------- The first things to check are: * Is your system clock at the correct time? * Does your host have working forward and reverse DNS? * Did you get a ticket? (klist) * Did you restart sshd after setting `GSSAPIAuthentication yes`? If those are correct, then in another window you can start a new instance of sshd in debug mode on a different port: # /usr/sbin/sshd -d -p99 Then try to connect to it: $ ssh -v -p99 testuser@pcN.ws.nsrc.org You will see logs at both the client and server side. --------------------------------------------------------------------------- Part 2: LDAP authorization ========================== This centralises your user/uid/gid/homedir management, and removes the need to add local users. We're going to configure it manually. In practice you'd probably just make a tarball containing all the preconfigured files and drop them onto each server which needed it. Install LDAP utils ------------------ # apt-get install ldap-utils libsasl2-modules-gssapi-mit # editor /etc/ldap/ldap.conf BASE dc=ws,dc=nsrc,dc=org URI ldap://ldap.ws.nsrc.org Now this is configured, you should be able to query the LDAP directory - but the server is set up only to allow read access if you have a Kerberos ticket. $ kinit testuser $ ldapsearch ... should list everything in ldap $ ldapsearch "(cn=*test*)" ... should list only entries matching the search query Automated Kerberos ticket ------------------------- For security, the LDAP server only permits connections which are Kerberos authenticated and encrypted. This means that the host itself needs a Kerberos ticket when doing LDAP lookups. (We could instead have used TLS security, but that would involve setting up a Certificate Authority, and we may as well leverage our Kerberos setup) We will run a cronjob every hour, using our existing keytab entry to obtain a ticket for `host/pcN.ws.nsrc.org` # editor /etc/cron.hourly/kerberos #!/bin/sh /usr/bin/kinit -k host/`hostname` -c /tmp/krb5cc_host Make it executable, and then run it once manually: # chmod +x /etc/cron.hourly/kerberos # /etc/cron.hourly/kerberos You can use this keytab to be able to do 'ldapsearch' when logged in as root: # KRB5CCNAME=/tmp/krb5cc_host ldapsearch Note: our LDAP queries will come from the caching daemon (nscd) which runs as root, and so this is all we need. If you wanted to run nscd as a different user, you would have to extend the cron script to make the ticket readable to that user. e.g. #!/bin/sh /usr/bin/kinit -k host/`hostname` -c /tmp/krb5cc_host umask 077 cp /tmp/krb5cc_host /tmp/krb5cc_nscd chown nscd /tmp/krb5cc_nscd Install nss_ldap ---------------- This is the library which intercepts password/group lookups and redirects them to LDAP. # apt-get install libnss-ldap nscd (Beware: there is an alternative package `libnss-ldapd` with a trailing "d". These exercises have been tested using `libnss-ldap`) Answer prompted questions as: LDAP server [ldap://ldap.ws.nsrc.org] Distinguished name of search base [dc=ws,dc=nsrc,dc=org] LDAP version to use [3] Make local root database admin [No] Does the LDAP database require login? [No] NOTE: The LDAP server starts with ldap:// not ldapi:// ! The configuration file is `/etc/ldap.conf`. We're going to replace it with a simple one which uses Kerberos authentication: # mv /etc/ldap.conf /etc/ldap.conf.example # editor /etc/ldap.conf krb5_ccname /tmp/krb5cc_host use_sasl on rootuse_sasl on base dc=ws,dc=nsrc,dc=org uri ldap://ldap.ws.nsrc.org ldap_version 3 sasl_secprops minssf=56 nss_initgroups_ignoreusers backup,bin,bind,daemon,games,gnats,irc,libuuid,list,lp,mail,man,news,nslcd,ntp,openldap,proxy,root,sshd,sync,sys,syslog,uucp,www-data We are also going to tweak `nscd.conf` to reduce caching of group information from 3600 to 600 seconds. # editor /etc/nscd.conf ... positive-time-to-live group 600 ... Configure nsswitch ------------------ This is the point where we actually start to use LDAP for lookups. # editor /etc/nsswitch.conf ... passwd: compat ldap group: compat ldap shadow: compat ldap ... # service nscd restart At this point you're ready to test: you should be able to map a username to a uid over LDAP, even though it doesn't exist in your local `/etc/passwd` file # id ldapuser uid=10004(ldapuser) gid=100(users) groups=100(users) If it fails, places to look are: * /var/log/auth.log * has root got a kerberos ticket? Use the following commands as root: # KRB5CCNAME=/tmp/krb5cc_host klist # KRB5CCNAME=/tmp/krb5cc_host ldapsearch * after any changes which might fix the problem, remember to restart nscd because it has both positive and negative caching * try stopping nscd, then try `id ldapuser` as root - there will be no caching, so it will make a separate LDAP query for each request. You can look at tcpdump, and logs on the LDAP server side. * if you control the LDAP server, run it in debug mode: # /etc/init.d/slapd stop # KRB5_KTNAME=/etc/ldap/krb5/krb5.keytab slapd -d 255 -u openldap -g openldap Home directory creation ----------------------- When a user first logs into a machine, you can create their home directory automatically via PAM (Pluggable Authentication Modules). # editor /etc/pam.d/common-session ... session required pam_mkhomedir.so umask=0022 skel=/etc/skel/ ... --------------------------------------------------------------------------- Miscellaneous Notes ------------------- Using kadmin to extract the key on the target host itself is almost always the best way to set up the shared host/service key. If joining a Microsoft Active Directory domain: you will need a third-party tool such as css_adkadmin (or it may be possible to use bits from samba). This may be a starting point: kinit Administrator css_adkadmin -r AD.NSRC.ORG -s dc1.ad.nsrc.org -q "ank -k -attr description=$HOSTNAME +randkey host/$HOSTNAME" css_adkadmin -r AD.NSRC.ORG -s dc1.ad.nsrc.org -q "xst +randkey host/$HOSTNAME" The alternative is to set a manual password on a host principal and then use ktutil to create a keytab with the same password. This is awkward, because (1) you need to use the right kvno, and (2) you need to repeat it for each encryption type which might be used on your network. [KDC side] kadmin addprinc host/pcX.ws.nsrc.org ... you are prompted for password getprinc host/pcX.ws.nsrc.org ... make a note of the kvno [host side] # ktutil ktutil: addent -password -p host/pcX.ws.nsrc.org -k 4 -e aes256-cts Password for host/pcX.ws.nsrc.org@WS.NSRC.ORG: ktutil: addent -password -p host/pcX.ws.nsrc.org -k 4 -e arcfour-hmac Password for host/pcX.ws.nsrc.org@WS.NSRC.ORG: ktutil: addent -password -p host/pcX.ws.nsrc.org -k 4 -e des3-hmac-sha1 Password for host/pcX.ws.nsrc.org@WS.NSRC.ORG: ktutil: list slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 4 host/pcX.ws.nsrc.org@WS.NSRC.ORG 2 4 host/pcX.ws.nsrc.org@WS.NSRC.ORG 3 4 host/pcX.ws.nsrc.org@WS.NSRC.ORG ktutil: wkt /etc/krb5.keytab