Subject: [nfsv4] Issue 38: Proposed text for RPC/Security Flavors/Transports section of 4.1

From: Mike Eisler <[email-masked]>
Date: Tue, 27 Jun 2006 16:23:14 -0700 (PDT)

http://www.nfsv4-editor.org/cgi-bin/roundup/nfsv4/file18/issue38.txt

The changes here mostly correspond to section 
 3.   RPC and Security Flavor

of RFC 3530. 

However, the callback authentication of NFSv4.1
is very different, and so this also required
text changes to BIND_BACKCHANNEL, so those edits have
been made too. Also, the method for using
client-to-server RPCSEC_GSS contexts in server-to-client
callbacks wasn't described yet, so I took care of that too.

_______________________________________________
nfsv4 mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/nfsv4

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 27 Jun 2006 18:29:48 -0500

> callbacks wasn't described yet, so I took care of that too.

Excellent.

---

From: Mike Eisler <[email-masked]>
Date: Wed, 28 Jun 2006 06:53:33 -0700 (PDT)

> callbacks wasn't described yet, so I took care of that too.

This morning I decided that using BIND_BACKCHANNEL to
update parameters on a back channel using the same
channel would be too much complexity. The issue
is that a server using a TCP connection for a call
back patch would also have to listen for RPC requests
originating from the client. So I changed
things so that when a channel is converted to a
back channel, the server assigns a back channel id
the client refers to on updates.

I also expanded the implementation description of
BIND_BACKCHANNEL to explain why multiple
RPCSEC_GSS contexts for a back channel are needed.

The updated proposed text is still at

In keeping with Spencer's caution around the use of
issues tracker versus the use of the WG email alias,
I am including the proposed text for this issue here:

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

Add somewhere:

X.  RPC and Security Flavor

   The NFS version 4.1 protocol is a Remote Procedure
   Call (RPC) application that uses RPC version 2 and
   the corresponding eXternal Data Representation (XDR)
   as defined in [RFC1831] and [RFC4506].  The RPCSEC_GSS
   security flavor as defined in [RFC2203] MUST be used
   as the mechanism to deliver stronger security for the
   NFS version 4 protocol.

X.1.  Ports and Transports

   Historically, NFS version 2 and version 3 servers
   have resided on port 2049.  The registered port 2049
   [RFC3232] for the NFS protocol should be the default
   configuration.  NFSv4 clients SHOULD NOT use the RPC
   binding protocols as described in [RFC1833].

   Where an NFS version 4 implementation supports
   operation over the IP network protocol, the supported
   transports between NFS and IP MUST have the following
   two attributes:

   1. The transport must support reliable delivery of data
      in the order it was sent.

   2. The transport must be among the IETF-approved
      congestion control transport protocols.

   At the time this document was written, the only
   two transports that had the above attributes were
   TCP and SCTP.  To enhance the possibilities for
   interoperability, an NFS version 4 implementation MUST
   support operation over the TCP transport protocol.

   If TCP is used as the transport, the client and server
   SHOULD use persistent connections for at least two
   reasons:

   1. This will prevent the weakening of TCP's
      congestion control via short lived connections and
      will improve performance for the WAN environment by
      eliminating the need for SYN handshakes.

   2. The NFSv4.1 callback model has changed from NFSv4.0,
      and requires the client and server to maintain a
      client-created channel for the server to use.

   As noted in the Security Considerations section,
   the authentication model for NFS version 4 has moved
   from machine-based to principal- based.  However, this
   modification of the authentication model does not imply
   a technical requirement to move the transport connection
   management model from whole machine-based to one based
   on a per user model.  In particular, NFS over TCP
   client implementations have traditionally multiplexed
   traffic for multiple users over a common TCP connection
   between an NFS client and server.  This has been true,
   regardless whether the NFS client is using AUTH_SYS,
   AUTH_DH, RPCSEC_GSS or any other flavor.  Similarly,
   NFS over TCP server implementations have assumed
   such a model and thus scale the implementation of TCP
   connection management in proportion to the number of
   expected client machines.   NFS version 4.1 will not
   modify this connection management model.  NFS version
   4.1 clients that violate this assumption can expect
   scaling issues on the server and hence reduced service.

   Note that for various timers, the client and server
   should avoid inadvertent synchronization of those
   timers.  For further discussion of the general issue
   refer to [Floyd].

X.1.1.  Client Retransmission Behavior

   When processing a request received over a reliable
   transport such as TCP, the NFS version 4.1 server
   MUST NOT silently drop the request, except if the
   transport connection has been broken.  Given such a
   contract between NFS version 4.1 clients and servers,
   clients MUST NOT retry a request unless one or both of
   the following are true:

   o  The transport connection has been broken

   o  The procedure being retried is the NULL procedure

   Since reliable transports, such as TCP, do not
   always synchronously inform a peer when the other
   peer has broken the connection (for example, when
   an NFS server reboots), the NFS version 4.1 client
   may want to actively "probe" the connection to see
   if has been broken.  Use of the NULL procedure is
   one recommended way to do so.  So, when a client
   experiences a remote procedure call timeout (of some
   arbitrary implementation specific amount), rather than
   retrying the remote procedure call, it could instead
   issue a NULL procedure call to the server.  If the
   server has died, the transport connection break will
   eventually be indicated to the NFS version 4.1 client.
   The client can then reconnect, and then retry the
   original request.  If the NULL procedure call gets a
   response, the connection has not broken.  The client
   can decide to wait longer for the original request's
   response, or it can break the transport connection and
   reconnect before re-sending the original request.

   For callbacks from the server to the client, the same
   rules apply, but the server doing the callback becomes
   the client, and the client receiving the callback
   becomes the server.

X.2.  Security Flavors

   Traditional RPC implementations have included
   AUTH_NONE, AUTH_SYS, AUTH_DH, and AUTH_KRB4 as security
   flavors.  With [RFC2203] an additional security
   flavor of RPCSEC_GSS has been introduced which uses
   the functionality of GSS-API [RFC2743].  This allows
   for the use of various security mechanisms by the RPC
   layer without the additional implementation overhead
   of adding RPC security flavors.  For NFS version 4, the
   RPCSEC_GSS security flavor MUST be implemented to enable
   the mandatory security mechanism.  Other flavors, such
   as, AUTH_NONE, AUTH_SYS, and AUTH_DH MAY be implemented
   as well.

X.2.1.  Security mechanisms for NFS version 4

   The use of RPCSEC_GSS requires selection of: mechanism,
   quality of protection, and service (authentication,
   integrity, privacy).  The remainder of this document
   will refer to these three parameters of the RPCSEC_GSS
   security as the security triple.

X.2.1.1.  Kerberos V5

   The Kerberos V5 GSS-API mechanism as described in
   [RFC1964] MUST be implemented.

   column descriptions:
   1 == number of pseudo flavor
   2 == name of pseudo flavor
   3 == mechanism's OID
   4 == RPCSEC_GSS service

   1      2     3                    4
   --------------------------------------------------------------------
   390003 krb5  1.2.840.113554.1.2.2 rpc_gss_svc_none
   390004 krb5i 1.2.840.113554.1.2.2 rpc_gss_svc_integrity
   390005 krb5p 1.2.840.113554.1.2.2 rpc_gss_svc_privacy

   Note that the pseudo flavor is presented here as
   a mapping aid to the implementor.  Because this NFS
   protocol includes a method to negotiate security and it
   understands the GSS-API mechanism, the pseudo flavor
   is not needed.  The pseudo flavor is needed for NFS
   version 3 since the security negotiation is done via
   the MOUNT protocol.

   For a discussion of NFS' use of RPCSEC_GSS and Kerberos
   V5, please see [RFC2623].

X.2.1.2.  LIPKEY as a security triple

   The LIPKEY GSS-API mechanism as described in [RFC2847]
   MUST be implemented and provide the following security
   triples.  The definition of the columns matches the
   previous subsection "Kerberos V5 as security triple"

   1      2        3                   4
   --------------------------------------------------------------------
   390006 lipkey   1.3.6.1.5.5.9       rpc_gss_svc_none
   390007 lipkey-i 1.3.6.1.5.5.9       rpc_gss_svc_integrity
   390008 lipkey-p 1.3.6.1.5.5.9       rpc_gss_svc_privacy

X.2.1.3.  SPKM-3 as a security triple

   The SPKM-3 GSS-API mechanism as described in [RFC2847]
   MUST be implemented and provide the following security
   triples.  The definition of the columns matches the
   previous subsection "Kerberos V5 as security triple".

   1      2        3                   5
   --------------------------------------------------------------------
   390009 spkm3    1.3.6.1.5.5.1.3     rpc_gss_svc_none
   390010 spkm3i   1.3.6.1.5.5.1.3     rpc_gss_svc_integrity
   390011 spkm3p   1.3.6.1.5.5.1.3     rpc_gss_svc_privacy

X.3.  Security Negotiation

   With the NFS version 4 server potentially offering
   multiple security mechanisms, the client needs a method
   to determine or negotiate which mechanism is to be
   used for its communication with the server.  The NFS
   server may have multiple points within its filesystem
   name space that are available for use by NFS clients.
   In turn the NFS server may be configured such that each
   of these entry points may have different or multiple
   security mechanisms in use.

   The security negotiation between client and server
   must be done with a secure channel to eliminate
   the possibility of a third party intercepting the
   negotiation sequence and forcing the client and server
   to choose a lower level of security than required or
   desired.  See the section "Security Considerations"
   for further discussion.

X.3.1.  SECINFO and SECINFO_NO_NAME

   The SECINFO and SECINFO_NO_NAME operations allow
   the client to determine, on a per filehandle basis,
   what security triple is to be used for server access.
   In general, the client will not have to use either
   operation except during initial communication with the
   server or when the client crosses policy boundaries at
   the server.  It is possible that the server's policies
   change during the client's interaction therefore forcing
   the client to negotiate a new security triple.

X.3.2.  Security Error

   Based on the assumption that each NFS version 4 client
   and server must support a minimum set of security (i.e.,
   LIPKEY, SPKM-3, and Kerberos-V5 all under RPCSEC_GSS),
   the NFS client will start its communication with the
   server with one of the minimal security triples.  During
   communication with the server, the client may receive an
   NFS error of NFS4ERR_WRONGSEC.  This error allows the
   server to notify the client that the security triple
   currently being used is not appropriate for access
   to the server's filesystem resources.  The client is
   then responsible for determining what security triples
   are available at the server and choose one which is
   appropriate for the client.  See the section for the
   "SECINFO" operation for further discussion of how the
   client will respond to the NFS4ERR_WRONGSEC error and
   use SECINFO.

X.4.  Callback RPC Authentication

   Callback authentication has changed in NFSv4.1 from
   NFSv4.0.

   NFSv4.0 required the NFS server to create a security
   context for RPCSEC_GSS, AUTH_DH, and AUTH_KERB4, and
   any other security flavor that had a security context.
   It also required that principal issuing the callback be
   the same as the principal that accepted the callback
   parameters (via SETCLIENTID), and that the client
   principal accepting the callback be the same as that
   which issued the SETCLIENTID.  This required the NFS
   client to have an assigned machine credential. NFSv4.1
   does not require a machine credential. Instead, NFSv4.1
   allows an RPCSEC_GSS security context initiated by
   the client and eswtablished on both the client and
   server to be used on callback RPCs sent by the server
   to the client. The BIND_BACKCHANNEL operation is used
   establish RPCSEC_GSS contexts (if the client so desires)
   on the server. No support for AUTH_DH, or AUTH_KERB4
   is specified.

X.5.  GSS Server Principal

   Regardless of what security mechanism under RPCSEC_GSS
   is being used, the NFS server, MUST identify itself
   in GSS-API via a GSS_C_NT_HOSTBASED_SERVICE name type.
   GSS_C_NT_HOSTBASED_SERVICE names are of the form:

         service@hostname

   For NFS, the "service" element is

         nfs

   Implementations of security mechanisms will convert
   nfs@hostname to various different forms.  For Kerberos
   V5, LIPKEY, and SPKM-3, the following form is
   RECOMMENDED:

         nfs/hostname

In 9.11.  Sessions Security Considerations delete:

 It is logical to use the same GSS context on a session's
 callback channel as that used on its operations
 channel(s), particularly when the connection is shared
 by both. The client must indicate to the server:

  - what security flavor(s) to use in the call back. A
  special callback flavor might be defined for this.

  - if the flavor is RPCSEC_GSS, then the client must
  have previously created an RPCSEC_GSS session with the
  server. The client offers to the server the the opaque
  handle<> value from the rpc_gss_init_res structure,
  the window size of RPCSEC_GSS sequence numbers, and an
  opaque gss_cb_handle.

  This exchange can be performed as part of session
  and clientid creation, and the issue warrants careful
  analysis before being specified.

In 22.42.2.  ARGUMENT (BIND_BACKCHANNEL)

OLD:

struct BIND_BACKCHANNEL4args {
    clientid4 clientid;
    uint32_t  callback_program;
    uint32_t  callback_ident;
    count4         maxrequestsize;
    count4         maxresponsesize;
    count4         maxrequests;
    switch (channelmode4 mode) {
    case DEFAULT:
        void;
    case STREAM:
        streamchannelattrs4 streamchanattrs;
    case RDMA:
        rdmachannelattrs4   rdmachanattrs;
    };
};

NEW:

union channelattrs4 switch (channelmode4 mode) {
    case DEFAULT:
        void;
    case STREAM:
        streamchannelattrs4 streamchanattrs;
    case RDMA:
        rdmachannelattrs4   rdmachanattrs;
};

struct gss_cb_parms4 {
   rpc_gss_service_t gcbp_service; /* RFC 2203 */
   opaque            gcbp_handle_from_server<>;
   opaque            gcbp_handle_from_client<>;
};

union callback_sec_parms4 switch (uint32_t secflavor) {
  case AUTH_NONE:
    void;
  case AUTH_SYS:
    authsys_parms cbsp_sys_cred; /* RFC 1831 */
  case RPCSEC_GSS:
    gss_cb_parms4 cbsp_gss_parms; 
};

union backchannel_id_arg4 switch (bool bcia_update) {
	case TRUE:
		uint64_t bcia_id;
	case FALSE:
		void; /* We are binding connection
                         this operation was issued
                         over. */
};

struct BIND_BACKCHANNEL4args {
    backchannel_id_arg44 bbca_bcid4;
    uint32_t  callback_program;
    uint32_t  callback_ident;
    count4         maxrequestsize;
    count4         maxresponsesize;
    count4         maxrequests;
    channelattrs4  bbca_channelattrs;
    callback_sec_parms4 bbc_sec_parms<>;
};

In 22.42.3 RESULT

OLD:

struct BIND_BACKCHANNEL4resok {
    count4         maxrequestsize;
    count4         maxresponsesize;
    count4         maxrequests;
    switch (channelmode4 mode) {
    case DEFAULT:
        void;
    case STREAM:
        streamchannelattrs4 streamchanattrs;
    case RDMA:
        rdmachannelattrs4   rdmachanattrs;
    };
};

NEW:

union backchannel_id_res4 switch (bool bcir_update) {
	case TRUE:
		void;
	case FALSE:
		uint64_t bcia_id; /* We are binding
                                     the connection
                                     this operation
                                     was issued over,
                                     and provide an
                                     identifier for
                                     future updates.
                                   */
};

struct BIND_BACKCHANNEL4resok {
    backchannel_id_res4 bbcr_bcid4;
    count4         maxrequestsize;
    count4         maxresponsesize;
    count4         maxrequests;
    channelattrs4  bbcr_channelattrs;
};

Changes to:

22.42.4.  DESCRIPTION

ADD:

  A client MAY issue BIND_BACKCHANNEL for a channel
  multiple times; a server MUST allow this. The purpose
  of doing so is to replace the values specfied in
  the arguments. However, to avoid the complexity of
  implementing the client and server such it has to process
  RPC messages originating from both client and server
  on the same connection, an update to a back channel
  MUST arrive over a non-back channel. The back channel
  being updated is identified via the bbca_bcid4 which
  is a switch union of type backchannel_id_arg4. If the
  switch variable bcia_update is TRUE, then what follows
  is the back channel identifier which was returned in a
  parallel switched union of type backchannel_id_res4.

  BIND_BACKCHANNEL MUST appear in COMPOUND that starts
  with SEQUENCE. The connection BIND_BACKCHANNEL is used
  with MUST have been previously bound via
  BIND_CONN_TO_SESSION.  The security flavor, and if
  applicable, principal and RPCSEC_GSS service used for
  BIND_BACKCHANNEL MUST match that used when the connection
  was bound to the session via BIND_CONN_TO_SESSION.

Changes to:

22.42.5.  IMPLEMENTATION

OLD:

No discussion at this time.

NEW:

The field bbc_sec_parms in the arguments is an array of
acceptable security credentials. Three security flavors
are supported: AUTH_NONE, AUTH_SYS, and RPCSEC_GSS. If
AUTH_NONE is specified for a credential, then this says
the client is allowed to use AUTH_NONE on all callbacks
for the session.  If AUTH_SYS is specified, then the
client is allowed to use AUTH_SYS on all callbacks, using
the credential specified cbsp_sys_cred. If RPCSEC_GSS is
specified, then the server is allowed to use the RPCSEC_GSS
context specified in cbsp_gss_parms as the RPCSEC_GSS
context in the credential of the RPC header of callbacks
to the client.

The RPCSEC_GSS context is specified with two RPCSEC_GSS
handles. The first handle, gcbp_handle_from_server,
is the fore handle the server returned to the client
when the RPCSEC_GSS context was created on the server.
The second handle, gcbp_handle_from_client is the back
handle the client will map to the RPCSEC_GSS context
to. The server can immediately use the RPCSEC_GSS context
using gcbp_handle_from_client as the value for "handle"
in the structure rpc_gss_cred_vers_1_t of the RPCSEC_GSS
handle, and gss_proc set to RPCSEC_GSS_DATA. Note that
while the GSS context state is shared between the fore
and back RPCSEC_GSS contexts, the fore and back RPCSEC_GSS
context state are independent of each other as far as the
RPCSEC_GSS sequence number.

Implementing RPCSEC_GSS callback support requires
the client and server change its RPCSEC_GSS
implementations. One possible set of changes includes:

- Adding a data structure that wraps the GSS-API
  context with a reference count.

- New functions to increment and decrement the reference
  count. If the reference count is decremented to the zero,
  the wrapper data structure and the GSS-API context it
  refers to would be freed.

- Change RPCSEC_GSS to create the wrapper data
  structure upon receiving GSS-API context from
  gss_accept_sec_context() and gss_init_sec_context().
  The reference count would be initialized to 1.

- Adding a function to map an existing
  RPCSEC_GSS handle to a pointer to the wrapper data
  structure. The reference count would be incremented.

- Adding a function to create a new RPCSEC_GSS
  handle from a pointer to the wrapper data structure.
  The reference count would be incremented.

- Replacing calls from RPCSEC_GSS that free GSS-API
  contexts, with calls to decrement the reference count
  on the wrapper data structure.

The protocol supports multiple channels to make operation
more robust such as in the case when the client does not
use a machine principal. In this case, the client is using
RPCSEC_GSS contexts created by normal principals. Such
principals are subject to "logging off" the client at
any time, and so the principals' contexts are subject
to removal at any time. By having multiple contexts from
multiple principals available for the back channel, the
probability of a valid RPCSEC_GSS context being available
to the server for callbacks increases.  Regardless, whether
a content for a machine principal or a normal principal
is used in the back channel, the client MUST monitor the
state of RPCSEC_GSS and GSS contexts. If it finds that a
context has been deleted or is near expiration, it needs
to use BIND_BACKCHANNEL to provide replacement contexts
for the server. If amount of time the server has no valid
context for call back operation exceeds the lease period,
the client is subject to having all delegation and layout
state revoked.