What a server audit with server_audit_notify.sh checks

The script runs Lynis, then checks failed SSH logins, listening ports, disk usage, large files and recent package installs. It saves each result to /var/log/server_audit and emails a summary.

Checks at a glance

All files go to /var/log/server_audit (or the --report-dir you set), and every file name ends with the start time of the run in the form _YYYY-MM-DD_HH-MM-SS.

Checks at a glance
CheckCommandOutput fileIn the email
Security auditlynis audit system --no-colors --quietlynis_<time>.log, lynis-report_<time>.datUp to 20 warnings
Failed SSH loginsgrep "Failed password" on the SSH logssh_failures_<time>.logCount and top 5 IPs
Large filesfind / -type f -size +100Mlarge_files_<time>.logAt the thorough level
Disk usagedf -hdisk_usage_<time>.logYes, without tmpfs and udev
Listening portsss -tuln or netstat -tulnlistening_ports_<time>.logCount and notable ports
Recent packages/var/log/dpkg.log or yum historyrecent_packages_<time>.logAt the thorough level

Lynis security audit

Lynis is an open-source security auditing tool for Linux, macOS and other Unix systems. The script runs lynis audit system --no-colors --quiet and saves the console output. It also passes --report-file, so Lynis writes its findings to lynis-report_<time>.dat. The script copies the last 20 warning[] entries from that file into the summary, each with its Lynis test ID.

If Lynis exits with an error, the script logs the exit status and carries on with the other checks.

The --level option changes what runs:

Lynis security audit
LevelLynis optionsOther differences
basic--tests-from-group "authentication ssh firewalls networking ports_packages"Skips the large file search
standardnone (all test groups)The default
thoroughnone (all test groups)Adds Lynis suggestions, large files and recent packages to the email

The standard and thorough levels run the same Lynis audit, as root, with every test group. The thorough level adds detail to the email. The script does not use the Lynis --pentest option, which the Lynis documentation describes as "Perform a penetration test scan (non-privileged)" and which skips tests that need root.

Failed SSH logins

The script reads the last 50 lines that contain "Failed password" from the first source it finds:

  1. /var/log/auth.log (Debian and Ubuntu with rsyslog)
  2. /var/log/secure (Red Hat style systems)
  3. The systemd journal, through journalctl -u ssh -u sshd

The summary names the source, shows how many lines it found (at most 50), and lists the five IP addresses that appear most often. If none of the sources exists, the section says "Source: none" and reports zero.

Listening ports

The script saves the output of ss -tuln, or netstat -tuln when ss is not installed. Both list listening TCP and UDP sockets with numeric addresses. The summary counts lines in the LISTEN state, which covers TCP only, and prints any socket on ports 22 (SSH), 25 (SMTP), 80 (HTTP), 443 (HTTPS), 3306 (MySQL) or 5432 (PostgreSQL).

If neither tool is installed, the script skips this check and says so in the summary.

Disk usage

The script saves df -h and copies it into the summary without tmpfs and udev lines. If any other file system shows 90% use or more, including 100%, the recommendations include "Free up disk space on partitions with 90% or more usage".

Large files

The script lists up to 20 files larger than 100 MB, largest first. It searches from / and skips /proc, /sys, /dev and /run, so it can take a while on large disks. The basic level skips this search.

Recent package installs

On systems with apt, the script saves the last 50 install lines from /var/log/dpkg.log. On systems with yum, it saves the first 20 lines of yum history.

What the emailed summary looks like

The email body has a short header and then the summary file. The layout below comes from the script at the standard level; values in angle brackets are filled in at run time.

Server Audit Notification
=========================

SERVER AUDIT SUMMARY
====================
Date: <date>
Hostname: <hostname>
IP Address: <first address from hostname -I>
Audit Level: standard
Issues Found: <yes or no>

SYSTEM INFORMATION
------------------
OS: <PRETTY_NAME from /etc/os-release>
Kernel: <uname -r>
Uptime: <uptime -p>

SECURITY WARNINGS
-----------------
- <Lynis warning text> [<Lynis test ID>]

FAILED SSH ATTEMPTS
-------------------
Source: <log file or journalctl>
<N> failed SSH login attempts found (last 50 at most)
Top IP addresses:
<count> <IP address>

DISK USAGE
----------
<df -h without tmpfs and udev>

LISTENING PORTS
---------------
Source: <ss -tuln or netstat -tuln>
<N> listening TCP sockets found
Notable ports:
<lines for ports 22, 25, 80, 443, 3306, 5432>

RECOMMENDATIONS
---------------
1. Review all security warnings
2. Investigate any suspicious failed login attempts
3. Check for unauthorized listening ports
4. Address Lynis security warnings
5. Free up disk space on partitions with 90% or more usage

For detailed information, see the full audit logs in /var/log/server_audit

Generated by server_audit_notify.sh
Powered by Forward Email - https://forwardemail.net

"Issues Found" is yes when there are Lynis warnings, failed SSH logins, or a file system at 90% or more. Recommendations 1 to 3 appear every time; number 4 appears when there are Lynis warnings, and number 5 when a file system is 90% full or more. The thorough level adds LYNIS SUGGESTIONS, LARGE FILES and RECENT PACKAGES sections.

The subject line is Server Audit Report: <hostname> - <YYYY-MM-DD>. By default the email goes out after every run; with --only-on-issues it goes out only when "Issues Found" is yes.

Files written on each run

Files written on each run
FileContents
audit_<time>.logProgress messages of the script and any curl error, with timestamps
summary_<time>.txtThe summary shown above
email_<time>.txtThe email that was sent, with headers
lynis-report_<time>.datThe Lynis report file with all warnings and suggestions
Six check filesOne file per check, listed in the table at the top

The script creates the report directory with mode 700. It does not write the SMTP password to any file.

What the script does not check

The script reports. It does not change system settings or fix findings, apart from installing lynis and curl when they are missing. It also does not check:

The Linux server audit checklist covers these areas with commands and sources.