选项:下面是可用的各个选项含义:
ro: 即为:read only,也就是客户端主机对共享资源仅仅有读权限。
rw: 即为:read write,也就是客户端主机对共享资源有读、写权限。
no_root_squash: 信任客户端,根据用户UID进行判断,如果登入到NFS主机的用户是ROOT,那么此用户就拥有对共享资源的最高权限。此参数很不安全,建议不要使用。
root_squash:系统预设值,当登入NFS主机的用户root 时,那么这个使用者的权限将被縮成为匿名使用者,也就是它的UID与GID都会变成nobody身份;只有可读权限,系统以此为预设值,显然是为了安全考虑。
all_squash:不管登陆NFS主机的是什么用户,都会将共享文件的UID和GID映射为匿名用户nobody。
no_all_squash:系统预设值,保留共享文件的UID和GID默认权限。也就是客户端用户的UID以及GID和服务端共享文件UID和GID相同时,才有对共享文件的读写权限。这种选项保证了共享文件的用户和组权限不会改变。
sync:资料同步写入磁盘中。默认选择。
async:资料会先暂时存放在内存中,不会直接写入硬盘。
一、ro vs rw(读写权限)
1.1 ro(只读)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(ro,sync,no_root_squash)
客户端操作结果:
# 挂载
mount -t nfs 192.168.1.10:/nfs_test /mnt
# 读操作 成功
cat /mnt/test.txt
# 输出: NFS测试文件
# 写操作 失败
touch /mnt/newfile.txt
# touch: cannot touch '/mnt/newfile.txt': Read-only file system
# 删除操作 失败
rm -f /mnt/test.txt
# rm: cannot remove '/mnt/test.txt': Read-only file system
1.2 rw(读写)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,sync,no_root_squash)
客户端操作结果:
# 挂载
mount -t nfs 192.168.1.10:/nfs_test /mnt
# 读操作 成功
cat /mnt/test.txt
# 输出: NFS测试文件
# 写操作 成功
touch /mnt/client_create.txt
ls /mnt/client_create.txt
# 输出: /mnt/client_create.txt
# 删除操作 成功
rm -f /mnt/client_create.txt
二、root_squash vs no_root_squash(root用户映射)
2.1 no_root_squash(信任root)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,sync,no_root_squash)
# 服务端查看文件权限
ls -n /nfs_test/test.txt
# -rw-r--r-- 0 0 22 Feb 11 10:00 /nfs_test/test.txt
# UID=0, GID=0 (root)
客户端root操作结果:
# 客户端以root身份操作
whoami
# root
# 创建文件
touch /mnt/root_file.txt
ls -n /mnt/root_file.txt
# -rw-r--r-- 0 0 0 Feb 11 10:05 /mnt/root_file.txt
# 客户端root在服务端创建的文件 UID=0, GID=0 (root)
# 删除服务端root文件
rm -f /mnt/test.txt 成功
# 服务端原本root拥有的文件被删除
2.2 root_squash(默认)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,sync,root_squash)
exportfs -ra
客户端root操作结果:
# 客户端以root身份操作
whoami
# root
# 创建文件
touch /mnt/root_squash_test.txt
ls -n /mnt/root_squash_test.txt
# -rw-r--r-- 65534 65534 0 Feb 11 10:10 /mnt/root_squash_test.txt
# 客户端root被映射为nfsnobody (UID=65534, GID=65534)
# 尝试删除服务端root文件
rm -f /mnt/test.txt
# rm: cannot remove '/mnt/test.txt': Permission denied
# 客户端root无法删除服务端root文件
服务端验证:
# 服务端查看映射用户
id nfsnobody
# uid=65534(nfsnobody) gid=65534(nfsnobody) groups=65534(nfsnobody)
# 查看文件所有者
ls -l /nfs_test/root_squash_test.txt
# -rw-r--r-- 1 nfsnobody nfsnobody 0 Feb 11 10:10 root_squash_test.txt
三、all_squash vs no_all_squash(所有用户映射)
3.1 all_squash(全部映射)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,sync,all_squash)
# 服务端创建测试用户
useradd -u 1001 testuser1
chown testuser1:testuser1 /nfs_test/test.txt
ls -l /nfs_test/test.txt
# -rw-r--r-- 1 testuser1 testuser1 22 Feb 11 10:15 /nfs_test/test.txt
客户端不同用户操作结果:
# 客户端创建不同用户
useradd -u 2001 clientuser1
useradd -u 2002 clientuser2
# 客户端user1操作
su - clientuser1
touch /mnt/client1_file.txt
ls -n /mnt/client1_file.txt
# -rw-r--r-- 65534 65534 0 Feb 11 10:20 /mnt/client1_file.txt
# clientuser1 被映射为 nfsnobody
# 客户端user2操作
su - clientuser2
touch /mnt/client2_file.txt
ls -n /mnt/client2_file.txt
# -rw-r--r-- 65534 65534 0 Feb 11 10:22 /mnt/client2_file.txt
# clientuser2 也被映射为 nfsnobody
# root操作
su - root
touch /mnt/root_file.txt
ls -n /mnt/root_file.txt
# -rw-r--r-- 65534 65534 0 Feb 11 10:25 /mnt/root_file.txt
# root 同样被映射为 nfsnobody
# 访问服务端testuser1的文件
cat /mnt/test.txt
# cat: /mnt/test.txt: Permission denied
# 所有客户端用户都被映射为nfsnobody,无权访问testuser1的文件
3.2 no_all_squash(默认,保留UID)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,sync,no_all_squash)
# 服务端创建用户
useradd -u 1001 serveruser
chown serveruser:serveruser /nfs_test/server_file.txt
客户端操作结果:
# 场景1: 客户端有相同UID用户 可访问
useradd -u 1001 clientuser
su - clientuser
cat /mnt/server_file.txt 成功
touch /mnt/client_on_server.txt
ls -l /mnt/client_on_server.txt
# -rw-r--r-- 1 1001 1001 0 Feb 11 10:30 /mnt/client_on_server.txt
# 场景2: 客户端UID不同 无权限
useradd -u 2002 otheruser
su - otheruser
cat /mnt/server_file.txt
# cat: /mnt/server_file.txt: Permission denied
touch /mnt/other_file.txt
# touch: cannot touch '/mnt/other_file.txt': Permission denied
四、sync vs async(写入模式)
4.1 sync(同步写入)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,sync,no_root_squash)
exportfs -ra
客户端测试:
# 清空缓存
echo 3 > /proc/sys/vm/drop_caches
# 测试写入
time dd if=/dev/zero of=/mnt/sync_test bs=1M count=100
# 服务端立即看到数据
ls -lh /nfs_test/sync_test
# -rw-r--r-- 1 root root 100M Feb 11 10:35 /nfs_test/sync_test
# 数据已写入磁盘
# 断电测试模拟(服务端强制重启)
sync # 即使不执行,数据也已持久化
4.2 async(异步写入)实际结果
服务端配置:
# /etc/exports
/nfs_test 192.168.1.100(rw,async,no_root_squash)
exportfs -ra
客户端测试:
# 清空缓存
echo 3 > /proc/sys/vm/drop_caches
# 测试写入
time dd if=/dev/zero of=/mnt/async_test bs=1M count=100
# 速度明显比sync快
# 立即查看服务端文件
ls -lh /nfs_test/async_test
# -rw-r--r-- 1 root root 100M Feb 11 10:40 /nfs_test/async_test
# 元数据已写入,但数据可能在内存中
# 模拟服务端突然断电(危险测试)
# 重启服务端后检查文件
ls -l /nfs_test/async_test
# 可能文件损坏或大小不正确
# 实际生产环境遇到过数据丢失!
性能对比结果:
# sync 测试结果
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 2.35 s, 44.6 MB/s
# async 测试结果
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.85 s, 123 MB/s
# async 比 sync 快约 3倍
五、选项组合实际应用场景
场景1:公共只读资源服务器
# 配置目标:任何人都只能读,不能写
/iso_images *(ro,sync,all_squash,anonuid=65534,anongid=65534)
# 实际效果:
# 所有客户端可读
# 无人可写
# root也被限制
# 文件权限统一为nfsnobody
场景2:内部开发服务器
# 配置目标:开发团队可读写,root不被信任
/dev_data 192.168.1.0/24(rw,sync,root_squash,no_all_squash)
# 实际效果:
# 开发人员UID匹配时正常读写
# root被降权为nfsnobody
# 需要在服务端和客户端同步用户UID
场景3:公共上传目录
| 参数 | 含义 | 说明 |
|---|---|---|
/uploads | 共享目录 | 服务端要共享的目录路径 |
* | 所有客户端 | 允许任何 IP 的客户端访问(生产环境危险!) |
rw | 读写权限 | 客户端可以读写 |
sync | 同步写入 | 数据写入磁盘后才返回成功 |
all_squash | 所有用户压缩 | 所有客户端用户都映射成匿名用户 |
anonuid=2000 | 匿名 UID | 映射后的用户 ID 为 2000 |
anongid=2000 | 匿名 GID | 映射后的组 ID 为 2000 |
# 配置目标:所有人都可上传,统一权限管理
/uploads *(rw,sync,all_squash,anonuid=2000,anongid=2000)
# 实际效果:
# 任何用户创建的文件都属于uid=2000
# 文件互相可覆盖(权限统一)
# 适合匿名FTP风格的目录
场景4:高性能计算集群
# 配置目标:追求性能,接受一定风险
/scratch 10.0.0.0/8(rw,async,no_root_squash,no_all_squash)
# 实际效果:
# 写入速度快3倍
# 断电可能丢数据
# root用户有完全控制权
六、选项选择决策表
| 业务需求 | 推荐选项 | 不推荐选项 | 原因 |
|---|---|---|---|
| 普通文件服务器 | rw,sync,root_squash | async,no_root_squash | 数据安全优先 |
| web静态资源 | ro,all_squash | rw,no_root_squash | 防篡改 |
| 数据库备份存储 | rw,sync,no_all_squash | async | 必须保证数据一致性 |
| 开发测试环境 | rw,async,root_squash | no_root_squash | 追求速度,安全次要 |
| 匿名上传目录 | rw,sync,all_squash,anonuid=2000 | no_all_squash | 统一权限管理 |
| 家目录共享 | rw,sync,root_squash,no_all_squash | all_squash | 保留用户隔离 |
| 只读软件仓库 | ro,sync,all_squash | rw,no_root_squash | 防误删 |
七、一句话记忆每个选项
| 选项 | 一句话记忆 |
|---|---|
| ro | 只能看,不能动 |
| rw | 既能看,也能改 |
| no_root_squash | 让root当上帝,危险! |
| root_squash | 把皇帝贬为平民 |
| all_squash | 众生平等,都是nobody |
| no_all_squash | 认UID不认人 |
| sync | 刀下见菜,立即落盘 |
| async | 先记帐,后付款 |
实际结果总结:
- root_squash 是安全底线,必须开
- sync 是数据保障,推荐开
- all_squash 是权限熔炉,公共目录开
- no_all_squash 是身份验证,用户目录开
发表回复