selinux导致nfs permission denied需按四步排查:先用getenforce和sestatus确认是否enforcing模式;再查nfs_export_all_rw等布尔值并启用;接着用ls -z检查共享目录上下文,设为public_content_rw_t并restorecon;最后通过ausearch+audit2why分析avc拒绝日志。

SELinux 是 Linux 中常被忽略但影响极深的一环,尤其在 NFS 挂载出现 Permission denied 时,它可能悄无声息地拦截访问,而日志里只显示模糊报错。排查关键不是“关不关 SELinux”,而是确认它是否在干预、干预在哪一层、如何精准放行。
确认 SELinux 是否处于 enforcing 模式
先看当前状态,避免误判:
-
getenforce—— 返回 Enforcing 才需继续排查;若为 Permissive 或 Disabled,问题大概率出在别处 -
sestatus—— 查看完整模式、策略类型(如 targeted)及当前上下文
检查 NFS 相关的布尔值开关
SELinux 不靠“全开/全关”,而是通过布尔值控制服务行为。NFS 共享依赖几个关键开关:
-
nfs_export_all_ro:允许导出只读 NFS 共享 -
nfs_export_all_rw:允许导出读写 NFS 共享(挂载后写入失败时最常需开启) -
use_nfs_home_dirs:若共享的是用户家目录类路径,建议启用
查看并临时启用(重启后仍生效加 -P):
getsebool nfs_export_all_rw<br>setsebool -P nfs_export_all_rw 1
验证共享目录的 SELinux 上下文
NFS 服务端导出的目录,其 SELinux 类型必须是 public_content_t 或 public_content_rw_t(读写场景)。默认创建的目录通常是 default_t,会被拒绝导出。
- 查当前上下文:
ls -Z /srv/nfs/share - 正确设置(读写):
sudo semanage fcontext -a -t public_content_rw_t "/srv/nfs/share(/.*)?" - 应用变更:
sudo restorecon -Rv /srv/nfs/share
注意:semanage 在某些系统需先安装 policycoreutils-python-utils。
抓取并分析 SELinux 拒绝日志
最直接证据来自审计日志:
- 实时监控拒绝事件:
sudo ausearch -m avc -ts recent | audit2why - 或过滤 NFS 相关:
sudo ausearch -m avc -m user_avc -ts today | grep -i nfs - 常见报错关键词:
avc: denied { export } for ... scontext=system_u:system_r:nfsd_t:s0—— 表明 NFS 守护进程被禁止导出该路径
用 audit2allow 可生成自定义策略模块(慎用于生产):
sudo ausearch -m avc -ts recent | audit2allow -M mynfsfix<br>sudo semodule -i mynfsfix.pp
客户端挂载时的 SELinux 注意点
客户端同样受 SELinux 约束,尤其是挂载点目录:
- 挂载前确保本地挂载点上下文兼容:
ls -Z /mnt/nfs,应为system_u:object_r:mnt_t:s0或default_t - 若挂载后无法访问文件,检查是否触发了
virt_sandbox_use_nfs(容器场景)或domain_can_network_connect(受限域)等扩展策略 - 临时测试可设挂载点为
context=system_u:object_r:public_content_t:s0,但非长期方案











