Lynis is an open-source security auditing tool for Linux and other Unix systems. It runs hundreds of local checks against the kernel, users, SSH, file permissions, installed software, logging and more, then reports warnings, hardening suggestions and a hardening index from 0 to 100. In this tutorial you will install the latest Lynis on Ubuntu 24.04, run a full audit, interpret and act on the results, tune the audit with a custom profile and schedule weekly audits.
Prerequisites
To follow this tutorial you need:
- A server running Ubuntu 24.04 LTS, for example a CubePath VPS.
- A non-root user with
sudoprivileges.
Lynis only reads the system and does not change anything, so it is safe to run on a production server. A full audit takes one to three minutes.
Step 1 - Installing Lynis from the CISOfy repository
Ubuntu's own lynis package is often several releases behind, and Lynis warns when it is outdated. CISOfy, the company behind Lynis, publishes an official APT repository with current versions.
Install the tools needed to add the repository key:
sudo apt update
sudo apt install curl gnupg
Download the CISOfy signing key into /etc/apt/keyrings:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://packages.cisofy.com/keys/cisofy-software-public.key | sudo gpg --dearmor -o /etc/apt/keyrings/cisofy-software-public.gpg
Add the repository, restricted to that key:
echo "deb [signed-by=/etc/apt/keyrings/cisofy-software-public.gpg] https://packages.cisofy.com/community/lynis/deb/ stable main" | sudo tee /etc/apt/sources.list.d/cisofy-lynis.list
Install Lynis:
sudo apt update
sudo apt install lynis
Check the version:
lynis show version
3.1.5
Your version may be newer. Because the package comes from a repository, regular apt upgrade runs keep Lynis current.
Step 2 - Running your first audit
Run a full system audit as root, so Lynis can read protected files such as /etc/shadow and the SSH daemon configuration:
sudo lynis audit system
Lynis prints each test group as it runs, with a coloured result per check:
[+] SSH Support
------------------------------------
- Checking running SSH daemon [ FOUND ]
- Searching SSH configuration [ FOUND ]
- OpenSSH option: AllowTcpForwarding [ SUGGESTION ]
- OpenSSH option: ClientAliveCountMax [ SUGGESTION ]
- OpenSSH option: PermitRootLogin [ OK ]
At the end it prints a summary:
Lynis security scan details:
Hardening index : 63 [############ ]
Tests performed : 262
Plugins enabled : 0
Components:
- Firewall [V]
- Malware scanner [X]
Files:
- Test and debug information : /var/log/lynis.log
- Report data : /var/log/lynis-report.dat
The hardening index is a rough score of how many applicable hardening measures are in place. A fresh Ubuntu install typically scores in the high 50s to mid 60s. Use the index to track progress over time on the same server, not to compare unrelated systems.
Step 3 - Reading warnings and suggestions
Lynis sorts findings into two categories:
- Warnings: problems that deserve attention soon, such as a pending reboot after a kernel update or a service with a known weak configuration.
- Suggestions: hardening improvements. Not all of them apply to every server.
Both are printed after the test output, each with a test ID:
Warnings (1):
----------------------------
! Reboot of system is most likely needed [KRNL-5830]
- Solution : reboot
https://cisofy.com/lynis/controls/KRNL-5830/
Suggestions (28):
----------------------------
* Consider hardening SSH configuration [SSH-7408]
- Details : MaxAuthTries (6 --> 3)
https://cisofy.com/lynis/controls/SSH-7408/
The same findings are stored in machine-readable form in /var/log/lynis-report.dat. Extract them with grep:
sudo grep '^warning\[\]=' /var/log/lynis-report.dat
sudo grep '^suggestion\[\]=' /var/log/lynis-report.dat
warning[]=KRNL-5830|Reboot of system is most likely needed|-|text:reboot|
suggestion[]=SSH-7408|Consider hardening SSH configuration|MaxAuthTries (6 --> 3)|-|
To see what a specific test checked and what it found, ask for its details:
sudo lynis show details SSH-7408
This prints the lines from /var/log/lynis.log that belong to that test, including the exact values Lynis compared.
Step 4 - Fixing findings
Work through the warnings first, then the suggestions, starting with the ones that reduce exposure to the network: SSH, open services and firewall. A practical order is:
- Warnings (pending reboots, vulnerable packages, weak services).
- Remote access: SSH configuration, firewall rules.
- Authentication: password policies, unused accounts.
- Logging and auditing.
- Everything else, judged case by case.
As an example, fix the SSH suggestions from the previous step. Create a drop-in file for the SSH daemon instead of editing the main configuration:
sudo nano /etc/ssh/sshd_config.d/60-hardening.conf
MaxAuthTries 3
AllowTcpForwarding no
ClientAliveCountMax 2
X11Forwarding no
Only set AllowTcpForwarding no if you do not use SSH tunnels to reach services on this server.
Check the syntax and reload SSH:
sudo sshd -t
sudo systemctl reload ssh
sshd -t prints nothing when the configuration is valid. Keep your current SSH session open and test a new login from another terminal before closing it.
Re-run only the SSH tests to confirm the fix:
sudo lynis audit system --tests-from-group ssh --quick
The fixed options now show [ OK ]. Run the full audit again after a batch of changes to see the new hardening index.
Step 5 - Customizing the audit with a profile
Some suggestions will never apply to your server. For example, Lynis suggests separate partitions for /home, /tmp and /var, which a typical VPS with a single root filesystem cannot provide without reinstalling. Instead of ignoring the same items on every run, skip them in a custom profile.
Lynis reads /etc/lynis/default.prf and then /etc/lynis/custom.prf. Never edit the default profile, as upgrades replace it. Create the custom one:
sudo nano /etc/lynis/custom.prf
# Single root filesystem on this VPS, separate partitions not applicable
skip-test=FILE-6310
# No USB or FireWire devices on a virtual machine
skip-test=USB-1000
skip-test=STRG-1846
Each skip-test line takes the ID shown next to a finding. Document why you skip each test, so the decision can be reviewed later.
Confirm Lynis loads your profile:
sudo lynis show profiles
/etc/lynis/default.prf
/etc/lynis/custom.prf
The next audit no longer runs the skipped tests.
Step 6 - Scheduling weekly audits
Regular audits catch configuration drift, such as a package that re-enabled a service or a new user with a weak shell setup. Run Lynis weekly with a systemd timer and keep a dated copy of each report so you can compare runs.
Create a directory for the reports:
sudo mkdir -p /var/log/lynis-reports
sudo chmod 700 /var/log/lynis-reports
Create the service unit:
sudo nano /etc/systemd/system/lynis-audit.service
[Unit]
Description=Weekly Lynis security audit
[Service]
Type=oneshot
Nice=10
ExecStart=/usr/bin/lynis audit system --cronjob
ExecStartPost=/bin/sh -c 'cp /var/log/lynis-report.dat /var/log/lynis-reports/report-$(date +%%F).dat'
The --cronjob option disables colours and interactive pauses, which is what you want for unattended runs. The %% escapes the % sign, which systemd would otherwise interpret itself.
Create the timer:
sudo nano /etc/systemd/system/lynis-audit.timer
[Unit]
Description=Run the Lynis audit every week
[Timer]
OnCalendar=Sun *-*-* 04:00:00
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.target
Enable the timer and run the audit once to test it:
sudo systemctl daemon-reload
sudo systemctl enable --now lynis-audit.timer
sudo systemctl start lynis-audit.service
ls /var/log/lynis-reports
report-2026-09-24.dat
To follow the hardening index over time, pull it from all saved reports:
sudo grep -H '^hardening_index=' /var/log/lynis-reports/*.dat
/var/log/lynis-reports/report-2026-09-24.dat:hardening_index=63
/var/log/lynis-reports/report-2026-10-04.dat:hardening_index=71
To see what changed between two runs, compare their warnings and suggestions:
sudo grep -E '^(warning|suggestion)\[\]=' /var/log/lynis-reports/report-2026-09-24.dat > ~/before.txt
sudo grep -E '^(warning|suggestion)\[\]=' /var/log/lynis-reports/report-2026-10-04.dat > ~/after.txt
diff ~/before.txt ~/after.txt
Lines starting with < were fixed, and lines starting with > are new findings that need a look.
Troubleshooting
Lynis reports that it is outdated. You are using the Ubuntu package instead of the CISOfy repository, or the repository is not being updated. Check with apt policy lynis that the installed version comes from packages.cisofy.com.
Many tests are skipped with "non-privileged mode". You ran Lynis without sudo. Some tests need root to read system files.
The APT repository fails with a signature error. The key file is missing or was saved without --dearmor. Repeat the key download from Step 1 and run sudo apt update again.
Conclusion
You installed Lynis from the official repository, ran a full audit, fixed a group of findings, skipped tests that do not apply to your server and scheduled weekly audits with dated reports. Treat the hardening index as a trend indicator and focus on warnings and network-facing suggestions first. As next steps, protect SSH against brute force with Fail2Ban, add a malware scanner such as ClamAV (which also clears the "Malware scanner" component in the report), and enable automatic security updates with unattended-upgrades.
