Tuesday Nov 23, 2010

Simple auto kinit for OS X

I wrote a couple small shell scripts to automate kinit when my MacBook Pro is connected to the internal company network. The first, kckinit, uses the OS X keychain to store my Kerberos password. The trick is to run the native kinit using < /dev/null. Apparently this will cause kinit to display a dialogue window which has a "remember in keychain" option. Once I did that I am able to run "kinit myprinc@FOO.COM #!/bin/ksh -p # This looks odd but kinit if it detects that stdin is being used will # pop up a password dialog window which allows the password for that # princ to be saved in the keychain and from then on will use the # keychain to get the password. if [[ $# -ne 1 || "$1" == @('-?'|'--help') ]] then echo "Usage: ${0##\*/} <sun|mit>" exit 1 fi case $1 mit) /usr/bin/kinit will@ATHENA.MIT.EDU < /dev/null;; sun) /usr/bin/kinit will@SUN.COM < /dev/null;; \*) print -u 2 "Usage: ${0##\*/} "; exit 1;; esac The second script calls the first one in a loop that runs in the background. I call the script auto_kinit. Here is the script:
#!/bin/ksh -p

(realm='SUN.COM'
princ="will@$realm"
host='foo.central.sun.com'

while true
do
	if (! /usr/bin/klist 2>/dev/null|\\
              /usr/bin/fgrep "Default principal: $princ" >/dev/null 2>&1) &&\\
	   (ping -c2 -oq $host >/dev/null 2>&1)
	then
		~/bin/kckinit sun
	fi
	sleep 45
done)&
It will detect when it is on the corporate network and do a kckinit while running as a background job. I've added auto_kinit as a login startup item.

Monday Nov 03, 2008

How to configure advanced kadmind logging in Solaris

After some experimenting and looking at source I've determined that the kadmind does have support for rotating its own log that is separate from the krb5kdc log (by default the kadmind logs to the log used by krb5kdc). To configure this, edit /etc/krb5/krb5.conf and add:
                                                                                                   
        admin_server = FILE:/var/krb5/kadmin.log                                                                        
        admin_server_rotate = {                                                                                         
                period = 1d                                                                                             
                versions = 10                                                                                           
        }                                                                                                               
in the [logging] section. Unfortunately, this is not documented properly in the krb5.conf man page but it basically works the same as the kdc_rotate parameter which is documented in man krb5.conf.
Note, to configure both the kdc and kadmind logging behavior to log to separate files, use something like:
                                                                                    
[logging]                                                                                                               
# commenting out default so kadmind will log to a separate file                                                         
#        default = FILE:/var/krb5/kdc.log                                                                               
        kdc = FILE:/var/krb5/kdc.log                                                                                    
        kdc_rotate = {                                                                                                  
                                                                                                                        
# How often to rotate kdc.log. Logs will get rotated no more                                                            
# often than the period, and less often if the KDC is not used                                                          
# frequently.                                                                                                           
                                                                                                                        
                period = 1d                                                                                             
                                                                                                                        
# how many versions of kdc.log to keep around (kdc.log.0, kdc.log.1, ...)                                               
                                                                                                                        
                versions = 10                                                                                           
        }                                                                                                               
                                                                                                                        
# controls kadmind logging                                                                                              
        admin_server = FILE:/var/krb5/kadmin.log                                                                        
        admin_server_rotate = {                                                                                         
                period = 1d                                                                                             
                versions = 10                                                                                           
        }                                                                                                               
This is the supported way to rotate the krb5kdc and kadmind logs. Also note that the kdc.conf man page is in error regarding the logging section. Use krb5.conf to control KDC logging instead.

Friday Mar 07, 2008

The Rough Guide to configuring a Solaris KDC to use a LDAP DS for the KDB

config_kdc_ldap.html Steps to configure a Solaris KDC and LDAP directory to store and
retrieve Kerberos records from the LDAP Directory Server.

OpenSolaris and Solaris 10 Update 5 were recently updated to allow a
Solaris KDC to use a LDAP Directory Server as the repository for the
Kerberos database.  This is a rough how-to to enabled this feature.

This document assumes that the LDAP directory already exists on the
Directory Server (DS).  Also note that the examples below assume the DS
is a Sun Java System Directory Server.  Other DS's can be used but the
procedure for creating and exporting the SSL certificate may differ.

In addition the examples below use various host names and domain names.
Wherever these occur you must substitute the appropriate host/domain
names for your environment.

Note, the Solaris KDC LDAP plugin only supports simple binds protected
by SSL (ldaps:) to the DS unlike the MITKC KDC LDAP plugin which also
support unix domain (ldapi:) binds to the DS.  The reason the Solaris
KDC LDAP plugin is so restricted is due to the native Solaris LDAP
library not supporting unix domain binds at this time.  Unix domain
binds do not require the SSL configuration below but do require the KDC
run on the same system as the DS.  SSL binds allow the KDC to run either
on the DS system or on a separate system.

1. Configure SSL for use between the KDC and DS.  Make sure the DS has a
   certificate and import that on the KDC if it is on a different
   system.  Here's the way to do that:

    (Note, the certificate for the DS must be stored in a local NSS
     compat certificate DB and the ldap_cert_path dbmodule paramter must
     point to the directory where the certificate DB resides.)

    ################## SSL Cert config steps Start ################################

    Steps to configure Solaris 10 to use DS 6.1 self signed certificate.
    When the directory instance is created it automatically creates a SS
    certificate.

    To use this on S10 as a client do:

    Export the PEM encoded DS SS certificate and save to
    /var/tmp/ds_cert (note /export/sun-ds6.1/directory/alias is the
    Directory instance).

        /usr/sfw/bin/certutil -L -n defaultCert \\
            -d /export/sun-ds6.1/directory/alias \\
            -P 'slapd-' -a > /var/tmp/ds_cert.pem

    Create the local certificate DB, just hit return twice when asked for a password:

        /usr/sfw/bin/certutil -N -d /var/ldap

    Add the DS SS PEM certificate to the local certificate DB:

        /usr/sfw/bin/certutil -A -n defaultCert -i /var/tmp/ds_cert.pem -a -t CT -d /var/ldap

    Or add the der certificate:

        /usr/sfw/bin/certutil -A -n defaultCert -i /var/tmp/ds_cert.der -r -t CT -d /var/ldap

    To test that SSL is working use (this example assumes that the
    "cn=directory manager" entry has admin priviledges on the LDAP
    directory):

        /usr/bin/ldapsearch -Z -P /var/ldap -D "cn=directory manager" \\
            -h ds-server.central.sun.com  -b "" -s base objectclass='\*'

    Some useful blog entries in regards to this topic:

    http://blogs.sun.com/baban/entry/steps_to_setup_ssl_using
    http://williamhathaway.com/?p=29

    Note that certain versions of JES DS 6.\* auto create a self-signed
    certificate where:

            Subject:
                "CN=ds-server,CN=636,CN=Directory Server,O=Sun Microsystems"
                     \^\^\^\^\^\^\^\^\^

    The problem with this is that CN=ds-server is the short hostname
    should really be the long form i.e. CN=ds-server.central.sun.com.

    End of Solaris 10 SSL config steps.
    ############################################

    Steps to configure a OpenSolaris KDC to use DS 6.1 self signed
    certificate:

    1. On DS export the self-signed DS certificate:

        /export/sun-ds6.1/ds6/bin/dsadm show-cert -F der /export/sun-ds6.1/directory2 \\
            defaultCert > /tmp/defaultCert.cert.der

    2. On OpenSolaris KDC import the DS certificate:

        pktool setpin keystore=nss dir=/var/ldap
        chmod a+r /var/ldap/\*.db
        pktool import keystore=nss objtype=cert trust="CT" \\
            infile=/home/willf/pub/defaultCert.certutil.der \\
            label=defaultCert dir=/var/ldap

    To list certs in the keystore:
        pktool list keystore=nss objtype=cert dir=/var/ldap

    To test try:

        /usr/bin/ldapsearch -Z -P /var/ldap -D "cn=directory manager" \\
            -h ds-server.central.sun.com  -b "" -s base objectclass='\*'

    or use shortname for host depending on the certificate.

    Note that if the self-signed DS certificate has expired, this will fail so
    remember to check the expiration date on the certificate and renew it if
    needed.  To renew using Java Enterprise DS 6.1 use:

    ds6/bin/dsadm renew-selfsign-cert ./directory0 defaultCert

    then export the certificate on the DS and import that on the clients/KDCs.

    ################## SSL Cert config steps End ##################################

2. Populate the directory (depends on DS so this may not be necessary).
   Note native Solaris idsconfig can be used to to setup standard
   directory root and containers if needed.

    If idsconfig is run to setup standard directory root and containers
    choose crypt for the password protection during the setup:

    Do you want to store passwords in "crypt" format (y/n/h)? [n] y
    "2 proxy" for Credential level,
    "2 simple" for the Authentication Method.

3. Add the Solaris Kerberos schema ldif file to the existing schema.  It
   is located here: /usr/share/lib/ldif/kerberos.ldif

   ldapmodify -h ds-server.central.sun.com -D "cn=directory manager" \\
        -f /usr/share/lib/ldif/kerberos.ldif

4. Create the Kerberos directory container entry in the LDAP directory.
   To create krbcontainer and realm on the DS use:

    - First make sure ldap_kerberos_container_dn in krb5.conf is set
      properly: (note dc=central,dc=sun,dc=com is the DS root container
      entry)

ldap_kerberos_container_dn = "cn=krbcontainer,dc=central,dc=sun,dc=com"

      In addition in the krb5.conf realm section set:

database_module = LDAP

      and add a [dbmodules] section like so:

[dbmodules]
    LDAP = {
        ldap_kerberos_container_dn = "cn=krbcontainer,dc=central,dc=sun,dc=com"
        db_library = kldap  # this must be kldap
        ldap_kdc_dn = "cn=kdc service,ou=profile,dc=central,dc=sun,dc=com"
        ldap_kadmind_dn = "cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com"
        ldap_cert_path = /var/ldap # path to NSS cert DB where the DS cert is stored
        ldap_servers = ldaps://ds-server.central.sun.com # or use shortname depending on cert
    }
##############################################################################################

    Here is an example krb5.conf:

[libdefaults]
        default_realm = ACME.COM

[realms]
        ACME.COM = {
                # Note, the KDC can run on the same system as the DS or
                # another system.
                kdc = bellyache.central.sun.com
                admin_server = bellyache.central.sun.com
                database_module = LDAP
        }

[domain_realm]
        .central.sun.com = ACME.COM

[dbmodules]
    LDAP = {
        db_library = kldap
        ldap_kerberos_container_dn = "cn=krbcontainer,dc=central,dc=sun,dc=com"
        ldap_kdc_dn = "cn=kdc service,ou=profile,dc=central,dc=sun,dc=com"
        ldap_kadmind_dn = "cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com"
        ldap_cert_path = /var/ldap
        ldap_servers = ldaps://ds-server.central.sun.com
   }

# The rest is standard for krb5.conf ...
###################################################################################

      (Note there is a minimum of 2 for the ldap_conns_per_server krb5.conf
      parameter).

      The setting of ldap_servers should always be ldaps: since the code
      currently does not support a insecure bind to the DS and ldapi:
      (LDAP over unix domain sockets) is currently not supported on
      Solaris at this time.  Also note that one should pay attention to
      the form of hostname found in the DS certificate.  If the short
      name is used then this should be used in the ldap_servers
      specification.  For example if the certificate has CN=ds-server in
      the Subject then:

ldap_servers = ldaps://ds-server

      should be used.  In most cases a CA issues certs with the fully
      qualified domain name, like ds-server.central.sun.com.

    - Next to create the Kerberos database (KDB) in the LDAP directory
      do (the -D arg is the DN of the DS admin allowed to make changes
      to the directory):

    kdb5_ldap_util -D <directory manager ID> create -r <realm> -s

    Example:

    kdb5_ldap_util -D "cn=directory manager" create -r ACME.COM -s

      This creates the krbcontainer and several other directory objects.
      It also creates a /var/krb5/.k5.<realm> master key stash file
      which is used by the KDC for decrypting the principal keys.

5. Create KDC service roles and stash the role passwords:

    For security/safety each KDC service (kdc and kadmin) has it's own
    role DN allowing finer setting of the ACL on the directory records.
    The ldap_kdc_dn role only needs read access at this point,
    ldap_kadmind_dn role needs access to create, modify and delete
    entries.

   - First create the KDC service role entries on the DS:

    To securely add the KDC service roles to the directory the following
    should be entered on the keyboard interactive (stdin) entry mode of
    the ldapmodify command.  This can also be entered via a file however
    there are security concerns given the clear text password for the
    roles is contained in the file.
    
    The contents should look like:

dn: cn=kdc service,ou=profile,dc=central,dc=sun,dc=com
cn: kdc service
sn: kdc service
objectclass: top
objectclass: person
userpassword: <some cleartext password for the kdc role>

dn: cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com
cn: kadmin service
sn: kadmin service
objectclass: top
objectclass: person
userpassword: <some cleartext password for the kadmin role>

    Note that if more protection is desired for the role password in the
    directory the following can be used.

userpassword: {md5}<role password converted to MD5 output>

    To get the MD5 conversion of the password "digest -a md5" can be
    used.

    To create the role entries in the LDAP directory do:

    ldapmodify -a -Z -h ds-server.central.sun.com -D "cn=directory manager"

    and enter the role information.  Use -Z to protect the information
    in transit.

   - Next the following parameters should be set in krb5.conf so the KDC
     can determine what DNs to use when binding to the DS:

    ldap_kdc_dn = "cn=kdc service,ou=profile,dc=central,dc=sun,dc=com"
    ldap_kadmind_dn = "cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com"):

   - Next stash the cleartext passwords for the kdc and kadmin service
     role DNs in the local password stash file used by the KDC to bind
     to the DS:

    kdb5_ldap_util stashsrvpw "cn=kdc service,ou=profile,dc=central,dc=sun,dc=com"
    kdb5_ldap_util stashsrvpw "cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com"

    which creates a /var/krb5/service_passwd file entry for the DN of the
    kdc and kadmin services.  This should contain the simple bind password
    that the KDC will use to authenticate and bind to the DS.  Note,
    the password must be entered as the clear text password (do not
    convert to MD5 if that was how the password was specified in the
    role entry).

    At this

6. Set the appropriate ACLs for the KDC related roles in the LDAP
   directory:

cat <<EOF | ldapmodify -h ds-server.central.sun.com -D "cn=directory manager"
# Set kadmin ACL for everything under krbcontainer.
dn: cn=krbcontainer,dc=central,dc=sun,dc=com
changetype: modify
add: aci
aci: (target="ldap:///cn=krbcontainer,dc=central,dc=sun,dc=com")(targetattr="krb\*")(version 3.0;\\
      acl kadmin_ACL; allow (all)\\
      userdn = "ldap:///cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com";)

# Set kadmin ACL for everything under the people subtree if there are
# mix-in entries for krb princs:
dn: ou=people,dc=central,dc=sun,dc=com
changetype: modify
add: aci
aci: (target="ldap:///ou=people,dc=central,dc=sun,dc=com")(targetattr="krb\*")(version 3.0;\\
      acl kadmin_ACL; allow (all)\\
      userdn = "ldap:///cn=kadmin service,ou=profile,dc=central,dc=sun,dc=com";)
EOF


7. Add kadmin princs to the kadm5.keytab:
(Note: <FQDN> must be replaced with the fully qualified domain name of
the system that the KDC is running on.  Example: kdc1.oracle.com)

kadmin.local -q "ktadd -k /etc/krb5/kadm5.keytab kadmin/<FQDN>"
kadmin.local -q "ktadd -k /etc/krb5/kadm5.keytab changepw/<FQDN>"
kadmin.local -q "ktadd -k /etc/krb5/kadm5.keytab kadmin/changepw"

8. Now start the KDC daemons.  At this point the KDC should be
   functioning to issue tickets and kadmin should work.

Other administrative commands:
-----------------------------------------------------------------------

To destroy a realm, use:

kdb5_ldap_util -D "cn=directory manager" destroy

-----------------------------------------------------------------------

To mix in Kerberos principal attributes to a directory entry of the
people objectclass: (note this mix in is useful when there are entries
of non-krb objectclass type like a people object class that one wants to
associate krb principal attributes with.)

1. Prep each entry to include krb principal attributes.  It should be modified
   like so:

# Adding the krbprincipalaux, krbprincipalaux and krbPrincipalName
# attributes
cat <<EOF | ldapmodify -h ds-server.central.sun.com -D "cn=directory manager"
dn: uid=willf,ou=people,dc=central,dc=sun,dc=com
changetype: modify
objectClass: krbprincipalaux
objectClass: krbTicketPolicyAux
krbPrincipalName: willf@ACME.COM
EOF

    Note the first component of the krbPrincipalName attribute does not
    have to match the entry's uid but it's generally good if this is the
    case.  (I need to double check this but I think it's also possible
    to have > 1 principal entries associated with a non krb object (like
    this people class entry)).

    Ideally one would write a script to pull all the people DN's from
    the LDAP directory and create a file that modifies them as above and
    feed that back to ldamodify.

2. Add a subtree attribute to the appropriate realm container entry:

        kdb5_ldap_util -D "cn=directory manager" modify \\
            -subtrees 'ou=people,dc=central,dc=sun,dc=com' -r ACME.COM

    This informs the KDC LDAP plugin that it should also search for
    principal entries from the 'ou=people,dc=central,dc=sun,dc=com' DN
    in addition to the ACME realm container DN which is searched by
    default.

3. Then either do a addprinc (either via kadmin or kadmin.local) to add the
   rest of the principal attributes including the secret key :

    kadmin.local -q 'addprinc willf'

   Or do:

    kdb5_util load -update dumpfile

   to migrate existing krb princs from the dumpfile to the LDAP
   directory.

-----------------------------------------------------------------------
To migrate all db2 KDB entries do:

1. While krb5.conf is configured to access the db2 KDB:

    kdb5_util dump > dumpfile

2. Configure krb5.conf to use the LDAP KDB then do:

    kdb5_util load -update dumpfile

Note kdb5_util uses the ldap_kadmind_dn role to bind by default.  This
can be overridden via the -x binddn arg but to be secure the DN password
should be stashed prior (see previous steps for how to do this).

Thursday Jun 16, 2005

Everything You Wanted to Know About Kerberos Enctypes But ...


I wrote a presentation about Kerberos encryption types (enctypes) and how they are used in Kerberos. It is aimed at both developers and administrators. You can download the PDF version here . Note, earlier versions of the presentation had a Sun Confidential label on the bottom of the slides which was left there by mistake. I have removed this label in the latest version of the presentation. I've updated the presentation slightly as of Oct 8,2007.

Technorati Tag: Technorati Tag:
About

user12615206

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today