Back to blog
Blog

Linux VPS security auditing in 2026: a practical baseline with Lynis, systemd-analyze, and OpenSSH checks

Linux VPS security auditing in 2026 with Lynis: run checks, fix findings safely, verify, and track drift over time.

By Anurag Singh
Updated on Apr 16, 2026
Category: Blog
Share article
Linux VPS security auditing in 2026: a practical baseline with Lynis, systemd-analyze, and OpenSSH checks

You can harden a server for weeks and still miss the one setting that bites you later. Linux VPS security auditing gives you a repeatable way to catch the gaps that actually matter: sloppy SSH policy, unexpected listeners, stale packages, noisy auth logs, and kernel/sysctl defaults that don’t match how the box is used.

This post sticks to a safe baseline. You’ll run an audit, read the report like an engineer (not a scorekeeper), apply changes that won’t strand you without SSH, and set up simple drift tracking so you notice when risk creeps back in.

Scenario: a small API VPS that needs a defensible baseline

Assume you run one VPS hosting an internal JSON API plus a small admin UI. You’re not chasing “perfect.” You want a baseline you can defend in a review: “We audit on a schedule, we keep the reports, and we fix the highest-risk findings first.”

  • Distro: Ubuntu Server 24.04 LTS (similar steps work on Debian 12)
  • Services: OpenSSH on port 22, Nginx reverse proxy, app listens on 127.0.0.1:8087
  • Goal: audit + baseline fixes + verification + ongoing checks

If you want a clean Linux environment to apply these controls end-to-end, start with a HostMyCode VPS so you own the kernel, firewall, and SSH policy. If you’d rather offload OS upkeep and routine maintenance, managed VPS hosting is the better fit.

What you’ll get out of Linux VPS security auditing (and what you won’t)

An audit tool can’t prove you’re secure. What it can do is give you quick, repeatable signal:

  1. Surface blind spots (forgotten services, risky permissions, weak crypto policy).
  2. Prioritize changes so you don’t spend a day polishing low-impact items.
  3. Create a baseline you can rerun after patches, migrations, or incidents.

For threat modeling and response planning, keep this paired with your runbooks. HostMyCode’s this VPS incident response checklist is a solid practical reference.

Prerequisites

  • Root access (or sudo) to a Linux VPS
  • Out-of-band access option (cloud console or recovery) if possible
  • Basic comfort with SSH and editing files in /etc
  • 10–20 minutes of downtime tolerance not required (we’ll avoid disruptive changes)

Before you touch security settings, make sure you can roll back. That usually means a verified backup plus a plan to restore. If you don’t already have that written down, keep this bookmarked: VPS backup strategy with restic + S3.

Step 1: capture a “before” snapshot of your current state

Audits are most useful when you can answer one question later: “What changed?” Start by recording a few basics.

  1. Check your OS and kernel:

    lsb_release -a
    uname -a

    Expected output looks like:

    Description:	Ubuntu 24.04.2 LTS
    Linux vps-api-01 6.8.0-xx-generic #... SMP ... x86_64 GNU/Linux
  2. List listening ports (this is where “surprise services” show up):

    ss -lntup | sed -n '1,40p'

    You want to see only what you expect, for example:

    tcp   LISTEN 0  4096 0.0.0.0:22    0.0.0.0:* users:("sshd",pid=1123,fd=3)
    tcp   LISTEN 0  4096 0.0.0.0:80    0.0.0.0:* users:("nginx",pid=1401,fd=6)
    tcp   LISTEN 0  4096 0.0.0.0:443   0.0.0.0:* users:("nginx",pid=1401,fd=7)
    tcp   LISTEN 0  4096 127.0.0.1:8087 0.0.0.0:* users:("api",pid=2310,fd=10)
  3. Quick look at recent auth events:

    sudo journalctl -u ssh --since "24 hours ago" --no-pager | tail -n 30

If disk space is already tight, deal with that first. Audit output and logs need room to breathe, and a full filesystem can turn routine tasks into outages. See VPS disk space troubleshooting.

Step 2: run Lynis and get a real report (not just a score)

Lynis remains one of the most useful “broad sweep” tools for Linux servers in 2026. It checks OS hardening, service exposure, logging, and common security settings. Treat the output like a punch list, not a verdict.

  1. Install Lynis from Ubuntu repositories:

    sudo apt update
    sudo apt install -y lynis
  2. Run an audit:

    sudo lynis audit system

    During the run, you’ll see tests like:

    [+] Boot and services
    [+] Kernel
    [+] Memory and processes
    [+] Users, groups and authentication
    [+] Shells
    [+] Networking
    [+] Printers and spools
    [+] Scheduled tasks
    [+] Accounting
    [+] Logging and files
  3. Open the report and focus on warnings and suggestions:

    sudo less /var/log/lynis-report.dat
    sudo less /var/log/lynis.log

Ignore the “Hardening index” as a goal. What matters is whether the findings map to real risk on your VPS: SSH policy, exposed services, patch status, firewall posture, and whether you can reconstruct events from logs.

Step 3: fix the high-signal items first (SSH, updates, firewall posture)

Lynis can produce a long list. Start with changes that reduce exposure quickly and rarely break production.

3.1 Lock down SSH without locking yourself out

Before you edit SSH, open a second root session and leave it open. That’s your safety line if you make a mistake.

  1. Edit your SSH server config:

    sudo nano /etc/ssh/sshd_config

    Apply a conservative baseline (adapt to your environment):

    # /etc/ssh/sshd_config
    Port 22
    Protocol 2
    PermitRootLogin no
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    PubkeyAuthentication yes
    AuthenticationMethods publickey
    AllowUsers deploy opsadmin
    X11Forwarding no
    AllowAgentForwarding no
    AllowTcpForwarding no
    ClientAliveInterval 300
    ClientAliveCountMax 2
    MaxAuthTries 4
    LoginGraceTime 30
    LogLevel VERBOSE
  2. Validate the config before restart:

    sudo sshd -t
    echo $?

    0 means syntax is OK.

  3. Restart SSH safely:

    sudo systemctl restart ssh
    sudo systemctl status ssh --no-pager
  4. Verify from a new terminal:

    ssh deploy@YOUR_SERVER_IP

If your access model is more complex (bastion, ProxyJump, MFA, audit logging), this guide stays practical: SSH bastion host setup.

3.2 Apply security updates with a controlled approach

On most VPS audits, the loudest finding is simple: pending updates. Patch first, then re-audit, so you’re not fixing issues that disappear after upgrades.

  1. See what’s pending:

    apt list --upgradable 2>/dev/null | sed -n '1,25p'
  2. Upgrade:

    sudo apt update
    sudo apt -y full-upgrade
  3. Remove unused packages:

    sudo apt -y autoremove --purge
  4. Reboot if the kernel or core libraries changed:

    sudo reboot

If you want a safer cadence (staging, snapshots, maintenance windows, rollback), follow VPS patch management in 2026 as the operating model.

3.3 Confirm firewall posture (and logging) matches reality

Lynis won’t manage your firewall for you. It only checks whether one exists and whether the setup looks reasonable. If you already run nftables, keep it. If you use UFW, keep it. The non-negotiable part is exposure: only publish what must be public.

Quick verification:

sudo ufw status verbose || true
sudo nft list ruleset | sed -n '1,120p' || true

If you’re on nftables and want audit-friendly rules plus safe rollbacks, use VPS firewall logging with nftables.

Step 4: use systemd-analyze to find risky boot-time and service behavior

This is where a lot of teams miss real issues. Auditing isn’t only crypto and permissions; it’s also “why is that daemon running?” and “what changed since last month?”

  1. See slow or unusual boot services:

    systemd-analyze blame | head -n 20
  2. List enabled units (hunt for things you never meant to run):

    systemctl list-unit-files --state=enabled | sed -n '1,80p'
  3. Inspect a suspicious service:

    systemctl cat SERVICE_NAME
    systemctl status SERVICE_NAME --no-pager

Common surprises on VPS images: remote management agents you didn’t choose, mail daemons you never use, or dev tooling that should have been removed after setup. Disable first and watch for fallout; uninstall later once you’re confident.

Step 5: tighten logging and audit signals (without filling the disk)

An audit only pays off if you can answer “what happened?” later. That requires predictable logging, sane retention, and rotation that won’t eat the filesystem.

5.1 Make journald persistent (but bounded)

Some images keep journald in volatile storage. After a reboot, your evidence disappears, which makes incident review painful.

  1. Edit journald config:

    sudo nano /etc/systemd/journald.conf

    Add (or adjust) these values:

    # /etc/systemd/journald.conf
    Storage=persistent
    SystemMaxUse=600M
    SystemMaxFileSize=80M
    MaxRetentionSec=14day
  2. Apply:

    sudo systemctl restart systemd-journald

For a broader setup (journald + Nginx + app logs), this is a good reference: VPS log rotation best practices in 2026.

5.2 Enable unattended audit signals (optional, but useful)

For many VPS workloads, a full auditd rule set is more weight than you need. A solid middle ground is making sure auth, sudo, and SSH events are consistently captured and easy to search. If you do run auditd, keep rules narrow and centered on privileged actions.

At minimum, confirm sudo logging works and is visible:

sudo journalctl -t sudo --since "7 days ago" --no-pager | tail -n 20

Step 6: address common Lynis findings with safe, concrete changes

Every server will produce a slightly different report. The fixes below show up constantly on real VPS hosts and tend to be low-risk if you apply them with care.

6.1 Remove or lock unused accounts

List users with a shell:

awk -F: '($7 ~ /(bash|sh|zsh)$/){print $1":"$6":"$7}' /etc/passwd

If you find an old user you no longer need:

sudo usermod -L olduser
sudo usermod -s /usr/sbin/nologin olduser

On production, don’t delete accounts on impulse. First confirm you’re not about to break cron jobs, systemd services, or deploy keys tied to that user.

6.2 Fix world-writable files and odd permissions

Search common local filesystems (skip virtual mounts):

sudo find / -xdev -type f -perm -0002 2>/dev/null | head -n 50

If you discover something like /opt/api/tmp/debug.log is world-writable, tighten it:

sudo chmod o-w /opt/api/tmp/debug.log

Then confirm the app still writes logs. This is a classic “looks safe, breaks quietly” change when an app logs to the wrong directory.

6.3 Review kernel and network sysctls (don’t cargo-cult)

Lynis will suggest sysctl tweaks. Only apply settings that match your role. For a typical VPS that doesn’t route traffic for other systems, these are usually sensible:

sudo tee /etc/sysctl.d/99-hostmycode-baseline.conf >/dev/null <<'EOF'
# HostMyCode baseline sysctl (review before use)
net.ipv4.ip_forward=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.tcp_syncookies=1
kernel.kptr_restrict=2
fs.protected_hardlinks=1
fs.protected_symlinks=1
EOF

sudo sysctl --system

Verification:

sysctl net.ipv4.ip_forward kernel.kptr_restrict

Expected output:

net.ipv4.ip_forward = 0
kernel.kptr_restrict = 2

Pitfall: if you run Docker with custom networking, Kubernetes, or act as a VPN gateway, you may need exceptions. This is the moment to document those choices, not “win” points in the report.

6.4 Confirm TLS endpoints and reverse proxy configuration

Lynis can flag old protocols and weak ciphers, but it doesn’t understand your full routing. If you use Nginx, confirm what’s actually enabled:

sudo nginx -T 2>/dev/null | grep -E "ssl_protocols|ssl_ciphers|listen 443" | head -n 40

Then verify from your workstation:

curl -sI https://your-api.example.com | head -n 10

If you host multiple apps behind one VPS, keep the proxy config boring and consistent. This guide is a strong reference: Nginx reverse proxy on a VPS.

Step 7: re-run the audit and track drift over time

After you make changes, rerun Lynis and save the delta. The simplest workflow is a timestamped archive of the report and a separate findings file.

  1. Create an audit directory:

    sudo mkdir -p /var/lib/security-audits/lynis
  2. Run Lynis and archive the report:

    ts=$(date -u +%Y%m%dT%H%M%SZ)
    sudo lynis audit system --quiet
    sudo cp /var/log/lynis-report.dat /var/lib/security-audits/lynis/lynis-report-${ts}.dat
    sudo cp /var/log/lynis.log /var/lib/security-audits/lynis/lynis-${ts}.log
  3. Extract the warnings and suggestions into a greppable file:

    sudo lynis show report | sed -n '/Warnings/,/Suggestions/p' | sudo tee /var/lib/security-audits/lynis/findings-${ts}.txt >/dev/null
    sudo wc -l /var/lib/security-audits/lynis/findings-${ts}.txt

What you’re looking for on the second run: fewer high-risk warnings around SSH, firewall state, and patching. Don’t try to clear every suggestion the same day. Capture it, decide if it’s worth the tradeoff, and move on.

Verification checklist (what “good” looks like)

  • SSH: password auth off, root login off, only known users allowed
  • Ports: ss -lntup shows only intended public listeners (typically 22/80/443)
  • Updates: no large backlog of upgradable security packages
  • Logs: journald persistent with bounded retention; auth events visible
  • Lynis: warnings reduced; remaining items documented as accepted risk

Common pitfalls you’ll hit (and how to avoid them)

  • Breaking SSH access: always keep a second session open; run sshd -t before restarting.
  • Chasing the hardening score: optimize for risk reduction, not a number. Some “findings” conflict with your workload.
  • Applying sysctl changes blindly: VPN gateways, containers, and routing hosts often need exceptions.
  • Audit without retention: if you don’t save reports, you can’t prove improvement or spot drift.
  • Log growth surprise: set bounds on journald and rotate app logs, or your “security effort” becomes a disk incident.

Rollback strategy (keep it boring and reliable)

Security changes should be easy to undo. Plan the rollback before you edit configs.

  • SSH rollback:
    • Keep a root console path (cloud console / recovery mode).
    • Before edits: sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date -u +%Y%m%dT%H%M%SZ)
    • If locked out via console: restore the backup and restart SSH.
  • sysctl rollback:
    • Move the baseline file out of the way: sudo mv /etc/sysctl.d/99-hostmycode-baseline.conf /root/
    • Re-apply defaults: sudo sysctl --system
  • package rollback:
    • If an upgrade breaks a service, pin and downgrade only the affected packages (document the reason).
    • For fast recovery, snapshots plus file-level backups are the practical answer. See VPS snapshot backup automation.

Next steps: turn one audit into a habit

Once the baseline is in place, the real win is consistency.

  1. Schedule monthly audits: run Lynis, archive the report, review findings for real risk.
  2. Alert on unexpected listeners: a simple daily check of ss -lntup diffed against a known-good list catches “mystery ports.”
  3. Add monitoring tied to security signals: auth spikes, repeated SSH failures, disk growth from logs. If you want a low-noise setup, see Linux VPS monitoring with Prometheus and Grafana.
  4. Write down exceptions: if you keep a risky setting for a reason, document it in /var/lib/security-audits/README.txt.

Summary

Linux VPS security auditing works best as a loop: measure, fix, verify, repeat. Lynis gives you fast coverage; your job is choosing changes that reduce real exposure without destabilizing the server. Save the reports, track drift, and treat each finding as a tradeoff you can explain.

If you want a VPS environment where you can apply these baselines cleanly (and reuse them across multiple servers), start with HostMyCode VPS or choose managed VPS hosting if you prefer help with ongoing maintenance under the same “Affordable & Reliable Hosting” approach.

Audits go faster when the underlying setup stays consistent: known images, clear network policy, and snapshots you can trust. HostMyCode provides that foundation on HostMyCode VPS. If your team is small, managed VPS hosting can cover the routine upkeep while you focus on the application.

FAQ

How often should I run Lynis on a VPS?

Monthly is a solid baseline for most teams. Also run it after major upgrades, migrations, or any change that adds ports or introduces new services.

Should I fix every Lynis suggestion?

No. Prioritize the findings that reduce risk for your workload: SSH policy, patching, exposed services, logging, and file permissions. For anything you keep, write down the reason.

Can Lynis replace a firewall, IDS, or WAF?

No. Lynis is a local audit tool. It helps you verify configuration and spot misconfigurations; it doesn’t block traffic or provide full real-time detection.

What’s the safest way to change SSH settings remotely?

Keep an active second session, validate with sshd -t, restart the service (don’t reboot), and confirm a new login works before closing your safety session.

What should I do if audits keep flagging “unknown services”?

Start with ss -lntup and systemctl status to identify what’s listening and why. Disable first, watch the system, then uninstall only if it’s clearly unused.

Linux VPS security auditing in 2026: a practical baseline with Lynis, systemd-analyze, and OpenSSH checks | HostMyCode