Security Negotiation¶
NFSv4 introduces in-band security negotiation through the SECINFO operation (op 33, RFC 7530 sec. 3.3). Unlike NFSv3, where supported authentication flavors were disclosed once at MOUNT time and applied globally to the export, NFSv4 allows the server to enforce different security policies per directory within the namespace. Clients can query the required security mechanisms for any path without triggering access denials.
SECINFO operation¶
SECINFO (op 33, RFC 7530 sec. 16.31) takes a filename component and returns an array of security triples that the server will accept for accessing that path. Each triple specifies either a simple RPC auth flavor or an RPCSEC_GSS mechanism with its OID, QOP, and service level.
SECINFO4resok = secinfo4[]
struct secinfo4 {
uint32_t flavor; -- AUTH_NONE(0), AUTH_SYS(1), RPCSEC_GSS(6), etc.
/* If flavor == RPCSEC_GSS: */
rpcsec_gss_info {
sec_oid4 oid; -- GSS mechanism OID (e.g., Kerberos V5)
uint32_t qop; -- quality of protection (0 = default)
rpc_gss_svc_t service; -- none(1), integrity(2), privacy(3)
}
}
Query examples¶
COMPOUND([PUTROOTFH, SECINFO("public")])
→ [AUTH_SYS(1)]
-- accepts AUTH_SYS: credential spoofing works
COMPOUND([PUTROOTFH, LOOKUP("srv"), SECINFO("restricted")])
→ [RPCSEC_GSS(6, oid=1.2.840.113554.1.2.2, svc=integrity)]
-- requires krb5i: credential spoofing blocked
COMPOUND([PUTROOTFH, LOOKUP("srv"), SECINFO("mixed")])
→ [AUTH_SYS(1), RPCSEC_GSS(6, oid=1.2.840.113554.1.2.2, svc=none)]
-- accepts both AUTH_SYS and krb5: AUTH_SYS is the weak link
SECINFO does not require access
SECINFO returns the supported flavors for a path without requiring the client to have access to the path itself. The server does not check whether the client's current credentials are authorized -- it simply reports what credentials would be accepted. This is by design (RFC 7530 sec. 3.3.1) and is the basis for nfswolf's security posture probing.
Kerberos pseudo-flavors¶
RFC 7530 Section 3.2.1.1 defines three Kerberos V5 pseudo-flavors that map to different RPCSEC_GSS service levels:
| Pseudo-flavor | Value | GSS OID | RPCSEC_GSS Service | Protection |
|---|---|---|---|---|
| krb5 | 390003 | 1.2.840.113554.1.2.2 | rpc_gss_svc_none | Authentication only |
| krb5i | 390004 | 1.2.840.113554.1.2.2 | rpc_gss_svc_integrity | Authentication + integrity |
| krb5p | 390005 | 1.2.840.113554.1.2.2 | rpc_gss_svc_privacy | Authentication + integrity + encryption |
These are called "pseudo-flavors" because they are not distinct RPC authentication flavors. They all use RPCSEC_GSS (flavor 6) with the Kerberos V5 GSS mechanism, differing only in the service level. The pseudo-flavor numbers are used in Linux NFS export configuration (sec=krb5,krb5i,krb5p) for convenience.
What each level protects¶
The client presents a Kerberos ticket to prove its identity. The server verifies the ticket and maps the Kerberos principal to a local UID. RPC arguments and data are sent in cleartext. An attacker cannot spoof credentials, but can observe all file data on the wire.
Same as krb5, plus every RPC message includes a cryptographic checksum. The server rejects any message whose checksum does not verify. An attacker cannot modify data in transit, but can still observe it.
Same as krb5i, plus all RPC arguments and data are encrypted. An attacker can see that NFS traffic is occurring but cannot read file contents or metadata.
NFS4ERR_WRONGSEC¶
When a client attempts an operation using a security flavor that does not match the server's policy for the target path, the server returns NFS4ERR_WRONGSEC (RFC 7530 sec. 3.3.2). This error does not indicate an authentication failure; it indicates a policy mismatch.
The expected client behavior on receiving NFS4ERR_WRONGSEC:
- Issue SECINFO for the path to discover accepted flavors
- Select an appropriate flavor from the response
- Retry the operation with the selected flavor
sequenceDiagram
participant C as Client
participant S as Server
C->>S: LOOKUP("restricted") [AUTH_SYS]
S->>C: NFS4ERR_WRONGSEC
C->>S: SECINFO("restricted")
S->>C: [RPCSEC_GSS(krb5i)]
Note over C: Switch to krb5i
C->>S: LOOKUP("restricted") [krb5i]
S->>C: OK + filehandle
AUTH_TOOWEAK¶
A related error, NFS4ERR_AUTH_TOOWEAK, is returned when the client's authentication is accepted but is not strong enough for the requested operation. This can occur when the server's policy requires a higher security level than the client provided. For example, the client authenticates with krb5 (authentication only) but the export requires krb5i (integrity).
AUTH_TOOWEAK as an oracle (F-1.8)
The distinction between NFS4ERR_WRONGSEC and NFS4ERR_AUTH_TOOWEAK reveals information about the server's security configuration. WRONGSEC means the flavor is completely rejected; AUTH_TOOWEAK means the flavor family is accepted but the service level is insufficient. An attacker can use these different errors to map out the exact security requirements per path.
The intended model vs reality¶
What RFC 7530 intended¶
RFC 7530 Section 3.2.1 states that RPCSEC_GSS with Kerberos V5 is mandatory to implement for both clients and servers. The intended deployment model is:
- Server announces Kerberos requirements via SECINFO
- Client negotiates to the strongest mutually-supported mechanism
- All operations use RPCSEC_GSS with authentication, integrity, or privacy
- AUTH_SYS is a legacy fallback, not the default
What most deployments actually do¶
The spec says Kerberos is mandatory to implement, not mandatory to use. RFC 7530 Section 3.2 explicitly states that other flavors "MAY be implemented as well." In practice:
| Environment | Typical configuration | AUTH_SYS available? |
|---|---|---|
| Linux knfsd (default) | sec=sys on all exports |
Yes -- spoofable |
| Linux knfsd (hardened) | sec=krb5 or sec=krb5p |
No -- requires Kerberos |
| Linux knfsd (mixed) | sec=krb5:sys on some exports |
Yes -- on exports with sys |
| Windows NFS | Kerberos via Active Directory | Depends on AD integration |
| NetApp / EMC | Varies by administrator policy | Often yes on v4, no on hardened |
| FreeBSD | sec=sys by default |
Yes -- spoofable |
The majority of NFSv4 deployments still accept AUTH_SYS because deploying Kerberos infrastructure (KDC, keytabs, principal management) is operationally expensive and many administrators do not bother. This means the fundamental credential-spoofing attack surface is unchanged from v3.
How nfswolf uses SECINFO¶
nfswolf probes SECINFO in several contexts to assess the server's security posture:
Scanner SECINFO probing¶
The scanner's v4 data collection phase issues SECINFO for each discovered export path. The response is included in the scan results and passed to the analyzer for security assessment.
Analyzer security checks¶
The analyzer examines SECINFO responses against several findings:
| Finding | What the analyzer checks |
|---|---|
| F-1.1 (UID/GID spoofing) | AUTH_SYS (flavor 1) in SECINFO response |
| F-1.7 (RPCSEC_GSS downgrade) | Both AUTH_SYS and RPCSEC_GSS present -- attacker can choose the weaker one |
| F-1.8 (AUTH_TOOWEAK) | Export requires Kerberos, blocks AUTH_SYS |
| F-5.5 (pseudo-FS leakage) | Export names visible via pseudo-FS even without access |
Shell SECINFO command¶
The secinfo operation is available in the v4 shell for interactive probing:
nfs> secinfo /srv/nfs/public
AUTH_SYS (1) -- credential spoofing possible
nfs> secinfo /srv/nfs/restricted
RPCSEC_GSS (6) -- Kerberos V5 (krb5i)
Credential escalation decision¶
When the shell encounters NFS4ERR_WRONGSEC or NFS4ERR_PERM, it consults the SECINFO response for the current path. If AUTH_SYS is accepted, the credential ladder is walked. If only RPCSEC_GSS is accepted, credential escalation is skipped for that path and the user is informed that Kerberos is enforced.
Downgrade attacks¶
When a server accepts both AUTH_SYS and RPCSEC_GSS (the sec=krb5:sys configuration on Linux), an attacker can simply choose AUTH_SYS. The server advertises both in the SECINFO response, and the client is free to pick either one. There is no enforcement of "use the strongest available."
This is finding F-1.7: the presence of AUTH_SYS in a SECINFO response alongside RPCSEC_GSS means the stronger mechanism provides no security benefit. The attacker will always choose AUTH_SYS.
Mixed security is no security
If any flavor in the SECINFO response is AUTH_SYS, the export is effectively unprotected. It does not matter that krb5p is also available. The attacker will not use it. The only secure configuration is to exclude AUTH_SYS entirely: sec=krb5 (or krb5i or krb5p) with no sys fallback.
Cross-version downgrade¶
When a server supports both NFSv3 and NFSv4, security policies may differ between versions. An export configured with sec=krb5 on NFSv4 may still be accessible via AUTH_SYS on NFSv3 if the v3 MOUNT configuration does not enforce the same policy.
nfswolf's auto-version detection probes v3 before v4. If v3 is available and accepts AUTH_SYS for an export that requires Kerberos on v4, the tool will use v3 by default, effectively bypassing the v4 security policy. This is the v4-to-v3 downgrade path documented in F-1.6.
The only defense is consistent security policy across all supported NFS versions, or disabling v2/v3 entirely on the server.