3.16 Samba 与 NFS 文件共享

预计阅读时间:16 分钟

📖 目录

学习目标

本章围绕 Linux 下的两种主流文件共享方案:NFS(Linux 原生的网络文件系统)与 Samba(Windows 互操作标准),从协议差异到配置排错逐一展开。

  • 理解 NFSv4 与 Samba(SMB/CIFS)的核心协议差异及适用场景
  • 掌握 NFS 服务端配置(/etc/exports)与客户端挂载
  • 掌握 Samba 共享目录配置(smb.conf)与用户认证
  • 能够排查常见的连接失败、权限拒绝、挂载超时问题
  • 了解安全加固要点:端口限制、Kerberos、SMB 加密

核心知识

1.1 NFS 关键概念

术语说明
NFSv3无状态协议,依赖 portmapper(rpcbind),端口不固定,防火墙不友好
NFSv4有状态协议,单端口 2049,集成锁管理、ACL、支持 Kerberos(sec=krb5
export服务器向客户端通告的目录或文件系统
idmapdNFSv4 用户 ID 映射,解决服务器与客户端 UID/GID 不一致问题
rpcbindNFSv3 依赖的 RPC 端口注册服务
pseudo-filesystemNFSv4 用单一虚拟根(/)统一暴露所有 export

1.2 Samba 关键概念

术语说明
SMB/CIFSServer Message Block 协议,Windows 原生文件共享协议
smbdSamba 核心守护进程,提供文件/打印共享服务(TCP 445)
nmbdNetBIOS 名称服务(TCP/UDP 137-139),向后兼容,非必需
share / workgroupSamba 暴露的共享资源名与工作组名
passdb backend用户密码后端:tdbsam(本地)、ldapsam(LDAP)、ads(AD)

知识关联

  • 前置知识:rhcsa01 磁盘分区与 LVM(挂载、autofs),1.7:用户与权限管理 用户与权限管理(UID/GID 模型),5.1:Linux 安全加固 Linux 安全加固(防火墙基础)
  • 后续影响3.13:备份策略与恢复 备份策略与恢复(NFS 作为备份目标存储),4.13:服务器初始化规范 服务器初始化规范(共享存储是基础设施一部分)
  • 配套技术:NFS 跨 Linux 共享,Samba 跨 Linux/Windows 共享。autofs 实现按需自动挂载。NFSv4 只需放行 TCP 2049;Samba 需 TCP 445。

原理讲解

2.1 NFS 协议演进

NFS(Network File System)由 Sun Microsystems 于 1984 年提出,设计目标是在 Unix 系统间透明共享文件。

  • NFSv2/v3:无状态——服务器无需维护客户端打开的文件状态,崩溃后可快速恢复。缺点:锁管理需额外 lockd,端口通过 rpcbind 动态分配,防火墙配置复杂。
  • NFSv4:有状态——将锁、ACL、挂载协商统一纳入协议,单端口 TCP 2049 穿透防火墙;引入 COMPOUND 操作合并 RPC 调用以减少网络开销;支持 sec=krb5i(完整性)和 sec=krb5p(隐私加密)。

2.2 SMB/CIFS 协议

SMB 由 IBM 于 1983 年发明,微软大幅扩展后成为 Windows 网络共享基石。Samba 是其开源实现。

  • CIFS(Common Internet File System):微软在 SMB 基础上推出的增强版本,增加符号链接、大文件支持等
  • SMB2/3:Vista 后引入 SMB2 减少命令数量;SMB3 增加多通道(Multichannel)、透明故障转移(SMB Direct RDMA)和端到端加密(SMB Encryption)
  • 认证机制:NTLM(挑战-响应,不推荐)→ Kerberos(AD 域环境)→ 与 AD/LDAP 集成

2.3 NFS vs Samba 核心差异

对比维度NFSv4Samba(SMB3)
设计哲学Unix 文件语义(UID/GID、权限位、ACL)Windows 文件语义(SID、DACL、流)
传输层单一 TCP 2049TCP 445(主)+ 137-139(NetBIOS)
加密Kerberos(krb5p)SMB Encryption / Kerberos
锁机制NFSv4 内置 lease-based 锁Opportunistic Locking(oplocks)
跨平台Linux/Unix 原生,macOS 需第三方Windows/macOS 原生,Linux 需 cifs.ko 内核模块
性能低延迟,元数据操作快高延迟场景多通道优化,大文件吞吐好
鉴权集成本地 UID / LDAP / Kerberos本地 smbpasswd / LDAP / AD 域

2.4 NFS 安全模型:root_squash 与 export 选项

NFS 的权限模型建立在"信任客户端"之上:客户端发来的请求携带 UID/GID,服务器默认直接按此映射到本地文件权限。这带来两个风险——客户端伪造 root(UID 0)即可读写服务器任意文件;客户端 UID 与服务器不一致时出现文件属主错乱(由 idmapd 缓解)。因此 export 选项是 NFS 安全的第一道闸门:

选项含义建议
root_squash(默认)客户端的 root 被映射为 nobody/nogroup始终保留,除非有明确理由
no_root_squash客户端 root 保持 UID 0 权限(危险)仅限完全可信的内网管理网段
all_squash所有客户端用户映射为 nobody匿名只读共享(如软件仓库)
rw / ro读写 / 只读导出按需最小化,备份目标常只读
sync / async写请求是否等待落盘再应答sync 保数据安全;async 提性能但断电丢数据
no_subtree_check关闭子目录检查,避免导出子目录时的 inode 不匹配问题导出子目录时建议加上

2.5 Samba 安全模型:用户映射与加密

Samba 的权限链路是"Windows 访问身份 → smbpasswd 校验 → 服务器本地文件权限"。三个要点:

  • 独立口令库:Samba 密码与系统密码分离(smbpasswd/tdbsam),改系统密码不影响 SMB 访问
  • 用户映射force user / force group 把访问者统一映射到本地账号,避免权限碎片化
  • 传输加密:SMB3 提供端到端加密(smb encrypt = required),密码之外的数据内容也被加密,默认仅密码加密

示例代码

3.1 NFSv4 服务端配置

# 安装
sudo apt install nfs-kernel-server

# 创建导出的目录
sudo mkdir -p /srv/nfs/data
sudo chown nobody:nogroup /srv/nfs/data
sudo chmod 755 /srv/nfs/data

# 编辑 /etc/exports
# /srv/nfs/data    192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# /srv/nfs/backup  *.example.com(rw,sync,no_subtree_check,root_squash)

# 重新加载导出
sudo exportfs -arv  # 输出: exporting 192.168.1.0/24:/srv/nfs/data

# 查看导出状态
sudo exportfs -v  # 输出: /srv/nfs/data 192.168.1.0/24(rw,wdelay,...)

# 防火墙(NFSv4 只需 2049)
sudo ufw allow from 192.168.1.0/24 to any port 2049 proto tcp

3.2 NFS 客户端挂载

# 安装客户端工具
sudo apt install nfs-common

# 手动挂载
sudo mount -t nfs4 192.168.1.10:/srv/nfs/data /mnt/data

# /etc/fstab 永久挂载
# 192.168.1.10:/srv/nfs/data  /mnt/data  nfs4  defaults,_netdev  0  0

# 用 autofs 按需挂载
# /etc/auto.master 添加:
# /mnt/nfs    /etc/auto.nfs  --timeout=300
# /etc/auto.nfs:
# data    -fstype=nfs4    192.168.1.10:/srv/nfs/data

# 验证挂载
mount | grep nfs  # 输出: 192.168.1.10:/srv/nfs/data on /mnt/data type nfs4 (rw,relatime,vers=4.2)
df -h /mnt/data  # 输出: Filesystem Size Used Avail Use% Mounted on

3.3 Samba 服务端配置

# 安装
sudo apt install samba

# 备份默认配置
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

# 最小化 /etc/samba/smb.conf
# [global]
#    workgroup = WORKGROUP
#    server string = File Server
#    netbios name = fileserver
#    security = user
#    map to guest = bad user
#    smb encrypt = desired
#
# [shared]
#    comment = Team Shared Folder
#    path = /srv/samba/shared
#    browseable = yes
#    read only = no
#    valid users = @sambausers
#    create mask = 0660
#    directory mask = 0770
#    force user = alice
#    force group = sambausers

# 创建共享目录与用户组
sudo groupadd sambausers
sudo mkdir -p /srv/samba/shared
sudo chgrp sambausers /srv/samba/shared
sudo chmod 2770 /srv/samba/shared

# 添加 Samba 用户
sudo smbpasswd -a alice
# 将用户加入组
sudo usermod -aG sambausers alice

# 测试配置
testparm  # 输出: Load smb config files from /etc/samba/smb.conf
#        Processing section "[shared]"
#        Loaded services file OK.

# 启动服务
sudo systemctl enable --now smbd nmbd  # 输出: Created symlink ...

# 防火墙
sudo ufw allow samba
# 或具体: ufw allow 445/tcp; ufw allow 137:139/tcp 137:139/udp

3.4 Samba 客户端挂载(Linux)

# 安装 cifs 工具
sudo apt install cifs-utils

# 手动挂载
sudo mount -t cifs //192.168.1.10/shared /mnt/smb -o username=alice,uid=1000,gid=1000

# /etc/fstab
# //192.168.1.10/shared  /mnt/smb  cifs  credentials=/etc/samba/cred,uid=1000,gid=1000,_netdev  0  0

# 凭据文件 /etc/samba/cred (chmod 600)
# username=alice
# password=secret
# domain=WORKGROUP

# 列出服务器上的共享
smbclient -L //192.168.1.10 -U alice  # 输出: Sharename       Type      Comment
#         shared          Disk      Team Shared Folder

# 交互式连接
smbclient //192.168.1.10/shared -U alice  # 输出: Try "help" to get a list of possible commands.

3.5 高级挂载选项与性能调优

# NFS 性能相关挂载选项
mount -t nfs4 -o rsize=1048576,wsize=1048576,noatime,hard,timeo=600,retrans=2 \
    192.168.1.10:/srv/nfs/data /mnt/data
# rsize/wsize     读写缓冲大小(单位字节),1MiB 是常见最优值
# noatime         不更新访问时间戳,减少一半以上元数据写操作
# hard + timeo    硬挂载+重试:网络抖动不丢数据,进程等待而非报错(软挂载易丢写)
# retrans         超时重传次数

# 查看当前挂载参数
nfsstat -m   # 或 cat /proc/mounts | grep nfs

# 吞吐测试(确认优化是否生效)
dd if=/dev/zero of=/mnt/data/test.bin bs=1M count=1024 conv=fdatasync
# 输出: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 9.7 s, 110 MB/s
# (千兆网卡实际吞吐上限约 110MB/s,除非链路聚合/万兆,否则不会更高)

# SMB 挂载常用调优
mount -t cifs //192.168.1.10/shared /mnt/smb \
    -o username=alice,vers=3.0,iocharset=utf8,cache=loose,acl
# cache=loose    客户端积极缓存,读密集场景吞吐更高
# acl            启用 POSIX ACL 映射

# 写入频繁场景:增大 cifs 文件系统缓存
# (老教程里的 echo 0 > /proc/fs/cifs/LinuxExtensionsEnabled 早已随内核移除,
#   现在通过挂载选项调优即可)

3.6 NFS 安全加固完整配置

# /etc/exports 生产级示例:精确网段 + 权限最小化
/srv/nfs/projects   10.0.0.0/24(rw,sync,no_subtree_check,root_squash)
/srv/nfs/backup     10.0.1.0/24(ro,sync,no_subtree_check,all_squash)
/srv/nfs/staging    10.0.2.5(rw,sync,no_subtree_check,no_root_squash)   # 单机白名单

# 防火墙:NFSv4 只放行 2049,v3 还需要 111+rpc 动态端口(尽量不用 v3)
ufw allow from 10.0.0.0/24 to any port 2049 proto tcp

# 禁用 NFSv3 与 rpcbind 暴露(nfs.conf 或 /etc/default/nfs-kernel-server)
# RPCNFSDOPTS="-N 3"        # 只提供 v4
# 重启后 rpcbind 通常仍在监听(本机 NFS 客户端和部分 RPC 服务依赖它),
# 只需确认它没有暴露到公网网卡:
ss -tlnp | grep 111

# Kerberos 加密挂载(需要 KDC 已就绪)
# 服务端 krb5.conf + 客户端 keytab 配置完成后:
mount -t nfs4 -o sec=krb5p 192.168.1.10:/srv/nfs/data /mnt/secure
# 验证加密是否生效
nfsstat -o rpc -c | grep -A1 "krb5p"   # 有 krb5p 计数即加密流量

3.7 Samba 高级配置:加密、访问控制与审计

# smb.conf 高级片段

# [global] 加固
#    smb encrypt = required        # 强制 SMB3 加密(数据内容加密)
#    min protocol = SMB2_10        # 禁用 SMB1(永恒之蓝漏洞源头)
#    server signing = required     # 强制签名,防中间人篡改
#    restrict anonymous = 2        # 禁止匿名枚举
#    guest ok = no
#    log level = 1
#    log file = /var/log/samba/log.%m   # 按客户端主机拆分日志
#    max log size = 10240

# [projects] 精细访问控制
#    path = /srv/samba/projects
#    read only = no
#    valid users = @developers        # 仅开发组成员可访问
#    write list = alice, bob          # 只有这两人可写
#    read list = @qa                  # QA 组只读
#    hide unreadable = yes            # 对无权读的用户隐藏文件名
#    veto files = /*.tmp/*.log/    # 屏蔽临时文件(注意:veto files 中只有 * 和 ? 是通配符,. 是字面字符)

# 配置校验三步曲
testparm -s                      # 输出最终生效配置
smbstatus -S                     # 查看当前共享的打开文件
tail -f /var/log/samba/log.smbd  # 审计访问日志

# 组管理:开发组
groupadd developers && usermod -aG developers alice
smbpasswd -a alice && smbpasswd -e alice   # -e 启用账号

# 客户端验证加密连接
smbclient //192.168.1.10/projects -U alice --option="client min protocol=SMB3"
# 提示: SMB3_11 dialect 支持且加密已启用

3.8 排错流程与配置校验

# NFS 排错:从服务端到客户端逐层验证
# ① 服务端导出是否正确
sudo exportfs -v
# ② 客户端能否看到导出列表(rpcbind/v4 可达性)
showmount -e 192.168.1.10
# ③ 直接挂载看报错(mount 失败信息比 fstab 完整)
mount -t nfs4 192.168.1.10:/srv/nfs/data /mnt/data
# ④ 服务器端实时日志
tail -f /var/log/syslog | grep -i nfs
# ⑤ 内核级错误
dmesg | grep -i nfs | tail

# Samba 排错:同样从底向上
# ① 配置文件语法
testparm
# ② 服务状态与端口
systemctl status smbd && ss -tlnp | grep 445
# ③ 客户端可达性
smbclient -L //192.168.1.10 -U alice -m SMB3
# ④ 详细日志(把 log level 临时调到 3)
# log level = 3

# 启动前演练:fstab 条目用 mount -a 验证,避免重启后挂载失败
sudo mount -a && echo "all fstab mounts OK"
# 若失败:单机恢复 → 从 /etc/fstab 中注释该行 → 修复后再恢复

# 变更管理习惯:任何 smb.conf / exports 修改前先备份
sudo cp /etc/samba/smb.conf{,.bak.$(date +%Y%m%d)}
sudo cp /etc/exports{,.bak.$(date +%Y%m%d)}

常见错误

错误现象可能原因解决方案
mount.nfs: access denied by server客户端 IP 不在 export 允许范围;版本不匹配检查 /etc/exports 子网/IP 与 exportfs -v;加 -o vers=4 指定版本
mount.nfs: Operation not permittedroot_squash 将 root 映射为 nobody 后权限不足确认是否需要 no_root_squash(仅信任网络)
mount error(13): Permission denied (cifs)Samba 用户密码错误;SMB 协议版本不兼容检查 smbpasswd;指定 vers=3.0vers=2.0
mount error(112): Host is down (cifs)Samba 服务未运行;防火墙拦截端口systemctl status smbdufw status 检查 445 放行
exportfs: Failed to stat ...导出目录不存在或权限错误确认目录已创建且服务端可读
rpc.nfsd: unable to create listening socketNFS 内核模块未加载;端口被占用sudo modprobe nfsdss -tlnp | grep 2049
Samba 写入文件后属主变为 nobodyforce user / 映射配置或 mount uid= 未设force user = alice;客户端 mount 加 uid=1000,gid=1000
idmapd: nss_getpwnam: ... not foundNFSv4 ID 映射无法解析远程 UID统一两端 UID,或用 LDAP;idmapd.confDomain = 需一致
mount.nfs: Connection timed out网络不通或服务端防火墙未放行 2049ping 服务端;ss -tlnp | grep 2049 确认监听;检查 ufw
Stale file handle(访问时)服务端导出目录被删除/重建或 exportfs 变更后,客户端持有旧句柄客户端 umount -f 后重新挂载;服务端变更导出目录时避免原地删除
tree connect failed: NT_STATUS_ACCESS_DENIED用户不在 valid users 列表,或 SMB 密码未设置usermod -aG 加入正确组;smbpasswd -a user 设置 SMB 口令
NT_STATUS_CONNECTION_RESETSMB1 被禁用而客户端强制用 SMB1;或加密要求不匹配客户端指定 vers=3.0;检查 smb encrypt 与服务端 min protocol

最佳实践

实践说明理由
优先使用 NFSv4使用 vers=4 挂载,单端口 2049 简化防火墙更安全、更少依赖 rpcbind
启用 Kerberos 加密(NFSv4)sec=krb5p 提供认证+加密防止中间人攻击和裸数据泄漏
Samba 启用 SMB3 加密smb encrypt = required强制 SMB3 加密传输,对标 Kerberos
限制 export 客户端范围精确到子网而非 *最小暴露面原则
配合 autofs对非关键共享使用 autofs 按需挂载减少 fstab 负担,提高系统启动可靠度
export 使用 root_squash除非必要,始终启用 root_squash防止客户端 root 在 NFS 共享上拥有全部权限
Samba 用户独立于系统用户Samba 密码与系统密码分开管理增加一层权限隔离
定期 audit 共享权限exportfs -vsmbstatus及时发现未授权的共享或连接
NFS 挂载选项用 hard + noatimehard 保证网络抖动不丢写,noatime 减半元数据开销数据一致性与性能兼得
禁用 SMB1、强制最小协议 SMB2_10SMB1 存在远程执行漏洞(WannaCry 传播途径)min protocol = SMB2_10
修改配置前备份 + 改后校验错误配置会让整站共享失效cp smb.conf{,.bak}testparmexportfs -vmount -a 演练
按客户端拆分 Samba 日志多客户端时快速定位问题来源log file = /var/log/samba/log.%m

练习题

  1. 搭建一个 NFSv4 服务,导出一个目录 /srv/nfs/projects,仅允许 10.0.0.0/24 子网读写访问并 squash root。写出 /etc/exports 配置行和客户端挂载命令。
  2. 编写 Samba 配置文件片段:共享 /srv/samba/backup,仅允许用户 bobcarol 写入,浏览所有权为 backup_team 组,新建文件权限 0640,目录 0750
  3. 假设客户端 mount NFS 时遇到 mount.nfs: access denied by server,列出至少三个排查步骤(按顺序)并解释每个步骤的目的。
  4. 在使用 sec=krb5p 的 NFSv4 环境中,客户端与服务器时间偏差 >5 分钟会怎样?如何诊断?
  5. 设计一个方案:用 autofs 自动挂载远程 Samba 共享 //192.168.10.5/data 到本地 /mnt/remote_data,超时 10 分钟。写出 auto.masterauto.smb 的关键配置。(提示:cifs 需 option -fstype=cifs
点击查看答案
  1. /etc/exports/srv/nfs/projects 10.0.0.0/24(rw,sync,no_subtree_check,root_squash)。客户端挂载:mount -t nfs4 10.0.0.100:/srv/nfs/projects /mnt/projects
  2. [backup] comment = Backup Share; path = /srv/samba/backup; browseable = yes; read only = no; valid users = bob, carol; write list = bob, carol; create mask = 0640; directory mask = 0750; force group = backup_team
  3. exportfs -v 检查服务端导出列表——确认客户端 IP 在允许范围;② showmount -e server 检查可达性——确认网络层无防火墙拦截;③ 客户端加 -o vers=4 指定 NFSv4——排除版本协商失败。
  4. Kerberos 要求客户端与服务器时间偏差不超过 5 分钟(默认),超出则认证失败,dmesg 中会出现 krb5: clock skew too great。诊断:两端运行 date 对比时间,确认 NTP 已同步。
  5. /etc/auto.master 添加:/mnt /etc/auto.smb --timeout=600/etc/auto.smb 添加:remote_data -fstype=cifs,username=user,password=pass,vers=3.0 ://192.168.10.5/data。注意凭据安全性建议用 credentials= 文件。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 Samba 和 NFS 的区别及适用场景尝试向他人讲解
命令操作能不查文档完成 Samba/NFS 服务端配置、客户端挂载在终端实际执行
原理掌握能说出 Samba 的 SMB/CIFS 协议和 NFS 的 RPC 机制画出流程图
故障排查能独立排查共享访问被拒、权限错误、挂载失败模拟故障并修复
最佳实践能说明为什么需要为文件共享配置访问控制和日志审计对比不同方案

本章总结

本章覆盖了 NFS 与 Samba 两大共享体系:NFS 适合纯 Linux/Unix 环境的透明挂载,Samba 用于与 Windows/macOS 混用。核心要点是守住安全底线——export 选项最小化、用户映射正确、端口按需放行、定期 testparm 校验配置。

速查表

命令/操作作用
sudo exportfs -arv重新导出所有 NFS 共享,广播给客户端
sudo exportfs -v查看当前导出详情(选项、客户端列表)
mount -t nfs4 -o sec=krb5p server:/path /mnt挂载 NFSv4 并启用 Kerberos 加密
testparm验证 smb.conf 语法,显示最终生效参数
smbpasswd -a user添加或更新 Samba 用户密码
smbstatus查看当前 Samba 活跃连接和打开的文件
smbclient -L //server -U user列出远程 Samba 服务器上的所有共享名
mount -t cifs //server/share /mnt -o username=user,vers=3.0挂载 SMB3 共享到本地
sudo systemctl restart smbd重启 Samba 服务
rpcinfo -p server查看远程 RPC 端口注册情况(NFSv3 排障)
showmount -e server查看服务端导出的所有目录
nfsstat -m查看 NFS 挂载参数与统计
mount -a按 /etc/fstab 演练挂载(重启前校验)
sudo mount -t cifs //srv/share /mnt -o username=u,vers=3.0挂载 SMB3 共享(显式指定协议版本)
sudo exportfs -v审计当前导出选项

学习路径

  1. 基础:掌握 NFS 导出与挂载、Samba 配置与用户管理
  2. 安全:配置 export 选项(root_squash / no_subtree_check)、启用 SMB 加密、NFS Kerberos
  3. 集成:结合 autofs 按需挂载;与 LDAP/AD 统一用户认证
  4. 生产:Samba AD 域控制器;NFSv4.2 服务器端拷贝 + 标签继承;性能调优(rsize/wsize/readdir size)

延伸阅读

常见问题

Samba 配置后 Windows 无法访问怎么办?
① Windows 功能中确保"SMB 1.0/CIFS 文件共享支持"已启用(但注意这是安全漏洞);② 检查防火墙(ufw allow samba);③ 确认 workgroup 名称和 Windows 一致;④ Samba 配置中的 valid users 或 valid groups 限制;⑤ Windows 用 \\IP\share 而非 \\hostname\share 先排除 DNS 问题。
NFS 和 Samba 的核心区别?
NFS 是 Unix/Linux 原生文件共享协议,性能更好(内核级实现),适合 Linux↔Linux。Samba 实现 Windows 使用的 SMB/CIFS 协议,适合跨平台共享。NFSv4 开始支持 ACL 和安全机制,但配置仍比 Samba 简单。混合环境建议两者都部署,各自服务对应平台。
NFS 挂载卡住怎么办?
NFS 挂载默认是硬挂载(hard),服务器不响应时进程会卡住等待。解决方法:挂载时加 soft,intr 选项(soft 超时报错,intr 允许中断)。或者用 mount -o hard,intr,timeo=30 设置超时时间。生产环境建议 hard 挂载配合监控,NFS 不可达时避免数据损坏。
↑ 回到顶部