Skip to content
shellhacks.dev
Security

How to Use Lynis to Audit a Linux Server in Real Scripts

Run a Lynis audit on a Linux server, read the hardening index, warnings and suggestions, look up a test ID, tune with a profile and track results over time.

6 min read
Summarize in AI
Illustration for "How to Use Lynis to Audit a Linux Server in Real Scripts": a shell script in an editor, a scrolling log, file permission bits.

Hardening checklists run to hundreds of items, and few people read them. Lynis is a shell script that does the checking for you: it inspects the system's configuration, services, accounts and permissions, and prints what it found against good practice. It does not fix anything, which makes it safe to run. This post shows how to run it and, more importantly, how to read the output without chasing a number. It sits with the other tools in hardening and rootkit scanners. The commands assume Lynis 3.1 on Debian 13.

Install and run

Shell
sudo apt install lynis
sudo lynis audit system --quick

The distribution package may be a few releases behind; a clone of the project repository (git clone https://github.com/CISOfy/lynis) and running ./lynis audit system from it gives the current tests. A normal run takes a minute or two. --quick skips the pauses between sections, which are there for people reading along. The output ends with a summary:

Text
  Hardening index : 71 [##############      ]
  Tests performed : 262
  Plugins enabled : 1

  Warnings (2):
  ! Found one or more vulnerable packages. [PKGS-7392]
  ! Reboot of host may be needed to use the latest kernel [KRNL-5830]

  Suggestions (31):
  * Install a PAM module for password strength testing [AUTH-9262]
  * Set a password on GRUB boot loader [BOOT-5122]

Read warnings first

Warnings are findings Lynis believes are real problems: an outdated package, a world-writable file, an insecure setting. Fix those or record why you accept them. Suggestions are a long list of hardening ideas of varying value, and some do not fit a given server: a GRUB password matters on a laptop and almost never in a cloud VM. Read them as a menu.

Shell
sudo lynis show details PKGS-7392
sudo grep -E '^(warning|suggestion)\[\]' /var/log/lynis-report.dat

show details explains what a test checked and what it found, including the exact items. The machine-readable report in /var/log/lynis-report.dat holds every result as key=value lines, and /var/log/lynis.log the verbose log of each test, which is where you look when a finding seems wrong.

The hardening index

The score rises with the number of passed tests. It is a trend line for one machine over time and a poor comparison between different machines, since the tests that apply vary. Chasing 100 leads to changes that add complexity or break things, such as disabling a service you need. A drop from one run to the next means something changed and is worth a look.

Tune with a profile

/etc/lynis/custom.prfText
# skip: no boot loader password in a cloud VM
skip-test=BOOT-5122
# skip: USB storage is not present on this host
skip-test=USB-1000
# accepted: the application requires this account to have a shell
config:config-data:...
Shell
sudo lynis audit system --profile /etc/lynis/custom.prf

Skipping tests with a comment explaining why is better than ignoring them in your head: the next person sees the reasoning. Keep the profile under version control with the rest of the configuration.

Track over time

Shell
sudo lynis audit system --cronjob --quiet
grep '^hardening_index=' /var/log/lynis-report.dat

--cronjob runs non-interactively without colors, for a timer or cron job; --quiet prints only warnings. Store the index and the list of warnings each week and alert on a new warning. Use it before and after changes to see their effect, and as a checklist when a server is new.

Where this does not apply

Lynis checks configuration against general good practice; it does not find vulnerabilities in your application, replace a penetration test or prove compliance. It reports on the machine it runs on, with the privileges it has; run as root for complete results. Some checks produce false warnings on unusual setups, such as containers. For standards-based scanning, tools like OpenSCAP check against a specific benchmark.

After a first audit, compare the warnings with shell script security and least privilege for scripts, since many findings are about accounts and services rather than the kernel. Fix the few that matter, then rerun and compare.

What the audit measures

Lynis is a shell-based auditing tool that runs on the machine itself, as root, and performs hundreds of small tests grouped by area: boot and services, kernel, accounts, file systems, networking, SSH, logging, package management and more. Each test looks at the configuration or the state of the system and records a result, a warning, a suggestion or nothing. It does not scan the network, send data anywhere by default, or change the system; it reads and reports. That makes it safe to run on a production machine, with the usual caution about the extra load for a few minutes. Its checks reflect common hardening guides, so a suggestion is a prompt to consider a setting and not a verdict that something is broken, and many suggestions do not fit a given machine, such as asking for a separate partition on a container host where it makes no sense. Read each in the light of what the machine does.

The results are stored in a log and a report file under /var/log, and the report is a simple key and value file that scripts can parse, which is how you turn a one-off audit into a series.

Reading warnings, suggestions and the index

Work through warnings first, since they mark things the tool considers more serious, and then suggestions in order of how cheap and safe they are. Each finding has an identifier such as SSH-7440, and lynis show details followed by the identifier prints the explanation and the test that produced it, which is the quickest way to decide whether it applies. The hardening index, a number out of 100, summarizes how many of the applicable checks passed. Treat it as a trend line for one machine over time and not as a security score. Two systems with the same index can have very different risk, and a high index on a machine with a vulnerable application says little. Raising the number by changing settings you do not understand is a poor use of time and can break services. Chase the findings that match your threat model: remote access, patching, accounts with weak authentication, services listening that you did not expect.

Making the report fit your machines

Create a custom profile in /etc/lynis/custom.prf to skip tests that do not apply, with skip-test=ID lines and a comment explaining each, so the next audit does not repeat findings you decided to accept. Keep those decisions in version control. Run the audit after every significant change and on a schedule, and keep the report files, so you can compare two runs with diff and see what changed. Use a current version: distribution packages are often old, and the project's own repository or a release tarball has newer tests, though you should verify downloads before running them as root. Feed the report to your monitoring or ticketing system if you manage many machines, and track the count of warnings per host. An audit that nobody acts on is a ritual, so pick the top three findings each time and fix them, then run again.

Acting on the first run

On the first audit of an older machine expect dozens of suggestions, and resist the urge to fix them all at once. Group them by area, fix the ones tied to remote access and authentication first, apply each in a test environment where you can, and re-run the audit after every few changes to confirm that the finding is gone and nothing new appeared. Record each change in your configuration management so a rebuilt machine gets the same settings, since a hardening done by hand on one server is lost at the next reinstall.

See the Lynis documentation and the control catalog.

Share

Keep reading

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.