Skip to content

Commit 89cb10b

Browse files
committed
refactor(file-ownership): use os.stat() instead of shelling out, extend default file list and modernize code
- Replace shell exec of `stat` with os.stat() + pwd/grp for better performance and robustness - Extend default file list with CIS benchmark-relevant files (login.defs, sudoers, sysctl, systemd, PAM, etc.) - Convert to f-strings, remove pylint directives, extract check_file() function - Update README with structured overview and accurate documentation
1 parent 685809f commit 89cb10b

File tree

4 files changed

+206
-136
lines changed

4 files changed

+206
-136
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Monitoring Plugins:
6464
* all plugins: ignore unknown arguments instead of generating an error (this helps with updating Icinga and Nagios service definitions considerably)
6565
* by-ssh, by-winrm, disk-usage, example, file-ownership, fs-ro, infomaniak-events, journald-query, logfile, matomo-reporting, mysql-logfile, php-status, pip-updates, systemd-unit: fix `append` parameters so that user-specified values replace defaults instead of being appended to them ([#540](https://github.com/Linuxfabrik/monitoring-plugins/issues/540))
6666
* file-count: stopping when number of files actually exceed thresholds, therefore dramatically faster for large directories
67+
* file-ownership: use `os.stat()` instead of shelling out to `stat`, improving performance and robustness
6768
* nextcloud-version: modernize code
6869
* php-status: always assume http://localhost/monitoring.php and, if not found, be tolerant
6970
* redis-status, valkey-status: modernize code and unify both plugins again after [PR #954](https://github.com/Linuxfabrik/monitoring-plugins/pull/954)

check-plugins/file-ownership/README.md

Lines changed: 80 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,30 @@
22

33
## Overview
44

5-
Checks the ownership (owner and group, both have to be names) of a list of files, and also (and always) most of the files defined in the CIS Security Benchmarks. Depending on the file and user (e.g. running as 'icinga') sudo (sudoers) is needed.
5+
Checks the ownership (owner and group) of a list of files against expected values. The default file list covers most files defined in the CIS Security Benchmarks for RHEL, Debian, Ubuntu and Fedora, plus several application-specific paths. Files that do not exist on the system are silently skipped.
6+
7+
Alerting Logic:
8+
9+
* WARN if any file's owner or group does not match the expected value.
10+
11+
Data Collection:
12+
13+
* Uses `os.stat()` to read file ownership directly, without shelling out to external commands.
14+
* Resolves numeric UIDs/GIDs to names. If a UID/GID has no corresponding name, the numeric value is displayed.
15+
16+
Compatibility:
17+
18+
* Linux only. Not compiled for Windows.
19+
* Depending on the file and user (e.g. running as `icinga`), sudo (sudoers) may be needed.
20+
21+
Important Notes:
22+
23+
* If `--filename` is specified, only the user-supplied files are checked. The default list is not used.
24+
* The following CIS-recommended files are excluded from the defaults because their ownership differs across RHEL, Debian, Ubuntu and SLES: `/etc/gshadow`, `/etc/gshadow-`, `/etc/shadow`, `/etc/shadow-`. To check these, supply them via `--filename` with suitable values.
625

726
Default files checked:
827

28+
* /boot/grub/grub.cfg: root:root
929
* /boot/grub/grub.conf: root:root
1030
* /boot/grub2/grub.cfg: root:root
1131
* /boot/grub2/grubenv: root:root
@@ -19,41 +39,53 @@ Default files checked:
1939
* /etc/cron.monthly: root:root
2040
* /etc/cron.weekly: root:root
2141
* /etc/crontab: root:root
42+
* /etc/default/grub: root:root
43+
* /etc/fstab: root:root
2244
* /etc/graylog/certs: graylog:graylog
23-
* /etc/group-: root:root
2445
* /etc/group: root:root
46+
* /etc/group-: root:root
47+
* /etc/hosts: root:root
2548
* /etc/hosts.allow: root:root
2649
* /etc/hosts.deny: root:root
27-
* /etc/issue.net: root:root
2850
* /etc/issue: root:root
51+
* /etc/issue.net: root:root
52+
* /etc/login.defs: root:root
53+
* /etc/logrotate.conf: root:root
54+
* /etc/logrotate.d: root:root
2955
* /etc/loolwsd/loolwsd.xml: lool:lool
3056
* /etc/motd: root:root
3157
* /etc/named.conf: root:named
32-
* /etc/passwd-: root:root
58+
* /etc/pam.d: root:root
3359
* /etc/passwd: root:root
60+
* /etc/passwd-: root:root
61+
* /etc/profile: root:root
62+
* /etc/rsyslog.conf: root:root
63+
* /etc/security/access.conf: root:root
64+
* /etc/security/limits.conf: root:root
65+
* /etc/shells: root:root
66+
* /etc/ssh/ssh_config: root:root
3467
* /etc/ssh/sshd_config: root:root
35-
* /etc/sssd/sssd.con: root:root
68+
* /etc/sssd/sssd.conf: root:root
69+
* /etc/sudoers: root:root
70+
* /etc/sudoers.d: root:root
71+
* /etc/sysctl.conf: root:root
72+
* /etc/sysctl.d: root:root
73+
* /etc/systemd/coredump.conf: root:root
74+
* /etc/systemd/journald.conf: root:root
75+
* /etc/systemd/logind.conf: root:root
76+
* /etc/systemd/system.conf: root:root
3677
* /home/ovirt: vdsm:kvm
37-
* /tmp/linuxfabrik-monitoring-plugins-sqlite.db: icinga:icinga
3878
* /tmp: root:root
79+
* /tmp/linuxfabrik-monitoring-plugins-sqlite.db: icinga:icinga
3980
* /var/hnet: hnet:hnet
4081
* /var/lib/unbound/root.key: unbound:unbound
41-
* /var/run/openldap: <ldap:ldap>
42-
43-
According to CIS the below mentioned files should also be checked by default, but we don't, because their owners differ on RHEL/CentOS, Debian/Ubuntu and SLES:
44-
45-
* /etc/gshadow
46-
* /etc/gshadow-
47-
* /etc/shadow
48-
* /etc/shadow-
49-
50-
If you also want to check for those ones, simply configure them in the monitoring software and supply the parameter `--filename` with suitable values.
82+
* /var/run/openldap: ldap:ldap
5183

5284

5385
## Fact Sheet
5486

5587
| Fact | Value |
56-
|----|----|
88+
|----|------|
5789
| Check Plugin Download | <https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/file-ownership> |
5890
| Check Interval Recommendation | Every 5 minutes |
5991
| Can be called without parameters | Yes |
@@ -72,42 +104,49 @@ options:
72104
-h, --help show this help message and exit
73105
-V, --version show program's version number and exit
74106
--filename FILES File to be checked, in the format `owner:group,path`
75-
(repeatable).
107+
(repeatable). If specified, the default file list is
108+
replaced entirely.
76109
```
77110

78111

79112
## Usage Examples
80113

114+
Using default file list:
115+
116+
```bash
117+
./file-ownership
118+
```
119+
120+
Output:
121+
122+
```text
123+
Everything is ok.
124+
125+
Path ! Expected ! Found
126+
---------------------------+-----------------+----------------
127+
/etc/anacrontab ! root:root ! root:root
128+
/etc/cron.d ! root:root ! root:root
129+
/etc/crontab ! root:root ! root:root
130+
/etc/default/grub ! root:root ! root:root
131+
/etc/fstab ! root:root ! root:root
132+
...
133+
```
134+
135+
Specifying custom files (replaces the entire default list):
136+
81137
```bash
82138
./file-ownership --filename root:root,/tmp --filename root:root,/etc/motd
83139
```
84140

85141
Output:
86142

87143
```text
88-
One or more problems with owners or groups.
89-
90-
Path Expected Found
91-
---- -------- -----
92-
/etc/anacrontab root:root root:root
93-
/etc/cron.d root:root root:root
94-
/etc/cron.daily root:root root:root
95-
/etc/cron.hourly root:root root:root
96-
/etc/cron.monthly root:root root:root
97-
/etc/cron.weekly root:root root:root
98-
/etc/crontab root:root root:root
99-
/etc/group root:root root:root
100-
/etc/group- root:root root:root
101-
/etc/gshadow- root:root root:root
102-
/etc/issue root:root root:root
103-
/etc/issue.net root:root root:root
104-
/etc/motd root:root markus.frei:root [WARNING]
105-
/etc/passwd root:root root:root
106-
/etc/passwd- root:root root:root
107-
/etc/shadow- root:root root:root
108-
/etc/ssh/sshd_config root:root root:root
109-
/tmp root:root root:root
110-
/var/lib/unbound/root.key unbound:unbound unbound:unbound
144+
Everything is ok.
145+
146+
Path ! Expected ! Found
147+
----------+-----------+----------
148+
/tmp ! root:root ! root:root
149+
/etc/motd ! root:root ! root:root
111150
```
112151

113152

0 commit comments

Comments
 (0)