Build comprehensive security audit compliance automation using Ansible playbooks to enforce security policies, monitor system configurations, and generate compliance reports across your Linux infrastructure fleet.
Prerequisites
- Ansible control node with SSH access
- Root or sudo privileges on target systems
- Basic understanding of security frameworks
- Familiarity with Ansible playbooks
What this solves
Security compliance requires continuous monitoring, policy enforcement, and regular reporting across your infrastructure. Manual compliance checks are time-consuming, error-prone, and don't scale with growing infrastructure. This tutorial shows you how to build a complete audit compliance automation system using Ansible that enforces security policies, monitors system configurations, and generates detailed compliance reports automatically.
Prerequisites
- Ansible control node with SSH access to target hosts
- Root or sudo privileges on all target systems
- Basic understanding of security frameworks (CIS, NIST, SOC2)
- Familiarity with Ansible playbooks and inventory management
Step-by-step configuration
Install and configure Linux audit framework
Start by installing the audit daemon and related tools on your target systems. The audit framework provides kernel-level monitoring of system calls, file access, and security events.
sudo apt update
sudo apt install -y auditd audispd-plugins aide rkhunter chkrootkit
Create Ansible directory structure
Set up a proper directory structure for your audit compliance automation project with organized roles, playbooks, and configuration files.
mkdir -p /opt/audit-compliance/{playbooks,roles,inventory,reports,templates}
cd /opt/audit-compliance
Create role directories
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/tasks
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/templates
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/handlers
mkdir -p roles/{audit-setup,compliance-check,security-hardening,reporting}/vars
Configure audit daemon baseline
Create an Ansible role to configure auditd with comprehensive rules for security monitoring. This establishes the foundation for compliance tracking.
---
- name: Install audit packages
package:
name:
- auditd
- audispd-plugins
- aide
state: present
- name: Configure auditd main configuration
template:
src: auditd.conf.j2
dest: /etc/audit/auditd.conf
backup: yes
notify: restart auditd
- name: Deploy comprehensive audit rules
template:
src: audit.rules.j2
dest: /etc/audit/rules.d/audit.rules
backup: yes
notify: restart auditd
- name: Initialize AIDE database
command: aide --init
args:
creates: /var/lib/aide/aide.db.new.gz
- name: Move AIDE database to production location
command: mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
args:
creates: /var/lib/aide/aide.db.gz
- name: Enable and start auditd service
systemd:
name: auditd
enabled: yes
state: started
Create comprehensive audit rules template
Define audit rules that cover critical security events including file access, privilege escalation, network connections, and system configuration changes.
# Delete all existing rules
-D
Buffer size for audit events
-b 8192
Failure mode (0=silent, 1=printk, 2=panic)
-f 1
Monitor file access and modifications
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege-escalation
-w /etc/sudoers.d/ -p wa -k privilege-escalation
Monitor authentication and authorization
-w /var/log/auth.log -p wa -k authentication
-w /var/log/secure -p wa -k authentication
-w /etc/ssh/sshd_config -p wa -k ssh-config
Monitor system configuration changes
-w /etc/hosts -p wa -k network-config
-w /etc/hostname -p wa -k network-config
-w /etc/resolv.conf -p wa -k network-config
-w /etc/crontab -p wa -k scheduled-tasks
-w /etc/cron.d/ -p wa -k scheduled-tasks
Monitor critical system calls
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-a always,exit -F arch=b32 -S clock_settime -k time-change
Monitor network connections
-a always,exit -F arch=b64 -S socket -F a0=10 -k network-socket
-a always,exit -F arch=b64 -S socket -F a0=2 -k network-socket
Monitor file permission changes
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -k file-permissions
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -k file-ownership
Monitor privilege escalation
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k privilege-escalation
Monitor kernel module loading
-w /sbin/insmod -p x -k kernel-modules
-w /sbin/rmmod -p x -k kernel-modules
-w /sbin/modprobe -p x -k kernel-modules
Make rules immutable
-e 2
Create compliance checking role
Build an Ansible role that performs automated compliance checks against security frameworks like CIS benchmarks and generates structured results.
---
- name: Create compliance report directory
file:
path: /var/log/compliance
state: directory
mode: '0750'
owner: root
group: root
- name: Check SSH configuration compliance
block:
- name: Verify SSH protocol version
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^Protocol'
line: 'Protocol 2'
state: present
check_mode: yes
register: ssh_protocol_check
failed_when: false
- name: Check SSH root login disabled
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
state: present
check_mode: yes
register: ssh_root_check
failed_when: false
- name: Verify SSH key authentication
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PubkeyAuthentication'
line: 'PubkeyAuthentication yes'
state: present
check_mode: yes
register: ssh_pubkey_check
failed_when: false
- name: Check file permission compliance
stat:
path: "{{ item.path }}"
register: file_permissions
loop:
- { path: '/etc/passwd', expected: '0644' }
- { path: '/etc/shadow', expected: '0640' }
- { path: '/etc/group', expected: '0644' }
- { path: '/etc/sudoers', expected: '0440' }
- name: Run AIDE file integrity check
command: aide --check
register: aide_check
failed_when: false
changed_when: false
- name: Check for rootkits with rkhunter
command: rkhunter --check --skip-keypress --report-warnings-only
register: rkhunter_check
failed_when: false
changed_when: false
- name: Generate compliance report
template:
src: compliance-report.j2
dest: "/var/log/compliance/compliance-{{ ansible_date_time.date }}.json"
mode: '0644'
vars:
compliance_results:
ssh_protocol: "{{ ssh_protocol_check }}"
ssh_root_login: "{{ ssh_root_check }}"
ssh_pubkey_auth: "{{ ssh_pubkey_check }}"
file_permissions: "{{ file_permissions }}"
aide_check: "{{ aide_check }}"
rkhunter_results: "{{ rkhunter_check }}"
timestamp: "{{ ansible_date_time.iso8601 }}"
hostname: "{{ ansible_hostname }}"
ip_address: "{{ ansible_default_ipv4.address }}"
Create security hardening role
Implement automated security hardening based on industry standards. This role enforces security policies and configurations across your infrastructure.
---
- name: Configure password policies
block:
- name: Set password minimum length
lineinfile:
path: /etc/login.defs
regexp: '^PASS_MIN_LEN'
line: 'PASS_MIN_LEN 12'
backup: yes
- name: Set password maximum age
lineinfile:
path: /etc/login.defs
regexp: '^PASS_MAX_DAYS'
line: 'PASS_MAX_DAYS 90'
backup: yes
- name: Set password minimum age
lineinfile:
path: /etc/login.defs
regexp: '^PASS_MIN_DAYS'
line: 'PASS_MIN_DAYS 1'
backup: yes
- name: Configure kernel parameters for security
sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
state: present
reload: yes
loop:
- { name: 'net.ipv4.ip_forward', value: '0' }
- { name: 'net.ipv4.conf.all.send_redirects', value: '0' }
- { name: 'net.ipv4.conf.default.send_redirects', value: '0' }
- { name: 'net.ipv4.conf.all.accept_source_route', value: '0' }
- { name: 'net.ipv4.conf.default.accept_source_route', value: '0' }
- { name: 'net.ipv4.conf.all.accept_redirects', value: '0' }
- { name: 'net.ipv4.conf.default.accept_redirects', value: '0' }
- { name: 'net.ipv4.conf.all.log_martians', value: '1' }
- { name: 'net.ipv4.conf.default.log_martians', value: '1' }
- { name: 'kernel.randomize_va_space', value: '2' }
- name: Disable unnecessary services
systemd:
name: "{{ item }}"
enabled: no
state: stopped
loop:
- avahi-daemon
- cups
- bluetooth
failed_when: false
- name: Configure file permissions for critical files
file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
owner: "{{ item.owner | default('root') }}"
group: "{{ item.group | default('root') }}"
loop:
- { path: '/etc/passwd', mode: '0644' }
- { path: '/etc/shadow', mode: '0640', group: 'shadow' }
- { path: '/etc/group', mode: '0644' }
- { path: '/etc/sudoers', mode: '0440' }
- { path: '/boot/grub/grub.cfg', mode: '0600' }
- name: Configure fail2ban for SSH protection
block:
- name: Install fail2ban
package:
name: fail2ban
state: present
- name: Configure fail2ban SSH jail
template:
src: jail.local.j2
dest: /etc/fail2ban/jail.local
backup: yes
notify: restart fail2ban
- name: Enable and start fail2ban
systemd:
name: fail2ban
enabled: yes
state: started
Create automated reporting role
Build comprehensive reporting capabilities that aggregate compliance data, generate dashboards, and send alerts for security violations.
---
- name: Create reporting directories
file:
path: "{{ item }}"
state: directory
mode: '0755'
owner: root
group: root
loop:
- /var/log/compliance/reports
- /var/log/compliance/alerts
- /opt/compliance-dashboard
- name: Generate HTML compliance dashboard
template:
src: dashboard.html.j2
dest: "/var/log/compliance/reports/compliance-dashboard-{{ ansible_date_time.date }}.html"
mode: '0644'
vars:
report_date: "{{ ansible_date_time.date }}"
total_hosts: "{{ groups['all'] | length }}"
- name: Create compliance summary report
template:
src: summary-report.j2
dest: "/var/log/compliance/reports/summary-{{ ansible_date_time.date }}.json"
mode: '0644'
vars:
compliance_summary:
report_date: "{{ ansible_date_time.iso8601 }}"
total_checks: 15
passed_checks: "{{ compliance_passed | default(0) }}"
failed_checks: "{{ compliance_failed | default(0) }}"
hostname: "{{ ansible_hostname }}"
ip_address: "{{ ansible_default_ipv4.address }}"
- name: Check for critical compliance failures
set_fact:
critical_failures: true
when: >
(ssh_root_check.changed | default(false)) or
(aide_check.rc | default(0) != 0) or
(rkhunter_check.rc | default(0) != 0)
- name: Send alert for critical failures
mail:
to: "{{ compliance_email | default('admin@example.com') }}"
subject: "CRITICAL: Compliance failure on {{ ansible_hostname }}"
body: |
Critical compliance failures detected on {{ ansible_hostname }} ({{ ansible_default_ipv4.address }})
Time: {{ ansible_date_time.iso8601 }}
Failures detected:
{% if ssh_root_check.changed | default(false) %}
- SSH root login not properly disabled
{% endif %}
{% if aide_check.rc | default(0) != 0 %}
- AIDE file integrity check failed
{% endif %}
{% if rkhunter_check.rc | default(0) != 0 %}
- Rootkit scanner detected issues
{% endif %}
Please investigate immediately.
when: critical_failures | default(false)
ignore_errors: yes
- name: Generate audit log analysis
shell: |
ausearch -ts today | aureport -au > /var/log/compliance/reports/audit-summary-{{ ansible_date_time.date }}.txt
ausearch -ts today | aureport -f >> /var/log/compliance/reports/audit-summary-{{ ansible_date_time.date }}.txt
ignore_errors: yes
- name: Collect system security metrics
shell: |
echo "Security Metrics Report - {{ ansible_date_time.iso8601 }}" > /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
echo "========================================" >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
echo "Failed login attempts:" >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
grep "Failed password" /var/log/auth.log | wc -l >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
echo "Successful sudo commands:" >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
grep "sudo:" /var/log/auth.log | grep "COMMAND" | wc -l >> /var/log/compliance/reports/security-metrics-{{ ansible_date_time.date }}.txt
ignore_errors: yes
Create main compliance playbook
Combine all roles into a comprehensive playbook that orchestrates the entire compliance automation workflow across your infrastructure.
---
- name: Automated Security Audit and Compliance
hosts: all
become: yes
gather_facts: yes
vars:
compliance_email: "security@example.com"
compliance_schedule: "daily"
retention_days: 30
pre_tasks:
- name: Create timestamp for this run
set_fact:
compliance_run_id: "{{ ansible_date_time.epoch }}"
roles:
- role: audit-setup
tags: ['setup', 'audit']
- role: security-hardening
tags: ['hardening', 'security']
- role: compliance-check
tags: ['compliance', 'check']
- role: reporting
tags: ['reporting', 'alerts']
post_tasks:
- name: Cleanup old compliance reports
find:
paths: /var/log/compliance/reports
age: "{{ retention_days }}d"
file_type: file
register: old_reports
- name: Remove old reports
file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_reports.files }}"
- name: Log compliance run completion
lineinfile:
path: /var/log/compliance/compliance.log
line: "{{ ansible_date_time.iso8601 }} - Compliance run {{ compliance_run_id }} completed on {{ ansible_hostname }}"
create: yes
mode: '0644'
- name: Generate consolidated compliance report
hosts: localhost
gather_facts: no
tasks:
- name: Create consolidated report directory
file:
path: /opt/compliance-reports
state: directory
mode: '0755'
- name: Generate infrastructure-wide compliance summary
template:
src: templates/infrastructure-summary.j2
dest: "/opt/compliance-reports/infrastructure-compliance-{{ ansible_date_time.date }}.html"
mode: '0644'
vars:
total_servers: "{{ groups['all'] | length }}"
report_timestamp: "{{ ansible_date_time.iso8601 }}"
tags: ['reporting', 'summary']
Create inventory and configuration
Set up your Ansible inventory with proper grouping and configure automation scheduling for regular compliance checks.
all:
children:
production:
hosts:
web-01:
ansible_host: 203.0.113.10
compliance_level: high
web-02:
ansible_host: 203.0.113.11
compliance_level: high
db-01:
ansible_host: 203.0.113.20
compliance_level: critical
staging:
hosts:
staging-01:
ansible_host: 203.0.113.50
compliance_level: medium
development:
hosts:
dev-01:
ansible_host: 203.0.113.60
compliance_level: low
vars:
ansible_user: ubuntu
ansible_ssh_private_key_file: ~/.ssh/compliance-key
compliance_email: security-team@example.com
report_retention_days: 90
Configure automated scheduling
Set up cron jobs and systemd timers to run compliance checks automatically and ensure continuous monitoring of your infrastructure.
# Create systemd service for compliance checks
sudo tee /etc/systemd/system/audit-compliance.service > /dev/null << 'EOF'
[Unit]
Description=Automated Security Audit and Compliance Check
After=network.target
[Service]
Type=oneshot
User=root
WorkingDirectory=/opt/audit-compliance
ExecStart=/usr/bin/ansible-playbook -i inventory/hosts.yml playbooks/audit-compliance.yml
StandardOutput=journal
StandardError=journal
EOF
Create systemd timer for daily execution
sudo tee /etc/systemd/system/audit-compliance.timer > /dev/null << 'EOF'
[Unit]
Description=Run audit compliance check daily
Requires=audit-compliance.service
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
EOF
Enable and start the timer
sudo systemctl daemon-reload
sudo systemctl enable audit-compliance.timer
sudo systemctl start audit-compliance.timer
Configure compliance templates
Create the reporting templates that generate readable compliance reports and dashboards for management and audit teams.
Security Compliance Dashboard
Security Compliance Dashboard
Generated: {{ ansible_date_time.iso8601 }} | Infrastructure: {{ total_hosts }} servers
Overall Compliance
{{ ((compliance_passed | default(12)) / 15 * 100) | round(1) }}%
Critical Issues
{{ compliance_failed | default(3) }}
Last Scan
{{ ansible_date_time.date }}
AIDE Status
{% if aide_check.rc == 0 %}PASS{% else %}FAIL{% endif %}
Compliance Check Results
Check
Status
Description
Risk Level
SSH Root Login
{% if not ssh_root_check.changed %}PASS{% else %}FAIL{% endif %}
Root login via SSH disabled
HIGH
File Integrity
{% if aide_check.rc == 0 %}PASS{% else %}FAIL{% endif %}
AIDE file integrity verification
CRITICAL
Rootkit Detection
{% if rkhunter_check.rc == 0 %}PASS{% else %}WARNING{% endif %}
RKHunter rootkit scan
HIGH
Advanced compliance automation
Integrate with external SIEM
Configure integration with external monitoring systems for centralized compliance tracking. This extends your automation to work with existing security infrastructure.
---
- name: Send compliance data to Splunk
uri:
url: "https://splunk.example.com:8088/services/collector"
method: POST
headers:
Authorization: "Splunk {{ splunk_hec_token }}"
Content-Type: "application/json"
body_format: json
body:
time: "{{ ansible_date_time.epoch }}"
host: "{{ ansible_hostname }}"
source: "ansible-compliance"
sourcetype: "compliance:audit"
event:
compliance_score: "{{ compliance_score | default(80) }}"
critical_failures: "{{ critical_failures | default(false) }}"
checks_passed: "{{ compliance_passed | default(12) }}"
checks_failed: "{{ compliance_failed | default(3) }}"
server_ip: "{{ ansible_default_ipv4.address }}"
environment: "{{ group_names[0] }}"
when: splunk_hec_token is defined
ignore_errors: yes
- name: Send alerts to security team Slack
uri:
url: "{{ slack_webhook_url }}"
method: POST
body_format: json
body:
text: "Security compliance alert for {{ ansible_hostname }}"
attachments:
- color: "{% if critical_failures | default(false) %}danger{% else %}good{% endif %}"
fields:
- title: "Hostname"
value: "{{ ansible_hostname }}"
short: true
- title: "IP Address"
value: "{{ ansible_default_ipv4.address }}"
short: true
- title: "Compliance Score"
value: "{{ ((compliance_passed | default(12)) / 15 * 100) | round(1) }}%"
short: true
- title: "Critical Issues"
value: "{{ compliance_failed | default(0) }}"
short: true
when: slack_webhook_url is defined and critical_failures | default(false)
ignore_errors: yes
Create custom compliance policies
Define organization-specific compliance policies that extend beyond standard frameworks to meet your unique security requirements.
---
custom_compliance_checks:
- name: "database_encryption"
description: "Verify database encryption at rest"
commands:
- "grep -i 'encrypt' /etc/mysql/mysql.conf.d/mysqld.cnf || echo 'not_found'"
expected_result: "encrypt"
risk_level: "critical"
- name: "backup_encryption"
description: "Verify backup encryption configuration"
commands:
- "gpg --list-keys | grep backup || echo 'no_backup_key'"
expected_result: "backup"
risk_level: "high"
- name: "network_segmentation"
description: "Check network segmentation rules"
commands:
- "iptables -L | grep -c 'REJECT\|DROP' || echo '0'"
expected_result: ">5"
risk_level: "medium"
- name: "container_security"
description: "Verify container runtime security"
commands:
- "docker info | grep 'Security Options' || echo 'not_configured'"
expected_result: "apparmor"
risk_level: "high"
organization_policies:
password_complexity:
min_length: 12
require_special: true
require_numbers: true
max_age_days: 90
access_controls:
sudo_timeout: 15
session_timeout: 900
max_login_attempts: 3
monitoring_requirements:
log_retention_days: 365
real_time_alerts: true
integrity_checks: "daily"
Verify your setup
Test your audit compliance automation to ensure it works correctly and generates proper reports across your infrastructure.
# Run compliance check on a single host
ansible-playbook -i inventory/hosts.yml playbooks/audit-compliance.yml --limit web-01 --tags compliance
Check systemd timer status
sudo systemctl status audit-compliance.timer
sudo systemctl list-timers audit-compliance.timer
Verify audit rules are loaded
sudo auditctl -l
Test compliance report generation
ansible-playbook -i inventory/hosts.yml playbooks/audit-compliance.yml --tags reporting --check
View recent compliance logs
sudo tail -f /var/log/compliance/compliance.log
Check AIDE database status
sudo aide --check | head -20
You can also integrate this with your existing monitoring infrastructure. For example, you might want to configure auditd with Elasticsearch and Kibana for compliance reporting to visualize your audit data, or set up audit log analysis dashboard with Grafana for real-time monitoring.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Auditd service fails to start | Invalid audit rules syntax | auditctl -D && auditctl -R /etc/audit/rules.d/audit.rules |
| AIDE check takes too long | Database includes too many files | Configure /etc/aide/aide.conf to exclude temporary directories |
| Ansible playbook fails with permission errors | SSH user lacks sudo privileges | Add user to sudoers: usermod -aG sudo username |
| Compliance reports not generated | Template directory missing | Create directory: mkdir -p /var/log/compliance/reports |
| Email alerts not sent | Mail system not configured | Install and configure postfix: apt install postfix mailutils |
| Systemd timer not executing | Timer not enabled or started | systemctl enable --now audit-compliance.timer |
Next steps
- Configure automated compliance scanning with OpenSCAP for additional framework support
- Integrate OSSEC with Splunk for centralized security monitoring to enhance threat detection
- Implement Linux security hardening with CIS benchmarks for comprehensive baseline security
- Configure Ansible Vault for secret management to secure sensitive compliance data
- Set up centralized logging for compliance monitoring with Elasticsearch for scalable log analysis
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Global variables
INSTALL_DIR="/opt/audit-compliance"
SCRIPT_USER="${SUDO_USER:-$(whoami)}"
# Error handling
cleanup() {
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
rm -rf "$INSTALL_DIR" 2>/dev/null || true
}
trap cleanup ERR
# Helper functions
log_info() { echo -e "${GREEN}$1${NC}"; }
log_warn() { echo -e "${YELLOW}$1${NC}"; }
log_error() { echo -e "${RED}$1${NC}"; }
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --help Show this help message"
echo " --no-verify Skip verification checks"
exit 1
}
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root or with sudo"
exit 1
fi
}
detect_distro() {
if [ ! -f /etc/os-release ]; then
log_error "/etc/os-release not found. Cannot detect distribution."
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
export PKG_MGR PKG_INSTALL PKG_UPDATE
}
install_packages() {
log_info "[2/8] Installing required packages..."
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_UPDATE
$PKG_INSTALL auditd audispd-plugins aide rkhunter chkrootkit ansible
else
$PKG_INSTALL audit audit-libs aide rkhunter chkrootkit ansible
fi
}
create_directory_structure() {
log_info "[3/8] Creating directory structure..."
mkdir -p "$INSTALL_DIR"/{playbooks,roles,inventory,reports,templates}
mkdir -p "$INSTALL_DIR"/roles/{audit-setup,compliance-check,security-hardening,reporting}/{tasks,templates,handlers,vars}
chown -R root:root "$INSTALL_DIR"
chmod -R 755 "$INSTALL_DIR"
}
create_ansible_config() {
log_info "[4/8] Creating Ansible configuration..."
cat > "$INSTALL_DIR/ansible.cfg" << 'EOF'
[defaults]
inventory = inventory/hosts
host_key_checking = False
gathering = smart
fact_caching = memory
retry_files_enabled = False
stdout_callback = yaml
bin_ansible_callbacks = True
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
EOF
chmod 644 "$INSTALL_DIR/ansible.cfg"
}
create_audit_role() {
log_info "[5/8] Creating audit setup role..."
cat > "$INSTALL_DIR/roles/audit-setup/tasks/main.yml" << 'EOF'
---
- name: Install audit packages
package:
name:
- "{{ 'auditd' if ansible_os_family == 'Debian' else 'audit' }}"
- "{{ 'audispd-plugins' if ansible_os_family == 'Debian' else 'audit-libs' }}"
- aide
state: present
- name: Configure auditd main configuration
template:
src: auditd.conf.j2
dest: /etc/audit/auditd.conf
backup: yes
mode: '0640'
owner: root
group: root
notify: restart auditd
- name: Deploy comprehensive audit rules
template:
src: audit.rules.j2
dest: /etc/audit/rules.d/audit.rules
backup: yes
mode: '0640'
owner: root
group: root
notify: restart auditd
- name: Initialize AIDE database
command: aide --init
args:
creates: /var/lib/aide/aide.db.new.gz
- name: Move AIDE database to production location
command: mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
args:
creates: /var/lib/aide/aide.db.gz
- name: Enable and start auditd service
systemd:
name: auditd
enabled: yes
state: started
EOF
cat > "$INSTALL_DIR/roles/audit-setup/templates/auditd.conf.j2" << 'EOF'
log_file = /var/log/audit/audit.log
log_format = RAW
log_group = adm
priority_boost = 4
flush = INCREMENTAL_ASYNC
freq = 50
num_logs = 5
disp_qos = lossy
dispatcher = /sbin/audispd
name_format = HOSTNAME
max_log_file = 50
max_log_file_action = ROTATE
space_left = 75
space_left_action = SYSLOG
admin_space_left = 50
admin_space_left_action = SUSPEND
disk_full_action = SUSPEND
disk_error_action = SUSPEND
use_libwrap = yes
tcp_listen_queue = 5
tcp_max_per_addr = 1
tcp_client_max_idle = 0
enable_krb5 = no
krb5_principal = auditd
EOF
cat > "$INSTALL_DIR/roles/audit-setup/templates/audit.rules.j2" << 'EOF'
-D
-b 8192
-f 1
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege-escalation
-w /etc/sudoers.d/ -p wa -k privilege-escalation
-w /var/log/auth.log -p wa -k authentication
-w /var/log/secure -p wa -k authentication
-w /etc/ssh/sshd_config -p wa -k ssh-config
-w /etc/hosts -p wa -k network-config
-w /etc/hostname -p wa -k network-config
-w /etc/resolv.conf -p wa -k network-config
-w /etc/crontab -p wa -k scheduled-tasks
-w /etc/cron.d/ -p wa -k scheduled-tasks
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-e 2
EOF
cat > "$INSTALL_DIR/roles/audit-setup/handlers/main.yml" << 'EOF'
---
- name: restart auditd
systemd:
name: auditd
state: restarted
EOF
}
create_compliance_playbook() {
log_info "[6/8] Creating compliance playbook..."
cat > "$INSTALL_DIR/playbooks/compliance-audit.yml" << 'EOF'
---
- name: Configure Audit Compliance Automation
hosts: all
become: yes
roles:
- audit-setup
- compliance-check
- security-hardening
- reporting
EOF
cat > "$INSTALL_DIR/inventory/hosts" << 'EOF'
[audit-targets]
localhost ansible_connection=local
[audit-targets:vars]
ansible_python_interpreter=/usr/bin/python3
EOF
}
create_systemd_service() {
log_info "[7/8] Creating systemd service for automated compliance checks..."
cat > /etc/systemd/system/audit-compliance.service << EOF
[Unit]
Description=Audit Compliance Automation
After=network.target
[Service]
Type=oneshot
WorkingDirectory=$INSTALL_DIR
ExecStart=/usr/bin/ansible-playbook playbooks/compliance-audit.yml
User=root
Group=root
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/audit-compliance.timer << 'EOF'
[Unit]
Description=Run audit compliance checks daily
Requires=audit-compliance.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable audit-compliance.timer
systemctl start audit-compliance.timer
chmod 644 /etc/systemd/system/audit-compliance.service
chmod 644 /etc/systemd/system/audit-compliance.timer
}
verify_installation() {
log_info "[8/8] Verifying installation..."
if ! systemctl is-active --quiet auditd; then
log_error "auditd service is not running"
return 1
fi
if [ ! -f /var/lib/aide/aide.db.gz ]; then
log_warn "AIDE database not found, this is normal on first run"
fi
if ! ansible --version &>/dev/null; then
log_error "Ansible installation failed"
return 1
fi
if ! systemctl is-enabled --quiet audit-compliance.timer; then
log_error "Compliance automation timer not enabled"
return 1
fi
log_info "Installation completed successfully!"
log_info "Audit compliance automation is now configured and scheduled to run daily"
log_info "Configuration directory: $INSTALL_DIR"
log_info "Run manually with: cd $INSTALL_DIR && ansible-playbook playbooks/compliance-audit.yml"
}
main() {
local skip_verify=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) usage ;;
--no-verify) skip_verify=true; shift ;;
*) log_error "Unknown option: $1"; usage ;;
esac
done
log_info "[1/8] Checking prerequisites..."
check_root
detect_distro
install_packages
create_directory_structure
create_ansible_config
create_audit_role
create_compliance_playbook
create_systemd_service
if [[ "$skip_verify" == false ]]; then
verify_installation
fi
}
main "$@"
Review the script before running. Execute with: bash install.sh