| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- .. SPDX-License-Identifier: GPL-2.0
- =======================
- NFSv4 client identifier
- =======================
- This document explains how the NFSv4 protocol identifies client
- instances in order to maintain file open and lock state during
- system restarts. A special identifier and principal are maintained
- on each client. These can be set by administrators, scripts
- provided by site administrators, or tools provided by Linux
- distributors.
- There are risks if a client's NFSv4 identifier and its principal
- are not chosen carefully.
- Introduction
- ------------
- The NFSv4 protocol uses "lease-based file locking". Leases help
- NFSv4 servers provide file lock guarantees and manage their
- resources.
- Simply put, an NFSv4 server creates a lease for each NFSv4 client.
- The server collects each client's file open and lock state under
- the lease for that client.
- The client is responsible for periodically renewing its leases.
- While a lease remains valid, the server holding that lease
- guarantees the file locks the client has created remain in place.
- If a client stops renewing its lease (for example, if it crashes),
- the NFSv4 protocol allows the server to remove the client's open
- and lock state after a certain period of time. When a client
- restarts, it indicates to servers that open and lock state
- associated with its previous leases is no longer valid and can be
- destroyed immediately.
- In addition, each NFSv4 server manages a persistent list of client
- leases. When the server restarts and clients attempt to recover
- their state, the server uses this list to distinguish amongst
- clients that held state before the server restarted and clients
- sending fresh OPEN and LOCK requests. This enables file locks to
- persist safely across server restarts.
- NFSv4 client identifiers
- ------------------------
- Each NFSv4 client presents an identifier to NFSv4 servers so that
- they can associate the client with its lease. Each client's
- identifier consists of two elements:
- - co_ownerid: An arbitrary but fixed string.
- - boot verifier: A 64-bit incarnation verifier that enables a
- server to distinguish successive boot epochs of the same client.
- The NFSv4.0 specification refers to these two items as an
- "nfs_client_id4". The NFSv4.1 specification refers to these two
- items as a "client_owner4".
- NFSv4 servers tie this identifier to the principal and security
- flavor that the client used when presenting it. Servers use this
- principal to authorize subsequent lease modification operations
- sent by the client. Effectively this principal is a third element of
- the identifier.
- As part of the identity presented to servers, a good
- "co_ownerid" string has several important properties:
- - The "co_ownerid" string identifies the client during reboot
- recovery, therefore the string is persistent across client
- reboots.
- - The "co_ownerid" string helps servers distinguish the client
- from others, therefore the string is globally unique. Note
- that there is no central authority that assigns "co_ownerid"
- strings.
- - Because it often appears on the network in the clear, the
- "co_ownerid" string does not reveal private information about
- the client itself.
- - The content of the "co_ownerid" string is set and unchanging
- before the client attempts NFSv4 mounts after a restart.
- - The NFSv4 protocol places a 1024-byte limit on the size of the
- "co_ownerid" string.
- Protecting NFSv4 lease state
- ----------------------------
- NFSv4 servers utilize the "client_owner4" as described above to
- assign a unique lease to each client. Under this scheme, there are
- circumstances where clients can interfere with each other. This is
- referred to as "lease stealing".
- If distinct clients present the same "co_ownerid" string and use
- the same principal (for example, AUTH_SYS and UID 0), a server is
- unable to tell that the clients are not the same. Each distinct
- client presents a different boot verifier, so it appears to the
- server as if there is one client that is rebooting frequently.
- Neither client can maintain open or lock state in this scenario.
- If distinct clients present the same "co_ownerid" string and use
- distinct principals, the server is likely to allow the first client
- to operate normally but reject subsequent clients with the same
- "co_ownerid" string.
- If a client's "co_ownerid" string or principal are not stable,
- state recovery after a server or client reboot is not guaranteed.
- If a client unexpectedly restarts but presents a different
- "co_ownerid" string or principal to the server, the server orphans
- the client's previous open and lock state. This blocks access to
- locked files until the server removes the orphaned state.
- If the server restarts and a client presents a changed "co_ownerid"
- string or principal to the server, the server will not allow the
- client to reclaim its open and lock state, and may give those locks
- to other clients in the meantime. This is referred to as "lock
- stealing".
- Lease stealing and lock stealing increase the potential for denial
- of service and in rare cases even data corruption.
- Selecting an appropriate client identifier
- ------------------------------------------
- By default, the Linux NFSv4 client implementation constructs its
- "co_ownerid" string starting with the words "Linux NFS" followed by
- the client's UTS node name (the same node name, incidentally, that
- is used as the "machine name" in an AUTH_SYS credential). In small
- deployments, this construction is usually adequate. Often, however,
- the node name by itself is not adequately unique, and can change
- unexpectedly. Problematic situations include:
- - NFS-root (diskless) clients, where the local DHCP server (or
- equivalent) does not provide a unique host name.
- - "Containers" within a single Linux host. If each container has
- a separate network namespace, but does not use the UTS namespace
- to provide a unique host name, then there can be multiple NFS
- client instances with the same host name.
- - Clients across multiple administrative domains that access a
- common NFS server. If hostnames are not assigned centrally
- then uniqueness cannot be guaranteed unless a domain name is
- included in the hostname.
- Linux provides two mechanisms to add uniqueness to its "co_ownerid"
- string:
- nfs.nfs4_unique_id
- This module parameter can set an arbitrary uniquifier string
- via the kernel command line, or when the "nfs" module is
- loaded.
- /sys/fs/nfs/net/nfs_client/identifier
- This virtual file, available since Linux 5.3, is local to the
- network namespace in which it is accessed and so can provide
- distinction between network namespaces (containers) when the
- hostname remains uniform.
- Note that this file is empty on name-space creation. If the
- container system has access to some sort of per-container identity
- then that uniquifier can be used. For example, a uniquifier might
- be formed at boot using the container's internal identifier:
- sha256sum /etc/machine-id | awk '{print $1}' \\
- > /sys/fs/nfs/net/nfs_client/identifier
- Security considerations
- -----------------------
- The use of cryptographic security for lease management operations
- is strongly encouraged.
- If NFS with Kerberos is not configured, a Linux NFSv4 client uses
- AUTH_SYS and UID 0 as the principal part of its client identity.
- This configuration is not only insecure, it increases the risk of
- lease and lock stealing. However, it might be the only choice for
- client configurations that have no local persistent storage.
- "co_ownerid" string uniqueness and persistence is critical in this
- case.
- When a Kerberos keytab is present on a Linux NFS client, the client
- attempts to use one of the principals in that keytab when
- identifying itself to servers. The "sec=" mount option does not
- control this behavior. Alternately, a single-user client with a
- Kerberos principal can use that principal in place of the client's
- host principal.
- Using Kerberos for this purpose enables the client and server to
- use the same lease for operations covered by all "sec=" settings.
- Additionally, the Linux NFS client uses the RPCSEC_GSS security
- flavor with Kerberos and the integrity QOS to prevent in-transit
- modification of lease modification requests.
- Additional notes
- ----------------
- The Linux NFSv4 client establishes a single lease on each NFSv4
- server it accesses. NFSv4 mounts from a Linux NFSv4 client of a
- particular server then share that lease.
- Once a client establishes open and lock state, the NFSv4 protocol
- enables lease state to transition to other servers, following data
- that has been migrated. This hides data migration completely from
- running applications. The Linux NFSv4 client facilitates state
- migration by presenting the same "client_owner4" to all servers it
- encounters.
- ========
- See Also
- ========
- - nfs(5)
- - kerberos(7)
- - RFC 7530 for the NFSv4.0 specification
- - RFC 8881 for the NFSv4.1 specification.
|