RFC 2224

NFS URL Scheme

๐Ÿ“… published October 1997, from ietf

RFC 2224: NFS URL Scheme ๐ŸŽ€

Okay bestie, this is RFC 2224, and it's called NFS URL Scheme โœจ. It was written by B. Callaghan from Sun Microsystems, Inc. It's marked Category: Informational, dated October 1997 ๐Ÿฆ‹. Let's get into it ๐Ÿ’…


Status of this Memo ๐ŸŒธ

This memo gives information to the Internet community. It is not a standard of any kind ๐Ÿ™ˆ Distribution is unlimited, so share it with everyone ๐Ÿ’œ

Copyright (C) The Internet Society (1997). All Rights Reserved. ๐Ÿ”’

Abstract ๐Ÿ”ฅ

So this RFC defines a brand new URL scheme called nfs ๐ŸŽ€ It's used to point at files and directories on NFS servers, using the general URL syntax from RFC 1738, "Uniform Resource Locators (URL)" ๐Ÿงš

The scheme uses the public filehandle and multi-component lookup [RFC2054, RFC2055] to get at server data with as little protocol overhead as possible ๐Ÿ’…โœจ

Quick background on NFS ๐ŸŒˆ It shares filesystems across networks, and it's built to be machine, operating system, network architecture, and transport protocol independent, which is honestly iconic ๐Ÿ‘‘ Right now there are two versions: version 2 [RFC1094] and version 3 [RFC1813]. Both sit on ONC RPC [RFC1831], its eXternal Data Representation (XDR) [RFC1832], and the Binding Protocol [RFC1833] ๐Ÿ’–

Table of Contents ๐Ÿฆ‹

   1.    URL Syntax . . . . . . . . . . . . . . . . . . . . . . .  2
   2.    URL Evaluation . . . . . . . . . . . . . . . . . . . . .  2
   3.    Server Connection  . . . . . . . . . . . . . . . . . . .  2
   4.    NFS Version  . . . . . . . . . . . . . . . . . . . . . .  2
   5.    Public Filehandle  . . . . . . . . . . . . . . . . . . .  3
   5.1     NFS Version 2 Public Filehandle  . . . . . . . . . . .  3
   5.2     NFS Version 3 Public Filehandle  . . . . . . . . . . .  3
   6.    Multi-component Lookup . . . . . . . . . . . . . . . . .  3
   6.1     Absolute vs Relative Pathname  . . . . . . . . . . . .  4
   6.2     Symbolic Links . . . . . . . . . . . . . . . . . . . .  5
   7.    Mount Protocol . . . . . . . . . . . . . . . . . . . . .  6
   8.    Bibliography . . . . . . . . . . . . . . . . . . . . . .  7
   9.    Security Considerations  . . . . . . . . . . . . . . . .  8
   10.   BNF for NFS URL Scheme . . . . . . . . . . . . . . . . .  9
   11.   Acknowledgements . . . . . . . . . . . . . . . . . . . . 10
   12.   Author's Address . . . . . . . . . . . . . . . . . . . . 10
   13.   Full Copyright Statement . . . . . . . . . . . . . . . . 11

1. URL Syntax ๐ŸŽ€

An NFS URL is based on the Common Internet Scheme Syntax from section 3.1 of RFC 1738 ๐Ÿงš It looks like this:

     nfs://<host>:<port><url-path>

The :<port> part is optional ๐Ÿ’• If you leave it out, port 2049 is assumed. The <url-path> is optional too ๐ŸŒธ

The <url-path> is a hierarchical directory path shaped like /<directory>/<directory>/<directory>/.../<name>. It must consist only of characters from the US-ASCII character set ๐Ÿ”ฅ Inside a <directory> or <name> component, the character "/" is reserved, so it must be encoded as described in Section 2.2 of RFC 1738. And if the <url-path> is omitted or is only "/", it must default to the path "." ๐Ÿ’…

2. URL Evaluation โœจ

A client must evaluate an NFS URL with a method called WebNFS [RFC2054, RFC2055] ๐Ÿฆ‹ It's great because it gets through firewalls and proxy servers really easily, and it uses a minimum number of messages ๐Ÿซถ WebNFS is defined for NFS versions 2 and 3. It assumes the server registers on TCP or UDP port 2049, and that it supports the public filehandle and multi-component lookup semantics covered in the sections below ๐ŸŒˆ

3. Server Connection ๐Ÿงš

The client must first try to create a TCP connection to <host> using the <port> you gave it ๐Ÿ’– If :<port> is left out, port 2049 gets used. If the server refuses the TCP connection, the client falls back to UDP ๐Ÿฆ‹

4. NFS Version ๐ŸŒธ

The client must first try NFS version 3 ๐Ÿ‘‘ If the server sends back an RPC PROG_MISMATCH error, the client must assume that NFS version 3 isn't supported and then retry the operation using an NFS version 2 public filehandle ๐Ÿ’…

5. Public Filehandle ๐Ÿ’œ

So normally, filehandles are made by the server, and they're used to uniquely identify a particular file or directory on that server ๐Ÿ”ฅ The client usually doesn't make them, and it doesn't really know what's inside one ๐Ÿ™ˆ

The public filehandle is the exception, the main character of this section ๐Ÿ‘‘ It's an NFS filehandle with a reserved value and special semantics that let you get an initial filehandle. A WebNFS client uses the public filehandle as that starting point instead of using the MOUNT protocol โœจ Since NFS version 2 and version 3 have different filehandle formats, the public filehandle is defined differently for each one ๐ŸŒˆ

The public filehandle is a zero filehandle. For NFS version 2, that's a filehandle with 32 zero octets. For a version 3 public filehandle, the length is zero ๐ŸŽ€

5.1 NFS Version 2 Public Filehandle ๐Ÿฆ‹

A version 2 filehandle is defined in RFC 1094 as an opaque value that takes up 32 octets ๐Ÿงš A version 2 public filehandle has a zero in each octet, so it's all zeros ๐Ÿ’–

    1                                                             32
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

5.2 NFS Version 3 Public Filehandle ๐ŸŒธ

A version 3 filehandle is defined in RFC 1813 as a variable length opaque value, up to 64 octets ๐ŸŒˆ The length of the filehandle is given by an integer in a 4 octet value, which says how many valid octets follow. A version 3 public filehandle has a length of zero ๐Ÿซถ

   +-+-+-+-+
   |   0   |
   +-+-+-+-+

6. Multi-component Lookup ๐Ÿ”ฅ

Normally, an NFS LOOKUP request (version 2 or 3) takes a directory filehandle plus the name of a directory member, and returns the filehandle of that member ๐Ÿ’… But if a client needs to evaluate a pathname with a bunch of components, it has to start with the directory filehandle of the first component and then send a series of LOOKUP requests, one component at a time ๐Ÿ˜ญ For example, evaluating the path "a/b/c" sends separate LOOKUP requests for each component: "a", "b", and "c" ๐Ÿ™ˆ

A LOOKUP request that uses the public filehandle can carry a pathname with multiple components ๐Ÿ‘‘ The server is expected to evaluate the whole pathname and return a filehandle for the final component โœจ

So instead of evaluating "a/b/c" like this:

        LOOKUP  FH=0x0  "a"  --->
                             <---  FH=0x1
        LOOKUP  FH=0x1  "b"  --->
                             <---  FH=0x2
        LOOKUP  FH=0x2  "c"  --->
                             <---  FH=0x3

Relative to the public filehandle, those three LOOKUP requests can be swapped for one multi-component lookup ๐Ÿงš

        LOOKUP  FH=0x0  "a/b/c"  --->
                                 <---  FH=0x3

Multi-component lookup is only supported for LOOKUP requests that are relative to the public filehandle ๐Ÿฆ‹

The <url-path> of an NFS URL must be evaluated as a multi-component lookup. That means the path components are separated by slashes, and the characters making up the path must be in the printable US-ASCII character set ๐Ÿ’– Characters that aren't in the "unreserved" set (see the BNF description below) can be included in pathname components, but they must be escaped ๐ŸŒˆ

If the <url-path> is empty or is only "/", the client must send a multi-component lookup for the pathname "." ๐ŸŽ€

6.1 Absolute vs. Relative Pathname ๐ŸŒธ

A multi-component pathname that starts with a slash is considered "absolute", and it gets evaluated relative to the server's root ๐Ÿ”ฅ A pathname that doesn't start with a slash is "relative", and it gets evaluated relative to the directory the public filehandle is associated with ๐Ÿ’…

Now, the initial "/" that starts the <url-path> of an NFS URL must not be passed to the server for multi-component lookup, because the pathname is supposed to be evaluated relative to the public filehandle directory ๐Ÿ˜ญ Here's an example. Say the public filehandle is associated with the server's directory "/a/b/c". Then this URL:

        nfs://server/d/e/f

gets evaluated with a multi-component lookup of the path "d/e/f", relative to the server's directory "/a/b/c". But this URL:

        nfs://server//a/b/c/d/e/f

finds the same file with an absolute multi-component lookup of the path "/a/b/c/d/e/f", relative to the server's filesystem root ๐Ÿงš Notice that a double slash is required at the start of the path ๐Ÿซถ

Not every WebNFS server can handle arbitrary absolute paths, bestie ๐Ÿ™ˆ The server must not return a filehandle if the path identifies a file or directory that isn't exported by the server ๐Ÿ”’ Also, some servers won't return a filehandle if the path names a file or directory in an exported filesystem that's different from the one the public filehandle is associated with ๐Ÿ’€

NFS supports symbolic links, which are the filesystem version of a relative URL ๐ŸŒˆ If a WebNFS client retrieves a filehandle for a symbolic link (you can tell from the file type attribute), it should send a READLINK request to the server to get the path that makes up the symbolic link ๐Ÿ’–

That path then gets combined with the URL that referenced the symbolic link, following the rules in RFC 1808 ๐ŸŒธ For a relative URL in the symbolic link text to be resolved successfully, it must contain only ASCII characters and conform to the syntax in RFC 1808 ๐ŸŽ€ This means a symbolic link can contain an entire URL, and that URL might use a scheme that isn't an NFS URL at all ๐Ÿ‘‘

A symbolic link path that begins with a slash gets evaluated as an absolute path, relative to the directory associated with the public filehandle. That might not be the same as the server's system root directory ๐Ÿ”ฅ If symbolic links with absolute paths are going to be evaluated correctly on both the client and the server, the public filehandle must be associated with the system root directory ๐Ÿ˜ญ

For example, say the symbolic link is named by the URL:

        nfs://server/a/b

Then these examples show how a new URL gets formed from the symbolic link text โœจ

         c                      = nfs://server/a/c

         c/d                    = nfs://server/a/c/d

         ../c                   = nfs://server/c

         /c/d                   = nfs://server/c/d

         nfs://server2/a/b      = nfs://server2/a/b

7. Mount Protocol โœจ

okay so the NFS URL is kinda limited when it comes to naming files on servers that don't support the public filehandle and multi-component lookup ๐Ÿ’€ bestie, it's a whole situation.

If the server returns an NFS3ERR_STALE, NFS3ERR_INVAL, or NFS3ERR_BADHANDLE error when the client uses a public filehandle, then the client should attempt to resolve the <url-path> to a filehandle using the MOUNT protocol. ๐Ÿฆ‹

MOUNT version 1 is described in Appendix A of RFC 1094, and version 3 is described in Appendix I of RFC 1813. Version 2 is basically identical to version 1, except it adds a procedure called MOUNTPROC_PATHCONF, which returns POSIX pathconf information from the server. ๐ŸŒธ

Now, the pathname sent to the server in a MOUNTPROC_MNT request is assumed to be a server native path, not the slash-separated path that RFC 1738 describes. ๐Ÿ™ˆ So the MOUNT protocol can reasonably be expected to map a <url-path> to a filehandle only on servers that support slash-separated ASCII native paths. In general, servers that don't support WebNFS access or slash-separated ASCII native paths should not advertise NFS URLs. not the NFS URLs being advertised somewhere they won't work ๐Ÿ˜ญ

At this point the client must already have some indication of which NFS protocol version the server supports. Since the filehandle format is different between NFS versions 2 and 3, the client must select the appropriate version of the MOUNT protocol. MOUNT versions 1 and 2 return only NFS version 2 filehandles, whereas MOUNT version 3 returns NFS version 3 filehandles. ๐Ÿงš

Unlike the NFS service, the MOUNT service is not registered on a well-known port. So the client must use the PORTMAP service to find the server's MOUNT port before it can send a MOUNTPROC_MNT request to get the filehandle for the requested path. the lookup has to happen in this order, no skipping ๐Ÿ’…

    Client                                       Server
    ------                                       ------

    -------------- MOUNT port ? -------------->  Portmapper
    <-------------- Port=984 ------------------

    ------- Filehandle for /export/foo ?  ---->  Mountd @ port 984
    <--------- Filehandle=0xf82455ce0..  ------

NFS servers commonly treat a client's successful MOUNTPROC_MNT request as a sign that the client has "mounted" the filesystem. They may keep track of this in a file that lists the filesystems clients currently have mounted. That record gets removed when the client sends a MOUNTPROC_UMNT request. So, once a WebNFS client gets a successful reply to a MOUNTPROC_MNT request, it should send a MOUNTPROC_UMNT request, so the server doesn't pile up a bunch of "mounted" records ๐Ÿงนโœจ


8.0 Bibliography ๐Ÿ“š

  • [RFC1738] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform Resource Locators (URL)," RFC 1738, December 1994. ๐Ÿ”—
  • [RFC1808] Fielding, R., "Relative Uniform Resource Locators," RFC 1808, June 1995.
  • [RFC1831] Srinivasan, R., "RPC: Remote Procedure Call Protocol Specification Version 2," RFC 1831, August 1995.
  • [RFC1832] Srinivasan, R., "XDR: External Data Representation Standard," RFC 1832, August 1995.
  • [RFC1833] Srinivasan, R., "Binding Protocols for ONC RPC Version 2," RFC 1833, August 1995.
  • [RFC1094] Sun Microsystems, Inc., "Network Filesystem Specification," RFC 1094, March 1989.
  • [RFC1813] Callaghan, B., Pawlowski, B. and P. Staubach, "NFS Version 3 Protocol Specification," RFC 1813, June 1995.
  • [RFC2054] Callaghan, B., "WebNFS Client Specification," RFC 2054, October 1996.
  • [RFC2055] Callaghan, B., "WebNFS Server Specification," RFC 2055, October 1996.
  • [Sandberg] Sandberg, R., D. Goldberg, S. Kleiman, D. Walsh, B. Lyon, "Design and Implementation of the Sun Network Filesystem," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, Summer 1985. The basic paper describing the SunOS implementation of the NFS version 2 protocol, and discusses the goals, protocol specification and trade-offs. ๐ŸŒŸ
  • [X/OpenNFS] X/Open Company, Ltd., X/Open CAE Specification: Protocols for X/Open Internetworking: XNFS, X/Open Company, Ltd., Apex Plaza, Forbury Road, Reading Berkshire, RG1 1AX, United Kingdom, 1991. This is an indispensable reference for the NFS and accompanying protocols, including the Lock Manager and the Portmapper. ๐Ÿ‘‘
  • [X/OpenPCNFS] X/Open Company, Ltd., X/Open CAE Specification: Protocols for X/Open Internetworking: (PC)NFS, Developer's Specification, X/Open Company, Ltd., Apex Plaza, Forbury Road, Reading Berkshire, RG1 1AX, United Kingdom, 1991. This is an indispensable reference for NFS protocol and accompanying protocols, including the Lock Manager and the Portmapper. ๐Ÿ’œ

9. Security Considerations ๐Ÿ”

this part is serious, bestie, read it carefully ๐Ÿšจ

Since the WebNFS server features are based on NFS protocol versions 2 and 3, the RPC based security considerations described in RFC 1094, RFC 1831, and RFC 1832 apply here too.

Server implementors should be careful, when implementing multi-component lookup, that the client cannot get unauthorized access to files or directories. For example, a path that includes multiple occurrences of "../" may locate a filesystem outside of the exported filesystem associated with the public filehandle. ๐Ÿ˜ฑ that's a classic traversal trap, so don't sleep on it!

Clients and servers may separately negotiate secure connection schemes for authentication, data integrity, and privacy. ๐Ÿซถ


10. BNF for NFS URL Scheme ๐Ÿงฉ

The syntax of the NFS URL is a subset of the Generic URL syntax described in RFC 1738. An NFS URL does not include user or password components, nor does it recognize "?" query or "#" fragment components. so no user:pass, no queries, no fragments, period ๐Ÿ™…โ€โ™€๏ธ

   nfsURL        = "nfs" ":" relativeURL
   relativeURL   = net_path | abs_path | rel_path
   net_path      = "//" hostport [ abs_path ]
   abs_path      = "/"  rel_path
   rel_path      = [ path_segments ]

   hostport      = host [ ":" port ]
   host          = hostname | hostnumber
   hostname      = *( domainlabel "." ) toplabel
   domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
   toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
   hostnumber    = 1*digit "." 1*digit "." 1*digit "." 1*digit
   port          = *digit

   url-path      = [ "/" ] path_segments
   path_segments = segment *( "/" segment )
   segment       = *pchar
   pchar         = unreserved | escaped | ":" | "@" | "&" | "=" | "+"

   reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
   unreserved    = alpha | digit | mark
   mark          = "$" | "-" | "_" | "." | "!" | "~" |
                   "*" | "'" | "(" | ")" | ","

   escaped       = "%" hex hex
   hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
                           "a" | "b" | "c" | "d" | "e" | "f"

   alphanum      = alpha | digit
   alpha         = lowalpha | upalpha

   lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
              "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
              "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
   upalpha  = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
              "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
              "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
   digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
              "8" | "9"

11. Acknowledgements ๐ŸŒท

This specification was extensively reviewed by the NFS group at SunSoft and brainstormed by Michael Eisler. thank you, legends ๐Ÿ™Œ


12. Author's Address ๐Ÿ“ฎ

Address comments related to this RFC to:

   brent@eng.sun.com


   Brent Callaghan
   Sun Microsystems, Inc.
   Mailstop Mpk17-201,
   901 San Antonio Road,
   Palo Alto, California 94303

   Phone: 1-415-786-5067
   EMail: brent.callaghan@eng.sun.com
   Fax:   1-415-786-5896

Okay, the legal bit has to stay word-for-word, so here it is exactly as written ๐Ÿค

   Copyright (C) The Internet Society (1997).  All Rights Reserved.

   This document and translations of it may be copied and furnished to
   others, and derivative works that comment on or otherwise explain it
   or assist in its implmentation may be prepared, copied, published
   andand distributed, in whole or in part, without restriction of any
   kind, provided that the above copyright notice and this paragraph are
   included on all such copies and derivative works.  However, this
   document itself may not be modified in any way, such as by removing
   the copyright notice or references to the Internet Society or other
   Internet organizations, except as needed for the purpose of
   developing Internet standards in which case the procedures for
   copyrights defined in the Internet Standards process must be
   followed, or as required to translate it into languages other than
   English.

   The limited permissions granted above are perpetual and will not be
   revoked by the Internet Society or its successors or assigns.

   This document and the information contained herein is provided on an
   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

โœจ and that's the whole thing, bestie. WebNFS, fully explained, no cap ๐Ÿ’–

๐Ÿ“ฆ where this page comes from