When working with rsyslog, the $FileCreateMode
directive is commonly used to define default permissions for newly created log files. However, this global setting affects all log files equally, which becomes problematic when you need different permission sets for specific log files - a common requirement in enterprise environments with strict security policies.
Rsyslog provides template-based file creation that allows granular permission control:
# Default permissions for most logs
$FileCreateMode 0640
# Special permissions for secure.log
$template SecureLogTemplate,"/var/log/secure.log"
$template SecureLogPerms,"0644"
if $programname == 'secure' then {
action(type="omfile"
FileCreateMode="0644"
file="/var/log/secure.log")
}
For more complex scenarios, combine templates with property filters:
template(name="AppLogTemplate" type="string" string="/var/log/%programname%.log")
template(name="AppLogPerms" type="string" string="0640")
if $programname == 'payment' then {
action(type="omfile"
template="AppLogTemplate"
FileCreateMode="0640"
fileCreatePath="/var/log/payment.log")
}
if $programname == 'api' then {
action(type="omfile"
template="AppLogTemplate"
FileCreateMode="0660"
fileCreatePath="/var/log/api.log")
}
While implementing custom permissions:
- Never set world-writable permissions (0222) on sensitive logs
- Consider SELinux contexts when available
- Use group permissions (e.g., 0660) for shared log access
After configuration changes:
# Verify rsyslog configuration
rsyslogd -N1
# Restart rsyslog
systemctl restart rsyslog
# Check resulting permissions
ls -la /var/log/
While rsyslog's $FileCreateMode
directive provides a global setting for log file permissions, many sysadmins encounter scenarios where different log files require distinct permission schemes. A web server's access logs might need world-readable permissions for monitoring tools, while authentication logs should remain strictly root-access only.
Rsyslog offers the $FileOwner
, $FileGroup
, and $FileCreateMode
parameters that can be scoped to specific rules:
# Global default (secure baseline)
$FileCreateMode 0640
# Special case for web logs
if $programname == 'nginx' then {
$FileCreateMode 0644
/var/log/nginx/access.log
stop
}
# Restricted auth logs
if $msg contains 'authentication' then {
$FileCreateMode 0600
/var/log/secure/auth.log
stop
}
For more complex scenarios, combine templates with permission controls:
template(name="SecureLogTemplate" type="string"
string="/var/log/secure/%programname%.log")
template(name="AppLogTemplate" type="string"
string="/var/log/apps/%programname%.log")
if $syslogtag contains 'auth' then {
$FileCreateMode 0600
action(type="omfile" dynaFile="SecureLogTemplate")
} else {
$FileCreateMode 0644
action(type="omfile" dynaFile="AppLogTemplate")
}
When dealing with dynamically named files (e.g., dated logs), ensure permission settings persist across rotations:
# Works with logrotate's create directive
$template DailySecureLog,"/var/log/secure-%$YEAR%-%$MONTH%-%$DAY%.log"
$FileCreateMode 0600
:msg, contains, "sudo" ?DailySecureLog
Verify rsyslog's effective permissions with:
rsyslogd -N1 # Test configuration
ps aux | grep rsyslog # Check running user
namei -l /path/to/logfile # Inspect permission chain