logrotate的create指令必须配对服务运行身份,格式为create 640 user group,否则新日志权限不匹配导致无法写入;同时需配合postrotate重载服务句柄,并注意SELinux、systemd保护机制及配置加载顺序。

logrotate 的 create 指令没配对服务运行身份
日志切割后权限是 root:root,但你的服务(比如 nginx、myapp)是以非 root 用户(如 www-data、myuser)运行的,新日志文件一创建就无法写入——这是最常见原因。logrotate 默认不创建新文件,也不改权限;一旦你加了 create 却只写了 644 或漏掉属主属组,就会继承默认行为或 fallback 到 root:root。
-
create必须带三个参数:create 640 myuser mygroup,顺序不能错:权限、属主、属组 - 属主必须和进程实际运行用户一致(查法:
ps -o user,comm -C nginx或systemctl show --property=User nginx.service) - 若服务用 systemd 管理且未显式设
User=,默认以root运行,此时create 640 root root是安全的;但多数 Web 服务已明确降权,不能照搬 - 权限值别硬套 644:640 表示属主可读写、属组可读、其他不可访问,既保安全又允运维组(如
adm)分析日志
服务没收到轮转通知,还在往旧文件句柄写
即使 create 配对了,如果服务没重载日志文件句柄,它会继续往已被重命名的旧文件(如 app.log.1)里追加——看起来“新日志空着”,其实是写偏了。这不是权限问题,而是信号没发到位。
- 确认配置中是否含
postrotate+endscript块,且里面调用了正确 reload 命令 - 常见错误写法:
/bin/kill -USR1 `cat /var/run/nginx.pid`——但 Nginx 在 systemd 下推荐用systemctl kill --signal=USR1 nginx或直接systemctl reload nginx - 避免在
postrotate中用service nginx reload:某些发行版该命令不触发真正的 reload,只是 restart - 加
sharedscripts:多个日志路径共用同一份postrotate脚本时必需,否则每个路径都单独执行一遍,可能重复发信号
SELinux 或 systemd 的上下文覆盖了 logrotate 权限
尤其在 RHEL/CentOS/Fedora 上,即使 create 640 myuser mygroup 生效了,新日志文件也可能被 SELinux 自动打上错误类型(如 admin_home_t),导致服务因策略拒绝写入;systemd 服务若启用了 ProtectSystem= 或 ReadOnlyPaths=,也会拦截写操作。
- 检查上下文:
ls -Z /var/log/myapp/app.log,正常应为system_u:object_r:var_log_t:s0 - 临时修复:
sudo restorecon -v /var/log/myapp/app.log;长期方案是在 logrotate 配置末尾加prerotate执行restorecon - 查 systemd 限制:
systemctl show --property=ProtectSystem,ReadOnlyPaths myapp.service,若返回strict或含/var/log,需调整 service 文件 - 不要关 SELinux:用
ausearch -m avc -ts recent | audit2why定位具体拒绝项,再用audit2allow生成策略
配置被其他文件覆盖或未生效
logrotate 加载顺序是:先读 /etc/logrotate.conf,再按字母序加载 /etc/logrotate.d/*。如果你的服务配置在 /etc/logrotate.d/myapp,但 /etc/logrotate.conf 里有全局 create,它会覆盖掉你本地的设置——而且不会报错。
- 运行
logrotate -d /etc/logrotate.conf(debug 模式)看实际解析出的create值是什么 - 在服务专属配置里显式写全
create,不要依赖全局配置 - 确保文件名不带点或波浪线(如
myapp.conf~),logrotate 会跳过它们 - 检查 cron 是否真在跑:
systemctl status cron或grep logrotate /var/log/syslog
真正卡住人的地方,往往不是 create 少写了哪个参数,而是服务身份、信号通知、安全模块、配置加载这四层之间存在隐性耦合——改完一行配置,得同步验证三处状态才敢说修好了。

















