요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. 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.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
NFSv4 client identifier의 목적과 관리 주체
1-16이 문서는 system restart 전후에 file open state와 lock state를 유지할 수 있도록 NFSv4 protocol이 client instance를 식별하는 방식을 설명합니다. 각 client는 특별한 identifier와 principal을 유지하며, administrator가 직접 설정하거나 site administrator의 script 또는 Linux distributor가 제공하는 tool로 설정할 수 있습니다.
NFSv4 identifier와 principal을 신중하게 선택하지 않으면 다른 client와 identity가 충돌하거나 재시작 뒤 기존 state를 회수하지 못할 수 있습니다. 따라서 이 두 값은 단순한 표시 문자열이 아니라 lease의 연속성과 권한을 결정하는 protocol identity입니다.
관리자가 정한 identity가 재시작 뒤 state 복구까지 이어지는 흐름입니다.
.. 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.
Lease 기반 file locking과 재시작 복구
17-46NFSv4는 `lease-based file locking`을 사용합니다. Server는 NFSv4 client마다 lease 하나를 만들고 그 client의 file open state와 lock state를 해당 lease 아래에 모읍니다. Lease는 server가 file lock 보장을 제공하면서 resource를 회수할 시점을 판단하는 기반입니다.
Client는 lease를 주기적으로 renew할 책임이 있습니다. Lease가 유효한 동안 server는 그 client가 만든 file lock이 계속 유지된다고 보장합니다. Client crash처럼 갱신이 멈추면 protocol이 정한 시간이 지난 뒤 server는 그 client의 open/lock state를 제거할 수 있습니다.
Client가 재시작하면 이전 lease에 연결된 state가 더 이상 유효하지 않으며 즉시 폐기해도 된다고 server에 알립니다. 반대로 server가 재시작한 경우에는 persistent client-lease 목록으로 재시작 전에 state를 보유했던 client와 새 `OPEN`·`LOCK` 요청을 보내는 client를 구분합니다. 이 구분 덕분에 server restart를 거쳐서도 file lock을 안전하게 복구할 수 있습니다.
정상 갱신, client restart, server restart에서 state를 처리하는 방식입니다.
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.
co_ownerid, boot verifier, principal
47-86각 NFSv4 client는 server가 client와 lease를 연결할 수 있도록 identifier를 제시합니다. 첫 요소 `co_ownerid`는 임의로 정할 수 있지만 고정되어야 하는 문자열입니다. 둘째 요소 boot verifier는 같은 client의 연속된 boot epoch를 구분하는 64-bit incarnation verifier입니다.
NFSv4.0 specification은 이 두 요소를 합쳐 `nfs_client_id4`라고 부르고, NFSv4.1 specification은 `client_owner4`라고 부릅니다. Server는 여기에 client가 identity를 제시할 때 사용한 principal과 security flavor를 연결합니다. 이후 lease 변경 operation을 authorize할 때 이 principal을 사용하므로, 실질적으로 principal은 identifier의 세 번째 요소입니다.
좋은 `co_ownerid`는 client reboot를 거쳐 지속되고, 중앙 할당 기관이 없어도 다른 client와 전역적으로 유일해야 합니다. Network에서 평문으로 보일 수 있으므로 client의 private information을 노출해서는 안 됩니다. 또한 restart 뒤 NFSv4 mount를 시도하기 전에 값이 확정되어 변경되지 않아야 하며 protocol상 최대 크기는 1024 byte입니다.
Protocol identifier와 권한 principal의 역할을 구분합니다.
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.
Lease stealing과 lock stealing 방지
87-122NFSv4 server는 `client_owner4`를 사용해 client마다 고유한 lease를 할당합니다. 서로 다른 client가 같은 identity를 제시하면 서로의 state를 방해할 수 있으며, 이를 `lease stealing`이라고 합니다.
서로 다른 client가 동일한 `co_ownerid`와 동일한 principal, 예를 들어 `AUTH_SYS`와 UID 0을 사용하면 server는 둘을 같은 client로 오인합니다. 각 client의 boot verifier는 다르므로 한 client가 계속 reboot하는 것처럼 보이고, 결국 어느 쪽도 open state나 lock state를 안정적으로 유지할 수 없습니다.
동일한 `co_ownerid`를 쓰되 principal이 다르면 server는 보통 첫 client는 정상 처리하고 뒤에 온 client는 거부합니다. 반대로 client의 `co_ownerid`나 principal이 안정적이지 않으면 server 또는 client restart 뒤 state recovery를 보장할 수 없습니다.
Client가 예상치 못하게 재시작한 뒤 다른 identity를 제시하면 기존 open/lock state가 orphan이 되어 server가 이를 제거할 때까지 잠긴 file에 접근하지 못합니다. Server restart 뒤 identity가 바뀌면 client는 state를 reclaim할 수 없고 그 사이 lock이 다른 client에 부여될 수 있는데, 이것이 `lock stealing`입니다. Lease stealing과 lock stealing은 denial of service 위험을 높이고 드물게 data corruption까지 일으킬 수 있습니다.
`co_ownerid`와 principal 조합별 server 동작입니다.
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.
Linux에서 고유 client identifier 선택
123-168Linux NFSv4 client는 기본적으로 `Linux NFS`라는 문자열 뒤에 client의 UTS node name을 붙여 `co_ownerid`를 만듭니다. 이 node name은 `AUTH_SYS` credential의 machine name에도 사용됩니다. 작은 배포에서는 대체로 충분하지만 hostname만으로는 고유성이 부족하거나 예기치 않게 바뀔 수 있습니다.
대표적인 위험 사례는 DHCP server가 고유 hostname을 주지 않는 NFS-root diskless client, 별도 network namespace를 쓰면서 고유 UTS namespace hostname은 쓰지 않는 container, 중앙 hostname 관리 없이 공통 NFS server를 사용하는 여러 administrative domain입니다. 마지막 경우에는 hostname에 domain name을 포함하지 않으면 고유성을 보장할 수 없습니다.
Linux는 두 가지 uniquifier mechanism을 제공합니다. `nfs.nfs4_unique_id` module parameter는 kernel command line 또는 `nfs` module load 시 임의의 고유 문자열을 지정합니다. Linux 5.3부터 제공되는 `/sys/fs/nfs/net/nfs_client/identifier`는 접근한 network namespace에 local하므로 hostname이 같은 container를 구별할 수 있습니다.
Network namespace를 만들면 해당 virtual file은 비어 있습니다. Container system이 container별 identity를 알고 있다면 boot 과정에서 그 값을 가공해 기록할 수 있습니다. 원문 예시는 `/etc/machine-id`의 SHA-256을 계산해 identifier file에 씁니다.
sha256sum /etc/machine-id | awk '{print $1}' \
> /sys/fs/nfs/net/nfs_client/identifier
Host 전체 설정과 network namespace별 설정을 비교합니다.
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
Lease 관리 operation의 보안
169-195Lease 관리 operation에는 cryptographic security 사용을 강하게 권장합니다. Kerberos가 구성되지 않은 Linux NFSv4 client는 client identity의 principal 부분으로 `AUTH_SYS`와 UID 0을 사용합니다. 이는 안전하지 않을 뿐 아니라 lease stealing과 lock stealing 위험도 높입니다.
Local persistent storage가 없는 client에서는 `AUTH_SYS`가 유일한 선택일 수 있으므로 이때는 `co_ownerid`의 고유성과 지속성이 특히 중요합니다. 반면 Kerberos keytab이 있으면 client는 server에 자신을 식별할 때 keytab의 principal 가운데 하나를 사용하려고 시도합니다.
이 동작은 `sec=` mount option으로 제어되지 않습니다. Kerberos principal을 가진 single-user client는 client host principal 대신 그 principal을 사용할 수도 있습니다. Kerberos를 사용하면 서로 다른 모든 `sec=` 설정의 operation이 같은 lease를 공유할 수 있습니다.
또한 Linux NFS client는 Kerberos 및 integrity QOS와 함께 `RPCSEC_GSS` security flavor를 사용해 전송 중 lease 변경 요청이 변조되는 것을 방지합니다.
Credential 방식에 따른 보안 특성과 보완 요구입니다.
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.
Lease 공유, state migration, 관련 명세
196-216Linux NFSv4 client는 접근하는 NFSv4 server마다 lease 하나만 설정합니다. 따라서 한 Linux client가 특정 server에 만든 여러 NFSv4 mount는 모두 같은 lease를 공유합니다.
Client가 open state와 lock state를 만든 뒤 data가 다른 server로 migration되면 NFSv4 protocol은 그 data를 따라 lease state도 다른 server로 이동할 수 있게 합니다. 실행 중인 application에서는 data migration이 보이지 않습니다.
Linux NFSv4 client는 만나는 모든 server에 같은 `client_owner4`를 제시함으로써 state migration을 지원합니다. 관련 user-space 문서는 `nfs(5)`와 `kerberos(7)`, protocol 명세는 NFSv4.0의 RFC 7530과 NFSv4.1의 RFC 8881을 참조합니다.
동일한 client_owner4가 server 사이 state 연속성을 유지합니다.
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.
요약·해설
client-identifier.rst:1-216NFSv4 client identity는 지속적이고 전역적으로 고유한 `co_ownerid`, boot epoch마다 달라지는 64-bit verifier, lease operation을 authorize하는 principal로 구성됩니다. 세 요소가 안정적이어야 client/server restart와 server 간 data migration 뒤에도 open·lock state를 안전하게 복구할 수 있습니다.
Linux 기본 hostname 기반 identity가 container, diskless client, 여러 administrative domain에서 충돌할 수 있으므로 `nfs.nfs4_unique_id` 또는 network namespace별 identifier file을 사용해 고유성을 보완합니다. 가능하면 Kerberos와 RPCSEC_GSS integrity를 사용해야 합니다.
운영 전에 확인할 핵심 조건입니다.