$linuxjunkies
>

Audit a Linux Server with Lynis

Run Lynis on any Linux server, interpret the hardening index and findings, apply the most impactful fixes, and automate weekly audits with a systemd timer.

IntermediateUbuntuDebianFedoraArch10 min readUpdated June 7, 2026

Before you start

  • Root or sudo access on the target server
  • Outbound HTTPS access to packages.cisofy.com for repository setup
  • Basic familiarity with sshd_config and sysctl parameters
  • A snapshot or backup taken before applying hardening changes

Lynis is an open-source security auditing tool that interrogates a running system and produces a hardening index score alongside prioritised findings. It works agentlessly, reads the live filesystem, and covers everything from kernel parameters and PAM configuration to file permissions and installed packages. Running it takes two minutes; understanding and acting on the output is where the real work begins.

Install Lynis

Use the official CISOfy repository where possible — the distro-packaged version is often months behind and may produce different scores against the current ruleset.

Debian / Ubuntu

curl -fsSL https://packages.cisofy.com/keys/cisofy-software-public.key \
  | sudo gpg --dearmor -o /usr/share/keyrings/cisofy-software.gpg
echo "deb [signed-by=/usr/share/keyrings/cisofy-software.gpg] \
  https://packages.cisofy.com/community/lynis/deb/ stable main" \
  | sudo tee /etc/apt/sources.list.d/cisofy-lynis.list
sudo apt update && sudo apt install lynis -y

Fedora / RHEL / Rocky

sudo rpm --import https://packages.cisofy.com/keys/cisofy-software-public.key
sudo tee /etc/yum.repos.d/cisofy-lynis.repo <<'EOF'
[lynis]
name=CISOfy Lynis
baseurl=https://packages.cisofy.com/community/lynis/rpm/
enabled=1
gpgcheck=1
gpgkey=https://packages.cisofy.com/keys/cisofy-software-public.key
EOF
sudo dnf install lynis -y

Arch Linux

sudo pacman -S lynis

Confirm the version after install — anything below 3.0 is outdated.

lynis show version

Run a System Audit

Lynis must run as root to read privileged files. The --auditor flag embeds your name in the report; omit it if you prefer.

sudo lynis audit system --auditor "your-name"

The scan takes 60–180 seconds. Do not interrupt it. You will see category banners scroll past — Kernel, Authentication, File Systems, Networking, and so on — each populated with OK, WARNING, or SUGGESTION markers.

Useful runtime flags

  • --quick — suppress the five-second pause between sections (useful in scripts).
  • --no-colors — plain output, good for piping to a log file.
  • --report-file /path/to/report.dat — write a machine-readable report alongside the human output.
  • --profile /etc/lynis/custom.prfload a custom profile (covered below).

Reading the Output and Score

When the scan finishes, Lynis prints a summary block. The most important line is the Hardening index:

  Hardening index : 62 [############        ]
  Tests performed : 258
  Plugins enabled : 0

The index runs from 0 to 100. Out-of-the-box servers typically score between 55 and 70. A production internet-facing server should target 80+. The score is relative to the tests Lynis actually ran — adding plugins or enabling enterprise checks will change the denominator.

Findings breakdown

Scroll up in the terminal (or pipe the run through tee) to see categorised findings. Three markers matter:

  • WARNING — exploitable or directly non-compliant condition. Fix these first.
  • SUGGESTION — best-practice improvement. Address these after warnings are clear.
  • OK — test passed; no action needed.

Every warning and suggestion references a test ID such as AUTH-9286. Use that ID to look up the full rationale:

sudo lynis show details AUTH-9286

Log and report files

Two files are written after every run:

  • /var/log/lynis.log — verbose per-test output; useful for debugging why a test failed.
  • /var/log/lynis-report.dat — key=value pairs suitable for SIEM ingestion or diffing between runs.
grep 'warning\|suggestion' /var/log/lynis-report.dat

Applying Fixes

Work through warnings before suggestions. The following examples represent the most common findings on a freshly provisioned server.

SSH hardening (SSH-7408, SSH-7412)

sudo nano /etc/ssh/sshd_config

Set or confirm these values:

PermitRootLogin no
PasswordAuthentication no
X11Forwarding no
AllowTcpForwarding no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
sudo systemctl reload sshd

Kernel hardening via sysctl (KRNL-6000)

sudo tee /etc/sysctl.d/99-hardening.conf <<'EOF'
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
EOF
sudo sysctl --system

Password policy (AUTH-9286)

Install and configure libpam-pwquality (Debian/Ubuntu) or libpwquality (Fedora/RHEL):

# Debian / Ubuntu
sudo apt install libpam-pwquality -y
sudo sed -i 's/^# minlen/minlen/' /etc/security/pwquality.conf
sudo sed -i 's/minlen.*/minlen = 12/' /etc/security/pwquality.conf
# Fedora / RHEL
sudo dnf install libpwquality -y
sudo sed -i 's/# minlen/minlen/' /etc/security/pwquality.conf
sudo sed -i 's/minlen.*/minlen = 12/' /etc/security/pwquality.conf

File permissions (FILE-7524)

Lynis often flags world-writable files or incorrect umask values. Set a stricter default umask system-wide:

echo 'umask 027' | sudo tee /etc/profile.d/hardening-umask.sh

Using Custom Profiles

A profile (.prf file) tells Lynis which tests to skip, which to enforce, and what your environment's accepted values are. This is essential for avoiding false positives — for example, a database server intentionally running without a firewall because it sits behind a load balancer.

Create a profile

sudo cp /etc/lynis/default.prf /etc/lynis/server-production.prf
sudo nano /etc/lynis/server-production.prf

Common directives inside the profile:

# Skip a specific test entirely
skip-test=FIRE-4512

# Override the minimum password length check
minimum-password-length=14

# Tell Lynis which package manager is authoritative (avoids some false positives)
package-manager-binary=/usr/bin/dpkg

# Set the expected firewall state
firewall-expected-status=enabled

Run with your custom profile:

sudo lynis audit system --profile /etc/lynis/server-production.prf

Commit your profile to version control alongside your Ansible playbooks or Terraform configuration so infrastructure changes stay auditable.

Automate Recurring Audits

Use a systemd timer rather than a cron job so you get proper logging via journald and dependency management.

sudo tee /etc/systemd/system/lynis-audit.service <<'EOF'
[Unit]
Description=Lynis security audit

[Service]
Type=oneshot
ExecStart=/usr/bin/lynis audit system --quick --no-colors \
  --profile /etc/lynis/server-production.prf
EOF
sudo tee /etc/systemd/system/lynis-audit.timer <<'EOF'
[Unit]
Description=Run Lynis audit weekly

[Timer]
OnCalendar=Mon 03:00
Persistent=true

[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now lynis-audit.timer

Verify Improvement

After applying fixes, re-run the audit and compare scores:

sudo lynis audit system --quick 2>&1 | tee /tmp/lynis-after.txt
grep 'Hardening index' /tmp/lynis-after.txt

For a diff between two report files, use the key=value format:

diff /var/log/lynis-report.dat.bak /var/log/lynis-report.dat

Keep a timestamped archive of lynis-report.dat after each weekly run so you can track the score over time and catch regressions introduced by package updates.

Troubleshooting

  • Score unexpectedly drops after an OS update — Lynis may have been updated with new tests. Run lynis show tests before and after to see if the test count changed.
  • Test shows WARNING but the fix is already applied — Check /var/log/lynis.log for the exact file or parameter Lynis inspected. The test may look in a location your config isn't using (e.g., distro overrides in /etc/ssh/sshd_config.d/).
  • Permission denied errors during scan — Lynis must run as root or with sudo. Running as a sudoer without a full root shell can miss some privileged file checks.
  • Plugin tests all skipped — Plugins require the Lynis enterprise edition. Community edition ships zero plugins; the skip messages are expected.
tested on:Ubuntu 24.04Debian 12Fedora 40Rocky 9

Frequently asked questions

Does Lynis make any changes to the system during a scan?
No. Lynis is read-only during a standard audit. It inspects files and configuration but never modifies anything. All remediation is manual and intentional.
What is a good hardening index target for a production server?
A freshly built server typically scores 55–70. Aim for 80 or above on internet-facing production systems. Scores above 90 are achievable but usually require trade-offs like disabling features you may legitimately need.
Can Lynis audit a remote server over SSH?
Not directly — Lynis is designed to run on the system it is auditing. For remote auditing, copy Lynis to the target and run it there, or use an orchestration tool like Ansible to push and execute it.
Why do some tests say SKIPPED even when the relevant software is installed?
A test is skipped when Lynis cannot locate the binary or configuration file it expects. Check /var/log/lynis.log for the specific path it searched and confirm your installation matches.
Is the community edition sufficient, or do I need the enterprise version?
The community edition covers the full test suite and is adequate for most teams. The enterprise version adds compliance reporting (PCI-DSS, HIPAA, ISO 27001 templates), plugins, and a central dashboard for managing multiple hosts.

Related guides