How to Monitor a chown or chmod command in CentOS/RHEL

The Ask

The directory/file ownership and permissions are getting changed by unknown users. How can we track these changes and find out who is changing the permissions/ownerships?

The Solution

The Linux system has a preinstalled tool named auditd, which is responsible for writing audit records on to the disk. This means that system users will be able to run auditd to configure rules and alerts for auditing functionality with the Linux system. One of the best things about auditd is that it is tightly integrated with the kernel, so it gives us the power to monitor almost everything we want, really.

Installing and Starting auditd

1. Verify if the auditd packages are pre-installed on the system. CentOS/RHEL 6,7 systems have auditd pre-installed.

# rpm -qa | grep -i audit
audit-libs-2.8.5-4.el7.x86_64
audit-2.8.5-4.el7.x86_64
audit-libs-python-2.8.5-4.el7.x86_64

2. If not present, you can install it using:

yum install audit

3. Make Sure auditd service is started and is enabled to run after boot automatically.

# systemctl status auditd        ### For CentOS/RHEL 7
# service auditd status          ### For CentOS/RHEL 6
# systemctl enable auditd      ### CentOS/RHEL 7
# chkconfig auditd on          ### CentOS/RHEL 6

Method 1 - Using an auditctl command (not persistent across reboots)

The auditctl method is not persistent across reboots and can be configured on the command line. Add the below 2 rules using the auditctl command for monitoring the chown and chmod commands.

For CentOS/RHEL 7

# auditctl -w /usr/bin/chmod -p x -k chmod_rule
# auditctl -w /usr/bin/chown -p x -k chown_rule
# auditctl -w /bin/chmod -p x -k chmod_rule
# auditctl -w /bin/chown -p x -k chown_rule

Here, -w: specify the file or binary for tracking -p: These are the permissions that we need to watch for. (In our case its only execute permission “x”) -k: Events in logs that match this rule will be associated with this key i.e. chown_rule and chmod_rule.

Method 2 - Using configuration files

We can also use the /etc/audit/audit.rules or /etc/audit/audit.d/audit.rules configuration files to add the auditd rules. The /etc/audit/audit.rules file is automatically generated from /etc/audit/rules.d. So it is recommended to add the rules to /etc/audit/rules.d/audit.rules rules files only.

For CentOS/RHEL 7:

# vi /etc/audit/rules.d/audit.rules
-w /usr/bin/chmod -p x -k chmod_rule
-w /usr/bin/chown -p x -k chown_rule

For CentOS/RHEL 6:

# /etc/audit/audit.rules
-w /bin/chmod -p x -k chmod_rule
-w /bin/chown -p x -k chown_rule

Restart the auditd service for the changes to take effect and rules to get generated in the /etc/audit/audit.rules rules file. Restart the auditd service with “service” command:

# service auditd restart
Stopping logging:                                          [  OK  ]
Redirecting start to /bin/systemctl start auditd.service

Verify the rules

You can view the configured rules using “auditctl -l” command:

# auditctl -l
-w /usr/bin/chmod -p x -k chmod_rule
-w /usr/bin/chown -p x -k chown_rule

Now let’s see the rules in action. Let’s change the permission of a file and see if we can see the corresponding auditd rule getting triggered. The log file /var/log/audit/audit.log logs all the auditd related log messages. You can tail this file to see the rules getting triggered. This file can be long and the system can generate a lot of logs in this file. To filter out the rules we are interested in, we can use the “ausearch” command with the key we specified while defining the rules. For example:

# touch /tmp/test
# chmod 777 /tmp/test

# ausearch -k chmod_rule
...
time->Sun Feb  9 03:11:55 2020
type=PROCTITLE msg=audit(1581217915.853:1357): proctitle=63686D6F6400373737002F746D702F74657374
type=PATH msg=audit(1581217915.853:1357): item=1 name="/lib64/ld-linux-x86-64.so.2" inode=306773 dev=103:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:ld_so_t:s0 objtype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1581217915.853:1357): item=0 name="/bin/chmod" inode=25188546 dev=103:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:bin_t:s0 objtype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=CWD msg=audit(1581217915.853:1357):  cwd="/etc/audit/rules.d"
type=EXECVE msg=audit(1581217915.853:1357): argc=3 a0="chmod" a1="777" a2="/tmp/test"
type=SYSCALL msg=audit(1581217915.853:1357): arch=c000003e syscall=59 success=yes exit=0 a0=1284850 a1=1283f30 a2=14627f0 a3=7ffeb56f35a0 items=2 ppid=2242 pid=4700 auid=1002 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=5 comm="chmod" exe="/usr/bin/chmod" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="chmod_rule"

As you can see the ausearch filters out only the rules associated with the key “chmod_rule”. You can see that root user (uid=0 gid=0) has fired the chmod command and we can track the time as well for the command. Similarly, we can filter out the chown command executions on the system using the key “chown_rule” with ausearch.