Home/Engineer/Security Hardening/Linux System Security Auditi…
Security HardeningAdvancedCentOSRHELUbuntuDebianSELinuxauditdLynis

Linux System Security Auditing — Lynis, auditd, and SELinux in Practice

From automated Lynis audits and auditd event tracing through SELinux policy enforcement — an in-depth guide to measuring and hardening production server security.

Contents
  1. A Three-Stage Security Audit Strategy
  2. Stage 1 — Automated Security Auditing with Lynis
  3. Stage 2 — Event Tracing with auditd
  4. Stage 3 — Applying SELinux Policy (RHEL/CentOS)
  5. Automation — Recurring Security Audit Script

A Three-Stage Security Audit Strategy

Production server security cannot be solved with a single tool. You need to combine three stages: measure (Lynis) → trace (auditd) → enforce (SELinux/AppArmor).


Stage 1 — Automated Security Auditing with Lynis

Lynis scans the entire system, produces a Hardening Index score, and reports weak findings.

Installation

Bash
# RHEL/CentOS
sudo yum install -y lynis

# Ubuntu/Debian
sudo apt install -y lynis

# ( save )
git clone https://github.com/CISOfy/lynis /usr/local/lynis

Running a Full System Audit

Bash
sudo lynis audit system

# (CI )
sudo lynis audit system --quiet

# Result file save
sudo lynis audit system --log-file /var/log/lynis.log --report-file /var/log/lynis-report.dat

Interpreting the Report

Bash
# check (100 )
grep "hardening_index" /var/log/lynis-report.dat

# WARNING
grep "^warning[]" /var/log/lynis-report.dat

# SUGGESTION
grep "^suggestion[]" /var/log/lynis-report.dat

Target score: Keep production servers at 75 or higher. For new servers, aim for 90+ during initial setup.

Manually Remediating Critical Findings

Bash
# AIDE file
sudo apt install -y aide
sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

#
echo "0 3 * * 0 root /usr/bin/aide --check" >> /etc/cron.d/aide-check

# file
sudo apt purge -y gcc make

# USB
echo "install usb-storage /bin/false" > /etc/modprobe.d/disable-usb-storage.conf

Stage 2 — Event Tracing with auditd

auditd records file access, system calls, and privilege changes in real time at the kernel level.

Install and Enable

Bash
sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd

Configuring Core Audit Rules

Bash
# /etc/audit/rules.d/hardening.rules

# (boot to )
-e 2

# when when when
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change

# User· when
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k identity
-w /etc/sudoers.d/ -p wa -k identity

# settings when
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/network/ -p wa -k system-locale

# · when
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins

# when (sudo, su)
-w /bin/su -p x -k priv-esc
-w /usr/bin/sudo -p x -k priv-esc
-w /etc/sudoers -p wa -k priv-esc

# run when ( path)
-a always,exit -F arch=b64 -S execve -k exec
Bash
#
sudo augenrules --load
sudo systemctl restart auditd

# check
sudo auditctl -l

Analyzing auditd Logs

Bash
#
sudo ausearch -k identity --interpret

# failed when
sudo ausearch -m USER_LOGIN --success no

# User
sudo ausearch -ua 1001 -m EXECVE --interpret | grep -A2 "type=EXECVE"

# 1when when
sudo ausearch -k priv-esc --start recent --interpret

#
sudo aureport --summary
sudo aureport --login --summary
sudo aureport --failed --summary

Alerting integration: Use the audisp-remote plugin to stream events in real time to a central SIEM (Splunk, Elastic).


Stage 3 — Applying SELinux Policy (RHEL/CentOS)

SELinux enforces which files and ports a process can access at the kernel level. Misconfiguration can take services down, so apply it in stages.

Understanding Modes

Bash
# check
getenforce          # Enforcing / Permissive / Disabled

#
sestatus

# when Permissive (, boot when )
sudo setenforce 0

# settings (/etc/selinux/config)
SELINUX=enforcing #
SELINUX=permissive # ,
SELINUX=disabled #

Analyzing Denial Logs and Generating Policy

Bash
# SELinux when check
sudo ausearch -m AVC --interpret | tail -30
sudo grep "denied" /var/log/audit/audit.log | tail -20

# audit2why
sudo ausearch -m AVC | audit2why

# audit2allow
sudo ausearch -m AVC | audit2allow -M my_custom_policy
sudo semodule -i my_custom_policy.pp

In Practice — SELinux Configuration for Nginx

Bash
# Nginx (8080) Listen
sudo semanage port -a -t http_port_t -p tcp 8080

# http list
sudo semanage port -l | grep http_port_t

# Nginx upstream
sudo setsebool -P httpd_can_network_connect 1

# Nginx NFS
sudo setsebool -P httpd_use_nfs 1

#
sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
sudo restorecon -Rv /data/www

AppArmor (Ubuntu Alternative)

Bash
# file check
sudo aa-status

# file
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

#
sudo journalctl -f | grep apparmor

# complain ( without )
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

Automation — Recurring Security Audit Script

Bash
#!/bin/bash
# /usr/local/bin/security-audit.sh

REPORT_DIR="/var/log/security-audit"
DATE=$(date +%Y%m%d)
mkdir -p "$REPORT_DIR"

echo "=== Security Audit: $DATE ===" > "$REPORT_DIR/$DATE.txt"

# Lynis
lynis audit system --quiet >> "$REPORT_DIR/$DATE.txt" 2>&1

# failed
echo "--- Failed Logins ---" >> "$REPORT_DIR/$DATE.txt"
aureport --failed --login >> "$REPORT_DIR/$DATE.txt"

# SUID file
find / -perm /4000 -type f 2>/dev/null | sort > /tmp/suid_current.txt
if [ -f /tmp/suid_baseline.txt ]; then
  diff /tmp/suid_baseline.txt /tmp/suid_current.txt | grep "^>" >> "$REPORT_DIR/$DATE.txt"
fi
cp /tmp/suid_current.txt /tmp/suid_baseline.txt

# ( when)
# mail -s "Security Audit $DATE" admin@example.com < "$REPORT_DIR/$DATE.txt"
Bash
# 2when run
echo "0 2 * * * root /usr/local/bin/security-audit.sh" > /etc/cron.d/security-audit
chmod 644 /etc/cron.d/security-audit
#SELinux#auditd#Lynis
Editorial note

AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us

Topic-related official docs (auto-linked · not per-claim sources)Linux man pages ↗OWASP documentation ↗

Questions & answers

Ask a question about this guide. We'll review and reply.