确认SELinux是否拦截需查avc: denied日志,用ausearch -m avc -ts recent或grep avc: denied /var/log/audit/audit.log;关键看scontext、tcontext、tclass和操作;上下文不匹配优先用chcon临时修复或semanage fcontext+restorecon永久修复;布尔值未启用(如httpd_can_network_connect_db)是常见原因,需setsebool -P开启;audit2allow仅作最后手段,须人工审核策略。

SELinux 不是“开启就能用”,而是必须先切到 permissive 模式看日志、调上下文和布尔值,再切回 enforcing——直接开 enforcing 十有八九服务起不来。
怎么确认 SELinux 真正在拦你?
别猜,直接查日志。只要看到 avc: denied,就是 SELinux 在拒绝访问:
- 运行
ausearch -m avc -ts recent快速抓最近的拒绝记录 - 或翻
/var/log/audit/audit.log,搜avc: denied行 - 关键字段要看:
scontext(进程类型,如httpd_t)、tcontext(目标类型,如user_home_t)、tclass=file、操作(如{ read }) - 如果
ps -eZ | grep httpd显示的上下文里没有httpd_t,说明进程压根没进 SELinux 管控域——可能服务根本没按 SELinux 规则启动
文件访问被拒?先看上下文,再决定用 chcon 还是 semanage fcontext
ls -Z /path 是第一步。比如你把网站目录挪到 /srv/myapp,ls -Z 发现类型是 default_t,而 httpd_t 默认不允许读它。
- 临时救急:
chcon -R -t httpd_sys_content_t /srv/myapp(重启或restorecon后失效) - 永久生效:必须用
semanage fcontext -a -t httpd_sys_content_t "/srv/myapp(/.*)?",再跑restorecon -Rv /srv/myapp - 漏掉正则里的
(/.*)?,子目录还是default_t,照样被拒 -
semanage fcontext -l | grep myapp可验证规则是否已注册进策略库
端口、网络、数据库连不上?先查 setsebool 布尔值
80% 的“服务起不来”问题,不是缺策略,而是布尔开关关着。比如 PHP 连 MySQL 失败,httpd_can_network_connect_db 默认是 off。
- 查所有布尔值:
getsebool -a | grep httpd或semanage boolean -l | grep httpd - 临时开:
setsebool httpd_can_network_connect_db on - 生产环境务必加
-P永久写入:setsebool -P httpd_can_network_connect_db on - 开了
httpd_can_network_connect却连不了 DB?大概率忘了开配套的httpd_can_network_connect_db - FTP 匿名上传失败?
ftpd_anon_write和ftp_home_dir得一起开,且文件类型还得是public_content_rw_t
能不能用 audit2allow 自动生成策略?
能,但它是最后一招,不是首选。它只做“最小放行”,不判断合理性。
- 生成模块:
ausearch -c 'myservice' -m avc -ts today | audit2allow -M mypolicy - 安装:
semodule -i mypolicy.pp - 风险:它可能允许不该允许的操作(比如给
httpd_t加了execmem),扩大攻击面 - 更安全的做法:先用
sealert -a /var/log/audit/audit.log(需装setroubleshoot)看建议,再手动调上下文或布尔值 - 真要用
audit2allow,务必人工审mypolicy.te再编译
最常被忽略的一点:改完上下文或布尔值后,必须重启对应服务(比如 systemctl restart httpd),否则新标签或开关不会被进程加载;而 restorecon 和 setsebool -P 本身不触发服务重载。


















