Check lynis-logfile¶
Overview¶
Evaluates the report of the lynis security audit that runs on the host once a day, for example through lynis.timer, and reports the hardening index, the findings (the lynis warnings) and the hardening suggestions of lynis, plus how many tests the lynis profile of the host skips, since an accepted test no longer shows up as a finding. The check itself does not run an audit, so it is fast and needs no more than read access to the report. Alerts when the hardening index is below the threshold, when lynis reports a finding, when the report is missing, incomplete or older than the maximum age, because then the daily audit has stopped, and when a partial audit has replaced the report of the full one. Security posture is informational drift rather than a time-critical availability event, so by default only WARNING is raised. Supports extended reporting via --lengthy. Requires root or sudo.
Important Notes:
- The check reads
/var/log/lynis-report.dat, which lynis writes when it audits the host as root. Something else has to run that audit once a day, for examplelynis.timer, which the Debian and Ubuntu packages ship, or a timer of your own on the Red Hat family, where the EPEL package only ships the units as documentation. The command the timer runs islynis audit system --cronjob. - lynis creates the report readable by root only (
umask 027), so run the check viasudo(see the sudoers files inassets/sudoers). TheLynis Service Setin the Icinga Director does exactly that on every host taggedlynis, and also checkslynis.serviceandlynis.timer. - lynis rewrites the report while it audits and writes the hardening index and the end of the audit last. An audit takes 20 seconds to a minute (measured on Debian 12/13, Rocky 8/9/10 and Ubuntu 22.04/24.04/26.04). A check that runs during that time reports the result of the last finished audit (OK if none is known yet), and the next run reads the finished report.
- Every audit that runs as root replaces the report, a partial one as well (
lynis audit system --tests ...,--tests-from-group ..., or thelynischeck with--lynis-test). The hardening index of such a report covers only the tests that ran, and if none of them awarded a hardening point, lynis reports a placeholder of 1. The check recognises a partial audit by the test groups recorded in the report and by fewer than 100 tests done (a full audit performs more than 200), and asks for a full audit instead of evaluating the report.--tests-from-category securitycounts as a full audit, since it runs all but a handful of tests. sudo lynis show details <test>on the host prints the details of a finding or suggestion from/var/log/lynis.log, the log of the last audit. Withoutsudo, lynis reads~/lynis.logof the calling user instead.- A security audit is posture drift, not a time-critical availability event, so by default only WARNING is raised. The default critical threshold is empty on purpose, to avoid paging someone at night for a hardening drop.
Data Collection:
- The state is the worst of: the hardening index against
--warning/--critical(Nagios ranges, default warns below 65), the presence of any lynis warning, and the age of the report against--max-age. - The age is the time since the audit finished, as lynis records it in the report (
report_datetime_end), not the modification time of the file. - Every lynis warning is listed under "Findings" with its test ID, its details where lynis gives any (the interface behind a
NETW-3015, for example) and a[WARNING]marker. A warning is a concrete finding, not noise; accept it on the host (see Troubleshooting), not in this plugin. - lynis suggestions are hardening advice. They are listed under "Suggestions" and do not change the state.
- Both lists are sorted by test ID.
- The skipped tests are the
skip-testentries (and the deprecatedtest_skip_alwaysentries) in/etc/lynis/custom.prf, or in the file given with--config-file. A skip of a single check within a test (SSH-7408:loglevel) counts as one. The count does not change the state, since a skipped test is an accepted one. It tells "0 suggestions" on a host that needs none from the same line on a host that skips them.--lengthylists the tests, each with the comment on the line above it in the profile. - The check reads one profile. Skips from another one lynis loads, such as a
default.prfwith local changes or a--profileon the audit command line, are not part of the count. - The check runs as root, so
--config-fileonly reads below/etc/lynis,/usr/local/etc/lynisand/usr/local/lynis, where lynis looks for its profiles, and follows no symlink in the last path component.
Fact Sheet¶
| Fact | Value |
|---|---|
| Check Plugin Download | https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/lynis-logfile |
| Nagios/Icinga Check Name | check_lynis_logfile |
| Check Interval Recommendation | Every hour |
| Can be called without parameters | Yes |
| Runs on | Linux |
| Compiled for Windows | No |
| Requirements | A daily lynis audit, for example lynis.timer; User with higher permissions |
| Uses State File | $TEMP/linuxfabrik-monitoring-plugins-lynis-logfile.db |
Help¶
usage: lynis-logfile [-h] [-V] [--always-ok] [--config-file CONFIG_FILE]
[-c CRIT] [--lengthy] [--max-age MAX_AGE] [--no-perfdata]
[-w WARN]
Evaluates the report of the lynis security audit that runs on the host once a
day, for example through lynis.timer, and reports the hardening index, the
findings (the lynis warnings) and the hardening suggestions of lynis, plus how
many tests the lynis profile of the host skips, since an accepted test no
longer shows up as a finding. The check itself does not run an audit, so it is
fast and needs no more than read access to the report. Alerts when the
hardening index is below the threshold, when lynis reports a finding, when the
report is missing, incomplete or older than the maximum age, because then the
daily audit has stopped, and when a partial audit has replaced the report of
the full one. Security posture is informational drift rather than a
time-critical availability event, so by default only WARNING is raised.
Supports extended reporting via --lengthy. Requires root or sudo.
options:
-h, --help show this help message and exit
-V, --version show program's version number and exit
--always-ok Always returns OK.
--config-file CONFIG_FILE
The lynis profile to read the skipped tests from. Has
to be below /etc/lynis, /usr/local/etc/lynis or
/usr/local/lynis. Example: `--config-
file=/etc/lynis/site.prf`. Default:
/etc/lynis/custom.prf
-c, --critical CRIT CRIT threshold for the hardening index (0-100).
Supports Nagios ranges. Empty by default, because a
daily hardening scan is posture drift, not a time-
critical event that should page someone at night.
Default: (no critical)
--lengthy Extended reporting.
--max-age MAX_AGE Maximum age of the report in hours. An older report
means that the daily audit no longer runs. Default: 26
(0 disables the check)
--no-perfdata Suppress the performance data section from the output.
The status message and the exit code are unaffected,
so alerting keeps working while trending data is
dropped.
-w, --warning WARN WARN threshold for the hardening index (0-100).
Supports Nagios ranges. The default alerts when the
index drops below 65. Default: 65:
Documentation:
https://linuxfabrik.github.io/monitoring-plugins/check-plugins/lynis-logfile/
Usage Examples¶
sudo ./lynis-logfile
Hardening index 60 [WARNING], 1 finding [WARNING], 49 suggestions, 2 skipped tests, audited 3h 12m ago
Findings:
* PKGS-7392: Found one or more vulnerable packages. [WARNING]
Suggestions:
* ACCT-9622: Enable process accounting.
* ACCT-9626: Enable sysstat to collect accounting (no results).
...
* USB-1000: Disable drivers like USB storage when not used, to prevent unauthorized storage or data theft.
To look up an item, run `sudo lynis show details PKGS-7392` on the host. To accept it, add `skip-test=PKGS-7392` to `/etc/lynis/custom.prf`.
List the skipped tests of a profile in another place:
sudo ./lynis-logfile --config-file=/usr/local/etc/lynis/custom.prf --lengthy
Hardening index 89, 0 findings, 0 suggestions, 2 skipped tests, audited 3h 12m ago
Skipped tests:
* KRNL-6000:KERNEL.SYSRQ: 0 takes away the emergency keys on the console of a hung host.
* NETW-2705
Warn below a hardening index of 70, critical below 50, and accept a report of up to two days:
sudo ./lynis-logfile --warning=70: --critical=50: --max-age=48
States¶
- OK if the hardening index is within the
--warning/--criticalrange, lynis reports no warning, and the report is not older than--max-age. - WARN if the hardening index drops below
--warning(default: 65), or lynis reports at least one warning. - WARN if the audit finished more than
--max-agehours ago (default: 26), because the daily audit has then stopped.--max-age 0switches this off. - WARN if there is no report, because the host is then not being audited.
- WARN if the report is incomplete and no audit is running, because the last audit did not finish.
- WARN if the report comes from a partial audit, because its hardening index and findings say nothing about the host.
- CRIT if the hardening index drops below
--critical(empty by default, so CRIT is never raised unless a threshold is set). - While an audit runs and the report is not complete yet, the result of the last finished audit stands; OK if none is known yet.
- UNKNOWN if the report cannot be read, most likely because the check does not run via
sudo. - UNKNOWN if the file given with
--config-fileis missing or outside of the directories lynis keeps its profiles in. Without--config-file, a missing/etc/lynis/custom.prfjust means that no test is skipped. --always-oksuppresses all alerts and always returns OK.
Perfdata / Metrics¶
| Name | Type | Description |
|---|---|---|
| findings | Number | Number of findings (lynis warnings). |
| hardening_index | Number | Hardening index of the host (0-100). |
| skipped_tests | Number | Number of tests the lynis profile skips. |
| suggestions | Number | Number of lynis suggestions. |
Troubleshooting¶
No lynis report found at /var/log/lynis-report.dat¶
No lynis audit has run on this host yet. Install lynis (from EPEL on the RHEL family, from the distribution on Debian and Ubuntu) and have it audit the host once a day, for example with sudo systemctl enable --now lynis.timer. On the Red Hat family, create the timer first: the EPEL package only ships lynis.service and lynis.timer below /usr/share/doc/lynis.
The report is readable by root only¶
The check does not run as root. Call it via sudo, as the Lynis Service Set and the tpl-service-lynis-logfile-sudo template in the Icinga Director do, and deploy the sudoers file from assets/sudoers.
The lynis report /var/log/lynis-report.dat is incomplete¶
The last audit did not finish, so the report lacks the hardening index and the end of the audit. sudo journalctl --unit lynis.service shows why the audit stopped. Start a new audit with sudo systemctl start lynis.service once the cause is fixed.
The lynis report /var/log/lynis-report.dat comes from a partial audit¶
Someone ran lynis as root with a selection of tests, for example sudo lynis audit system --tests MAIL-8818 while looking into a finding, and this replaced the report of the full audit. The hardening index of such a report covers only the selected tests, which is why it looks absurdly low (often 1), and the findings and suggestions of all other tests are gone. Start a full audit with sudo lynis audit system --cronjob, or wait for the next daily one. Next time, look into a single test without replacing the report: sudo lynis show details <test> prints what the last full audit logged to /var/log/lynis.log. A partial audit replaces that log as well, so it only helps after the next full audit.
Failed to read the lynis profile¶
The file given with --config-file does not exist, or it is not below /etc/lynis, /usr/local/etc/lynis or /usr/local/lynis. The check runs as root and reads nothing else, so that the parameter cannot be used to look at other files of the host. Move the profile to one of these directories.
The report is older than --max-age¶
systemctl list-timers lynis.timershows when the timer last ran and when it runs next. An inactive timer is not enabled:sudo systemctl enable --now lynis.timer.systemctl status lynis.serviceandsudo journalctl --unit lynis.serviceshow whether the last run failed.- A host that was switched off for a while catches up after the next boot if the timer is
Persistent=true.
Accepting a finding you do not want to fix¶
The plugin never silences individual lynis warnings; every warning raises at least WARNING. Acceptance belongs in lynis itself, where a test is skipped when its ID is listed with skip-test= in a profile. For example, to accept this finding:
* PKGS-7392: Found one or more vulnerable packages. [WARNING]
Add the test ID to the host's /etc/lynis/custom.prf:
skip-test=PKGS-7392
The next audit no longer reports PKGS-7392. A single check within a test is skipped with skip-test=SSH-7408:loglevel. Lynis refuses to run at all if a line of a profile other than a comment contains a character outside of letters, digits and /[]()_|,.:;=-, so keep the reason for an exception on a comment line of its own.
Credits, License¶
- Authors: Linuxfabrik GmbH, Zurich
- License: The Unlicense, see LICENSE file.