logo_kerberos.gif

Difference between revisions of "Projects/Audit"

From K5Wiki
Jump to: navigation, search
(Add "Future work" and more details on events)
(Extended Dictionary section)
Line 38: Line 38:
 
:: PA error;
 
:: PA error;
 
:: chosen by KDC enctype;
 
:: chosen by KDC enctype;
  +
:: session key cleared (Common Criteria FCS_CKM.1, FCS_CKM.4);
 
:: kdc request:
 
:: kdc request:
 
::: kdc options;
 
::: kdc options;
 
::: requested ticket start/end/renew_till times;
 
::: requested ticket start/end/renew_till times;
 
::: requested/available enctypes;
 
::: requested/available enctypes;
::: 2nd [[#Ticket details||ticket]];
+
::: 2nd [[#Ticket details|ticket]];
 
::: AD type;
 
::: AD type;
 
::: PA type;
 
::: PA type;
 
::: addresses;
 
::: addresses;
 
:: kdc reply:
 
:: kdc reply:
::: [[#Ticket details||ticket]];
+
::: [[#Ticket details|ticket]];
 
::: client principal;
 
::: client principal;
 
::: PA type.
 
::: PA type.
 
   
 
====TGS exchange====
 
====TGS exchange====
Line 58: Line 58:
 
:: client’s address and port;
 
:: client’s address and port;
 
:: chosen by KDC enctype;
 
:: chosen by KDC enctype;
  +
:: session key cleared (Common Criteria FCS_CKM.1, FCS_CKM.4);
 
:: client’s flags;
 
:: client’s flags;
 
:: cross realm name;
 
:: cross realm name;
Line 71: Line 72:
 
::: requested/available enctypes;
 
::: requested/available enctypes;
 
::: KDC options;
 
::: KDC options;
::: number of second tickets;
+
::: number of second [[#Ticket details|tickets]];
 
::: requested ticket start/end/renew_till times;
 
::: requested ticket start/end/renew_till times;
 
::: AD type;
 
::: AD type;
Line 78: Line 79:
 
::: client principal;
 
::: client principal;
 
::: PA type;
 
::: PA type;
::: [[#Ticket details||ticket]].
+
::: [[#Ticket details|ticket]].
   
 
====Policy====
 
====Policy====
Line 88: Line 89:
 
====Ticket details====
 
====Ticket details====
 
::client and server principals;
 
::client and server principals;
::flags
+
::flags;
 
::start/end/renew_till times;
 
::start/end/renew_till times;
 
::authtime;
 
::authtime;
Line 205: Line 206:
 
"pa_error", TYPE_NUM, preauth_err, // state->preauth_err
 
"pa_error", TYPE_NUM, preauth_err, // state->preauth_err
 
/* request */
 
/* request */
"kdcreq.msg_type", TYPE_STR, state->req_msg_type,
+
"req.msg_type", TYPE_STR, state->req_msg_type,
"kdcreq.client", TYPE_STR, state->req_client,
+
"req.client", TYPE_STR, state->req_client,
"kdcreq.server", TYPE_STR, state->req_server,
+
"req.server", TYPE_STR, state->req_server,
"kdcreq.kdc_options", TYPE_STR, state->req_kdc_options,
+
"req.kdc_options", TYPE_STR, state->req_kdc_options,
"kdcreq.start", TYPE_NUM, req_from, // state->req_from
+
"req.start", TYPE_NUM, req_from, // state->req_from
"kdcreq.end", TYPE_NUM, req_end, // state->req_end
+
"req.end", TYPE_NUM, req_end, // state->req_end
"kdcreq.renew_till", TYPE_NUM, req_time, // state->req_rtime
+
"req.renew_till", TYPE_NUM, req_time, // state->req_rtime
 
/* reply */
 
/* reply */
"kdcrep.msg_type", TYPE_STR,state->rep_msg_type,
+
"rep.msg_type", TYPE_STR,state->rep_msg_type,
"kdcrep.client", TYPE_STR, state->rep_client,
+
"rep.client", TYPE_STR, state->rep_client,
"kdcrep.server", TYPE_STR, state->rep_server,
+
"rep.server", TYPE_STR, state->rep_server,
"kdcrep.tkt.server", TYPE_STR, state->rep_tkt_server,
+
"rep.tkt.server", TYPE_STR, state->rep_tkt_server,
"kdcrep.tkt.flags", TYPE_NUM, rep_tkt_flags, // state->rep_tkt_flags
+
"rep.tkt.flags", TYPE_NUM, rep_tkt_flags, // state->rep_tkt_flags
"kdcrep.tkt.start", TYPE_NUM, rep_tarttime, // state->rep_tarttime
+
"rep.tkt.start", TYPE_NUM, rep_tarttime, // state->rep_tarttime
"kdcrep.tkt.end", TYPE_NUM, rep_endtime, // pstate->rep_endtime,
+
"rep.tkt.end", TYPE_NUM, rep_endtime, // pstate->rep_endtime,
"kdcrep.tkt.renew_till", TYPE_NUM, rep_renew_till, // state->rep_renew_till
+
"rep.tkt.renew_till", TYPE_NUM, rep_renew_till, // state->rep_renew_till
"kdcrep.tkt.authtime", TYPE_NUM, rep_authtime, // state->rep_authtime,
+
"rep.tkt.authtime", TYPE_NUM, rep_authtime, // state->rep_authtime,
"kdcrep.tkt.tr_type", TYPE_NUM, rep_transited_type // state->rep_transited_type
+
"rep.tkt.tr_type", TYPE_NUM, rep_transited_type // state->rep_transited_type
"kdcrep.tkt.skey_etype", TYPE_NUM, rep_session_enctype, // state->rep_session_enctype
+
"rep.tkt.skey_etype", TYPE_NUM, rep_session_enctype, // state->rep_session_enctype
"kdcrep.tkt.caddrs", TYPE_STR, state->rep_caddrs
+
"rep.tkt.caddrs", TYPE_STR, state->rep_caddrs
 
);
 
);
 
return rc;
 
return rc;
Line 230: Line 231:
   
   
=== Dictionary of the field names ===
+
== Dictionary==
   
 
The possible basic field names are:
 
The possible basic field names are:
* "event_id" for audit event ID
 
  +
* "event_status" to indicate if the event is reported on success or failure.
 
  +
{| class="wikitable" style="border: 3px solid #59121e"
* "tkt_id" for ticket ID;
 
  +
|+
* "client" and "server" for client and service principal names;
 
  +
|-
* "full_address" for address and portport
 
  +
! Key
* "pa_error" for pre-authentication error;
 
  +
! style="padding-left: 2em; padding-right: 2em;" | Type
* "skey_etype" and "avail_etypes" for available key types and chosen enc type;
 
  +
! Comments
* "sesskey_cleared" to indicate that session key was cleared;
 
  +
|-
* "start", "end" and "renew_till" for the ticket's start/end/renew-until times;
 
  +
| tkt_id || style="padding-left: 2em "| STR || ticket ID
* "rep_flags" for reply flags;
 
  +
|-
* "kdc_status" for KDC status message;
 
  +
| kdc_time || style="padding-left: 2em "| NUM || KDC time
* "plugins" and "plugins_base_dir" for available plugins (reported on KDC startup);
 
  +
|-
* etc.
 
  +
| client || style="padding-left: 2em "| STR|| client’s principal
 
  +
|-
  +
| service || style="padding-left: 2em "| STR|| requested service principal
  +
|-
  +
| kdc_status || style="padding-left: 2em "| TR|| KDC status (“ISSUE” on success)
  +
|-
  +
| fromaddr || style="padding-left: 2em "| STR|| client’s address
  +
|-
  +
|fromport || style="padding-left: 2em "| NUM || client’s port
  +
|-
  +
| full_address || style="padding-left: 2em "| STR|| Alternative to "fromport"/"fromaddr"
  +
|-
  +
| pa_err || style="padding-left: 2em "| NUM || PA error
  +
|-
  +
|skey_etype || style="padding-left: 2em "| NUM || chosen by KDC session key enc type
  +
|-
  +
|skey_cleared || style="padding-left: 2em "| BOOL || was session key cleared
  +
|-
  +
|xrealm|| style="padding-left: 2em "| STR || cross realm name
  +
|-
  +
|altc_princ|| style="padding-left: 2em "| STR || alternate client principal
  +
|-
  +
|alts_princ || style="padding-left: 2em "| STR || alternate server principal
  +
|-
  +
|server2 || style="padding-left: 2em "| STR || u2u requested server principal
  +
|-
  +
|is_referral|| style="padding-left: 2em "| BOOL || is it referral request
  +
|-
  +
|tkt_renewed|| style="padding-left: 2em "| BOOL || was ticket renewed
  +
|-
  +
|req.addresses || style="padding-left: 2em "| STR || requested addresses
  +
|-
  +
|req.avail_etypes || style="padding-left: 2em "| STR || requested/available enc types
  +
|-
  +
|req.kdc_options || style="padding-left: 2em "| NUM || KDC options (forwardable, allow_postdate etc)
  +
|-
  +
|req.pa_type || style="padding-left: 2em "| STR|| PA type
  +
|-
  +
|req.ad_type || style="padding-left: 2em "| STR || AD type
  +
|-
  +
|req.tkt_start || style="padding-left: 2em "| NUM || requested ticket start time
  +
|-
  +
|req.tkt_end || style="padding-left: 2em "| NUM || requested ticket end time
  +
|-
  +
|req.tkt_renew_till || style="padding-left: 2em "| NUM || requested ticket renew-till time
  +
|-
  +
| req.num_secondtkt|| style="padding-left: 2em "| NUM || number of second tickets (U2U etc)
  +
|-
  +
|req.sname || style="padding-left: 2em "| STR || requested service principal
  +
|-
  +
| req.cname || style="padding-left: 2em "| STR || client's principal
  +
|-
  +
|rep.sname || style="padding-left: 2em "| STR || service principal in ticket
  +
|-
  +
| rep.cname || style="padding-left: 2em "| STR || client principal in ticket
  +
|-
  +
| rep.pa_type || style="padding-left: 2em "| STR || reply PA type
  +
|-
  +
| rep.caddrs || style="padding-left: 2em "| STR || addresses in ticket
  +
|-
  +
| rep.rep_flags || style="padding-left: 2em "| NUM || ticket flags
  +
|-
  +
| rep.ad_type || style="padding-left: 2em "| STR || ticket AD type
  +
|-
  +
| rep.rep_authtime || style="padding-left: 2em "| NUM || ticket authtime
  +
|-
  +
| rep.tkt_start || style="padding-left: 2em "| NUM || ticket start time
  +
|-
  +
| rep.tkt_end || style="padding-left: 2em "| NUM || ticket end time
  +
|-
  +
| rep.tkt_renew_till|| style="padding-left: 2em "| NUM || ticket renewed-till time
  +
|-
  +
|rep.tr_type|| style="padding-left: 2em "| NUM || ticket transited type
  +
|-
  +
|rep.tr_contents|| style="padding-left: 2em "| STR|| ticket transited-realms list
  +
|-
  +
|}
  +
  +
  +
   
   
Line 254: Line 333:
   
 
;--with-audit-plugin=simple: (For demo and testing purposes) Build the audit plugin "simple" and enable audit plugin.
 
;--with-audit-plugin=simple: (For demo and testing purposes) Build the audit plugin "simple" and enable audit plugin.
  +
   
 
== Future work ==
 
== Future work ==
Line 259: Line 339:
 
# Make reporting auditable events configurable. For example, one can choose to report TGS_REQ, but not AS_REQ etc;
 
# Make reporting auditable events configurable. For example, one can choose to report TGS_REQ, but not AS_REQ etc;
 
# Define and make configurable the DETAILED and BASIC levels of the events.
 
# Define and make configurable the DETAILED and BASIC levels of the events.
  +
   
 
== Test implementation ==
 
== Test implementation ==

Revision as of 14:26, 29 May 2013

This is an early stage project for MIT Kerberos. It is being fleshed out by its proponents. Feel free to help flesh out the details of this project. After the project is ready, it will be presented for review and approval.


Purpose

Create an Audit infrastructure within MIT Kerberos to monitor security related events on the KDC. In future expand Kerberos Audit facility to the application servers, kadmin if it remains desirable.


Requirements

The new audit system should be:

  • build-time enabled;
  • run-time pluggable;
  • simple, so it could be easily replaced with the OS specific implementations;


Events

This section details the categories of the auditable events and the associated information.

Audit module loaded/unloaded

Startup and shutdown of the audit system must be recorded by audit system;

KDC started/stopped

Startup and shutdown of the KDC must be recorded by audit system;

Authentication

(Common Criteria Class FIA)

AS exchange

ticket ID (if available);
KDC time;
client’s principal;
requested service principal;
KDC status message (“ISSUE” on success);
client’s address and port;
PA error;
chosen by KDC enctype;
session key cleared (Common Criteria FCS_CKM.1, FCS_CKM.4);
kdc request:
kdc options;
requested ticket start/end/renew_till times;
requested/available enctypes;
2nd ticket;
AD type;
PA type;
addresses;
kdc reply:
ticket;
client principal;
PA type.

TGS exchange

ticket ID (if available);
KDC time;
KDC status message (“ISSUE” on success);
client’s address and port;
chosen by KDC enctype;
session key cleared (Common Criteria FCS_CKM.1, FCS_CKM.4);
client’s flags;
cross realm name;
alternate client principal;
alternate server principal;
u2u requested server principal;
is it referral request;
was ticket renewed;
kdc request:
requested service principal;
client’s principal;
addresses;
requested/available enctypes;
KDC options;
number of second tickets;
requested ticket start/end/renew_till times;
AD type;
PA type;
kdc reply:
client principal;
PA type;
ticket.

Policy

Policies violation when processing requests;
AS request;
TGS request;
S4U2PROXY request.

Ticket details

client and server principals;
flags;
start/end/renew_till times;
authtime;
transited encoding type and contents;
key type;
addresses.


Design details

The following are highlights of this new feature:

Ticket ID

Ticket ID is recorded as part of audit messages. This allows to link tickets to their initial TGT at any stage of the Kerberos exchange.
Ticket ID is created as a hash of AS session key or client principal name plus timestamp or some other way;
TODO: Consider a new authorization data element AD_TKT_ID per http://tools.ietf.org/html/draft-ietf-krb-wg-cammac-04 draft to securely communicate ticket id between all Kerberos exchange participants.

Hybrid

The proposal is a hybrid of variadic key-type-value triplet (KTV) and one-API-per-event approaches.

On the KDC side call audit event-specific functions, whose input consists of the event-id, event-status and event-specific structure. If event-specific callback is implemented by the audit plugin, strip the event-specific structure from the security sensitive information and then pass the pointer to the event-specific structure to the plugin. Otherwise, fallback to the generic function with variadic KTV arguments. In the latter case all non-string values should be converted into the strings and the key-types serve as a hint to the plugin implementor about the "original" type of the key-value.


KDC facing API

/* Audit plugin loaded/unloaded */
krb5_error_code 
load_audit_plugin(krb5_context context);
krb5_error_code 
unload_audit_plugin(krb5_context context);
/* event specific functions */
krb5_error_code 
kau_kdc_start(krb5_context context, struct server_handle shdl, int status);
krb5_error_code 
kau_kdc_stop(krb5_context context, krb5_error_code status);
krb5_error_code 
kau_as_req(krb5_context context, struct as_req_state *state, int status);
krb5_error_code 
kau_tgs(krb5_context context, struct tgs_req_audit_state *state, int status);

Pluggable interface

/* Audit plugin vtable */
typedef struct krb5_audit_vtable_st {
   /* Mandatory: name of module. */
   char             *name;
   kau_open_fn       open;
   kau_close_fn      close;
   kau_generic_fn    generic;
   kau_kdc_start_fn  kdc_start;
   kau_kdc_stop_fn   kdc_stop;
   kau_as_req_fn     as_req;
   kau_tgs_req_fn    tgs_req;
} *krb5_audit_vtable;

typedef krb5_error_code
(*kau_open_fn)(kau_ctx *au_ctx);

typedef krb5_error_code
(*kau_close_fn)(kau_ctx au_ctx);

/* general purpose interface to pass unspecified number of 
 *  key-type-value triplets to a plugable interface.
 */
typedef krb5_error_code
(*kau_generic_fn)(kau_ctx au_ctx, const int event_id, const int status, ... );

/* one-API-per-event surrogate */
typedef krb5_error_code
(*kau_kdc_start_fn)(kau_ctx au_ctx, const int event_id, const int status,
                    struct server_handle_san shdl);
typedef krb5_error_code
(*kau_kdc_stop_fn)(kau_ctx au_ctx, const int event_id, const int status);
typedef krb5_error_code
(*kau_as_req_fn)(kau_ctx au_ctx, const int event_id, const int status,
                 struct as_req_state_san *state);
typedef krb5_error_code
(*kau_tgs_fn)(kau_ctx au_ctx, const int event_id, const int status,
              struct tgs_req_state_san *state);

where new types server_handle_san, as_req_state_san and tgs_req_state_san are sanitized variants of server_handle, as_req_state and tgs_req_state structures respectively.

Example

krb5_error_code
kau_as_req(krb5_context context, struct as_req_state *state,
          krb5_error_code  status)
{
   krb5_error_code rc = 0;
   ...
   /* If audit plugin event-specific callback is implemented, call it */
   if (hdl->vt.as_req) {
       rc = hdl->vt.as_req(hdl->au_ctx, event_id, event_status, state);
       return rc;
   }
   /* Otherwise, try the generic one. */
   if (hdl->vt.generic)
       rc = rec_as_req(hdl->au_ctx, event_id, event_status, state);
   return rc;
}

static krb5_error_code
rec_as_req(krb5_context context, struct as_req_state_san *state,
          krb5_error_code status)
{
   krb5_error_code rc = 0;
   ...
   /* All values with TYPE_NUM type-hint are string representations of 
    * their numeric conterparts in 'state' structure.
    */
   hdl->vt.record(hdl->au_ctx, event_id, event_status,
                  "tkt_id",             TYPE_NUM, tkt_id,              // state->tkt_id 
                  "kdc_status",         TYPE_STR, state->status,
                  "full_address",       TYPE_STR, state->full_address,                 
                  "skey_etype",         TYPE_NUM, session_key_enctype, //  state->session_key_enctype
                  "pa_error",           TYPE_NUM, preauth_err,         //  state->preauth_err
                  /* request */
                  "req.msg_type",    TYPE_STR, state->req_msg_type,
                  "req.client",      TYPE_STR, state->req_client,   
                  "req.server",      TYPE_STR, state->req_server,  
                  "req.kdc_options", TYPE_STR, state->req_kdc_options,
                  "req.start",       TYPE_NUM, req_from,  // state->req_from
                  "req.end",         TYPE_NUM, req_end,   // state->req_end
                  "req.renew_till",  TYPE_NUM, req_time,  // state->req_rtime 
                  /* reply */
                  "rep.msg_type",    TYPE_STR,state->rep_msg_type,
                  "rep.client",      TYPE_STR, state->rep_client,
                  "rep.server",      TYPE_STR, state->rep_server,
                  "rep.tkt.server",  TYPE_STR, state->rep_tkt_server,
                  "rep.tkt.flags",   TYPE_NUM, rep_tkt_flags,    // state->rep_tkt_flags
                  "rep.tkt.start",   TYPE_NUM, rep_tarttime,     // state->rep_tarttime
                  "rep.tkt.end",     TYPE_NUM, rep_endtime,      // pstate->rep_endtime,
                  "rep.tkt.renew_till",  TYPE_NUM, rep_renew_till,      // state->rep_renew_till
                  "rep.tkt.authtime",    TYPE_NUM, rep_authtime,        // state->rep_authtime,
                  "rep.tkt.tr_type",     TYPE_NUM, rep_transited_type   // state->rep_transited_type
                  "rep.tkt.skey_etype",  TYPE_NUM, rep_session_enctype, // state->rep_session_enctype
                  "rep.tkt.caddrs",      TYPE_STR, state->rep_caddrs
   );
   return rc;
}


Dictionary

The possible basic field names are:

Key Type Comments
tkt_id STR ticket ID
kdc_time NUM KDC time
client STR client’s principal
service STR requested service principal
kdc_status TR KDC status (“ISSUE” on success)
fromaddr STR client’s address
fromport NUM client’s port
full_address STR Alternative to "fromport"/"fromaddr"
pa_err NUM PA error
skey_etype NUM chosen by KDC session key enc type
skey_cleared BOOL was session key cleared
xrealm STR cross realm name
altc_princ STR alternate client principal
alts_princ STR alternate server principal
server2 STR u2u requested server principal
is_referral BOOL is it referral request
tkt_renewed BOOL was ticket renewed
req.addresses STR requested addresses
req.avail_etypes STR requested/available enc types
req.kdc_options NUM KDC options (forwardable, allow_postdate etc)
req.pa_type STR PA type
req.ad_type STR AD type
req.tkt_start NUM requested ticket start time
req.tkt_end NUM requested ticket end time
req.tkt_renew_till NUM requested ticket renew-till time
req.num_secondtkt NUM number of second tickets (U2U etc)
req.sname STR requested service principal
req.cname STR client's principal
rep.sname STR service principal in ticket
rep.cname STR client principal in ticket
rep.pa_type STR reply PA type
rep.caddrs STR addresses in ticket
rep.rep_flags NUM ticket flags
rep.ad_type STR ticket AD type
rep.rep_authtime NUM ticket authtime
rep.tkt_start NUM ticket start time
rep.tkt_end NUM ticket end time
rep.tkt_renew_till NUM ticket renewed-till time
rep.tr_type NUM ticket transited type
rep.tr_contents STR ticket transited-realms list



Configuration

The following ./configure option to be added:

--with-audit-plugin=simple
(For demo and testing purposes) Build the audit plugin "simple" and enable audit plugin.


Future work

  1. Make reporting auditable events configurable. For example, one can choose to report TGS_REQ, but not AS_REQ etc;
  2. Define and make configurable the DETAILED and BASIC levels of the events.


Test implementation

We will use libaudit module available on Fedora, Debian, Suse for the first round.

Some "simple" audit plugin will be implemented and Python test system will become aware of its existence. New ./configure --with-audit-plugin option will be introduced to build "simple" audit plugin for testing purpose. If audit is enabled and audit plugin is available, "make check" will store audit messages into audit log file.

References

  1. Common Criteria for Information Technology Security Evaluation http://www.commoncriteriaportal.org/files/ccfiles/CCPART2V3.1R4.pdf
  2. Oracle Solaris Auditing http://docs.oracle.com/cd/E19963-01/html/821-1456/auditov-1.html
  3. Understanding Linux Audit http://doc.opensuse.org/products/draft/SLES/SLES-security_sd_draft/cha.audit.comp.html
  4. Advanced Security Audit Policy Settings http://technet.microsoft.com/en-us/library/dd772712(v=ws.10).aspx
  5. Events Classification in Log Audit http://airccse.org/journal/nsa/0410ijnsa5.pdf
  6. CEE Log Syntax (CLS) Encoding http://cee.mitre.org/language/1.0-beta1/cls.html