Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
This commit is contained in:
@@ -0,0 +1,575 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################
|
||||
#### Audit Log Analyzer Script for SELinux and AppArmor ####
|
||||
#### Parses denial logs and suggests fix commands ####
|
||||
#### ####
|
||||
#### Author: Phil Connor ####
|
||||
#### Contact: contact@mylinux.work ####
|
||||
#### License: MIT ####
|
||||
#### Version 1.00 ####
|
||||
#### ####
|
||||
#### To use this script chmod it to 755 ####
|
||||
#### or simply type bash <filename.sh> ####
|
||||
#############################################################
|
||||
|
||||
# ── Colors ────────────────────────────────────────────────
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ── Defaults ──────────────────────────────────────────────
|
||||
MODE="recent"
|
||||
OUTPUT_FILE=""
|
||||
QUIET=0
|
||||
TOTAL_DENIALS=0
|
||||
UNIQUE_TYPES=0
|
||||
SUGGESTED_FIXES=0
|
||||
|
||||
# ── Functions ─────────────────────────────────────────────
|
||||
|
||||
usage() {
|
||||
echo -e "${BOLD}Audit Log Analyzer — SELinux & AppArmor${NC}"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --help Show this help message"
|
||||
echo " --recent Analyze denials from the last hour only (default)"
|
||||
echo " --all Analyze all denials in the log"
|
||||
echo " --output FILE Save suggested fixes to FILE"
|
||||
echo " --quiet Show suggestions only, suppress raw denial lines"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " sudo bash $0 --recent"
|
||||
echo " sudo bash $0 --all --output fixes.txt"
|
||||
echo " sudo bash $0 --quiet --output /tmp/fixes.txt"
|
||||
exit 0
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}Error: This script must be run as root.${NC}"
|
||||
echo "Please run with: sudo bash $0"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
detect_mac_system() {
|
||||
SELINUX_ACTIVE=0
|
||||
APPARMOR_ACTIVE=0
|
||||
|
||||
# Check SELinux
|
||||
if command -v getenforce &>/dev/null; then
|
||||
SELINUX_STATUS=$(getenforce 2>/dev/null)
|
||||
if [[ "$SELINUX_STATUS" == "Enforcing" || "$SELINUX_STATUS" == "Permissive" ]]; then
|
||||
SELINUX_ACTIVE=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check AppArmor
|
||||
if command -v aa-status &>/dev/null; then
|
||||
if aa-status &>/dev/null; then
|
||||
APPARMOR_ACTIVE=1
|
||||
fi
|
||||
elif [[ -d /sys/module/apparmor ]]; then
|
||||
APPARMOR_ACTIVE=1
|
||||
fi
|
||||
|
||||
if [[ $SELINUX_ACTIVE -eq 0 && $APPARMOR_ACTIVE -eq 0 ]]; then
|
||||
echo -e "${YELLOW}Warning: Neither SELinux nor AppArmor appears to be active on this system.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
output_line() {
|
||||
local line="$1"
|
||||
echo -e "$line"
|
||||
if [[ -n "$OUTPUT_FILE" ]]; then
|
||||
echo -e "$line" | sed 's/\x1b\[[0-9;]*m//g' >> "$OUTPUT_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── SELinux Analysis ──────────────────────────────────────
|
||||
|
||||
parse_selinux_denial() {
|
||||
local line="$1"
|
||||
|
||||
local scontext tcontext tclass perm comm name path
|
||||
|
||||
scontext=$(echo "$line" | grep -oP 'scontext=\K[^ ]+')
|
||||
tcontext=$(echo "$line" | grep -oP 'tcontext=\K[^ ]+')
|
||||
tclass=$(echo "$line" | grep -oP 'tclass=\K[^ ]+')
|
||||
perm=$(echo "$line" | grep -oP '\{ \K[^}]+')
|
||||
comm=$(echo "$line" | grep -oP 'comm="\K[^"]+')
|
||||
name=$(echo "$line" | grep -oP 'name="\K[^"]+')
|
||||
path=$(echo "$line" | grep -oP 'path="\K[^"]+')
|
||||
|
||||
if [[ $QUIET -eq 0 ]]; then
|
||||
output_line "${RED}DENIAL:${NC} $line"
|
||||
fi
|
||||
|
||||
output_line "${CYAN} Source context:${NC} $scontext"
|
||||
output_line "${CYAN} Target context:${NC} $tcontext"
|
||||
output_line "${CYAN} Class:${NC} $tclass"
|
||||
output_line "${CYAN} Permission:${NC} $perm"
|
||||
[[ -n "$comm" ]] && output_line "${CYAN} Command:${NC} $comm"
|
||||
[[ -n "$path" ]] && output_line "${CYAN} Path:${NC} $path"
|
||||
|
||||
suggest_selinux_fix "$scontext" "$tcontext" "$tclass" "$perm" "$path" "$name"
|
||||
output_line ""
|
||||
}
|
||||
|
||||
suggest_selinux_fix() {
|
||||
local scontext="$1" tcontext="$2" tclass="$3" perm="$4" path="$5" name="$6"
|
||||
|
||||
((SUGGESTED_FIXES++))
|
||||
|
||||
# Port binding denials
|
||||
if [[ "$tclass" == "tcp_socket" || "$tclass" == "udp_socket" ]]; then
|
||||
local stype
|
||||
stype=$(echo "$scontext" | cut -d: -f3)
|
||||
output_line "${GREEN} Suggested fix (port rule):${NC}"
|
||||
output_line "${GREEN} semanage port -a -t ${stype} -p tcp <PORT_NUMBER>${NC}"
|
||||
output_line "${YELLOW} (Replace <PORT_NUMBER> with the actual port)${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
# File access denials
|
||||
if [[ -n "$path" && ("$tclass" == "file" || "$tclass" == "dir" || "$tclass" == "lnk_file") ]]; then
|
||||
local ttype
|
||||
ttype=$(echo "$tcontext" | cut -d: -f3)
|
||||
output_line "${GREEN} Suggested fix (file context):${NC}"
|
||||
output_line "${GREEN} semanage fcontext -a -t ${ttype} \"${path}\"${NC}"
|
||||
output_line "${GREEN} restorecon -Rv \"${path}\"${NC}"
|
||||
|
||||
# Also check for boolean solutions
|
||||
suggest_selinux_boolean "$scontext" "$tcontext" "$tclass" "$perm"
|
||||
return
|
||||
fi
|
||||
|
||||
# General boolean suggestion
|
||||
suggest_selinux_boolean "$scontext" "$tcontext" "$tclass" "$perm"
|
||||
}
|
||||
|
||||
suggest_selinux_boolean() {
|
||||
local scontext="$1" tcontext="$2" tclass="$3" perm="$4"
|
||||
local stype
|
||||
stype=$(echo "$scontext" | cut -d: -f3)
|
||||
|
||||
# Try to find relevant booleans
|
||||
if command -v getsebool &>/dev/null; then
|
||||
local booleans
|
||||
booleans=$(getsebool -a 2>/dev/null | grep -i "${stype%%_t}" | head -5)
|
||||
if [[ -n "$booleans" ]]; then
|
||||
output_line "${GREEN} Possibly relevant booleans:${NC}"
|
||||
while IFS= read -r bool_line; do
|
||||
local bool_name
|
||||
bool_name=$(echo "$bool_line" | cut -d' ' -f1)
|
||||
output_line "${GREEN} setsebool -P ${bool_name} on${NC}"
|
||||
done <<< "$booleans"
|
||||
fi
|
||||
fi
|
||||
|
||||
output_line "${YELLOW} If no boolean applies, consider generating a custom policy module (see below).${NC}"
|
||||
}
|
||||
|
||||
categorize_selinux_denial() {
|
||||
local line="$1"
|
||||
local tclass
|
||||
tclass=$(echo "$line" | grep -oP 'tclass=\K[^ ]+')
|
||||
|
||||
case "$tclass" in
|
||||
file|dir|lnk_file|fifo_file|sock_file)
|
||||
echo "file_access"
|
||||
;;
|
||||
tcp_socket|udp_socket|rawip_socket|netlink_socket)
|
||||
echo "network"
|
||||
;;
|
||||
*_port_t)
|
||||
echo "port_binding"
|
||||
;;
|
||||
process|process2)
|
||||
echo "process"
|
||||
;;
|
||||
*)
|
||||
echo "other"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
analyze_selinux() {
|
||||
output_line "${BOLD}═══════════════════════════════════════════════════${NC}"
|
||||
output_line "${BOLD} SELinux Audit Log Analysis${NC}"
|
||||
output_line "${BOLD}═══════════════════════════════════════════════════${NC}"
|
||||
output_line ""
|
||||
|
||||
local selinux_status
|
||||
selinux_status=$(getenforce 2>/dev/null)
|
||||
output_line "${CYAN}SELinux status:${NC} $selinux_status"
|
||||
output_line ""
|
||||
|
||||
# Gather denials
|
||||
local denials=""
|
||||
|
||||
if [[ "$MODE" == "recent" ]]; then
|
||||
if command -v ausearch &>/dev/null; then
|
||||
denials=$(ausearch -m avc -ts recent 2>/dev/null | grep "type=AVC")
|
||||
fi
|
||||
# Fallback to log file
|
||||
if [[ -z "$denials" && -f /var/log/audit/audit.log ]]; then
|
||||
local one_hour_ago
|
||||
one_hour_ago=$(date -d '1 hour ago' '+%s' 2>/dev/null)
|
||||
if [[ -n "$one_hour_ago" ]]; then
|
||||
denials=$(awk -v cutoff="$one_hour_ago" '
|
||||
/type=AVC/ {
|
||||
match($0, /msg=audit\(([0-9]+)\./, arr)
|
||||
if (arr[1] >= cutoff) print
|
||||
}
|
||||
' /var/log/audit/audit.log)
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [[ -f /var/log/audit/audit.log ]]; then
|
||||
denials=$(grep "type=AVC" /var/log/audit/audit.log)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$denials" ]]; then
|
||||
output_line "${GREEN}No AVC denials found.${NC}"
|
||||
output_line ""
|
||||
return
|
||||
fi
|
||||
|
||||
# Group denials by category
|
||||
declare -A categories
|
||||
local denial_count=0
|
||||
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
((denial_count++))
|
||||
local category
|
||||
category=$(categorize_selinux_denial "$line")
|
||||
categories["$category"]+="$line"$'\n'
|
||||
done <<< "$denials"
|
||||
|
||||
TOTAL_DENIALS=$denial_count
|
||||
|
||||
# Count unique types
|
||||
local unique
|
||||
unique=$(echo "$denials" | grep -oP 'tclass=\K[^ ]+' | sort -u | wc -l)
|
||||
UNIQUE_TYPES=$unique
|
||||
|
||||
# Display grouped results
|
||||
for category in "file_access" "network" "port_binding" "process" "other"; do
|
||||
if [[ -n "${categories[$category]}" ]]; then
|
||||
local label
|
||||
case "$category" in
|
||||
file_access) label="File Access Denials" ;;
|
||||
network) label="Network Denials" ;;
|
||||
port_binding) label="Port Binding Denials" ;;
|
||||
process) label="Process Denials" ;;
|
||||
other) label="Other Denials" ;;
|
||||
esac
|
||||
|
||||
output_line "${BOLD}── ${label} ──────────────────────────────────${NC}"
|
||||
output_line ""
|
||||
|
||||
while IFS= read -r denial_line; do
|
||||
[[ -z "$denial_line" ]] && continue
|
||||
parse_selinux_denial "$denial_line"
|
||||
done <<< "${categories[$category]}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Generate policy module suggestion with audit2allow
|
||||
if command -v audit2allow &>/dev/null; then
|
||||
output_line "${BOLD}── Policy Module Suggestion ──────────────────────${NC}"
|
||||
output_line ""
|
||||
local policy
|
||||
if [[ "$MODE" == "recent" ]]; then
|
||||
policy=$(ausearch -m avc -ts recent 2>/dev/null | audit2allow 2>/dev/null)
|
||||
else
|
||||
policy=$(audit2allow < /var/log/audit/audit.log 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [[ -n "$policy" ]]; then
|
||||
output_line "${GREEN}audit2allow suggests the following policy:${NC}"
|
||||
output_line "$policy"
|
||||
output_line ""
|
||||
output_line "${YELLOW}To create and install a custom module:${NC}"
|
||||
output_line "${GREEN} ausearch -m avc -ts recent | audit2allow -M my_custom_policy${NC}"
|
||||
output_line "${GREEN} semodule -i my_custom_policy.pp${NC}"
|
||||
else
|
||||
output_line "${CYAN}No policy suggestions generated by audit2allow.${NC}"
|
||||
fi
|
||||
output_line ""
|
||||
else
|
||||
output_line "${YELLOW}Note: Install audit2allow (policycoreutils-python-utils) for automatic policy generation.${NC}"
|
||||
output_line ""
|
||||
fi
|
||||
}
|
||||
|
||||
# ── AppArmor Analysis ────────────────────────────────────
|
||||
|
||||
find_apparmor_log_source() {
|
||||
if [[ -f /var/log/syslog ]]; then
|
||||
echo "syslog"
|
||||
elif [[ -f /var/log/kern.log ]]; then
|
||||
echo "kern.log"
|
||||
elif command -v journalctl &>/dev/null; then
|
||||
echo "journalctl"
|
||||
else
|
||||
echo "none"
|
||||
fi
|
||||
}
|
||||
|
||||
parse_apparmor_denial() {
|
||||
local line="$1"
|
||||
|
||||
local profile operation denied_mask path info
|
||||
|
||||
profile=$(echo "$line" | grep -oP 'profile="\K[^"]+')
|
||||
[[ -z "$profile" ]] && profile=$(echo "$line" | grep -oP 'apparmor="\K[^"]+')
|
||||
operation=$(echo "$line" | grep -oP 'operation="\K[^"]+')
|
||||
denied_mask=$(echo "$line" | grep -oP 'requested_mask="\K[^"]+')
|
||||
[[ -z "$denied_mask" ]] && denied_mask=$(echo "$line" | grep -oP 'denied_mask="\K[^"]+')
|
||||
path=$(echo "$line" | grep -oP 'name="\K[^"]+')
|
||||
info=$(echo "$line" | grep -oP 'info="\K[^"]+')
|
||||
|
||||
if [[ $QUIET -eq 0 ]]; then
|
||||
output_line "${RED}DENIAL:${NC} $line"
|
||||
fi
|
||||
|
||||
[[ -n "$profile" ]] && output_line "${CYAN} Profile:${NC} $profile"
|
||||
[[ -n "$operation" ]] && output_line "${CYAN} Operation:${NC} $operation"
|
||||
[[ -n "$path" ]] && output_line "${CYAN} Path:${NC} $path"
|
||||
[[ -n "$denied_mask" ]] && output_line "${CYAN} Denied mask:${NC} $denied_mask"
|
||||
[[ -n "$info" ]] && output_line "${CYAN} Info:${NC} $info"
|
||||
|
||||
suggest_apparmor_fix "$profile" "$operation" "$path" "$denied_mask"
|
||||
output_line ""
|
||||
}
|
||||
|
||||
suggest_apparmor_fix() {
|
||||
local profile="$1" operation="$2" path="$3" denied_mask="$4"
|
||||
|
||||
((SUGGESTED_FIXES++))
|
||||
|
||||
# Build the permission string from the denied mask
|
||||
local perm_str=""
|
||||
case "$denied_mask" in
|
||||
r) perm_str="r" ;;
|
||||
w) perm_str="w" ;;
|
||||
rw) perm_str="rw" ;;
|
||||
x) perm_str="ix" ;;
|
||||
rx) perm_str="rix" ;;
|
||||
rwx) perm_str="rwix" ;;
|
||||
k) perm_str="k" ;;
|
||||
l) perm_str="l" ;;
|
||||
m) perm_str="m" ;;
|
||||
*) perm_str="$denied_mask" ;;
|
||||
esac
|
||||
|
||||
if [[ -n "$path" && -n "$perm_str" ]]; then
|
||||
output_line "${GREEN} Suggested rule to add to profile:${NC}"
|
||||
output_line "${GREEN} ${path} ${perm_str},${NC}"
|
||||
fi
|
||||
|
||||
# Show the profile file path
|
||||
if [[ -n "$profile" ]]; then
|
||||
local profile_file="/etc/apparmor.d/${profile//\//.}"
|
||||
# Try to find the actual profile file
|
||||
if [[ -f "/etc/apparmor.d/$profile" ]]; then
|
||||
profile_file="/etc/apparmor.d/$profile"
|
||||
elif [[ -f "/etc/apparmor.d/${profile//\//.}" ]]; then
|
||||
profile_file="/etc/apparmor.d/${profile//\//.}"
|
||||
else
|
||||
# Search for it
|
||||
local found
|
||||
found=$(grep -rl "profile $profile" /etc/apparmor.d/ 2>/dev/null | head -1)
|
||||
[[ -n "$found" ]] && profile_file="$found"
|
||||
fi
|
||||
output_line "${CYAN} Profile file:${NC} $profile_file"
|
||||
fi
|
||||
|
||||
output_line "${YELLOW} Or run interactively:${NC}"
|
||||
output_line "${GREEN} aa-logprof${NC}"
|
||||
}
|
||||
|
||||
analyze_apparmor() {
|
||||
output_line "${BOLD}═══════════════════════════════════════════════════${NC}"
|
||||
output_line "${BOLD} AppArmor Audit Log Analysis${NC}"
|
||||
output_line "${BOLD}═══════════════════════════════════════════════════${NC}"
|
||||
output_line ""
|
||||
|
||||
# Show AppArmor status
|
||||
if command -v aa-status &>/dev/null; then
|
||||
local enforced loaded
|
||||
enforced=$(aa-status 2>/dev/null | grep -c "enforce")
|
||||
loaded=$(aa-status 2>/dev/null | grep -c "loaded")
|
||||
output_line "${CYAN}AppArmor profiles loaded:${NC} $loaded"
|
||||
output_line "${CYAN}Profiles in enforce mode:${NC} $enforced"
|
||||
output_line ""
|
||||
fi
|
||||
|
||||
# Find log source
|
||||
local log_source
|
||||
log_source=$(find_apparmor_log_source)
|
||||
|
||||
if [[ "$log_source" == "none" ]]; then
|
||||
output_line "${RED}Error: Cannot find AppArmor log source.${NC}"
|
||||
output_line "${YELLOW}Checked: /var/log/syslog, /var/log/kern.log, journalctl${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
# Gather denials
|
||||
local denials=""
|
||||
|
||||
if [[ "$log_source" == "journalctl" ]]; then
|
||||
if [[ "$MODE" == "recent" ]]; then
|
||||
denials=$(journalctl --since "1 hour ago" --no-pager 2>/dev/null | grep -i "apparmor.*DENIED")
|
||||
else
|
||||
denials=$(journalctl --no-pager 2>/dev/null | grep -i "apparmor.*DENIED")
|
||||
fi
|
||||
else
|
||||
local log_file
|
||||
[[ "$log_source" == "syslog" ]] && log_file="/var/log/syslog"
|
||||
[[ "$log_source" == "kern.log" ]] && log_file="/var/log/kern.log"
|
||||
|
||||
if [[ "$MODE" == "recent" ]]; then
|
||||
local one_hour_ago
|
||||
one_hour_ago=$(date -d '1 hour ago' '+%b %e %H:%M' 2>/dev/null)
|
||||
if [[ -n "$one_hour_ago" ]]; then
|
||||
denials=$(awk -v cutoff="$(date -d '1 hour ago' '+%s' 2>/dev/null)" '
|
||||
/apparmor.*DENIED/ || /apparmor.*denied/ {
|
||||
print
|
||||
}
|
||||
' "$log_file" | tail -100)
|
||||
else
|
||||
# Fallback: last 100 denial lines
|
||||
denials=$(grep -i "apparmor.*DENIED" "$log_file" | tail -100)
|
||||
fi
|
||||
else
|
||||
denials=$(grep -i "apparmor.*DENIED" "$log_file")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$denials" ]]; then
|
||||
output_line "${GREEN}No AppArmor denials found.${NC}"
|
||||
output_line ""
|
||||
return
|
||||
fi
|
||||
|
||||
local denial_count=0
|
||||
local -A seen_profiles
|
||||
|
||||
output_line "${BOLD}── AppArmor Denials ─────────────────────────────${NC}"
|
||||
output_line ""
|
||||
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
((denial_count++))
|
||||
parse_apparmor_denial "$line"
|
||||
|
||||
local p
|
||||
p=$(echo "$line" | grep -oP 'profile="\K[^"]+')
|
||||
[[ -n "$p" ]] && seen_profiles["$p"]=1
|
||||
done <<< "$denials"
|
||||
|
||||
TOTAL_DENIALS=$denial_count
|
||||
UNIQUE_TYPES=${#seen_profiles[@]}
|
||||
|
||||
# Suggest aa-logprof for interactive fixing
|
||||
output_line "${BOLD}── Interactive Fix Suggestion ────────────────────${NC}"
|
||||
output_line ""
|
||||
output_line "${YELLOW}For interactive profile updates, run:${NC}"
|
||||
output_line "${GREEN} aa-logprof${NC}"
|
||||
output_line ""
|
||||
output_line "${YELLOW}To set a profile to complain mode for testing:${NC}"
|
||||
for prof in "${!seen_profiles[@]}"; do
|
||||
output_line "${GREEN} aa-complain $prof${NC}"
|
||||
done
|
||||
output_line ""
|
||||
}
|
||||
|
||||
# ── Summary ───────────────────────────────────────────────
|
||||
|
||||
print_summary() {
|
||||
output_line "${BOLD}═══════════════════════════════════════════════════${NC}"
|
||||
output_line "${BOLD} Summary${NC}"
|
||||
output_line "${BOLD}═══════════════════════════════════════════════════${NC}"
|
||||
output_line ""
|
||||
output_line " Total denials found: ${BOLD}${TOTAL_DENIALS}${NC}"
|
||||
output_line " Unique denial types: ${BOLD}${UNIQUE_TYPES}${NC}"
|
||||
output_line " Suggested fixes: ${BOLD}${SUGGESTED_FIXES}${NC}"
|
||||
output_line ""
|
||||
|
||||
if [[ -n "$OUTPUT_FILE" ]]; then
|
||||
output_line "${GREEN}Suggestions saved to: ${OUTPUT_FILE}${NC}"
|
||||
output_line ""
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Parse Arguments ───────────────────────────────────────
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
usage
|
||||
;;
|
||||
--recent)
|
||||
MODE="recent"
|
||||
shift
|
||||
;;
|
||||
--all)
|
||||
MODE="all"
|
||||
shift
|
||||
;;
|
||||
--output)
|
||||
if [[ -z "$2" || "$2" == --* ]]; then
|
||||
echo -e "${RED}Error: --output requires a filename argument.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
OUTPUT_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--quiet|-q)
|
||||
QUIET=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Unknown option: $1${NC}"
|
||||
echo "Use --help for usage information."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ── Main ──────────────────────────────────────────────────
|
||||
|
||||
check_root
|
||||
|
||||
# Clear output file if specified
|
||||
if [[ -n "$OUTPUT_FILE" ]]; then
|
||||
true > "$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
echo -e "${BOLD}Audit Log Analyzer v1.00${NC}"
|
||||
echo -e "${CYAN}Mode: ${MODE}${NC}"
|
||||
echo ""
|
||||
|
||||
detect_mac_system
|
||||
|
||||
if [[ $SELINUX_ACTIVE -eq 1 ]]; then
|
||||
analyze_selinux
|
||||
fi
|
||||
|
||||
if [[ $APPARMOR_ACTIVE -eq 1 ]]; then
|
||||
analyze_apparmor
|
||||
fi
|
||||
|
||||
print_summary
|
||||
Reference in New Issue
Block a user