Set up comprehensive Linux audit logging with auditd, integrate with Elasticsearch 8 and Kibana 8 for centralized analysis, and create compliance dashboards for PCI DSS, HIPAA, and SOX reporting requirements.
Prerequisites
- Root or sudo access
- At least 4GB RAM for Elasticsearch
- Java 11 or higher
- 10GB free disk space minimum
What this solves
This tutorial configures Linux auditd to capture comprehensive system activity logs, integrates them with Elasticsearch 8 and Kibana 8 for centralized storage and analysis, and creates compliance dashboards for regulatory requirements like PCI DSS, HIPAA, and SOX. You'll set up audit rules for file access, system calls, network connections, and user activities, then use Filebeat for log shipping and Kibana for visualization and alerting.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions of all components.
sudo apt update && sudo apt upgrade -y
Install auditd and audit utilities
Install the Linux audit framework and utilities for managing audit rules and logs.
sudo apt install -y auditd audispd-plugins
Configure comprehensive audit rules
Create audit rules to monitor file access, system calls, network connections, and authentication events for compliance reporting.
# File access monitoring for PCI DSS
-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 /var/log/auth.log -p wa -k authentication
-w /var/log/secure -p wa -k authentication
System call monitoring
-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
-w /etc/localtime -p wa -k time-change
Network configuration changes
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale
-w /etc/sysconfig/network-scripts/ -p wa -k system-locale
Discretionary access control permission modification
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod
Unauthorized file access attempts
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access
Privileged commands monitoring
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged
-a always,exit -F path=/bin/mount -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged
-a always,exit -F path=/bin/umount -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged
Make the configuration immutable
-e 2
Configure auditd service settings
Configure audit daemon settings for proper log rotation, remote logging capabilities, and performance optimization.
# Log file configuration
log_file = /var/log/audit/audit.log
log_format = RAW
log_group = adm
priority_boost = 4
flush = INCREMENTAL_ASYNC
freq = 50
Disk space management
max_log_file = 50
num_logs = 10
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
Network settings for centralized logging
tcp_listen_port = 60
tcp_listen_queue = 5
tcp_max_per_addr = 1
tcp_client_ports = 1024-65535
tcp_client_max_idle = 0
Performance settings
write_logs = yes
name_format = HOSTNAME
local_events = yes
Install Java for Elasticsearch
Elasticsearch requires Java 11 or later. Install OpenJDK which provides the necessary runtime environment.
sudo apt install -y openjdk-11-jdk
Install Elasticsearch 8
Add the official Elastic repository and install Elasticsearch with security features enabled by default.
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
sudo apt install -y elasticsearch
Configure Elasticsearch for audit logging
Configure Elasticsearch with appropriate memory settings, cluster configuration, and security settings for audit log storage.
# Cluster configuration
cluster.name: audit-cluster
node.name: audit-node-1
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node
Security settings
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
Index lifecycle management
action.destructive_requires_name: true
cluster.routing.allocation.disk.threshold_enabled: true
cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
cluster.routing.allocation.disk.watermark.flood_stage: 95%
Set Elasticsearch memory limits
Configure JVM heap size to half of available RAM for optimal performance. This prevents OutOfMemory errors while leaving memory for the OS and other processes.
-Xms2g
-Xmx2g
Start and configure Elasticsearch
Enable and start Elasticsearch service, then configure the built-in users and create audit-specific indices.
sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch
Wait for service to start
sleep 30
Reset the elastic user password
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic --batch
Install Kibana 8
Install Kibana for visualization and dashboard creation. Kibana will connect to Elasticsearch for audit log analysis.
sudo apt install -y kibana
Configure Kibana connection
Configure Kibana to connect to Elasticsearch with proper security settings and generate enrollment token.
# Generate enrollment token for Kibana
sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
Configure Kibana with the enrollment token (replace TOKEN with actual token)
sudo /usr/share/kibana/bin/kibana-setup --enrollment-token TOKEN
Configure Kibana settings
Set up Kibana configuration for audit log visualization with appropriate security and network settings.
server.port: 5601
server.host: "0.0.0.0"
server.name: "audit-kibana"
server.publicBaseUrl: "http://example.com:5601"
elasticsearch.hosts: ["https://127.0.0.1:9200"]
elasticsearch.serviceAccountToken: "AAEAAWVsYXN0aWMva2liYW5hL2tpYmFuYS1zZXJ2aWNlLWFjY291bnQ6..."
logging.appenders.file.type: file
logging.appenders.file.fileName: /var/log/kibana/kibana.log
logging.appenders.file.layout.type: json
i18n.locale: "en"
Install Filebeat for log shipping
Install Filebeat to ship audit logs from auditd to Elasticsearch with proper parsing and field mapping.
sudo apt install -y filebeat
Configure Filebeat for audit logs
Configure Filebeat to parse audit logs, extract compliance-relevant fields, and ship them to Elasticsearch with proper indexing.
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/audit/audit.log
fields:
logtype: audit
compliance: true
fields_under_root: true
multiline.pattern: '^type='
multiline.negate: true
multiline.match: after
processors:
- decode_json_fields:
fields: ["message"]
target: ""
overwrite_keys: true
- timestamp:
field: "@timestamp"
layouts:
- '2006-01-02T15:04:05.000Z'
- '2006-01-02T15:04:05Z'
test:
- '2023-01-15T14:30:00.123Z'
output.elasticsearch:
hosts: ["https://127.0.0.1:9200"]
protocol: "https"
username: "elastic"
password: "YOUR_ELASTIC_PASSWORD"
ssl.certificate_authorities: ["/etc/elasticsearch/certs/http_ca.crt"]
index: "audit-logs-%{+yyyy.MM.dd}"
template.name: "audit-logs"
template.pattern: "audit-logs-*"
template.settings:
index.number_of_shards: 1
index.number_of_replicas: 0
index.mapping.total_fields.limit: 10000
setup.kibana:
host: "http://127.0.0.1:5601"
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
- dissect:
tokenizer: 'type=%{audit_type} msg=audit(%{timestamp}:%{sequence}): %{audit_data}'
field: "message"
target_prefix: "audit"
Create Elasticsearch index template for audit logs
Create a proper index template with field mappings optimized for audit log analysis and compliance reporting.
curl -X PUT "https://127.0.0.1:9200/_index_template/audit-logs" \
-u elastic:YOUR_ELASTIC_PASSWORD \
-k \
-H "Content-Type: application/json" \
-d '{
"index_patterns": ["audit-logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index.lifecycle.name": "audit-policy",
"index.lifecycle.rollover_alias": "audit-logs"
},
"mappings": {
"properties": {
"@timestamp": {"type": "date"},
"audit.type": {"type": "keyword"},
"audit.timestamp": {"type": "date"},
"audit.sequence": {"type": "long"},
"audit.uid": {"type": "keyword"},
"audit.gid": {"type": "keyword"},
"audit.auid": {"type": "keyword"},
"audit.ses": {"type": "keyword"},
"audit.comm": {"type": "keyword"},
"audit.exe": {"type": "keyword"},
"audit.key": {"type": "keyword"},
"audit.success": {"type": "keyword"},
"audit.exit": {"type": "keyword"},
"audit.ppid": {"type": "long"},
"audit.pid": {"type": "long"},
"host.hostname": {"type": "keyword"},
"logtype": {"type": "keyword"},
"compliance": {"type": "boolean"}
}
}
},
"priority": 100,
"_meta": {
"description": "Template for audit logs with compliance fields"
}
}'
Create index lifecycle policy
Set up an index lifecycle management policy to automatically manage audit log indices based on retention requirements.
curl -X PUT "https://127.0.0.1:9200/_ilm/policy/audit-policy" \
-u elastic:YOUR_ELASTIC_PASSWORD \
-k \
-H "Content-Type: application/json" \
-d '{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "5GB",
"max_age": "7d"
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"set_priority": {
"priority": 50
},
"allocate": {
"number_of_replicas": 0
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"set_priority": {
"priority": 0
},
"allocate": {
"number_of_replicas": 0
}
}
},
"delete": {
"min_age": "2555d"
}
}
}
}'
Start all services
Enable and start auditd, Kibana, and Filebeat services to begin collecting and processing audit logs.
sudo systemctl enable --now auditd
sudo systemctl enable --now kibana
sudo systemctl enable --now filebeat
Load audit rules
sudo augenrules --load
Restart auditd to apply rules
sudo systemctl restart auditd
Create Kibana compliance dashboards
Import pre-built compliance dashboard templates and create custom visualizations for PCI DSS, HIPAA, and SOX reporting.
# Import Filebeat audit module dashboards
sudo filebeat setup --dashboards
Create custom compliance index patterns
curl -X POST "http://127.0.0.1:5601/api/saved_objects/index-pattern/audit-logs-*" \
-H "kbn-xsrf: true" \
-H "Content-Type: application/json" \
-d '{
"attributes": {
"title": "audit-logs-*",
"timeFieldName": "@timestamp",
"fields": "[{\"name\":\"@timestamp\",\"type\":\"date\",\"searchable\":true,\"aggregatable\":true},{\"name\":\"audit.type\",\"type\":\"string\",\"searchable\":true,\"aggregatable\":true},{\"name\":\"audit.key\",\"type\":\"string\",\"searchable\":true,\"aggregatable\":true}]"
}
}'
Configure Kibana alerting for compliance violations
Set up Watcher alerts for compliance violations, failed authentication attempts, and unauthorized access patterns.
curl -X PUT "https://127.0.0.1:9200/_watcher/watch/failed_logins" \
-u elastic:YOUR_ELASTIC_PASSWORD \
-k \
-H "Content-Type: application/json" \
-d '{
"trigger": {
"schedule": {
"interval": "5m"
}
},
"input": {
"search": {
"request": {
"search_type": "query_then_fetch",
"indices": ["audit-logs-*"],
"body": {
"query": {
"bool": {
"must": [
{
"match": {
"audit.type": "USER_AUTH"
}
},
{
"match": {
"audit.success": "no"
}
},
{
"range": {
"@timestamp": {
"gte": "now-5m"
}
}
}
]
}
},
"aggs": {
"failed_attempts": {
"cardinality": {
"field": "audit.uid"
}
}
}
}
}
}
},
"condition": {
"compare": {
"ctx.payload.aggregations.failed_attempts.value": {
"gt": 5
}
}
},
"actions": {
"send_email": {
"email": {
"profile": "standard",
"to": ["admin@example.com"],
"subject": "Security Alert: Multiple Failed Login Attempts",
"body": "Alert: {{ctx.payload.aggregations.failed_attempts.value}} failed login attempts detected in the last 5 minutes. Please investigate immediately."
}
}
}
}'
Create compliance reporting dashboards
Access Kibana web interface
Access Kibana through your web browser to create compliance dashboards. Use the elastic user credentials.
# Get Kibana enrollment token if needed
sudo /usr/share/kibana/bin/kibana-verification-code
Access Kibana at: http://your-server-ip:5601
Login with user: elastic
Password: (the password you reset earlier)
Create PCI DSS compliance dashboard
Create visualizations specifically for PCI DSS compliance requirements including access monitoring, authentication tracking, and system change detection.
Create HIPAA compliance dashboard
Build HIPAA-specific visualizations focusing on data access auditing, user activity monitoring, and breach detection patterns.
Create SOX compliance dashboard
Develop SOX compliance visualizations emphasizing financial system access, administrative changes, and segregation of duties monitoring.
Verify your setup
# Check auditd status and rules
sudo systemctl status auditd
sudo auditctl -l
Verify Elasticsearch is running and accessible
curl -k -u elastic:YOUR_ELASTIC_PASSWORD https://127.0.0.1:9200/_cluster/health
Check Kibana status
sudo systemctl status kibana
Verify Filebeat is shipping logs
sudo systemctl status filebeat
curl -k -u elastic:YOUR_ELASTIC_PASSWORD "https://127.0.0.1:9200/_cat/indices/audit-logs-*"
Test audit logging with a sample event
sudo touch /etc/test-audit-file
sudo rm /etc/test-audit-file
Check if the event appears in logs
sudo ausearch -k identity -ts recent
Configure advanced alerting
Set up privilege escalation alerts
Configure alerts for unauthorized privilege escalation attempts and suspicious sudo usage patterns.
curl -X PUT "https://127.0.0.1:9200/_watcher/watch/privilege_escalation" \
-u elastic:YOUR_ELASTIC_PASSWORD \
-k \
-H "Content-Type: application/json" \
-d '{
"trigger": {
"schedule": {
"interval": "2m"
}
},
"input": {
"search": {
"request": {
"indices": ["audit-logs-*"],
"body": {
"query": {
"bool": {
"must": [
{
"match": {
"audit.key": "privileged"
}
},
{
"range": {
"@timestamp": {
"gte": "now-2m"
}
}
}
]
}
},
"aggs": {
"user_attempts": {
"terms": {
"field": "audit.uid",
"size": 10
}
}
}
}
}
}
},
"condition": {
"compare": {
"ctx.payload.hits.total.value": {
"gt": 10
}
}
},
"actions": {
"log_alert": {
"logging": {
"level": "warn",
"text": "High privilege escalation activity detected: {{ctx.payload.hits.total.value}} events in 2 minutes"
}
}
}
}'
Configure file access violation alerts
Set up monitoring for unauthorized access attempts to sensitive files and directories.
curl -X PUT "https://127.0.0.1:9200/_watcher/watch/file_access_violations" \
-u elastic:YOUR_ELASTIC_PASSWORD \
-k \
-H "Content-Type: application/json" \
-d '{
"trigger": {
"schedule": {
"interval": "1m"
}
},
"input": {
"search": {
"request": {
"indices": ["audit-logs-*"],
"body": {
"query": {
"bool": {
"must": [
{
"match": {
"audit.key": "access"
}
},
{
"match": {
"audit.success": "no"
}
},
{
"range": {
"@timestamp": {
"gte": "now-1m"
}
}
}
]
}
}
}
}
}
},
"condition": {
"compare": {
"ctx.payload.hits.total.value": {
"gte": 1
}
}
},
"actions": {
"log_alert": {
"logging": {
"level": "error",
"text": "Unauthorized file access attempt detected: {{ctx.payload.hits.total.value}} violations"
}
}
}
}'
Performance optimization
Optimize audit rule performance
Fine-tune audit rules to reduce performance impact while maintaining compliance coverage.
# Exclude high-volume, low-value events
-a never,exit -F arch=b64 -S adjtimex -F auid=unset
-a never,exit -F arch=b32 -S adjtimex -F auid=unset
Reduce noise from system processes
-a never,exit -F auid=-1
-a never,exit -F auid=4294967295
Exclude non-compliance relevant directories
-a never,exit -F dir=/proc
-a never,exit -F dir=/sys
-a never,exit -F dir=/dev/pts
Rate limit high-frequency events
-a exit,always -F arch=b64 -S open -F success=0 -F auid>=500 -F rate=100
Configure log compression and archival
Set up automatic compression and archival of older audit logs to manage disk usage while maintaining compliance retention periods.
/var/log/audit/audit.log {
missingok
rotate 99
daily
notifempty
create 0600 root root
compress
delaycompress
postrotate
/bin/kill -HUP cat /var/run/auditd.pid 2> /dev/null 2> /dev/null || true
endscript
}
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Elasticsearch won't start | Insufficient memory or Java heap size | Increase RAM or reduce heap size in /etc/elasticsearch/jvm.options.d/heap.options |
| Kibana shows connection errors | Elasticsearch SSL certificate issues | Copy /etc/elasticsearch/certs/http_ca.crt to Kibana config directory and update kibana.yml |
| Filebeat not shipping logs | Permission issues or wrong log path | Check sudo journalctl -u filebeat and verify /var/log/audit/audit.log permissions |
| High CPU usage from auditd | Too many audit rules or high-frequency events | Review rules in /etc/audit/rules.d/ and add exclusion rules for noisy processes |
| Disk space filling up rapidly | No log rotation or retention policy | Configure proper logrotate settings and Elasticsearch ILM policy |
| Missing compliance data in dashboards | Incorrect field mapping or parsing | Check Filebeat processors and Elasticsearch field mappings with GET /_mapping |
| Watcher alerts not triggering | Wrong query syntax or conditions | Test queries manually in Kibana Dev Tools and verify Watcher is enabled |
Next steps
- Configure ELK stack for centralized logging with Elasticsearch 8, Logstash 8, and Kibana 8 for additional log sources
- Configure OSSEC active response for automated threat blocking to complement audit monitoring
- Configure Elasticsearch cross-cluster replication for disaster recovery for compliance data backup
- Set up Grafana alerting with Prometheus and Elasticsearch metrics for comprehensive monitoring
- Implement Linux security hardening with CIS benchmarks for additional compliance controls
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'
# Configuration variables
ELASTICSEARCH_VERSION="8.11.0"
KIBANA_VERSION="8.11.0"
FILEBEAT_VERSION="8.11.0"
ELASTIC_PASSWORD=""
KIBANA_ENCRYPTION_KEY=""
# Usage function
usage() {
echo "Usage: $0 [--elastic-password PASSWORD] [--help]"
echo " --elastic-password PASSWORD Set Elasticsearch password (default: auto-generated)"
echo " --help Show this help message"
exit 1
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--elastic-password)
ELASTIC_PASSWORD="$2"
shift 2
;;
--help)
usage
;;
*)
echo -e "${RED}Error: Unknown option $1${NC}"
usage
;;
esac
done
# Error handling
cleanup() {
echo -e "${RED}Installation failed. Cleaning up...${NC}"
systemctl stop auditd elasticsearch kibana filebeat 2>/dev/null || true
}
trap cleanup ERR
# Check prerequisites
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Error: This script must be run as root${NC}"
exit 1
fi
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
AUDIT_LOG="/var/log/auth.log"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
AUDIT_LOG="/var/log/secure"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
AUDIT_LOG="/var/log/secure"
;;
*)
echo -e "${RED}Error: Unsupported distribution: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}Error: Cannot detect distribution${NC}"
exit 1
fi
echo -e "${GREEN}Starting auditd + ELK Stack installation for compliance monitoring${NC}"
# Generate passwords if not provided
if [[ -z "$ELASTIC_PASSWORD" ]]; then
ELASTIC_PASSWORD=$(openssl rand -base64 32)
fi
KIBANA_ENCRYPTION_KEY=$(openssl rand -hex 32)
echo -e "${YELLOW}Generated credentials will be saved to /root/elk-credentials.txt${NC}"
echo "[1/8] Updating system packages..."
$PKG_UPDATE
echo "[2/8] Installing auditd and dependencies..."
case "$PKG_MGR" in
apt)
$PKG_INSTALL auditd audispd-plugins curl gnupg2 software-properties-common
;;
dnf|yum)
$PKG_INSTALL audit audit-libs curl gnupg2
;;
esac
echo "[3/8] Configuring comprehensive audit rules..."
cat > /etc/audit/rules.d/compliance.rules << 'EOF'
# File access monitoring for PCI DSS
-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 /var/log/auth.log -p wa -k authentication
-w /var/log/secure -p wa -k authentication
# System call monitoring
-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
-w /etc/localtime -p wa -k time-change
# Network configuration changes
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
# Permission modifications
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
# Unauthorized access attempts
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
# Privileged commands
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/bin/mount -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/bin/umount -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
# Make configuration immutable
-e 2
EOF
# Configure auditd settings
cat > /etc/audit/auditd.conf << 'EOF'
log_file = /var/log/audit/audit.log
log_format = ENRICHED
log_group = root
priority_boost = 4
flush = INCREMENTAL_ASYNC
freq = 50
num_logs = 10
disp_qos = lossy
dispatcher = /sbin/audispd
name_format = HOSTNAME
max_log_file = 100
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
chmod 640 /etc/audit/auditd.conf
chown root:root /etc/audit/auditd.conf
echo "[4/8] Installing Elasticsearch..."
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elastic-keyring.gpg
case "$PKG_MGR" in
apt)
echo "deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" > /etc/apt/sources.list.d/elastic-8.x.list
apt update
$PKG_INSTALL elasticsearch=$ELASTICSEARCH_VERSION
;;
dnf|yum)
cat > /etc/yum.repos.d/elasticsearch.repo << EOF
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
EOF
$PKG_INSTALL --enablerepo=elasticsearch elasticsearch-$ELASTICSEARCH_VERSION
;;
esac
# Configure Elasticsearch
cat > /etc/elasticsearch/elasticsearch.yml << EOF
cluster.name: compliance-cluster
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: localhost
http.port: 9200
discovery.type: single-node
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
EOF
chown root:elasticsearch /etc/elasticsearch/elasticsearch.yml
chmod 660 /etc/elasticsearch/elasticsearch.yml
echo "[5/8] Installing and configuring Kibana..."
case "$PKG_MGR" in
apt)
$PKG_INSTALL kibana=$KIBANA_VERSION
;;
dnf|yum)
$PKG_INSTALL --enablerepo=elasticsearch kibana-$KIBANA_VERSION
;;
esac
cat > /etc/kibana/kibana.yml << EOF
server.port: 5601
server.host: "localhost"
elasticsearch.hosts: ["http://localhost:9200"]
elasticsearch.username: "elastic"
elasticsearch.password: "$ELASTIC_PASSWORD"
xpack.encryptedSavedObjects.encryptionKey: "$KIBANA_ENCRYPTION_KEY"
EOF
chown root:kibana /etc/kibana/kibana.yml
chmod 660 /etc/kibana/kibana.yml
echo "[6/8] Installing and configuring Filebeat..."
case "$PKG_MGR" in
apt)
$PKG_INSTALL filebeat=$FILEBEAT_VERSION
;;
dnf|yum)
$PKG_INSTALL --enablerepo=elasticsearch filebeat-$FILEBEAT_VERSION
;;
esac
cat > /etc/filebeat/filebeat.yml << EOF
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/audit/audit.log
fields:
logtype: auditd
fields_under_root: true
output.elasticsearch:
hosts: ["localhost:9200"]
username: "elastic"
password: "$ELASTIC_PASSWORD"
index: "auditd-logs-%{+yyyy.MM.dd}"
setup.template.name: "auditd-logs"
setup.template.pattern: "auditd-logs-*"
setup.kibana:
host: "localhost:5601"
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
EOF
chown root:root /etc/filebeat/filebeat.yml
chmod 600 /etc/filebeat/filebeat.yml
echo "[7/8] Starting and enabling services..."
systemctl daemon-reload
systemctl enable auditd elasticsearch kibana filebeat
systemctl start auditd
systemctl start elasticsearch
# Wait for Elasticsearch to start
echo "Waiting for Elasticsearch to start..."
sleep 30
# Set elastic password
curl -X POST "localhost:9200/_security/user/elastic/_password" -H "Content-Type: application/json" -d"{\"password\":\"$ELASTIC_PASSWORD\"}" -u elastic:changeme 2>/dev/null || true
systemctl start kibana
systemctl start filebeat
echo "[8/8] Saving credentials and verifying installation..."
cat > /root/elk-credentials.txt << EOF
Elasticsearch Password: $ELASTIC_PASSWORD
Kibana Encryption Key: $KIBANA_ENCRYPTION_KEY
Access URLs:
Kibana: http://localhost:5601
Elasticsearch: http://localhost:9200
Username: elastic
Password: $ELASTIC_PASSWORD
EOF
chmod 600 /root/elk-credentials.txt
# Verification checks
echo -e "${YELLOW}Performing verification checks...${NC}"
if systemctl is-active --quiet auditd; then
echo -e "${GREEN}✓ auditd is running${NC}"
else
echo -e "${RED}✗ auditd is not running${NC}"
fi
if systemctl is-active --quiet elasticsearch; then
echo -e "${GREEN}✓ Elasticsearch is running${NC}"
else
echo -e "${RED}✗ Elasticsearch is not running${NC}"
fi
if systemctl is-active --quiet kibana; then
echo -e "${GREEN}✓ Kibana is running${NC}"
else
echo -e "${RED}✗ Kibana is not running${NC}"
fi
if systemctl is-active --quiet filebeat; then
echo -e "${GREEN}✓ Filebeat is running${NC}"
else
echo -e "${RED}✗ Filebeat is not running${NC}"
fi
echo -e "${GREEN}Installation completed successfully!${NC}"
echo -e "${YELLOW}Credentials saved to: /root/elk-credentials.txt${NC}"
echo -e "${YELLOW}Access Kibana at: http://localhost:5601${NC}"
echo -e "${YELLOW}Username: elastic${NC}"
echo -e "${YELLOW}Password: $ELASTIC_PASSWORD${NC}"
Review the script before running. Execute with: bash install.sh