跳转至

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

实践任务

  1. 配置 NFS 共享 /data/nfs_share,允许 192.168.1.0/24 读写访问,验证 exportfs -v 输出
  2. 在同一台或另一台 Debian 机器上挂载 NFS 共享,创建文件并确认服务端可见
  3. 配置 Samba 共享 /data/smb_share,只允许 ops 用户访问,用 testparm 验证配置无误
  4. 从 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 usersforce 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 将直接利用这些共享目录作为备份目标。