Work In Progress --- SECOND DRAFT --- SECOND DRAFT --- SECOND DRAFT --- SECOND DRAFT --- Work In Progress

CAVEAT: This document has been somewhat overtaken by events. The current plan is to implement wallet to support ssh keys and X.509 certificates, but not keytabs. We propose to support keytabs via a conduit from the the Prometheus system when that system is fully operational, rather than as described below.

Wallet Evaluation

This is the evaluation report for Project 129 - Wallet Implementation. Comments are invited.

Contents

1. Introduction

The wallet (http://www.eyrie.org/~eagle/software/wallet/) is 'a system for managing secure data, authorization rules to retrieve or change that data, and audit rules for documenting actions taken on that data.' We are interested in it as a possible replacement for our in-house Kerberos keytab management tool kdcregister, as a way of managing host SSH keys, and as a way of managing X.509 certificates. This report summarises how wallet works, how we might configure and deploy it here, and what changes we would need to make to the existing codebase before deployment.

Summary: The wallet should allow us, in conjunction with the Prometheus system, to manage keytabs for all principals of interest. It should also allow management of SSH host keys and externally-obtained X.509 certificates. Management of local X.509 certificates is not currently proposed.

2. Wallet overview

The wallet is a client/server system built on top of the remctl protocol (http://www.eyrie.org/~eagle/software/remctl/) and using Kerberos GSS-API authentication. The wallet client itself has limited knowledge of the implementation: it mostly just sends commands to the server to be responded to appropriately.

All interaction with the wallet system - including all admin tasks - is intended be done over protocol; i.e. via the wallet client. The only exception should be the initial set-up.

The default remctld configuration allows any authenticated user to run the wallet backend, and relies on the wallet's ACLs (see below) for all access control. This seems reasonable, but can be more tightly controlled by replacing ANYUSER in the remctld configuration with a path to an ACL file, and only allowing users authorised by that ACL file to run wallet commands.

(Q: Do the remctld ACLs allow pattern-matching? The docs imply they don't, in which case their use in this case may not be a suitable option for us.)

2.1 Wallet objects

In the current (v0.11) release, the wallet has native support for two types of 'object' data items: Kerberos keytabs, and (arbitrary) files.

2.1.1 Wallet keytab objects

The wallet backend supports keytab objects by running kadmin under the auspices of a principal established for the purpose. (The fixed keytab corresponding to this principal needs to be set up one time only, at installation time.) The principal used should be created so that the backend has the minimum possible privileges in the KDC consistent with the kinds of principals and keytabs the wallet server will be used to maintain.

Only one Kerberos realm is supported for a given wallet implementation, and all keytab objects stored must be in that realm. By default, whenever a keytab object is retrieved from the wallet, the key is changed in the Kerberos KDC and the wallet returns a keytab for the new key. (That is, the usual ktadd behaviour applies.) The wallet system can also be configured so that, optionally, the existing keys of keytab objects are preserved when retrieved from the KDC. Heimdal Kerberos doesn't require any special support for this; for MIT Kerberos, the wallet backend achieves it by running (via remctl) another backend which must be installed on the KDC - this backend then runs kadmin.local. The kadmin.local binary used must support the -norandkey option. This option is included in MIT Kerberos 1.7 or later; patches are available for earlier versions.

It is important to note that, in all cases, keytabs themselves are not stored in the wallet database; only the metadata pertaining to them is stored.

2.1.2 Wallet file objects

The wallet backend supports file objects by storing their contents in a directory set up for the purpose on the wallet server. There are no known limitations on the content of any file stored in this way.

2.2 Wallet ACLs

The wallet authorisation and ACL design is rich, fine-grained - and potentially confusing. Since this has implications for our deployment, a summary highlighting the relevant points is as follows:

  1. There are two types of wallet user: administrators, and everyone else.

    Administrators are users which are authorised by the special ACL ADMIN.

  2. An ACL is an object in the wallet database which can either be created manually by an administrator via a call to the wallet client, or by the wallet system itself in response to an autocreate operation. An ACL consists of zero or more ACL entries, each of which takes the form

    <scheme> <identifier>

    where <scheme> specifies the semantics of <identifier>.

    Only two schemes are currently defined in the wallet software, krb5 and netdb. Of these, only the krb5 scheme is of interest to us; the corresponding identifier is a single fully-qualified Kerberos principal. Additional schemes can be defined, however.

    Note: wallet ACLs for the Kerberos scheme do not currently support pattern-matching; instead, they require a literal match to a single Kerberos principal.

  3. A user is deemed to be authorised by an ACL if any entry in that ACL implies authorisation. There is no support for negative ACL entries.

  4. Every data object in the wallet must have an 'owner' ACL (also referred to in the documentation as the object's 'owner') which contains ACL entries for all users who have ownership rights over that data object. By default, owners have get, store and show rights on the object.

  5. In addition, a data object may also have ACLs for get, store, show, destroy and flag operations. An ACL for get, store or show - if it exists - overrides the default owner rights for those operations as implied by the owner ACL.

  6. Administrators are permitted to perform any operation except get and store. In order to perform get and store operations on any data object, they must first add themselves to the appropriate ACL. (That is, either the specific ACL, or the owner ACL.)

2.3 Wallet operations

The wallet server implements the following operations:

autocreate Create an object with default ACLs
check Determine whether an object exists
create Create a new wallet entry for an object
destroy Delete the wallet entry for a given object
owner Set the owner of an object
acl Set an ACL on an object
expires Set the expiration of an object
flag Set or clear flags on an object
show Show the metainformation about the object
get Retrieve the named object from the wallet
store Store the named object in the wallet

The first nine operations manipulate or display the metadata of the object; the final two operations store or retrieve the object itself.

The create, owner, acl, and expires operations are only available to wallet administrators.

Wallet data objects are created either by an administrator explicitly using the create command, or by an autocreate operation. (Note that, in either case, what's created is the metadata that pertains to the object; not the content of the object itself.)

autocreate works as follows:

  1. When a wallet user attempts to get or store an object that doesn't already exist, (as determined by the check call), the wallet client attempts autocreate. On the server, the type and name of the object are passed to a policy function (default_owner, which, if it exists, must be specified in the site-wide wallet configuration file, normally /etc/wallet/wallet.conf), which returns an ACL.

  2. If the name of the ACL returned by default_owner does not match that of an existing ACL, then the ACL is created in the ACL database. Then, if the calling user is authorized by that ACL, the object is created, and that ACL becomes the object's new owner. Otherwise,

  3. If the name of the ACL returned by default_owner matches that of an existing ACL, then the value of the existing ACL is compared to the value of the ACL returned by default_owner. If these values do not match, creation fails. Otherwise, if the calling user is authorized by that ACL, the object is created, and that ACL becomes the object's new owner.

Note that, for an autocreated keytab, the keytab is extracted as well as created. That is, if the autocreate is successful, the wallet client then performs the get.

(Note also that this always leaves the new ACLs in the database, regardless of whether the autocreate of the object worked or not. As the author of the software notes, this 'may not be the best behaviour' ...)

2.4 Wallet namespace

The wallet does not itself impose any naming scheme either on any object (unless the object backend involved specifically rejects the name) or any ACL: the responsibility for designing a reasonable namespace policy belongs to each implementing site, and requires an careful analysis of the entire set of objects planned to be stored in the wallet.

Local site naming policies, once decided, can be enforced by the two policy functions verify_name and verify_acl_name. Either of these policy functions can also be used to enforce additional site-specific checks at the time of object or ACL creation. For both functions, a return value of undef or the empty string means that creation is allowed; if any other value is returned creation is disallowed and that values is returned to the client as an error string.

3. Use cases

The specification for Project 129 - Wallet Implementation lists four cases where we might want to use wallet:

  • Management of keytabs - to replace the existing system based on kdcregister.
  • Management of externally obtained X.509 certificates.
  • Management of SSH host keys, such that they persist across reinstalls.
  • Management of local X.509 certificates, possibly to replace SIXKTS.

3.1 General design principles

The general design principles for our deployment of the wallet are as follows:

Principals and keytabs

  1. Kerberos principals for which the wallet will be used to manage keytabs must already exist in the KDC. The wallet itself will have no authority to create new principals.
  2. The wallet backend will have authority (subject, in addition, to the authority of the principal running the wallet client) to extract keytabs for any principal of the form */*@INF.ED.AC.UK, except for principals of the form */admin@INF.ED.AC.UK.

ACL's

  1. We will use only wallet owner ACL's; no more specific ACL's will be used.
  2. The wallet krb5 scheme ACL handling code will be patched to allow pattern matching.

Access rights

  1. The owner ACL of every object held in the wallet will include the ACL entry
    krb5 */admin@INF.ED.AC.UK
    which gives any */admin@INF.ED.AC.UK principal complete rights over the object.
  2. All wallet objects representing service keytabs belonging to a host, the SSH private key belonging to a host, and any third-party X.509 certificates belonging to a host, should all be downloadable (and storeable, as appropriate) by both the hostclient/<FQDN> principal (where <FQDN> is the fully-qualified domain name of that host), and any Informatics */admin principal.

Other

  1. We will rely on autocreate to populate the wallet database with objects and owner ACL's.
  2. The wallet client code will be patched to support authentication via a source keytab to allow programmatic extraction of keytabs and file objects, e.g. by LCFG components.

3.2 Management of keytabs

We need a system for keytab management for various types of principal. Two important cases are

  1. principals belonging to machines - e.g. hostclient/<FQDN> and service<FQDN> - for which keytabs are currently extracted by kdcregister either at machine install time (or, later, at Kerberos component re-configuration time), and
  2. principals to be used by users wanting to run long-running jobs,

but there will be other cases as well. All that can probably be guaranteed is that all principals of interest will take the form */*@INF.ED.AC.UK.

An initial driver for the current project was the complete replacement of the local utility kdcregister: there was a concern that kdcregister could not be guaranteed to continue to build and work over future OS upgrade cycles. (See also Project 69 - Improve Host key management.) However, recent work done by Stephen Quinney and Simon Wilkinson now means that kdcregister builds directly against modern Kerberos, so the major impetus to replace it no longer exists.

Note that, in its current form, kdcregister actually creates principals in the KDC, as well as subsequently extracting the corresponding keytab entries. However, the new account management system Prometheus is expected to have complete responsibility for the life-cycle (and, specifically, the creation) of all principals in the KDC - including those belonging to machines and their services - so the expectations for the wallet now are that it will be used to extract keytabs for principals which already exist. This has implications for the configuration of the wallet system.

In other words: the requirement for the current project is the management of keytabs for the various additional 'Identity' principals which may be created by (or assigned to) an existing 'Entity' principal; and, as two particular cases, principals which are used by users wanting to run long-running jobs, and service/host principals.

The following notes describe the deployment of wallet to suit this requirement; Appendix A outlines how the wallet could instead be used to replace the use of kdcregister in its current form, were that ever to be required.

3.2.1 Wallet keytab naming policy

For keytab objects, our naming policy will be that:

  1. The name of the wallet keytab object will be the (fully-qualified) name of the principal to which the object refers.

    E.g. ldaprep/ancona.inf.ed.ac.uk in the case of a keytab corresponding to a service principal; idurkacz/longrunning in the case of a keytab corresponding to a principal associated with an parent identity; etc.

  2. For any particular host, any keytab object which should be downloadable by any administrator user or by the hostclient key itself, will be be owned by the ACL named hostclient/<FQDN>, where FQDN is the fully-qualified name of the host.

    E.g. ldaprep/ancona.inf.ed.ac.uk will be owned by the owner ACL hostclient/ancona.inf.ed.ac.uk.

  3. For any particular entity, any identity keytab object which should be downloadable by that entity will be owned by the ACL named entity.

    E.g. idurkacz/longrunning will be owned by the owner ACL named idurkacz.

3.2.2 Required wallet configuration

  1. The wallet backend needs the minimum necessary privileges to extract keytabs for the principals of interest from the KDC. To arrange this:

    1. Manually add the principal wallet/<FQDN>@INF.ED.AC.UK to the KDC, where <FQDN> is the fully-qualified domain name of the server on which the wallet backend is to run. (In our deployment, the wallet backend should run on the same machine as the master KDC.) This is the principal which the wallet backend will use to authenticate to the KDC.

    2. In the file /var/kerberos/krb5kdc/kadm5.acl file on the master KDC, add the entries

      wallet/<FQDN>@INF.ED.AC.UK ADMCIL */admin@INF.ED.AC.UK
      wallet/<FQDN>@INF.ED.AC.UK ADMciL */*@INF.ED.AC.UK

      (Again, <FQDN> is the fully-qualified domain name of the server on which the wallet backend is to run.)

  2. Declare, to the wallet system, that all Informatics administrator (i.e. */admin@INF.ED.AC.UK principals) users are wallet 'administrator' users.

    The only viable way to do this is to patch the wallet krb5 scheme ACL handling code to allow pattern-matching, so that any principal of the form */admin@INF.ED.AC.UK is deemed a wallet administrator. Then, as a one-time set-up at initial wallet configuration time, add the single ACL entry:

    krb5 */admin@INF.ED.AC.UK

    to the the wallet ADMIN ACL.

  3. Add a policy function verify_name - something like the following - to the /etc/wallet/wallet.config file:
      sub verify_name {
        my ($type, $name, $user) = @_;
        if (type eq 'keytab') {
          my $realm = 'INF.ED.AC.UK';
          return "non-primary keytab not allowed" unless $name =~ m|/|;
          my ($field1, $field2) = split ('/', $name, 2);
    
          if ($field2 =~ m/\./) {  # service principal case
            my ($hostname, $domainname) = split('.', $field2, 2);
            return "invalid domainname" unless $domainname eq 'inf.ed.ac.uk';
            return "invalid hostname" unless gethostbyname($field2);
          }
          else {                   # entity/identity principal case
            if (($user eq $field1) or ($user =~ m|/admin$|)) {
               if ( ! user_has_role($field1, $field2)) {
                 return "role $field2 not assigned to $field1"
               }
            }
            else {
              return "$user not allowed to create $name";
            }
          }
        }
      }
    

    The idea is to enforce naming conventions, basic correctness, and some additional authorisation. The exact checks to be applied may need more attention.

  4. Add a policy function default_owner - something like the following - to the /etc/wallet/wallet.config file:

       sub default_owner {
         my ($type, $name) = @_;    # e.g. 'keytab host/ancona.inf.ed.ac.uk', 
                                    #      'keytab ldaprep/ancona.inf.ed.ac.uk', 
                                    #      'keytab idurkacz/longrunning',
                                    #       etc.
         if ($type eq 'keytab') {
           my $realm = 'INF.ED.AC.UK';
           return unless $name =~ m|/|;
           my ($field1, $field2) = split ('/', $name, 2);
    
           if ($field2 =~ m/\./) {  # service principal case
             my $acl_name = "hostclient/$field2";
             my @acl = ([ 'krb5', '*/admin@realm' ],
                        [ 'krb5', "hostclient/$field2\@$realm" ]);
             return ($acl_name, @acl);
    
           else { # entity/identity principal case
             my $acl_name = "$field1";
             my @acl = ([ 'krb5', '*/admin@realm' ],
                        [ 'krb5', "$field1\@$realm" ]);
             return ($acl_name, @acl);
           }
         }
       }
    

    For service principals, the idea is that the wildcard'ed */admin principal entry allows any computing officer to extract (via autocreate) the initial hostclient keytab via the wallet at machine install time, and that, thereafter, the hostclient principal can itself extract further keytabs from the wallet.

    For entity/identity principals, the idea is that either the user involved, or any computing officer, can extract the required keytab.

3.2.3 Usage of keytabs stored in the wallet

Assuming (again) that all principals referred to will have already been created in the KDC by the Prometheus system, wallet keytabs can be used as follows.

3.2.3.1 Service principals

Keytabs for service principals are currently maintained by the Kerberos component. The current system works as follows:

  1. At host install time, the kerberos component creates the hostclient/<FQDN>@INF.ED.AC.UK principal via a call to kdcregister using the -p principal switch, where principal has been set to the admin principal of the installing computing officer. (The installing computing officer must be physically present to enter his/her corresponding admin password.)

  2. At host-install time (or, later, at any subsequent reconfiguration of the Kerberos component), the host principal host/<FQDN>@INF.ED.AC.UK and all other service principals of the type <service>/<FQDN>@INF.ED.AC.UK are (created by the kerberos component via a call to kdcregister using the -k source-keytab switch, where source-keytab points to the keytab file created by the previous step which contains the hostclient/<FQDN>@INF.ED.AC.UK as its initial entry. (This all proceeds without human intervention.)

This can be reorganised to use wallet as follows:

  1. In the Kerberos component, replace the call

    kdcregister -p <principal> <name>

    by a call of

    wallet -u <principal> get keytab <name>

  2. In the Kerberos component, replace the call

    kdcregister -k <source-keytab> <name>

    in point 2 by a call of

    wallet -u hostclient/<FQDN>@INF.ED.AC.UK -K <source-keytab> <source get keytab <name>

    Note: this assumes the wallet client has been patched to support authentication via a keytab - the new -K switch. The alternative, if this is not done, is to use kinit and to replace the above call with something like:

    (export KRB5CCNAME=`mktemp -t walletkrb5cc.XXXXXX`; kinit -k -t <source-keytab> hostclient/<FQDN>@INF.ED.AC.UK; wallet get keytab <name>; kdestroy)

3.2.3.2 Entity/identity principals

Keytabs for entity/identity principals can be extracted by their owners (or by CO's on their behalf) by a call of

wallet get -f <keytab_file> keytab <name>

Keytab objects for which keys are required to be preserved for subsequent retrievals should then be flagged correspondingly:

wallet flag set keytab <name> unchanging

The flag can be later be cleared if necessary:

wallet flag clear keytab <name> unchanging

3.3 Management of externally-obtained X.509 certificates

We need a system for managing externally obtained X.509 certificates, so that these can be maintained over machine reinstalls.

3.3.1 Wallet externally-obtained X.509 certificate naming policy

Some discussion is needed about the numbers of X.509 certificates involved, and what the naming policy to be applied to these should be. For the sake of discussion here, let us say that:

  1. The name of each X.509 certificate object for host server will be
    <server>-x509-<id>
    where <id> is the identifier of the certificate.
  2. For any particular host, all X.509 certificate objects (which should be storeable and downloadable by either the hostclient principal of the host in question, or by any Informatics administrator) will be owned by the ACL named hostclient/<FQDN>, where FQDN is the fully-qualified name of the host.

3.3.2 Required wallet configuration

In order to allow externally-obtained X.509 certificates to be correctly autocreate'd as file objects in the wallet, logic something like the following needs to be added to the policy function default_owner in the /etc/wallet/wallet.config file:

     my ($type, $name) = @_;   # e.g. 'file ancona-ssh-rsa'
     if ($type eq 'file') {
       my $realm = 'INF.ED.AC.UK';
       return unless $name =~ m|-|;
       my ($hostname, $filetype, $id) = split ('-', $name, 3);
 
       return unless $filetype eq 'x509';
      
       my $acl_name = "hostclient/$hostname.inf.ed.ac.uk";
       my @acl = ([ 'krb5', '*/admin@realm' ],
                  [ 'krb5', "hostclient/$hostname.inf.ed.ac.uk\@$realm" ]);
       return ($acl_name, @acl);
     }

The intention is that SSH keys are owned by both the relevant hostclient principal, and all Informatics */admin principals.

3.3.3 Usage of externally-obtained X.509 certificates stored in the wallet

More discussion is needed about the use of wallet to manaage externally-obtained X.509 certificates. In outline, the usage should be similar to that for SSH keys below; what needs clarification is which components (or other software) need amending to store and extract certificates to and from the wallet.

3.4 Management of SSH host keys

We need a system for managing SSH host keys, so that these can be maintained over machine reinstalls. It is necessary only to preserve the private keys; the corresponding public key can be regenerated by call to ssh-keygen -y -f <private-key>.

3.4.1 Wallet SSH host key naming policy

  1. The name of the SSH private key object for host server will be
    <server>-ssh-<type>
    where <type> is the type of the key (rsa1, rsa or dsa).
  2. For any particular host, the SSH private key object (which should be storeable and downloadable by either the hostclient principal of the host in question, or by any Informatics administrator) will be owned by the ACL named hostclient/<FQDN>, where FQDN is the fully-qualified name of the host.

3.4.2 Required wallet configuration

In order to allow SSH keys to be correctly autocreate'd as file objects in the wallet, logic something like the following needs to be added to the policy function default_owner in the /etc/wallet/wallet.config file:

     my ($type, $name) = @_;   # e.g. 'file ancona-ssh-rsa'
     if ($type eq 'file') {
       my $realm = 'INF.ED.AC.UK';
       return unless $name =~ m|-|;
       my ($hostname, $filetype, $id) = split ('-', $name, 3);
 
       return unless $filetype eq 'ssh';
      
       my $acl_name = "hostclient/$hostname.inf.ed.ac.uk";
       my @acl = ([ 'krb5', '*/admin@realm' ],
                  [ 'krb5', "hostclient/$hostname.inf.ed.ac.uk\@$realm" ]);
       return ($acl_name, @acl);
     }

The intention is that SSH keys are owned by both the relevant hostclient principal, and all Informatics */admin principals.

3.4.3 Usage of SSH keys stored in the wallet

The generation of SSH host keys is currently performed by the /etc/init.d/sshd script which is explicitly called the LCFG openssh component at start time. That script generates rsa1, rsa and dsa keys in the /etc/ssh directory if any of those don't currently exist.

In order to use the wallet to manage SSH host keys, the Start method of the LCFG openssh component needs to be amended with logic like the following:

  IF managing-ssh-keys-with wallet THEN
    FOREACH keytype IN (rsa1, rsa, dsa) DO
      IF key of keytype does not exist in /etc/ssh THEN
        wallet check file <host>-ssh-<keytype>
        IF key exists in wallet THEN
          wallet get file <host>-ssh-<keytype>
        ENDIF
      ENDIF
    ENDFOR  
  ENDIF

  /etc/init.d/sshd start

  IF managing-ssh-keys-with wallet THEN
    FOREACH keytype IN (rsa1, rsa, dsa) DO
      wallet check file <host>-ssh-<keytype>
      IF key of keytype does not exist in wallet THEN
        wallet store file <host>-ssh-<keytype>
      ENDIF
    ENDFOR  
  ENDIF

(That is, allow /etc/init.d/sshd (as currently) to perform the actual key generation when this is required.)

The assumption is that the wallet client has been patched to support authentication via a keytab, and that it has been called under the auspices of the principal hostclient/<FQDN>@INF.ED.AC.UK. The alternative is to use kinit to obtain a ticket via a keytab - see 3.2.3.1 above.

3.5 Management of local X.509 certificates

To manage local X.509 certificates using wallet, we would need to completely replace the current SIXKTS system by a new wallet backend module which is able to generate and sign local certificates. The wallet system supports additional backend modules - so this is possible -, but the details of doing this have not been investigated at all in the course of this evaluation.

An argument needs to be made regarding the necessity or desirability of replacing SIXKTS before this aspect should be considered further.

4. Configuration and deployment

4.1 Wallet software

The wallet software has been packaged as world/wallet-0.11-1.inf.src.rpm, world/wallet-client-0.11-1.inf.i386.rpm and world/wallet-server-0.11-1.inf.i386.rpm.

Currently, the only patch is to install the server Perl modules in vendor_perl rather than site_perl. For keytab operation we need, in addition, to at least patch the krb5 scheme ACL handling code to support pattern matching.

4.2 Wallet client configuration

All that the wallet client needs to know (other than stock defaults, all of which should be suitable in our case) is the name of the wallet server. This can be given as an option on the command line, configured into the binary at RPM build time, or declared in an [appdefaults] section of the client machine's /etc/krb5.conf file.

It seems easiest to configure the server name wallet into the binary, and set up the appropriate DNS CNAME.

4.3 Wallet server configuration

Apart from the necessary remctld configuration (which can be handled by the remctld component), the wallet server is completely configured by the single file /etc/wallet/wallet.conf. (For more details, man Wallet::Config.)

(Comment: the name/location of this file can be changed, if necessary, by setting the WALLET_CONFIG environment variable.)

/etc/wallet/wallet.conf is Perl source code. As well as configuration variables, it contains policy functions if those are deemed to be necessary.

We will need to set at least the following variables:

Variable Value
$DB_DRIVER e.g. 'SQLite'
$DB_INFO e.g. '/var/lib/wallet/wallet.sqlite'
$FILE_BUCKET e.g. '/var/lib/wallet/wallet_file_bucket'
$KEYTAB_FILE e.g '/etc/wallet/wallet.keytab'
$KEYTAB_KADMIN '/usr/kerberos/sbin/kadmin'
$KEYTAB_KRBTYPE 'MIT'
$KEYTAB_PRINCIPAL 'wallet/@INF.ED.AC.UK'
$KEYTAB_REALM 'INF.ED.AC.UK'
$KEYTAB_TMP e.g. '/var/tmp/wallet_keytab_tmp'
$KEYTAB_REMCTL_CACHE as appropriate
$KEYTAB_REMCTL_HOST as appropriate
$KEYTAB_REMCTL_PRINCIPAL as appropriate

(The final three variables relate to the configuration necessary to preserve existing keys - this has not yet been tested.)

The additional wallet backend needed to preserve existing keys, must be installed on a KDC (not necessarily the master.) The wallet server itself can run anywhere, but for security reasons it makes sense to also run it on a KDC since it needs to be managed as securely as is the KDC itself.

As implementation details, we need to decide on the type of backend database to be used: the options are SQLite or MySQL.

We also need to include the policy functions default_owner and verify_name.

Creation of /etc/wallet/wallet.conf could all be done by the file component, but it makes sense to provide a wallet component which in addition to handling the configuration file also contains the logic necessary to perform the one-off initial configuration tasks needed to set up a wallet server. In order that this can an LCFG-level component, any site-specific policy code which is eventually to be included in the generated /etc/wallet/wallet.conf file should be abstracted out to a file which is Perl require'd by the /etc/wallet/wallet.conf should component resources make this choice.

4.4 Status / auditing reports

A mechanism should be set up to provide regular auditing reports regarding the current usage of the wallet system. This is possible (man Wallet::Report) but the details, and our requirements, remain to be defined.

4.5 Backing up the system

Apart from the configuration file /etc/wallet/wallet.config, all of the the wallet system's database is held in its back-end database and the 'file bucket' directory which contains the contents of all file objects.

Backing up the system therefore means that these two data stores need to be backed up in some secure way. Likewise, transferring the system to a new server means copying this data securely.

5. Recommendations

We should deploy the wallet generally as described above. In particular:

Necessary wallet code changes

  1. Patch the krb scheme ACL handling code to allow pattern matching.
  2. Patch the wallet client to allow authentication via a source keytab.
  3. Provide an LCFG wallet component.

Keytabs

On the assumption that the Prometheus system takes responsibility for the creation of all principals involved (including the hostclient/ principal of a machine prior to its installation), the wallet should be used to manage all service/host and entity/identity principals. This requires code changes to other systems:

  1. The Kerberos component should be amended to replace calls to kdcregister by calls to wallet when managing all service/host keys.
  2. The version of kadmin.local in use on the KDC's should be patched to support the -norandkey option to ktadd.
  3. The wallet client should be provided (either directly, or via wrapper scripts) to users in order to allow them to manage keytabs as appropriate, depending on their assigned roles.

Externally-obtained X.509 certificates

The wallet should be used to manage externally-obtained X.509 certificates, but more discussion is required about what certificates are involved and how they should be handled.

SSH host keys

The wallet should be used manage SSH host keys as described in 3.4.

Local X.509 certificates

No action should be taken to manage local X.509 certificates.

Appendix A - Replacement of kdcregister by wallet

As mentioned in 3.2, the following notes describe how wallet could be used to replace kdcregister exactly as it is currently used (in particular, at machine install time) to both create principals, as well as to extract corresponding keytab entries. Note that we are not proposing to use wallet in this way, but these notes are included for completeness.

A.1 Current system

The keytabs of interest here are those corresponding to the principals hostclient/<FQDN>@INF.ED.AC.UK, host/<FQDN>@INF.ED.AC.UK and <service>/<FQDN>@INF.ED.AC.UK; these are currently created solely by the kerberos component.

In detail, the current system works as follows:

  1. At host install time, the kerberos component creates the hostclient/<FQDN>@INF.ED.AC.UK principal via a call to kdcregister using the -p principal switch, where principal has been set to the admin principal of the installing computing officer. (The installing computing officer must be physically present to enter his/her corresponding admin password.)

    This works, since the /var/kerberos/krb5kdc/kadm5.acl file on the master KDC gives any */admin@INF.ED.AC.UK principal control over any hostclient/*@INF.ED.AC.UK principal by virtue of the ACL entry:

    */admin@INF.ED.AC.UK * hostclient/*@INF.ED.AC.UK +preauth -postdateable -proxiable -dup-skey

  2. At host-install time (or, importantly, later, at any subsequent reconfiguration of the Kerberos component), the host principal host/<FQDN>@INF.ED.AC.UK and all other service principals of the type <service>/<FQDN>@INF.ED.AC.UK are (re-)created by the kerberos component via a call to kdcregister using the -k source-keytab switch, where source-keytab points to the keytab file created by the previous step which contains the hostclient/<FQDN>@INF.ED.AC.UK as its initial entry. (This all proceeds without human intervention.)

    This works, since the /var/kerberos/krb5kdc/kadm5.acl file on the master KDC gives any hostclient/<FQDN>@INF.ED.AC.UK principal control over all service principals on its corresponding host by virtue of the ACL entry:

    hostclient/*@INF.ED.AC.UK aDmciL */*1@INF.ED.AC.UK

A.2 Replacement by wallet

The current system can be replaced by wallet, as follows:

A.2.1 Wallet keytab naming policy

For keytab objects, our naming policy will be that:

  1. The name of the wallet keytab object will be the (fully-qualified) name of the principal to which the object refers, e.g. ldaprep/ancona.inf.ed.ac.uk.
  2. For any particular host, any keytab object which should be downloadable by any administrator user or by the host key itself, will be be owned by the ACL named hostclient/<FQDN>, where FQDN is the fully-qualified name of the host, e.g. hostclient/ancona.inf.ed.ac.uk.

A.2.2 Initial wallet configuration

  1. Give the wallet backend the minimum necessary privileges to create the principals of interest in the KDC:

    1. Manually add the principal wallet/<FQDN>@INF.ED.AC.UK to the KDC, where <FQDN> is the fully-qualified domain name of the server on which the wallet backend is to run. (It seems sensible that the wallet backend should in fact run on the same machine as the master KDC.) This is the principal which the wallet backend will use to authenticate to the KDC.

    2. In the file /var/kerberos/krb5kdc/kadm5.acl file on the master KDC, replace the current entries

      hostclient/*@INF.ED.AC.UK aDmciL */*1@INF.ED.AC.UK

      */admin@INF.ED.AC.UK * hostclient/*@INF.ED.AC.UK +preauth -postdateable -proxiable -dup-skey

      by the entries

      wallet/<FQDN>@INF.ED.AC.UK aDmciL host/*@INF.ED.AC.UK
      wallet/<FQDN>@INF.ED.AC.UK aDmciL ldap/*@INF.ED.AC.UK
      wallet/<FQDN>@INF.ED.AC.UK aDmciL ldaprep/*@INF.ED.AC.UK

      ... (and all other service principals as necessary - this list to be auto-configured by the Kerberos component in some way) ...

      wallet/<FQDN>@INF.ED.AC.UK aDmciL hostclient/*@INF.ED.AC.UK +preauth -postdateable -proxiable -dup-skey

      (Again, <FQDN> is the fully-qualified domain name of the server on which the wallet backend is to run.)

      (Q: What restrictions (i.e. the +preauth etc. suffixes), if any, should we have on the above ACL entries? Is there any need to retain the existing restrictions on the ACL entry which pertains to the hostclient/*@INF.ED.AC.UK target?)

      (Q: How are we going to auto-configure the above list of service principals in the kadm5.acl if we can't decide on a safe way to wildcard it. A new spanning map? An alternative to all of the above would be to run the wallet backend as wallet/admin@INF.ED.AC.UK. Would we be happy with that?)

  2. Declare, to the wallet system, that all Informatics administrator (i.e. */admin@INF.ED.AC.UK principals) users are wallet 'administrator' users.

    The only viable way to do this is to patch the wallet krb5 scheme ACL handling code to allow pattern-matching, so that any principal of the form */admin@INF.ED.AC.UK is deemed a wallet administrator. Then, as a one-time set-up at initial wallet configuration time, add the single ACL entry:

    krb5 */admin@INF.ED.AC.UK

    to the the wallet ADMIN ACL.

    Comments:

    1. The alternative to using the krb5 scheme ACL without patching the handling code to allow pattern-matching would be to add an ACL entry for every Informatics admin principal to the wallet ADMIN ACL, resulting in multiple wallet ADMIN ACL entries like:

      krb5 idurkacz/admin@INF.ED.AC.UK
      krb5 sxw/admin@INF.ED.AC.UK
      ...

      But this isn't practical: there is no programmatic interface to the wallet database which would allow this to be automated on reconfiguration were a 'wallet' LCFG component to be involved. In any case, even this wouldn't help since we also need to embed an ACL entry for all Informatics admin principals in the autocreated ACLs mentioned in the next point - and those certainly could not easily be regenerated on the reconfiguration of any component.)

    2. There are (at least) two other alternatives to using the krb5 scheme and having to patch its code, neither or which is attractive, but both of which might as well be mentioned for completeness:

      • Add a new ACL scheme called infcaps (or similar) to the wallet system which authorises a user if and only if he/she has the single listed capability. Then, as a one-time set-up at initial wallet configuration time, add the single ACL entry:

        infcaps sysmans

        to the the wallet ADMIN ACL. Suitably amend the default_owner policy function.

      • Use an ACL scheme based on AFS PTS groups. In fact, such a scheme is in the software author's current 'to-do' list.

  3. Add a policy function default_owner - something like the following - to the /etc/wallet/wallet.config file:

        sub default_owner {
          my ($type, $name) = @_;    # e.g. 'keytab host/ancona.inf.ed.ac.uk', 
                                     #      'keytab ldaprep/ancona.inf.ed.ac.uk', 
                                     #      'file blah', etc.
          if ($type eq 'keytab') {
            my $realm = 'INF.ED.AC.UK';
            return unless $name =~ m|/|;
            my ($service, $instance) = split ('/', $name, 2);
            my $acl_name = "hostclient/$instance";
            my @acl = ([ 'krb5', '*/admin@realm' ],
                       [ 'krb5', "hostclient/$instance\@$realm" ]);
            return ($acl_name, @acl);
          }
        }
    

    (The idea here is that the wildcard'ed */admin principal entry allows any computing officer to create (via autocreate) the initial hostclient principal/keytab via the wallet, and that, thereafter, the hostclient principal can itself autocreate further principals via the wallet.)

A.2.3 Kerberos component changes

  1. Replace the call

    kdcregister -p <principal> <name>

    in A.1, point 1 by a call of

    wallet -u <principal> get keytab <name>

    This will work by virtue of the autocreate.

  2. Replace the call

    kdcregister -k <source-keytab> <name>

    in A.1, point 2 by a call of

    (export KRB5CCNAME=`mktemp -t walletkrb5cc.XXXXXX`; kinit -k -t <source-keytab> hostclient/<FQDN>@INF.ED.AC.UK; wallet get keytab <name>; kdestroy)

    Explanation: currently the wallet client doesn't support authentication via a keytab. The alternative to using kinit in this way is to patch the client to support such authentication.

Appendix B - Planned future wallet features

Some verbatim extracts from the wallet author's current 'to-do' list at http://www.eyrie.org/~eagle/software/wallet/todo.html which refer to features likely to be of interest to us:

Client:

  • Support authenticating with a keytab.

ACLs:

  • Write the [AFS] PTS ACL verifier.

  • Support for pattern matching in ACLs.

Objects:

  • Implement an ssh keypair wallet object. The server can run ssh-keygen to generate a public/private key pair and return both to the client, which would split them apart. Used primarily for host keys. May need a side table to store key types, or a naming convention.

  • Implement an X.509 certificate object. I expect this would store the public and private key as a single file in the same format that Apache can read for combined public and private keys. There were requests for storing the CSR, but I don't see why you'd want to do that. Start with store support. The file code is mostly sufficient here, but it would be nice to automatically support object expiration based on the expiration time for the certificate.

  • Implement an X.509 CA so that you can get certificate objects without storing them first. Need to resolve naming conventions if you want to run multiple CAs on the same wallet server (but why?). Should this be a different type than stored certificates?

-- IanDurkacz - 26 Mar 2010

Topic revision: r11 - 15 Jan 2013 - 13:05:24 - IanDurkacz
 
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback
This Wiki uses Cookies