17 - 网络文件系统与共享(NFS、Samba)
前提条件
- 已完成 LVM 逻辑卷创建与挂载(
/mnt/lvmdata可用,或单独准备/data目录) - 以 root 身份登录,或 ops 用户执行
sudo -i切换至 root 环境 - 系统运行在 Debian 12 Bookworm
- 虚拟机环境:VMware Workstation Pro(建议创建第二台 Debian 虚拟机作为客户端测试)
- 防火墙已配置基础规则(本章会补充放行 NFS / Samba 所需端口)
全局参数
主机名 linuxdc,IP 192.168.1.100/24,SSH 端口 2222,运维用户 ops
NFS 与 Samba 对比
| 维度 | NFS | Samba |
|---|---|---|
| 协议 | NFS v3/v4(Linux 原生) | SMB/CIFS(Windows 原生) |
| 适用客户端 | Linux / Unix | Windows / macOS / Linux |
| 性能 | 高(内核态实现) | 中(用户态守护进程) |
| 权限模型 | Unix UID/GID 直接映射 | 独立 Samba 账号数据库 |
| 加密传输 | NFSv4 支持 Kerberos | SMB3 原生加密 |
| 典型生产场景 | K8s PV、数据库共享、集群存储 | 用户文件共享、跨平台协作 |
详细步骤
1. NFS 服务端配置
安装 NFS 服务端:
apt update
apt install -y nfs-kernel-server
创建共享目录:
mkdir -p /data/nfs_share
chown nobody:nogroup /data/nfs_share
chmod 755 /data/nfs_share
权限说明
测试环境可使用 chmod 777,生产环境应根据实际需求收紧权限。nobody:nogroup 是 NFS 匿名访问的默认映射身份,若需要精确的用户映射请配合 NFSv4 + idmapd。
配置 NFS 导出规则:
vim /etc/exports
添加以下行(允许 192.168.1.0/24 网段读写访问):
/data/nfs_share 192.168.1.0/24(rw,sync,no_subtree_check,root_squash)
NFS 导出常用选项说明:
| 选项 | 说明 | 安全建议 |
|---|---|---|
rw |
允许读写 | 按需改为 ro(只读) |
ro |
只读访问 | 优先用于无需写入的共享 |
sync |
同步写盘后响应客户端 | 生产必须开启,防数据丢失 |
async |
异步写盘,性能高但有风险 | 仅临时/测试环境可用 |
no_subtree_check |
关闭子树校验,提升性能 | 推荐启用 |
root_squash |
客户端 root 映射为 nobody(安全) |
生产推荐 |
no_root_squash |
客户端 root 保持 root 权限 | 高危,仅受信任内网可用 |
应用配置并重启服务:
exportfs -ra
systemctl restart nfs-kernel-server
systemctl enable nfs-kernel-server
exportfs -v
防火墙放行 NFS 端口(nftables 示例):
# NFS 主端口
nft add rule inet filter input tcp dport 2049 ct state new accept
nft add rule inet filter input udp dport 2049 ct state new accept
# RPC portmapper
nft add rule inet filter input tcp dport 111 ct state new accept
nft add rule inet filter input udp dport 111 ct state new accept
# 保存规则
nft list ruleset > /etc/nftables.conf
若使用 ufw:
ufw allow from 192.168.1.0/24 to any port nfs
ufw reload
检查点
exportfs -v 输出显示 /data/nfs_share 的导出规则及客户端网段。ss -tuln | grep 2049 显示 NFS 正在监听。
2. NFS 客户端挂载
在客户端机器(另一台 Debian 或同一台测试)安装工具:
apt install -y nfs-common
临时挂载并测试:
mkdir -p /mnt/nfs
mount -t nfs 192.168.1.100:/data/nfs_share /mnt/nfs
df -h /mnt/nfs
touch /mnt/nfs/testfile.txt
ls /mnt/nfs
永久挂载(/etc/fstab):
192.168.1.100:/data/nfs_share /mnt/nfs nfs defaults,_netdev,noatime 0 0
_netdev 挂载选项说明
NFS 依赖网络,若 fstab 中不加 _netdev,系统启动时会在网络就绪之前尝试挂载,导致挂载失败并进入 emergency mode,严重时卡死启动流程。_netdev 告知 systemd 将该挂载推迟到网络服务启动之后执行。
测试 fstab 配置:
umount /mnt/nfs
mount -a
df -h /mnt/nfs
检查点
mount -a 无报错,df -h /mnt/nfs 显示 NFS 服务端的磁盘空间,/mnt/nfs/testfile.txt 可见。
3. Samba 服务端配置
安装 Samba:
apt install -y samba
创建共享目录并设置权限:
mkdir -p /data/smb_share
chown ops:ops /data/smb_share
chmod 770 /data/smb_share
备份并编辑配置文件:
cp /etc/samba/smb.conf /etc/samba/smb.conf.bak-$(date +%F)
vim /etc/samba/smb.conf
在文件末尾添加共享定义:
[smb_share]
path = /data/smb_share
browseable = yes
writable = yes
valid users = ops
create mask = 0664
directory mask = 0775
force group = ops
Samba 配置关键参数说明:
| 参数 | 示例值 | 说明 |
|---|---|---|
path |
/data/smb_share |
共享的本地路径 |
browseable |
yes |
是否在网络浏览列表中可见 |
writable |
yes |
允许写入(等价于 read only = no) |
valid users |
ops |
允许访问的用户,多用户用空格分隔 |
create mask |
0664 |
新建文件的权限掩码 |
directory mask |
0775 |
新建目录的权限掩码 |
force group |
ops |
强制新建文件归属到指定组 |
检查配置语法:
testparm
设置 Samba 用户密码(必须是已存在的系统用户):
smbpasswd -a ops # 添加 Samba 账户并设置密码
smbpasswd -e ops # 启用该账户
启动并设置开机自启:
systemctl restart smbd nmbd
systemctl enable smbd nmbd
防火墙放行 Samba 端口(nftables 示例):
nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport { 139, 445 } ct state new accept
nft add rule inet filter input ip saddr 192.168.1.0/24 udp dport { 137, 138 } ct state new accept
nft list ruleset > /etc/nftables.conf
若使用 ufw:
ufw allow samba
ufw reload
检查点
testparm 无语法错误输出,systemctl status smbd 显示 active (running),smbclient -L localhost -U ops 能列出 smb_share 共享。
4. Samba 客户端访问
Windows 客户端:
在文件资源管理器地址栏输入:\\192.168.1.100\smb_share,输入用户名 ops 和 Samba 密码。
Linux 客户端:
apt install -y cifs-utils
mkdir -p /mnt/smb
mount -t cifs //192.168.1.100/smb_share /mnt/smb \
-o username=ops,vers=3.0,uid=ops,gid=ops
永久挂载(/etc/fstab,密码写入凭据文件避免明文):
vim /root/.smbcredentials
# 内容:
# username=ops
# password=your-samba-password
chmod 600 /root/.smbcredentials
fstab 条目:
//192.168.1.100/smb_share /mnt/smb cifs credentials=/root/.smbcredentials,vers=3.0,_netdev,uid=ops,gid=ops 0 0
实践任务
- 配置 NFS 共享
/data/nfs_share,允许192.168.1.0/24读写访问,验证exportfs -v输出 - 在同一台或另一台 Debian 机器上挂载 NFS 共享,创建文件并确认服务端可见
- 配置 Samba 共享
/data/smb_share,只允许 ops 用户访问,用testparm验证配置无误 - 从 Windows 宿主机或 Linux 客户端访问 Samba 共享,上传、下载文件并验证权限
自测问题
1. NFS 中 no_root_squash 选项的作用和安全风险是什么?
默认的 root_squash 会将客户端发来的 root 用户(UID=0)映射为服务端的 nobody 用户,使客户端 root 失去对 NFS 共享的特权操作能力。no_root_squash 取消此映射,客户端 root 以服务端 root 身份操作共享目录,拥有完整权限。
安全风险:若攻击者控制了任何客户端机器,即可以 root 身份读写 NFS 服务端的所有共享文件,包括覆盖二进制文件、修改配置、写入 SSH 公钥等高危操作。生产环境应使用 root_squash,仅在受控内网的受信任节点(如备份服务器)确有需要时才考虑 no_root_squash。
2. Samba 的 valid users 和 force group 参数分别控制什么?
| 参数 | 作用 | 示例 |
|---|---|---|
valid users |
白名单:只有列出的用户才能访问该共享(未列出的用户即使密码正确也被拒绝) | valid users = ops admin @devteam |
force group |
强制将该共享内所有新建文件 / 目录的所属组设置为指定组,无论创建者实际属于哪个组 | force group = ops |
两者配合使用可实现:只有 ops 用户能登录,且所有文件自动归属 ops 组,方便团队成员共同管理。
3. 如何让 NFS 客户端在网络不可达时自动挂载失败而不卡住开机?
在 /etc/fstab 的挂载选项中加入 _netdev:
192.168.1.100:/data/nfs_share /mnt/nfs nfs defaults,_netdev,noatime 0 0
_netdev 标记该文件系统依赖网络,systemd 会将其挂载推迟到 network-online.target 完成之后。若网络超时或 NFS 服务端不可达,挂载失败不会阻塞系统进入多用户模式,只在日志中记录错误。可进一步加 soft,timeo=30 选项限制等待时间。
4. 生产环境中 NFS 和 Samba 哪个更适合 Windows 客户端访问?
Samba(SMB/CIFS 协议)更适合 Windows 客户端。Windows 原生支持 SMB 协议,无需安装额外驱动,在文件资源管理器中即可像本地磁盘一样使用,支持 Windows ACL、文件锁、DFS 等特性。NFS 客户端虽然 Windows 也有(Services for NFS),但需要额外安装组件,权限映射复杂,且性能和兼容性通常不如 Samba。因此:Linux ↔ Linux 共享优先 NFS;涉及 Windows 客户端的场景优先 Samba。
总结
NFS 是 Linux 集群与容器环境中高效文件共享的标准方式,Samba 是跨平台(尤其是 Windows)文件共享的事实标准。生产中 NFS 常用于 Kubernetes PV、数据库数据目录共享;Samba 用于用户文件共享和跨平台协作。后续备份章节的 rsync / borg 将直接利用这些共享目录作为备份目标。