On most distributions, two group memberships cover nearly everything an analyst needs: adm for the text logs in /var/log on Debian and Ubuntu, and systemd-journal for the full system journal. Add the account with sudo usermod -aG adm,systemd-journal <user> and start a new login session. A few logs stay root-only by design, notably /var/log/secure and /var/log/messages on Red Hat-family systems and everything under /var/log/audit. For those, use narrowly scoped sudo, not a root shell.
Giving someone root just so they can read logs is the kind of shortcut that shows up in the next audit, or the next incident. This guide covers the least-privilege way, plus the traps that make “just add them to a group” less simple than it sounds.
Who can read what
| Log | Debian / Ubuntu | RHEL / Rocky / Alma |
|---|---|---|
| /var/log/auth.log / /var/log/secure | root and adm | root only |
| /var/log/syslog / /var/log/messages | root and adm | root only |
| Web server logs | root and adm | root only (the httpd log directory is locked) |
| System journal (journalctl) | root, systemd-journal, adm | root, systemd-journal, wheel |
| /var/log/audit/audit.log | root only | root only |
Exact ownership varies with distribution and version, so check on the box itself:
id
ls -l /var/log/auth.log /var/log/secure 2>/dev/null
getfacl /var/log/journal 2>/dev/null
Option 1: Group membership
sudo usermod -aG adm,systemd-journal analyst
Two details matter. The -a is not optional: without it, usermod -G replaces the user’s groups instead of adding to them. And group changes only apply to new sessions. Log out and back in, or start a fresh login shell, before testing. “I added the group and it still says permission denied” is almost always an old session.
On Red Hat-family systems, adm doesn’t unlock /var/log/secure or /var/log/messages. Those files are root-only there. Use Option 2 or 3.
Option 2: Narrow sudo for root-only logs
Grant specific commands, not a shell. Create /etc/sudoers.d/log-readers with visudo -f:
%logreaders ALL=(root) NOPASSWD: /usr/sbin/ausearch, /usr/local/bin/read-secure-log
read-secure-log is a small root-owned script (mode 0755, owned by root) that does exactly one thing:
#!/bin/sh
exec /usr/bin/zcat -f /var/log/secure /var/log/secure-*
Why a wrapper instead of cat /var/log/secure* in sudoers? Because a * in a sudoers argument matches anything, spaces included. cat /var/log/secure /etc/shadow matches cat /var/log/secure*. A wrapper with no arguments has no such hole.
Don’t grant journalctl through sudo. It opens a pager (less), and !sh inside less gives you a root shell. For journal access, use the systemd-journal group instead.
Option 3: Group ownership that survives rotation
Setting an ACL directly works until the next rotation: sudo setfacl -m g:logreaders:r /var/log/secure. Then the file is recreated, and the ACL is gone. To make access stick, have new files created with the right group in the first place, in both places that create them:
- logrotate, in the file’s stanza: create 0640 root logreaders
- rsyslog, on the action that writes it: action(type=”omfile” file=”/var/log/secure” fileGroup=”logreaders” fileCreateMode=”0640″)
Test it with logrotate -f on a non-production box before rolling it out.
Containers
Don’t add analysts to the docker group just to read container logs. Membership in docker is effectively root on that host. Get container logs from your log collector or SIEM instead, or ask the platform team for read-only access there.
When it goes wrong
| Symptom | Likely cause | Fix |
|---|---|---|
| Still Permission denied after usermod | Old session | Log out and back in |
| User lost other groups | usermod -G without -a | Re-add them; always use -aG |
| journalctl shows only the user’s own logs | Not in systemd-journal (or adm / wheel) | Add the group; new session |
| Access worked yesterday, not today | ACL lost when the log rotated | Use Option 3 |
| adm doesn’t help with /var/log/secure | Red Hat-family files are root-only | Use Option 2 or 3 |