先确认SELinux是否拦截:运行sestatus看是否为Enforcing模式,再用ausearch -m avc -ts recent | grep 服务名或journalctl -t kernel | grep avc查AVC拒绝日志,出现avc: denied即坐实;临时验证可setenforce 0后重启服务,若成功即为SELinux上下文不匹配所致。

怎么看是不是SELinux在拦你
服务启动失败但日志只报 Permission denied,文件权限、属主、端口、配置都对得上——这时候别急着改 chmod 或 chown,先查 SELinux。运行 sestatus 看输出是不是 enforcing;再立刻执行 ausearch -m avc -ts recent | tail -10(或 journalctl -t kernel | grep avc | tail -10),只要看到 avc: denied 行,基本就坐实了。
典型线索包括:
-
scontext=system_u:system_r:httpd_t:s0(进程上下文)和tcontext=system_u:object_r:default_t:s0(目标文件上下文)不匹配 -
tclass=dir或tclass=file后跟着{ read open search }等被拒动作 - 路径是你自己放的非标准位置,比如
/srv/myapp、/opt/app
为什么chcon临时改了还是不行
chcon -t httpd_sys_content_t /srv/myapp 这类命令确实能快速验证问题,但它只改当前文件/目录的上下文,不递归子项,也不持久——系统重启、restorecon 执行、甚至某些 RPM 更新后都会被重置。
真正要稳住,得走策略注册流程:
- 先用
semanage fcontext -l | grep httpd_sys确认已有规则范围,避免冲突 - 添加永久规则:
semanage fcontext -a -t httpd_sys_content_t "/srv/myapp(/.*)?"(注意正则括号和问号必须转义或加引号) - 立即生效:
restorecon -Rv /srv/myapp,它会按新规则批量修正所有匹配路径的上下文
漏掉 restorecon 是常见坑——semanage 只登记规则,不自动重刷上下文。
nginx 或 php-fpm 写 storage 目录失败怎么办
读取静态资源用 httpd_sys_content_t,但写入 storage、runtime 这类目录需要更细的策略:进程得有写权限,文件上下文也得允许写。
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
分两步处理:
- 给目录设写入型上下文:
semanage fcontext -a -t httpd_sys_rw_content_t "/srv/myapp/storage(/.*)?" - 启用对应布尔值:
setsebool -P httpd_can_network_connect_db on(如果连 DB)、setsebool -P httpd_read_user_content on(如果读用户家目录) - 别忘了
restorecon -Rv /srv/myapp/storage
注意:httpd_sys_rw_content_t 不等于开放所有写操作,它只允许 httpd_t 类型进程执行策略明确授权的写行为,比盲目 chcon -t default_t 安全得多。
audit2allow 生成的 .te 文件到底能不能直接用
当 avc 日志里出现大量新拒绝项,且你确认是合理访问(比如 PHP 需要访问某个 socket 路径),可以用 audit2allow -a -M myapp 生成模块。但生成的 myapp.te 默认是宽松策略,常含冗余规则。
关键检查点:
- 打开
myapp.te,删掉所有allow行里带sysadm、unconfined或admin字样的规则——这些是危险信号 - 确保主体类型(如
httpd_t)和客体类型(如var_run_t)是你真实环境中的,不是模板默认值 - 安装前先测试:
semodule -i myapp.pp,再跑一次服务,观察是否还有新 avc 拒绝
最易被忽略的是:audit2allow 基于“已发生的拒绝”生成策略,但它不会自动覆盖旧模块。如果之前装过同名模块,得先 semodule -r myapp 再重装,否则新规则可能被屏蔽。

















