a1a17e81a1
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.
483 lines
15 KiB
Bash
483 lines
15 KiB
Bash
#!/bin/bash
|
|
################################################################################
|
|
# Script Name: install-ossec.sh
|
|
# Version: 1.0
|
|
# Description: Automated OSSEC HIDS installation — server or agent mode,
|
|
# file integrity monitoring, rootkit detection, log analysis,
|
|
# active response, email alerts, and syscheck configuration
|
|
# on Debian/Ubuntu and RHEL/Rocky/AlmaLinux
|
|
#
|
|
# Author: Phil Connor
|
|
# Contact: contact@mylinux.work
|
|
# Website: https://mylinux.work
|
|
# License: MIT
|
|
#
|
|
# Usage:
|
|
# sudo ./install-ossec.sh --mode server
|
|
# sudo ./install-ossec.sh --mode agent --server-ip 10.0.1.10
|
|
# sudo ./install-ossec.sh --mode local
|
|
# sudo ./install-ossec.sh --mode server --email admin@example.com
|
|
# sudo ./install-ossec.sh --dry-run --mode server
|
|
# sudo ./install-ossec.sh --uninstall
|
|
#
|
|
################################################################################
|
|
|
|
set -euo pipefail
|
|
|
|
# ============================================================================
|
|
# DEFAULTS
|
|
# ============================================================================
|
|
|
|
readonly VERSION="1.0"
|
|
readonly SCRIPT_NAME="${0##*/}"
|
|
readonly LOG_FILE="/var/log/ossec-install.log"
|
|
|
|
INSTALL_MODE=""
|
|
SERVER_IP=""
|
|
EMAIL_ADDR=""
|
|
EMAIL_SMTP="localhost"
|
|
ACTIVE_RESPONSE=true
|
|
SYSCHECK_FREQUENCY="21600"
|
|
SYSCHECK_DIRS="/etc,/usr/bin,/usr/sbin,/bin,/sbin"
|
|
ROOTCHECK=true
|
|
LOG_ANALYSIS=true
|
|
DRY_RUN=false
|
|
UNINSTALL=false
|
|
OSSEC_VERSION="3.7.0"
|
|
OSSEC_DIR="/var/ossec"
|
|
|
|
# OS detection
|
|
OS_ID=""
|
|
OS_VERSION=""
|
|
PKG_MGR=""
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
# ============================================================================
|
|
# HELPER FUNCTIONS
|
|
# ============================================================================
|
|
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOG_FILE" 2>/dev/null || true; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; echo "[WARN] $(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOG_FILE" 2>/dev/null || true; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOG_FILE" 2>/dev/null || true; }
|
|
log_step() { echo -e "${CYAN}[STEP]${NC} $*"; echo "[STEP] $(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOG_FILE" 2>/dev/null || true; }
|
|
|
|
show_usage() {
|
|
cat <<EOF
|
|
Usage: sudo $SCRIPT_NAME [OPTIONS]
|
|
|
|
Installs and configures OSSEC HIDS (Host-based Intrusion Detection System).
|
|
|
|
REQUIRED:
|
|
--mode TYPE Installation type: server, agent, or local
|
|
|
|
OPTIONS:
|
|
--server-ip IP Manager IP (required for agent mode)
|
|
--email ADDRESS Email address for alerts
|
|
--smtp SERVER SMTP server for email alerts (default: localhost)
|
|
--no-active-response Disable active response (firewall blocking)
|
|
--syscheck-freq SECS Syscheck frequency in seconds (default: 21600 = 6h)
|
|
--syscheck-dirs DIRS Comma-separated directories to monitor
|
|
--no-rootcheck Disable rootkit detection
|
|
--no-log-analysis Disable log analysis
|
|
--version VER OSSEC version to install (default: $OSSEC_VERSION)
|
|
--dry-run Show what would be done
|
|
--uninstall Remove OSSEC
|
|
-h, --help Show this help message
|
|
|
|
MODES:
|
|
server OSSEC manager — receives alerts from agents, runs analysis
|
|
agent OSSEC agent — connects to a server, sends events
|
|
local Standalone — all features, no agent/server communication
|
|
|
|
EXAMPLES:
|
|
# Install OSSEC server with email alerts
|
|
sudo $SCRIPT_NAME --mode server --email admin@example.com
|
|
|
|
# Install OSSEC agent pointing to server
|
|
sudo $SCRIPT_NAME --mode agent --server-ip 10.0.1.10
|
|
|
|
# Standalone installation
|
|
sudo $SCRIPT_NAME --mode local
|
|
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
parse_args() {
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--mode) INSTALL_MODE="$2"; shift 2 ;;
|
|
--server-ip) SERVER_IP="$2"; shift 2 ;;
|
|
--email) EMAIL_ADDR="$2"; shift 2 ;;
|
|
--smtp) EMAIL_SMTP="$2"; shift 2 ;;
|
|
--no-active-response) ACTIVE_RESPONSE=false; shift ;;
|
|
--syscheck-freq) SYSCHECK_FREQUENCY="$2"; shift 2 ;;
|
|
--syscheck-dirs) SYSCHECK_DIRS="$2"; shift 2 ;;
|
|
--no-rootcheck) ROOTCHECK=false; shift ;;
|
|
--no-log-analysis) LOG_ANALYSIS=false; shift ;;
|
|
--version) OSSEC_VERSION="$2"; shift 2 ;;
|
|
--dry-run) DRY_RUN=true; shift ;;
|
|
--uninstall) UNINSTALL=true; shift ;;
|
|
-h|--help) show_usage ;;
|
|
*) log_error "Unknown option: $1"; show_usage ;;
|
|
esac
|
|
done
|
|
|
|
if ! $UNINSTALL && [ -z "$INSTALL_MODE" ]; then
|
|
log_error "--mode is required (server, agent, or local)"
|
|
show_usage
|
|
fi
|
|
|
|
if [ "$INSTALL_MODE" = "agent" ] && [ -z "$SERVER_IP" ]; then
|
|
log_error "Agent mode requires --server-ip"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_root() {
|
|
if [[ $EUID -ne 0 ]]; then
|
|
log_error "This script must be run as root (sudo)"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# ============================================================================
|
|
# OS DETECTION
|
|
# ============================================================================
|
|
|
|
detect_os() {
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
OS_ID="${ID}"
|
|
OS_VERSION="${VERSION_ID}"
|
|
else
|
|
log_error "Cannot detect OS"
|
|
exit 1
|
|
fi
|
|
|
|
case "$OS_ID" in
|
|
ubuntu|debian) PKG_MGR="apt" ;;
|
|
rhel|rocky|almalinux|centos|fedora) PKG_MGR="dnf"; command -v dnf &>/dev/null || PKG_MGR="yum" ;;
|
|
*) log_error "Unsupported OS: $OS_ID"; exit 1 ;;
|
|
esac
|
|
|
|
log_info "Detected OS: $OS_ID $OS_VERSION (package manager: $PKG_MGR)"
|
|
}
|
|
|
|
# ============================================================================
|
|
# DEPENDENCIES
|
|
# ============================================================================
|
|
|
|
install_dependencies() {
|
|
log_step "Installing build dependencies..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would install build dependencies"
|
|
return
|
|
fi
|
|
|
|
case "$PKG_MGR" in
|
|
apt)
|
|
apt-get update -qq
|
|
apt-get install -y -qq build-essential make gcc libevent-dev libpcre2-dev \
|
|
libssl-dev libsystemd-dev zlib1g-dev wget tar
|
|
;;
|
|
dnf|yum)
|
|
$PKG_MGR groupinstall -y "Development Tools" 2>/dev/null || true
|
|
$PKG_MGR install -y -q gcc make libevent-devel pcre2-devel openssl-devel \
|
|
systemd-devel zlib-devel wget tar
|
|
;;
|
|
esac
|
|
|
|
log_info "Dependencies installed"
|
|
}
|
|
|
|
# ============================================================================
|
|
# DOWNLOAD AND COMPILE
|
|
# ============================================================================
|
|
|
|
download_ossec() {
|
|
log_step "Downloading OSSEC ${OSSEC_VERSION}..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would download OSSEC ${OSSEC_VERSION}"
|
|
return
|
|
fi
|
|
|
|
local url="https://github.com/ossec/ossec-hids/archive/refs/tags/${OSSEC_VERSION}.tar.gz"
|
|
local tmpdir="/tmp/ossec-build"
|
|
|
|
rm -rf "$tmpdir"
|
|
mkdir -p "$tmpdir"
|
|
cd "$tmpdir"
|
|
|
|
wget -q "$url" -O "ossec-${OSSEC_VERSION}.tar.gz"
|
|
tar xzf "ossec-${OSSEC_VERSION}.tar.gz"
|
|
|
|
log_info "Downloaded and extracted OSSEC ${OSSEC_VERSION}"
|
|
}
|
|
|
|
install_ossec() {
|
|
log_step "Installing OSSEC in ${INSTALL_MODE} mode..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would install OSSEC as ${INSTALL_MODE}"
|
|
return
|
|
fi
|
|
|
|
local tmpdir="/tmp/ossec-build/ossec-hids-${OSSEC_VERSION}"
|
|
cd "$tmpdir"
|
|
|
|
# Generate preloaded-vars.conf for non-interactive install
|
|
cat > etc/preloaded-vars.conf <<PRELOAD
|
|
USER_LANGUAGE="en"
|
|
USER_NO_STOP="y"
|
|
USER_INSTALL_TYPE="${INSTALL_MODE}"
|
|
USER_DIR="${OSSEC_DIR}"
|
|
USER_ENABLE_EMAIL="$([ -n "$EMAIL_ADDR" ] && echo y || echo n)"
|
|
USER_EMAIL_ADDRESS="${EMAIL_ADDR:-admin@example.com}"
|
|
USER_EMAIL_SMTP="${EMAIL_SMTP}"
|
|
USER_ENABLE_SYSCHECK="y"
|
|
USER_ENABLE_ROOTCHECK="$(${ROOTCHECK} && echo y || echo n)"
|
|
USER_ENABLE_ACTIVE_RESPONSE="$(${ACTIVE_RESPONSE} && echo y || echo n)"
|
|
USER_ENABLE_FIREWALL_RESPONSE="$(${ACTIVE_RESPONSE} && echo y || echo n)"
|
|
USER_UPDATE="n"
|
|
PRELOAD
|
|
|
|
if [ "$INSTALL_MODE" = "agent" ]; then
|
|
echo "USER_AGENT_SERVER_IP=\"${SERVER_IP}\"" >> etc/preloaded-vars.conf
|
|
fi
|
|
|
|
# Run the install
|
|
./install.sh
|
|
|
|
log_info "OSSEC installed to ${OSSEC_DIR}"
|
|
}
|
|
|
|
# ============================================================================
|
|
# CONFIGURATION
|
|
# ============================================================================
|
|
|
|
configure_ossec() {
|
|
log_step "Configuring OSSEC..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would configure syscheck directories and rules"
|
|
return
|
|
fi
|
|
|
|
local ossec_conf="${OSSEC_DIR}/etc/ossec.conf"
|
|
|
|
if [ ! -f "$ossec_conf" ]; then
|
|
log_warn "ossec.conf not found — skipping custom configuration"
|
|
return
|
|
fi
|
|
|
|
# Update syscheck frequency
|
|
if grep -q "<frequency>" "$ossec_conf"; then
|
|
sed -i "s|<frequency>[0-9]*</frequency>|<frequency>${SYSCHECK_FREQUENCY}</frequency>|g" "$ossec_conf"
|
|
log_info "Set syscheck frequency to ${SYSCHECK_FREQUENCY} seconds"
|
|
fi
|
|
|
|
# Add additional syscheck directories
|
|
IFS=',' read -ra DIRS <<< "$SYSCHECK_DIRS"
|
|
for dir in "${DIRS[@]}"; do
|
|
dir=$(echo "$dir" | xargs)
|
|
if ! grep -q "<directories.*>${dir}<" "$ossec_conf" 2>/dev/null; then
|
|
sed -i "/<\/syscheck>/i\\ <directories check_all=\"yes\" realtime=\"yes\">${dir}</directories>" "$ossec_conf"
|
|
log_info "Added syscheck directory: ${dir}"
|
|
fi
|
|
done
|
|
|
|
# Add common ignore paths to reduce noise
|
|
local ignores=(
|
|
"/etc/mtab"
|
|
"/etc/resolv.conf"
|
|
"/etc/adjtime"
|
|
"/etc/mail/statistics"
|
|
"/etc/random-seed"
|
|
"/etc/sysstat"
|
|
)
|
|
for ign in "${ignores[@]}"; do
|
|
if ! grep -q "<ignore>${ign}</ignore>" "$ossec_conf" 2>/dev/null; then
|
|
sed -i "/<\/syscheck>/i\\ <ignore>${ign}</ignore>" "$ossec_conf"
|
|
fi
|
|
done
|
|
|
|
log_info "OSSEC configuration updated"
|
|
}
|
|
|
|
# ============================================================================
|
|
# FIREWALL
|
|
# ============================================================================
|
|
|
|
configure_firewall() {
|
|
if [ "$INSTALL_MODE" != "server" ]; then
|
|
return
|
|
fi
|
|
|
|
log_step "Opening OSSEC server port (1514/udp)..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would open port 1514/udp"
|
|
return
|
|
fi
|
|
|
|
if command -v ufw &>/dev/null && ufw status | grep -q "active"; then
|
|
ufw allow 1514/udp
|
|
log_info "Opened port 1514/udp via ufw"
|
|
elif command -v firewall-cmd &>/dev/null; then
|
|
firewall-cmd --permanent --add-port=1514/udp
|
|
firewall-cmd --reload
|
|
log_info "Opened port 1514/udp via firewalld"
|
|
elif command -v nft &>/dev/null; then
|
|
nft add rule inet filter input udp dport 1514 accept 2>/dev/null || true
|
|
log_info "Opened port 1514/udp via nftables"
|
|
fi
|
|
}
|
|
|
|
# ============================================================================
|
|
# SERVICE
|
|
# ============================================================================
|
|
|
|
start_ossec() {
|
|
log_step "Starting OSSEC..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would start OSSEC"
|
|
return
|
|
fi
|
|
|
|
"${OSSEC_DIR}/bin/ossec-control" start
|
|
|
|
sleep 3
|
|
|
|
if "${OSSEC_DIR}/bin/ossec-control" status | grep -q "running"; then
|
|
log_info "OSSEC is running"
|
|
else
|
|
log_warn "OSSEC may not have started — check ${OSSEC_DIR}/logs/ossec.log"
|
|
fi
|
|
}
|
|
|
|
# ============================================================================
|
|
# VERIFICATION
|
|
# ============================================================================
|
|
|
|
verify_installation() {
|
|
log_step "Verifying installation..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Installation summary:"
|
|
echo " Mode: ${INSTALL_MODE}"
|
|
echo " Directory: ${OSSEC_DIR}"
|
|
echo " Syscheck freq: ${SYSCHECK_FREQUENCY}s"
|
|
echo " Active response: ${ACTIVE_RESPONSE}"
|
|
echo " Rootcheck: ${ROOTCHECK}"
|
|
echo " Email: ${EMAIL_ADDR:-disabled}"
|
|
[ "$INSTALL_MODE" = "agent" ] && echo " Server IP: ${SERVER_IP}"
|
|
return
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== OSSEC Installation Summary ==="
|
|
echo "Mode: ${INSTALL_MODE}"
|
|
echo "Version: ${OSSEC_VERSION}"
|
|
echo "Install dir: ${OSSEC_DIR}"
|
|
echo "Active response: ${ACTIVE_RESPONSE}"
|
|
echo "Rootcheck: ${ROOTCHECK}"
|
|
echo "Syscheck freq: ${SYSCHECK_FREQUENCY}s ($(( SYSCHECK_FREQUENCY / 3600 ))h)"
|
|
echo ""
|
|
|
|
echo "=== Process Status ==="
|
|
"${OSSEC_DIR}/bin/ossec-control" status
|
|
echo ""
|
|
|
|
echo "=== Syscheck Status ==="
|
|
"${OSSEC_DIR}/bin/syscheck_control" -l 2>/dev/null | head -5 || echo "(syscheck not yet run)"
|
|
echo ""
|
|
|
|
if [ "$INSTALL_MODE" = "server" ]; then
|
|
echo "=== Agent Management ==="
|
|
echo "To add agents:"
|
|
echo " ${OSSEC_DIR}/bin/manage_agents"
|
|
echo ""
|
|
fi
|
|
|
|
echo "=== Useful Commands ==="
|
|
echo " Status: ${OSSEC_DIR}/bin/ossec-control status"
|
|
echo " Restart: ${OSSEC_DIR}/bin/ossec-control restart"
|
|
echo " Logs: tail -f ${OSSEC_DIR}/logs/ossec.log"
|
|
echo " Alerts: tail -f ${OSSEC_DIR}/logs/alerts/alerts.log"
|
|
echo ""
|
|
log_info "Installation complete. Logs: $LOG_FILE"
|
|
}
|
|
|
|
# ============================================================================
|
|
# UNINSTALL
|
|
# ============================================================================
|
|
|
|
uninstall_ossec() {
|
|
log_step "Uninstalling OSSEC..."
|
|
|
|
if $DRY_RUN; then
|
|
log_info "[DRY RUN] Would stop and remove OSSEC"
|
|
return
|
|
fi
|
|
|
|
if [ -x "${OSSEC_DIR}/bin/ossec-control" ]; then
|
|
"${OSSEC_DIR}/bin/ossec-control" stop 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -d "$OSSEC_DIR" ]; then
|
|
rm -rf "$OSSEC_DIR"
|
|
log_info "Removed ${OSSEC_DIR}"
|
|
fi
|
|
|
|
# Remove ossec user/group
|
|
userdel ossec 2>/dev/null || true
|
|
userdel ossecm 2>/dev/null || true
|
|
userdel ossecr 2>/dev/null || true
|
|
groupdel ossec 2>/dev/null || true
|
|
|
|
log_info "OSSEC uninstalled"
|
|
exit 0
|
|
}
|
|
|
|
# ============================================================================
|
|
# MAIN
|
|
# ============================================================================
|
|
|
|
main() {
|
|
parse_args "$@"
|
|
|
|
echo ""
|
|
echo "============================================"
|
|
echo " OSSEC Install Script v${VERSION}"
|
|
echo " https://mylinux.work"
|
|
echo "============================================"
|
|
echo ""
|
|
|
|
check_root
|
|
detect_os
|
|
|
|
if $UNINSTALL; then
|
|
uninstall_ossec
|
|
fi
|
|
|
|
install_dependencies
|
|
download_ossec
|
|
install_ossec
|
|
configure_ossec
|
|
configure_firewall
|
|
start_ossec
|
|
verify_installation
|
|
}
|
|
|
|
main "$@"
|