Appearance
Lynis Security Auditing Tool Cheat Sheet
Overview
Lynis is an open-source security auditing tool for Unix-based systems (Linux, macOS, BSD). It performs comprehensive security scans to assess system hardening, compliance, and security posture. Lynis checks for vulnerabilities, misconfigurations, and provides recommendations for improving system security.
⚠️ Warning: This tool is intended for authorized security auditing and system assessment only. Ensure you have proper authorization before running on any system.
Installation
Package Manager Installation
bash
# Ubuntu/Debian
sudo apt update
sudo apt install lynis
# CentOS/RHEL/Fedora
sudo yum install lynis
# or
sudo dnf install lynis
# Arch Linux
sudo pacman -S lynis
# macOS with Homebrew
brew install lynis
# Kali Linux (pre-installed)
lynis --version
Manual Installation
bash
# Download latest version
wget https://downloads.cisofy.com/lynis/lynis-3.0.8.tar.gz
tar -xzf lynis-3.0.8.tar.gz
cd lynis
# Run directly
./lynis audit system
# Install system-wide
sudo cp -R lynis /opt/
sudo ln -s /opt/lynis/lynis /usr/local/bin/lynis
Git Installation
bash
# Clone repository
git clone https://github.com/CISOfy/lynis.git
cd lynis
# Run from source
./lynis audit system
# Update to latest version
git pull origin master
Basic Usage
Command Structure
bash
# Basic syntax
lynis [command] [options]
# Get help
lynis --help
lynis show help
# Check version
lynis --version
Available Commands
Command | Description |
---|---|
audit system | Perform system security audit |
audit dockerfile | Audit Dockerfile for security issues |
show | Display information (commands, groups, tests) |
update info | Show update information |
configure | Configure Lynis settings |
System Auditing
Basic System Audit
bash
# Standard system audit
sudo lynis audit system
# Quick audit (reduced tests)
sudo lynis audit system --quick
# Audit with specific tests only
sudo lynis audit system --tests-from-group authentication
# Audit with custom profile
sudo lynis audit system --profile /path/to/custom.prf
Audit Options
bash
# Verbose output
sudo lynis audit system --verbose
# Quiet mode (minimal output)
sudo lynis audit system --quiet
# No colors in output
sudo lynis audit system --no-colors
# Skip specific tests
sudo lynis audit system --skip-test AUTH-9262,AUTH-9264
# Include specific tests only
sudo lynis audit system --tests AUTH-9262,AUTH-9264
Output and Reporting
bash
# Generate report in specific directory
sudo lynis audit system --logfile /var/log/lynis.log --report-file /var/log/lynis-report.dat
# Upload results (requires license)
sudo lynis audit system --upload
# Cronjob mode (non-interactive)
sudo lynis audit system --cronjob
# Pentest mode (show warnings as findings)
sudo lynis audit system --pentest
Test Categories and Groups
Available Test Groups
Group | Description |
---|---|
accounting | Process accounting and auditing |
authentication | Authentication and authorization |
banners | System banners and messages |
boot_services | Boot process and services |
containers | Container security |
crypto | Cryptography and certificates |
file_integrity | File integrity monitoring |
file_permissions | File and directory permissions |
filesystems | Filesystem security |
firewalls | Firewall configuration |
hardening | System hardening |
kernel | Kernel security |
logging | Logging and monitoring |
malware | Malware detection |
networking | Network security |
php | PHP security |
ports_packages | Ports and packages |
printers | Printer security |
processes | Running processes |
scheduling | Task scheduling |
shells | Shell security |
ssh | SSH configuration |
storage | Storage security |
system_integrity | System integrity |
tooling | Security tooling |
virtualization | Virtualization security |
webservers | Web server security |
Running Specific Test Groups
bash
# Authentication tests
sudo lynis audit system --tests-from-group authentication
# Network security tests
sudo lynis audit system --tests-from-group networking
# SSH configuration tests
sudo lynis audit system --tests-from-group ssh
# Multiple groups
sudo lynis audit system --tests-from-group "authentication,networking,ssh"
# Exclude specific groups
sudo lynis audit system --tests-from-group "!malware,!containers"
Individual Test Execution
bash
# List all available tests
lynis show tests
# Run specific test
sudo lynis audit system --tests AUTH-9262
# Run multiple specific tests
sudo lynis audit system --tests "AUTH-9262,AUTH-9264,AUTH-9266"
# Show test details
lynis show test AUTH-9262
Configuration and Customization
Configuration File
bash
# Default configuration locations
/etc/lynis/default.prf
~/.lynis/default.prf
./default.prf
# Create custom configuration
sudo cp /etc/lynis/default.prf /etc/lynis/custom.prf
sudo nano /etc/lynis/custom.prf
# Use custom configuration
sudo lynis audit system --profile /etc/lynis/custom.prf
Common Configuration Options
bash
# Example custom.prf configuration
# Skip specific tests
skip-test=AUTH-9262
skip-test=AUTH-9264
# Configure specific settings
config:ssh_daemon_config_file:/etc/ssh/sshd_config
config:nginx_conf_file:/etc/nginx/nginx.conf
# Set compliance standards
compliance_standards=cis,pci-dss,iso27001
# Configure plugins
plugin=compliance
plugin=security
# Set log file location
logfile=/var/log/lynis-custom.log
# Configure colors
colors=yes
# Set warning level
warning_level=normal
Environment Variables
bash
# Set Lynis data directory
export LYNIS_DATA_DIR=/opt/lynis
# Set custom profile
export LYNIS_PROFILE=/etc/lynis/custom.prf
# Disable colors
export LYNIS_COLORS=no
# Set log file
export LYNIS_LOGFILE=/var/log/lynis-audit.log
Advanced Features
Compliance Auditing
bash
# CIS (Center for Internet Security) compliance
sudo lynis audit system --compliance cis
# PCI-DSS compliance
sudo lynis audit system --compliance pci-dss
# ISO 27001 compliance
sudo lynis audit system --compliance iso27001
# Multiple compliance standards
sudo lynis audit system --compliance "cis,pci-dss,iso27001"
# Generate compliance report
sudo lynis audit system --compliance cis --report-file /var/log/cis-compliance.dat
Container Security Auditing
bash
# Audit Docker containers
sudo lynis audit dockerfile Dockerfile
# Audit container runtime
sudo lynis audit system --tests-from-group containers
# Audit specific container
docker run --rm -v /:/hostfs:ro --pid=host cisofy/lynis lynis audit system
# Kubernetes security audit
sudo lynis audit system --tests-from-group "containers,kubernetes"
Plugin System
bash
# List available plugins
lynis show plugins
# Enable specific plugins
sudo lynis audit system --plugin compliance
sudo lynis audit system --plugin security
# Custom plugin development
# Create plugin in /usr/share/lynis/plugins/
# Follow plugin development guidelines
Automation and Scripting
Automated Security Auditing Script
bash
#!/bin/bash
# Automated Lynis security audit script
HOSTNAME=$(hostname)
DATE=$(date +%Y%m%d_%H%M%S)
LOG_DIR="/var/log/lynis"
REPORT_DIR="/var/reports/lynis"
EMAIL_RECIPIENT="security@company.com"
BASELINE_SCORE=75
# Create directories
sudo mkdir -p "$LOG_DIR" "$REPORT_DIR"
# Function to run audit
run_audit() {
local audit_type=$1
local output_prefix="${REPORT_DIR}/${HOSTNAME}_${audit_type}_${DATE}"
echo "[+] Running $audit_type audit..."
sudo lynis audit system \
--cronjob \
--logfile "${output_prefix}.log" \
--report-file "${output_prefix}.dat" \
--tests-from-group "$audit_type"
return $?
}
# Function to parse results
parse_results() {
local report_file=$1
local audit_type=$2
if [ -f "$report_file" ]; then
# Extract key metrics
local hardening_index=$(grep "hardening_index=" "$report_file" | cut -d'=' -f2)
local tests_performed=$(grep "tests_performed=" "$report_file" | cut -d'=' -f2)
local warnings=$(grep "total_warnings=" "$report_file" | cut -d'=' -f2)
local suggestions=$(grep "total_suggestions=" "$report_file" | cut -d'=' -f2)
echo "=== $audit_type Audit Results ===" >> "${REPORT_DIR}/summary_${DATE}.txt"
echo "Hardening Index: $hardening_index%" >> "${REPORT_DIR}/summary_${DATE}.txt"
echo "Tests Performed: $tests_performed" >> "${REPORT_DIR}/summary_${DATE}.txt"
echo "Warnings: $warnings" >> "${REPORT_DIR}/summary_${DATE}.txt"
echo "Suggestions: $suggestions" >> "${REPORT_DIR}/summary_${DATE}.txt"
echo "" >> "${REPORT_DIR}/summary_${DATE}.txt"
# Check if score meets baseline
if [ "$hardening_index" -lt "$BASELINE_SCORE" ]; then
echo "[WARNING] Hardening index ($hardening_index%) below baseline ($BASELINE_SCORE%)"
send_alert "$audit_type audit score below baseline: $hardening_index%"
fi
fi
}
# Function to send alerts
send_alert() {
local message=$1
echo "[ALERT] $message"
echo "$message" | mail -s "Lynis Security Alert - $HOSTNAME" "$EMAIL_RECIPIENT"
}
# Function to generate HTML report
generate_html_report() {
local summary_file="${REPORT_DIR}/summary_${DATE}.txt"
local html_file="${REPORT_DIR}/report_${DATE}.html"
cat > "$html_file" << EOF
<!DOCTYPE html>
<html>
<head>
<title>Lynis Security Audit Report - $HOSTNAME</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background-color: #f0f0f0; padding: 10px; border-radius: 5px; }
.warning { color: red; font-weight: bold; }
.good { color: green; font-weight: bold; }
.section { margin: 20px 0; padding: 10px; border: 1px solid #ccc; }
</style>
</head>
<body>
<div class="header">
<h1>Lynis Security Audit Report</h1>
<p>Host: $HOSTNAME</p>
<p>Date: $(date)</p>
</div>
<div class="section">
<h2>Audit Summary</h2>
<pre>$(cat "$summary_file")</pre>
</div>
<div class="section">
<h2>Recommendations</h2>
<p>Review the detailed log files for specific recommendations and remediation steps.</p>
</div>
</body>
</html>
EOF
echo "[+] HTML report generated: $html_file"
}
# Main execution
echo "[+] Starting automated Lynis security audit for $HOSTNAME"
# Run different audit categories
AUDIT_CATEGORIES=("authentication" "networking" "ssh" "filesystems" "kernel")
for category in "${AUDIT_CATEGORIES[@]}"; do
if run_audit "$category"; then
parse_results "${REPORT_DIR}/${HOSTNAME}_${category}_${DATE}.dat" "$category"
else
echo "[ERROR] Failed to run $category audit"
send_alert "Failed to run $category audit on $HOSTNAME"
fi
done
# Generate reports
generate_html_report
# Cleanup old reports (keep last 30 days)
find "$REPORT_DIR" -name "*.log" -mtime +30 -delete
find "$REPORT_DIR" -name "*.dat" -mtime +30 -delete
echo "[+] Automated audit complete. Reports saved in $REPORT_DIR"
Continuous Monitoring Script
bash
#!/bin/bash
# Continuous Lynis monitoring script
INTERVAL=86400 # 24 hours
CONFIG_FILE="/etc/lynis/monitoring.conf"
BASELINE_DIR="/var/lib/lynis/baselines"
CURRENT_DIR="/var/lib/lynis/current"
# Load configuration
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
fi
# Default values
ALERT_THRESHOLD=${ALERT_THRESHOLD:-10}
EMAIL_ALERTS=${EMAIL_ALERTS:-"security@company.com"}
SLACK_WEBHOOK=${SLACK_WEBHOOK:-""}
# Function to create baseline
create_baseline() {
echo "[+] Creating security baseline..."
mkdir -p "$BASELINE_DIR"
sudo lynis audit system --cronjob \
--logfile "${BASELINE_DIR}/baseline.log" \
--report-file "${BASELINE_DIR}/baseline.dat"
# Extract baseline metrics
grep "hardening_index=" "${BASELINE_DIR}/baseline.dat" | cut -d'=' -f2 > "${BASELINE_DIR}/baseline_score.txt"
grep "total_warnings=" "${BASELINE_DIR}/baseline.dat" | cut -d'=' -f2 > "${BASELINE_DIR}/baseline_warnings.txt"
echo "[+] Baseline created successfully"
}
# Function to run current audit
run_current_audit() {
local timestamp=$(date +%Y%m%d_%H%M%S)
mkdir -p "$CURRENT_DIR"
echo "[+] Running current security audit..."
sudo lynis audit system --cronjob \
--logfile "${CURRENT_DIR}/current_${timestamp}.log" \
--report-file "${CURRENT_DIR}/current_${timestamp}.dat"
# Create symlinks to latest
ln -sf "${CURRENT_DIR}/current_${timestamp}.log" "${CURRENT_DIR}/latest.log"
ln -sf "${CURRENT_DIR}/current_${timestamp}.dat" "${CURRENT_DIR}/latest.dat"
return $?
}
# Function to compare with baseline
compare_with_baseline() {
local current_score=$(grep "hardening_index=" "${CURRENT_DIR}/latest.dat" | cut -d'=' -f2)
local current_warnings=$(grep "total_warnings=" "${CURRENT_DIR}/latest.dat" | cut -d'=' -f2)
if [ -f "${BASELINE_DIR}/baseline_score.txt" ]; then
local baseline_score=$(cat "${BASELINE_DIR}/baseline_score.txt")
local baseline_warnings=$(cat "${BASELINE_DIR}/baseline_warnings.txt")
local score_diff=$((current_score - baseline_score))
local warning_diff=$((current_warnings - baseline_warnings))
echo "[+] Security Score: $current_score% (baseline: $baseline_score%, diff: $score_diff%)"
echo "[+] Warnings: $current_warnings (baseline: $baseline_warnings, diff: $warning_diff)"
# Check for significant degradation
if [ "$score_diff" -lt "-$ALERT_THRESHOLD" ]; then
send_alert "Security score degraded by ${score_diff}% (current: $current_score%, baseline: $baseline_score%)"
fi
if [ "$warning_diff" -gt "$ALERT_THRESHOLD" ]; then
send_alert "Warning count increased by $warning_diff (current: $current_warnings, baseline: $baseline_warnings)"
fi
else
echo "[WARNING] No baseline found. Creating baseline..."
create_baseline
fi
}
# Function to send alerts
send_alert() {
local message=$1
local hostname=$(hostname)
local timestamp=$(date)
echo "[ALERT] $message"
# Email alert
if [ ! -z "$EMAIL_ALERTS" ]; then
echo "Security Alert for $hostname at $timestamp: $message" | \
mail -s "Lynis Security Alert - $hostname" "$EMAIL_ALERTS"
fi
# Slack alert
if [ ! -z "$SLACK_WEBHOOK" ]; then
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"🚨 Security Alert for $hostname: $message\"}" \
"$SLACK_WEBHOOK"
fi
# Syslog
logger "LYNIS_ALERT: $message"
}
# Function to generate trend report
generate_trend_report() {
local report_file="/var/reports/lynis_trend_$(date +%Y%m%d).html"
cat > "$report_file" << EOF
<!DOCTYPE html>
<html>
<head>
<title>Lynis Security Trend Report</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<h1>Security Trend Analysis</h1>
<canvas id="trendChart" width="400" height="200"></canvas>
<script>
// Generate trend chart from historical data
// This would be populated with actual historical data
var ctx = document.getElementById('trendChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Week 1', 'Week 2', 'Week 3', 'Week 4'],
datasets: [{
label: 'Security Score',
data: [75, 78, 76, 80],
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
max: 100
}
}
}
});
</script>
</body>
</html>
EOF
echo "[+] Trend report generated: $report_file"
}
# Main monitoring loop
echo "[+] Starting Lynis continuous monitoring"
echo "[+] Interval: $INTERVAL seconds"
echo "[+] Alert threshold: $ALERT_THRESHOLD"
# Create baseline if it doesn't exist
if [ ! -f "${BASELINE_DIR}/baseline.dat" ]; then
create_baseline
fi
while true; do
echo "[+] $(date): Running security audit..."
if run_current_audit; then
compare_with_baseline
# Generate weekly trend report
if [ "$(date +%u)" -eq 1 ]; then # Monday
generate_trend_report
fi
else
send_alert "Failed to run security audit"
fi
echo "[+] $(date): Audit complete, sleeping for $INTERVAL seconds"
sleep "$INTERVAL"
done
Compliance Reporting Script
bash
#!/bin/bash
# Compliance reporting script for multiple standards
STANDARDS=("cis" "pci-dss" "iso27001")
OUTPUT_DIR="/var/reports/compliance"
DATE=$(date +%Y%m%d)
# Function to run compliance audit
run_compliance_audit() {
local standard=$1
local output_file="${OUTPUT_DIR}/${standard}_compliance_${DATE}"
echo "[+] Running $standard compliance audit..."
sudo lynis audit system \
--compliance "$standard" \
--cronjob \
--logfile "${output_file}.log" \
--report-file "${output_file}.dat"
# Generate compliance summary
generate_compliance_summary "$standard" "${output_file}.dat"
}
# Function to generate compliance summary
generate_compliance_summary() {
local standard=$1
local report_file=$2
local summary_file="${OUTPUT_DIR}/${standard}_summary_${DATE}.txt"
if [ -f "$report_file" ]; then
echo "=== $standard Compliance Summary ===" > "$summary_file"
echo "Date: $(date)" >> "$summary_file"
echo "Host: $(hostname)" >> "$summary_file"
echo "" >> "$summary_file"
# Extract compliance metrics
local total_tests=$(grep "tests_performed=" "$report_file" | cut -d'=' -f2)
local passed_tests=$(grep -c "result=OK" "$report_file")
local failed_tests=$(grep -c "result=WARNING\|result=SUGGESTION" "$report_file")
local compliance_percentage=$((passed_tests * 100 / total_tests))
echo "Total Tests: $total_tests" >> "$summary_file"
echo "Passed: $passed_tests" >> "$summary_file"
echo "Failed: $failed_tests" >> "$summary_file"
echo "Compliance: $compliance_percentage%" >> "$summary_file"
echo "" >> "$summary_file"
# Extract failed controls
echo "Failed Controls:" >> "$summary_file"
grep "result=WARNING\|result=SUGGESTION" "$report_file" | \
sed 's/.*test=\([^|]*\).*/\1/' | sort -u >> "$summary_file"
echo "[+] $standard compliance summary generated: $summary_file"
fi
}
# Main execution
mkdir -p "$OUTPUT_DIR"
for standard in "${STANDARDS[@]}"; do
run_compliance_audit "$standard"
done
# Generate consolidated report
echo "[+] Generating consolidated compliance report..."
cat "${OUTPUT_DIR}"/*_summary_${DATE}.txt > "${OUTPUT_DIR}/consolidated_compliance_${DATE}.txt"
echo "[+] Compliance reporting complete. Reports saved in $OUTPUT_DIR"
Integration with Other Tools
SIEM Integration
bash
# Syslog integration for SIEM
# Configure rsyslog to forward Lynis alerts
echo "if \$msg contains 'LYNIS_ALERT' then @@siem.company.com:514" | sudo tee -a /etc/rsyslog.conf
sudo systemctl restart rsyslog
# JSON output for structured logging
sudo lynis audit system --cronjob | jq -R -s -c 'split("\n") | map(select(length > 0))'
Ansible Integration
yaml
# Ansible playbook for Lynis deployment
---
- name: Deploy and run Lynis security audit
hosts: all
become: yes
tasks:
- name: Install Lynis
package:
name: lynis
state: present
- name: Create Lynis directories
file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- /var/log/lynis
- /var/reports/lynis
- name: Copy Lynis configuration
template:
src: lynis.prf.j2
dest: /etc/lynis/custom.prf
mode: '0644'
- name: Run Lynis audit
command: lynis audit system --cronjob --profile /etc/lynis/custom.prf
register: lynis_result
- name: Collect Lynis reports
fetch:
src: /var/log/lynis.log
dest: ./reports/{{ inventory_hostname }}_lynis.log
flat: yes
Docker Integration
dockerfile
# Dockerfile for Lynis container
FROM ubuntu:20.04
RUN apt-get update && \
apt-get install -y lynis && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY lynis-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/lynis-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/lynis-entrypoint.sh"]
CMD ["audit", "system"]
Performance Optimization
Resource Management
bash
# Optimize for large systems
sudo lynis audit system --quick --no-colors
# Limit specific resource-intensive tests
sudo lynis audit system --skip-test KRNL-6000,PROC-3602
# Run with nice priority
sudo nice -n 10 lynis audit system
# Monitor resource usage
top -p $(pgrep lynis)
Parallel Execution
bash
# Run multiple test groups in parallel
sudo lynis audit system --tests-from-group authentication &
sudo lynis audit system --tests-from-group networking &
sudo lynis audit system --tests-from-group ssh &
wait
# Parallel compliance audits
for standard in cis pci-dss iso27001; do
sudo lynis audit system --compliance "$standard" &
done
wait
Troubleshooting
Common Issues
bash
# Permission issues
sudo chown -R root:root /usr/share/lynis
sudo chmod +x /usr/share/lynis/lynis
# Missing dependencies
sudo apt install --fix-missing
# Configuration issues
lynis show settings
lynis show profile
# Test execution issues
sudo lynis audit system --debug --verbose
Debug Mode
bash
# Enable debug output
sudo lynis audit system --debug
# Verbose logging
sudo lynis audit system --verbose --logfile /tmp/lynis-debug.log
# Test specific functionality
lynis show tests | grep AUTH
sudo lynis audit system --tests AUTH-9262 --debug
Log Analysis
bash
# Analyze Lynis logs
grep "WARNING\|SUGGESTION" /var/log/lynis.log
# Extract hardening recommendations
grep "Hardening" /var/log/lynis.log
# Monitor real-time execution
tail -f /var/log/lynis.log
Best Practices
Security Auditing Strategy
- Regular audits: Schedule weekly or monthly audits
- Baseline establishment: Create security baselines for comparison
- Incremental improvements: Address findings systematically
- Compliance mapping: Map findings to compliance requirements
- Trend analysis: Monitor security posture over time
Operational Considerations
bash
# Production-safe auditing
sudo lynis audit system --quick --cronjob
# Staged rollout
# 1. Test on development systems
# 2. Validate on staging environment
# 3. Deploy to production with monitoring
# Change management
# Document all configuration changes
# Track remediation progress
# Validate fixes with re-audits
Reporting and Communication
bash
# Executive summary generation
grep "hardening_index\|total_warnings\|total_suggestions" /var/log/lynis-report.dat
# Technical details for teams
grep "suggestion\|warning" /var/log/lynis.log | head -20
# Compliance reporting
sudo lynis audit system --compliance cis --report-file cis-compliance.dat
Resources
- Lynis Official Website
- Lynis GitHub Repository
- Lynis Documentation
- CIS Benchmarks
- Security Hardening Guides
This cheat sheet provides a comprehensive reference for using Lynis. Always ensure you have proper authorization before conducting security audits and system assessments.