Jun 23, 2023 3 min read

Two Things You Should Know About Logrotate Behavior in Linux

Two Things You Should Know About Logrotate Behavior in Linux
Table of Contents

While developing a logrotate configuration for the Ghost CMS system, I learned some things about the behavior of logrotate that I wanted to make note of:

1. Creating a new log file with the create directive is often unnecessary.

I didn't need to create a new logfile with create 644 ghost ghost in the config. logrotate's man page indicates that any of the log file attributes (i.e. mode, owner, group) may be committed and the new log file will use the same values as the original, but it appears that in the extreme case where everything is omitted, indeed including the create directive itself, the new log file is created anyway with identical attributes as the original.
This makes sense if you read between the lines for the nocreate command: Why would such a command that disables new log file creation outright exist if the above wasn't the default behavior?

2. There's a difference in behavior if you call logrotate with the config /etc/logrotate.conf vs. directly using a config from /etc/logrotate.d/.

At least when it comes to the log directory permissions.

Take a look at the output of the following command when logrotate is executed while directly specifying a /etc/logrotate.d/ghost configuration:

root@PrintingPress:/var/lib/logrotate# /usr/sbin/logrotate /etc/logrotate.d/ghost --state /home/wwwserver/logrotateState -vf

considering log /var/www/ghost/content/logs/https___engineerworkshop_com_production.error.log
error: skipping /var/www/ghost/content/logs/https___engineerworkshop_com_production.error.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
logrotate error: Parent directory has insecure permissions (It's world writable or writable by group which is not "root")

The above error is a showstopper. logrotate will not rotate the logs with the above error. On the surface, this error seems solved easily enough; indeed, all of Ghost's logs in the Ghost content directory are owned by a ghost user and ghost group. So theoretically, all you would have to do to fix this is updated the configuration to include the su directive to something like su ghost ghost.

Now, this all sounds reasonable, until you realize that if you were to instead execute logrotate /etc/logrotate.conf (as root would in its daily cron job and which ultimately does still use the configurations in /etc/logrotate.d/), you get no such error. The /etc/logrotate.d/ghost logrotation executes flawlessly with no modifications necessary.

So why is there such a big difference between the two when ultimately they're both using the exact same configuration?

Well, for that answer, we have to go to logrotate's developers. kdudka gives us some valuable insight into the expected behavior here:

  1. When logrotate is run by root, which is the majority of the time, it is insecure for logrotate to write files into directories that are world writable or writable by group which is not "root"

Yes.

  1. When logrotate is run by a user other than root, it checks directory permissions as if it was run by root.

It does not. The check is only effective if su is not used and getuid() returns 0 -- see the code:

https://github.com/logrotate/logrotate/blob/44a097a2/logrotate.c#L1241

  1. The su command can be used to disable the check for directories world writable or writable by group which is not "root"

Yes.

Source: kdudka - Clarify why logrotate checks permissions when not run as root

In other words, if you're running logrotate and the log directory you're rotating is open to writes from any user other than root, you need to use su.

Okay, but that still doesn't answer the question, why don't we get this error when using /etc/logrotate.conf? We're logged in as root there.

Well, it turns out that's not quite true, in the first few lines of /etc/logrotate.conf we see that the configuration contains su root syslog.

Mystery solved!

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to The Engineer's Workshop.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.