NFS 与 CIFS 网络文件系统:服务端配置、挂载调优与安全

深入 Linux 网络文件系统:NFS v3 到 v4.2 的演进与伪文件系统、exports 导出与权限模型、客户端挂载选项与性能调优、idmap 与 Kerberos 安全、Samba/CIFS 共享配置与凭据管理、软硬挂载与排错、以及一套可落地的安全加固清单。

引言

多台机器共享同一份文件,最简单的方式是「网络文件系统」:服务端导出目录,客户端把它挂载成本地路径,读写就像本地文件。Linux 世界有两大阵营——NFS(Unix 原生,类 Unix 环境首选)与 CIFS/SMB(Windows 原生,Samba 让 Linux 也能提供服务)。选错协议或配错挂载选项,轻则性能腰斩,重则出现「文件明明写了却读不到」「客户端卡死无法卸载」的诡异故障。

本文从协议演进讲起,完整覆盖 NFS 服务端导出与客户端挂载、v4 的伪文件系统与 idmap、Samba 共享与 CIFS 挂载、性能调优与排错,以及安全加固。目标是让你既能搭起一套可靠的文件共享,也能在出问题时快速定位。

前置:网络配置与连通性排查见 Linux 网络配置与排查 ,权限与 ACL 见 Linux 用户权限与安全加固 ,防火墙放行见 Linux 防火墙与 nftables 。

1. 网络文件系统概览:NFS vs CIFS/SMB

两者解决同一个问题,但设计哲学与适用场景不同:

维度NFSCIFS/SMB
出身Sun,Unix 原生Microsoft,Windows 原生
认证AUTH_SYS(UID/GID)或 Kerberos用户/密码、域、Kerberos
锁NLM(v3)/ 内建(v4)内建
跨平台Linux↔Unix 最佳Windows↔Linux 互通最佳
典型端口2049(v4 单端口)445(SMB3)
适用集群共享、HPC、容器 PV办公共享、Windows 互操作
选择直觉:
  纯 Linux 集群 / Kubernetes PV / HPC  → NFS
  需要和 Windows 客户端互通 / 域认证  → CIFS(Samba)
  两者都要  → Samba 同时提供 SMB 与 NFS(或各跑一个)

心智:NFS 是「Unix 语义的网络磁盘」,CIFS 是「Windows 语义的网络共享」。语义差异体现在权限、锁、大小写敏感性上,混用时要特别小心。

2. NFS 版本演进:v3 到 v4.2

# 查服务端与客户端支持的版本
nfsstat -s        # 服务端统计
nfsstat -c        # 客户端统计
cat /proc/fs/nfsd/versions   # 服务端启用的版本(如 +4.2 +4.1 +4 +3 +2)
版本关键特性端口
v3无状态、需 NLM 锁、多端口2049 + portmap/rpcbind
v4.0有状态、单端口 2049、内建锁、伪文件系统2049
v4.1pNFS 并行访问、会话与 trunking2049
v4.2server-side copy、稀疏文件、fallocate2049

v4 的单端口特性极大简化了防火墙:v3 需要放行 2049 加 rpcbind(111)与一堆动态端口,v4 只需 2049。

# 只启用 v4.2(服务端,/etc/nfs.conf 或发行版对应文件)
# [nfsd]
# vers4.2=y
# vers3=n

记忆:新部署一律优先 NFSv4.1/4.2——单端口好放行、内建锁、支持 Kerberos,且避免了 v3 的 rpcbind 与 NLM 一堆端口。

3. 搭建 NFS 服务端:exports 与权限

# 安装
sudo apt install nfs-kernel-server      # Debian/Ubuntu
sudo dnf install nfs-utils              # RHEL 系
# /etc/exports
/data/shared    192.168.1.0/24(rw,sync,no_subtree_check)
/data/ro        *(ro,root_squash)
/home           client1.example.com(rw,async,no_root_squash)
选项含义
rw / ro读写 / 只读
sync / async同步落盘(安全)/ 异步(快,可能丢数据)
root_squash客户端 root 映射为匿名用户(默认,安全)
no_root_squash保留 root 权限(危险,仅信任网络用)
all_squash所有用户都映射为匿名
no_subtree_check关闭子树检查(提升兼容与性能)
noacl / acl是否支持 POSIX ACL
# 应用导出并查看
sudo exportfs -ra                     # 重新导出全部
sudo exportfs -v                      # 查看当前导出与选项
sudo systemctl enable --now nfs-server

# 放行防火墙(v4 单端口)
sudo firewall-cmd --add-service=nfs --permanent
sudo firewall-cmd --reload
权限的关键:NFS 默认用「客户端上报的 UID/GID」做鉴权(AUTH_SYS)
→ 客户端 root 被 root_squash 映射为 nobody
→ 要让共享目录可写,需保证 UID/GID 在两端一致,或调 squash 策略

铁律:no_root_squash 只在对端完全可信时使用。它允许客户端 root 在共享目录里为所欲为,是 NFS 被入侵后横向移动的常见跳板。

4. 挂载 NFS 客户端与 mount 选项调优

# 查看服务端导出
showmount -e nfs-server
# 挂载
sudo mount -t nfs4 nfs-server:/data/shared /mnt/shared
# 写入 fstab
echo "nfs-server:/data/shared /mnt/shared nfs4 rw,hard,rsize=1048576,wsize=1048576,_netdev 0 0" | sudo tee -a /etc/fstab
选项作用建议
hard / soft服务端不可达时无限重试 / 超时返回错误数据盘用 hard,避免静默丢数据
intr允许中断 hard 挂载的等待老内核需要,新版默认
rsize / wsize单次读写块大小1MB(1048576)常最优
timeo超时(单位 0.1s)网络差可调大
retrans重传次数配合 timeo
_netdev等网络就绪再挂载fstab 必加
nconnect单挂载点的 TCP 连接数v4.1+ 可设 4~16 提升吞吐
noatime不更新访问时间减少写
# nconnect 提升多流并发吞吐(需 v4.1+)
sudo mount -t nfs4 -o nconnect=8 nfs-server:/data/shared /mnt/shared

心法:hard + _netdev 是生产 NFS 挂载的底线。soft 会在服务端短暂不可达时让应用收到 I/O 错误,可能造成静默数据损坏;_netdev 保证开机时网络就绪后才挂载,避免启动卡死。

5. NFSv4:伪文件系统、idmap 与 Kerberos

v4 用伪文件系统把服务端所有导出组织成一棵树,客户端挂载根 / 就能看到全部:

服务端伪文件系统(/etc/exports 里的 fsid 决定挂载点):
  /                       ← 伪根
  ├─ data/shared          ← 对应 /data/shared
  └─ home                 ← 对应 /home
客户端:mount -t nfs4 nfs-server:/ /mnt

idmap 解决 v4 的「user@domain 字符串身份」与本地 UID/GID 的映射:

# /etc/idmapd.conf(两端一致)
# [General]
# Domain = example.com
# [Mapping]
# Nobody-User = nobody
# Nobody-Group = nogroup

sudo systemctl enable --now nfs-idmapd
# 检查映射
nfsidmap -l

**Kerberos(sec=krb5)**让 NFS 从「信任 UID」升级为「密码学认证」:

# 挂载时指定安全级别
sudo mount -t nfs4 -o sec=krb5p nfs-server:/data/shared /mnt
sec 级别认证完整性加密
sysAUTH_SYS无无
krb5Kerberos无无
krb5iKerberos有无
krb5pKerberos有有(性能最低)

记忆:sys 信任客户端自报身份,krb5p 全加密最安全也最慢。跨不可信网络必须上 Kerberos;内网可信环境 sys 才可接受。

6. CIFS/SMB 服务端:Samba 配置

sudo apt install samba        # 或 dnf install samba
# /etc/samba/smb.conf
[global]
   workgroup = WORKGROUP
   server string = File Server
   security = user                 # 用户级认证
   map to guest = bad user

[shared]
   path = /srv/shared
   browseable = yes
   writable = yes
   valid users = alice, bob
   create mask = 0644
   directory mask = 0755
   force group = sharedgrp
# 创建 Samba 用户(需先有系统用户)
sudo useradd -M -s /sbin/nologin alice
sudo smbpasswd -a alice            # 设置 SMB 密码
sudo testparm                      # 校验配置语法
sudo systemctl enable --now smbd nmbd

# 放行防火墙
sudo firewall-cmd --add-service=samba --permanent && sudo firewall-cmd --reload
# 列出共享(本机)
smbclient -L localhost -U alice
段作用
[global]全局设置(认证方式、工作组)
[共享名]每个共享目录一段
valid users允许访问的用户
writable / read only写权限
create mask / directory mask新建文件/目录权限

心法:Samba 用户与系统用户是两套密码——smbpasswd 管 SMB 认证,系统密码管本地登录。用 -M -s /sbin/nologin 建「只用于 SMB、不能本地登录」的账号最安全。

7. 挂载 CIFS 客户端与凭据管理

# 交互式挂载
sudo mount -t cifs //server/shared /mnt/shared -o username=alice,uid=1000,gid=1000

# 用凭据文件(避免密码出现在命令行/ps 里)
sudo tee /root/.smbcred >/dev/null <<'EOF'
username=alice
password=secret
domain=WORKGROUP
EOF
sudo chmod 600 /root/.smbcred
sudo mount -t cifs //server/shared /mnt/shared -o credentials=/root/.smbcred,uid=1000,gid=1000,vers=3.1.1
# /etc/fstab
//server/shared /mnt/shared cifs credentials=/root/.smbcred,uid=1000,gid=1000,vers=3.1.1,_netdev,nofail 0 0
选项作用
credentials=从文件读账号密码
uid= / gid=强制挂载点归属(SMB 无 Unix UID)
vers=3.1.1协议版本(避免协商到过老的 SMB1)
iocharset=utf8中文文件名
nofail挂载失败不阻塞开机

铁律:CIFS 挂载必须显式指定 uid/gid——SMB 协议不带 Unix 身份,不指定的话所有文件都会归 root,普通用户无法写。同时锁死 vers=3.1.1,杜绝降级到不安全的 SMB1。

8. 性能调优与排错

# 性能:加大 rsize/wsize 与 nconnect
mount -t nfs4 -o rsize=1048576,wsize=1048576,nconnect=8 server:/data /mnt

# 用 dd 粗测吞吐
dd if=/dev/zero of=/mnt/test bs=1M count=1024 oflag=direct
dd if=/mnt/test of=/dev/null bs=1M iflag=direct

# 看 RPC 统计与重传
nfsstat -c
nfsiostat 1 5           # 每挂载点的 IO 延迟与吞吐(sysstat 包)
# 排错:连不上先分层确认
ping nfs-server                     # 1. 网络通不通
rpcinfo -p nfs-server               # 2. v3 的 RPC 服务是否注册
showmount -e nfs-server             # 3. 导出是否可见
sudo mount -v -t nfs4 ... /mnt      # 4. 详细挂载日志
dmesg | tail -30                    # 5. 内核报错
journalctl -u nfs-server            # 6. 服务端日志
现象原因对策
mount: access denied导出未包含该客户端/权限不足检查 /etc/exports 与 exportfs -v
写文件后读不到async 缓存 + 多客户端缓存改 sync 或加 actimeo=0
挂载点卡死无法卸载hard 挂载 + 服务端失联umount -f 或 -l(lazy)
CIFS 中文乱码缺 iocharset加 iocharset=utf8
吞吐低rsize/wsize 太小设 1MB + nconnect
文件权限全 rootCIFS 未设 uid/gid加 uid=/gid=

心法:NFS 排错按「网络 → RPC → 导出 → 挂载 → 日志」逐层确认。大多数「挂不上」是导出范围或防火墙问题,而非协议本身。

9. 安全与访问控制

# 1. 限制导出范围,绝不用 *(rw)
# /etc/exports: /data 192.168.1.0/24(rw,sync,root_squash,no_subtree_check)

# 2. 用 Kerberos 替代 AUTH_SYS
mount -t nfs4 -o sec=krb5p server:/data /mnt

# 3. 只暴露必要端口(v4 仅 2049)
sudo nft add rule inet filter input tcp dport 2049 ip saddr 192.168.1.0/24 accept

# 4. Samba 锁死协议版本,禁用 SMB1
# smb.conf [global]: server min protocol = SMB3
加固项做法
最小导出范围用 CIDR 精确到子网,禁用 *
root 保护保持 root_squash,禁 no_root_squash
加密认证NFS 用 sec=krb5p,SMB 用 SMB3 加密
协议版本禁用 NFSv2 与 SMB1
防火墙仅放行可信子网到 2049/445
审计记录挂载与访问日志
# 查看谁在挂载、谁在访问(服务端)
showmount -a
cat /proc/fs/nfsd/clients/*/info 2>/dev/null

铁律:永远不要用 *(rw,no_root_squash)。这是 NFS 最经典的高危配置,等于把服务端的 root 权限开放给整个网络;确需写权限时用「限定子网 + root_squash + UID 对齐」。

10. 速查表

需求命令
查导出showmount -e server
重载导出exportfs -ra
挂 NFSv4mount -t nfs4 server:/data /mnt
高性能挂载-o rsize=1048576,wsize=1048576,nconnect=8
安全挂载-o sec=krb5p
强制卸载umount -f /mnt 或 -l
看 RPC 统计nfsstat -c
看挂载点性能nfsiostat 1
校验 Sambatestparm
加 SMB 用户smbpasswd -a alice
挂 CIFSmount -t cifs //s/shared /mnt -o credentials=...,uid=,gid=
列 SMB 共享smbclient -L server -U user

一句话记忆:NFS 是 Unix 语义网络磁盘、CIFS 是 Windows 语义共享;NFS 服务端 exports 控权限、客户端用 hard+_netdev 保可靠、nconnect+大 rsize/wsize 提性能、sec=krb5p 保安全;Samba 用 smbpasswd 管 SMB 用户、CIFS 挂载必须锁 vers=3.1.1 并指定 uid/gid——永远别开 no_root_squash 与 *(rw)。

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「linux」更多文章

  1. PAM 认证与权限提升:模块栈、密码策略与 sudo 深入
  2. LVM 与 RAID 存储管理:卷管理、快照与软阵列运维
  3. cgroups v2 资源控制:统一层级、CPU/内存/IO 与 systemd 集成