OSSEC Sistema de detección de intrusiones con sede en el anfitrión
"Clase de la hoja" idbutton id="ossec-copy-btn" class="copy-btn" onclick="copyAllCommands()" Copiar todos los comandos
########################################################################################################################################################################################################################################################## Generar PDF seleccionado/button
■/div titulada
Sinopsis
OSSEC es un completo sistema de detección de intrusiones basado en host (HIDS) de código abierto que proporciona análisis de registros, monitoreo de integridad de archivos, monitoreo de políticas, detección de rootkit, alerta en tiempo real y capacidad de respuesta activa. Funciona en una arquitectura cliente-servidor y es ampliamente utilizado para monitoreo de seguridad, cumplimiento y detección de incidentes en diversos entornos de TI, incluyendo servidores, estaciones de trabajo y dispositivos de red.
NOVEDAD Nota: OSSEC requiere una configuración adecuada y un ajuste de reglas para minimizar falsos positivos. Debe desplegarse con fuentes de registro apropiadas y políticas de vigilancia para una cobertura de seguridad eficaz.
Instalación
Instalación de servidor (Ubuntu/Debian)
# Download OSSEC
wget https://github.com/ossec/ossec-hids/archive/3.7.0.tar.gz
tar -xzf 3.7.0.tar.gz
cd ossec-hids-3.7.0
# Install dependencies
sudo apt update
sudo apt install build-essential gcc make libevent-dev zlib1g-dev libssl-dev libpcre2-dev
# Run installation script
sudo ./install.sh
# Installation prompts:
# 1. Language: en
# 2. Installation type: server
# 3. Installation directory: /var/ossec (default)
# 4. Email notification: your-email@domain.com
# 5. SMTP server: localhost
# 6. Run integrity check daemon: y
# 7. Run rootkit detection engine: y
# 8. Enable active response: y
# 9. Enable firewall response: y
# 10. White list IP addresses: your-management-ip
# Start OSSEC
sudo /var/ossec/bin/ossec-control start
Instalación del agente
# Download and extract OSSEC
wget https://github.com/ossec/ossec-hids/archive/3.7.0.tar.gz
tar -xzf 3.7.0.tar.gz
cd ossec-hids-3.7.0
# Install dependencies
sudo apt install build-essential gcc make
# Run installation script
sudo ./install.sh
# Installation prompts:
# 1. Language: en
# 2. Installation type: agent
# 3. Installation directory: /var/ossec (default)
# 4. OSSEC server IP: server-ip-address
# 5. Run integrity check daemon: y
# 6. Run rootkit detection engine: y
# 7. Enable active response: y
# Start OSSEC agent
sudo /var/ossec/bin/ossec-control start
Instalación
# Ubuntu/Debian (using Atomicorp repository)
wget -q -O - https://www.atomicorp.com/RPM-GPG-KEY.atomicorp.txt|sudo apt-key add -
echo "deb https://updates.atomicorp.com/channels/atomic/ubuntu focal main"|sudo tee /etc/apt/sources.list.d/atomic.list
sudo apt update
sudo apt install ossec-hids-server
# CentOS/RHEL/Fedora
sudo dnf install epel-release
sudo dnf install ossec-hids-server
# Start and enable service
sudo systemctl start ossec-hids
sudo systemctl enable ossec-hids
Docker Instalación
# Pull OSSEC image
docker pull xetus/ossec-server
# Run OSSEC server
docker run -d --name ossec-server \
-p 1514:1514/udp \
-p 1515:1515 \
-v ossec-data:/var/ossec/data \
-v ossec-logs:/var/ossec/logs \
-v ossec-etc:/var/ossec/etc \
xetus/ossec-server
# Create custom Dockerfile
cat > Dockerfile << 'EOF'
FROM xetus/ossec-server
COPY custom-rules/ /var/ossec/rules/
COPY ossec.conf /var/ossec/etc/
ENTRYPOINT ["/opt/ossec-docker-entrypoint.sh"]
EOF
docker build -t custom-ossec .
Configuración básica
Configuración del servidor (/var/ossec/etc/ossec.conf)
<ossec_config>
<global>
<email_notification>yes</email_notification>
<email_to>admin@example.com</email_to>
<smtp_server>localhost</smtp_server>
<email_from>ossec@example.com</email_from>
<email_maxperhour>12</email_maxperhour>
<email_log_source>alerts.log</email_log_source>
<agents_disconnection_time>600</agents_disconnection_time>
<agents_disconnection_alert_time>0</agents_disconnection_alert_time>
</global>
<rules>
<include>rules_config.xml</include>
<include>pam_rules.xml</include>
<include>sshd_rules.xml</include>
<include>telnetd_rules.xml</include>
<include>syslog_rules.xml</include>
<include>arpwatch_rules.xml</include>
<include>symantec-av_rules.xml</include>
<include>symantec-ws_rules.xml</include>
<include>pix_rules.xml</include>
<include>named_rules.xml</include>
<include>smbd_rules.xml</include>
<include>vsftpd_rules.xml</include>
<include>pure-ftpd_rules.xml</include>
<include>proftpd_rules.xml</include>
<include>ms_ftpd_rules.xml</include>
<include>ftpd_rules.xml</include>
<include>hordeimp_rules.xml</include>
<include>roundcube_rules.xml</include>
<include>wordpress_rules.xml</include>
<include>cimserver_rules.xml</include>
<include>vpopmail_rules.xml</include>
<include>vmpop3d_rules.xml</include>
<include>courier_rules.xml</include>
<include>web_rules.xml</include>
<include>web_appsec_rules.xml</include>
<include>apache_rules.xml</include>
<include>nginx_rules.xml</include>
<include>php_rules.xml</include>
<include>mysql_rules.xml</include>
<include>postgresql_rules.xml</include>
<include>ids_rules.xml</include>
<include>squid_rules.xml</include>
<include>firewall_rules.xml</include>
<include>cisco-ios_rules.xml</include>
<include>netscreenfw_rules.xml</include>
<include>sonicwall_rules.xml</include>
<include>postfix_rules.xml</include>
<include>sendmail_rules.xml</include>
<include>imapd_rules.xml</include>
<include>mailscanner_rules.xml</include>
<include>dovecot_rules.xml</include>
<include>ms-exchange_rules.xml</include>
<include>racoon_rules.xml</include>
<include>vpn_concentrator_rules.xml</include>
<include>spamd_rules.xml</include>
<include>msauth_rules.xml</include>
<include>mcafee_av_rules.xml</include>
<include>trend-osce_rules.xml</include>
<include>ms-se_rules.xml</include>
<include>zeus_rules.xml</include>
<include>solaris_bsm_rules.xml</include>
<include>vmware_rules.xml</include>
<include>ms_dhcp_rules.xml</include>
<include>asterisk_rules.xml</include>
<include>ossec_rules.xml</include>
<include>attack_rules.xml</include>
<include>local_rules.xml</include>
</rules>
<syscheck>
<frequency>79200</frequency>
<directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
<directories check_all="yes">/bin,/sbin,/boot</directories>
<ignore>/etc/mtab</ignore>
<ignore>/etc/hosts.deny</ignore>
<ignore>/etc/mail/statistics</ignore>
<ignore>/etc/random-seed</ignore>
<ignore>/etc/random.seed</ignore>
<ignore>/etc/adjtime</ignore>
<ignore>/etc/httpd/logs</ignore>
<ignore>/etc/utmpx</ignore>
<ignore>/etc/wtmpx</ignore>
<ignore>/etc/cups/certs</ignore>
<ignore>/etc/dumpdates</ignore>
<ignore>/etc/svc/volatile</ignore>
<nodiff>/etc/ssl/private.key</nodiff>
</syscheck>
<rootcheck>
<disabled>no</disabled>
<check_files>yes</check_files>
<check_trojans>yes</check_trojans>
<check_dev>yes</check_dev>
<check_sys>yes</check_sys>
<check_pids>yes</check_pids>
<check_ports>yes</check_ports>
<check_if>yes</check_if>
<frequency>79200</frequency>
<rootkit_files>/var/ossec/etc/shared/rootkit_files.txt</rootkit_files>
<rootkit_trojans>/var/ossec/etc/shared/rootkit_trojans.txt</rootkit_trojans>
<system_audit>/var/ossec/etc/shared/system_audit_rcl.txt</system_audit>
<system_audit>/var/ossec/etc/shared/system_audit_ssh.txt</system_audit>
<system_audit>/var/ossec/etc/shared/cis_debian_linux_rcl.txt</system_audit>
<system_audit>/var/ossec/etc/shared/cis_rhel_linux_rcl.txt</system_audit>
<system_audit>/var/ossec/etc/shared/cis_rhel5_linux_rcl.txt</system_audit>
</rootcheck>
<global>
<white_list>127.0.0.1</white_list>
<white_list>^localhost.localdomain$</white_list>
<white_list>192.168.1.0/24</white_list>
</global>
<remote>
<connection>secure</connection>
<port>1514</port>
<protocol>udp</protocol>
</remote>
<alerts>
<log_alert_level>1</log_alert_level>
<email_alert_level>7</email_alert_level>
</alerts>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/messages</location>
</localfile>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/secure</location>
</localfile>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/maillog</location>
</localfile>
<localfile>
<log_format>apache</log_format>
<location>/var/log/httpd/access_log</location>
</localfile>
<localfile>
<log_format>apache</log_format>
<location>/var/log/httpd/error_log</location>
</localfile>
</ossec_config>
Configuración del agente
<ossec_config>
<client>
<server-ip>192.168.1.100</server-ip>
<config-profile>ubuntu, ubuntu18, ubuntu18.04</config-profile>
</client>
<client_buffer>
<disabled>no</disabled>
<length>5000</length>
<events_per_second>500</events_per_second>
</client_buffer>
<logging>
<log_alert_level>1</log_alert_level>
</logging>
<syscheck>
<frequency>79200</frequency>
<directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
<directories check_all="yes">/bin,/sbin</directories>
<ignore>/etc/mtab</ignore>
<ignore>/etc/hosts.deny</ignore>
<ignore>/etc/mail/statistics</ignore>
<ignore>/etc/random-seed</ignore>
<ignore>/etc/adjtime</ignore>
<ignore>/etc/httpd/logs</ignore>
<ignore>/etc/utmpx</ignore>
<ignore>/etc/wtmpx</ignore>
<ignore>/etc/cups/certs</ignore>
<ignore>/etc/dumpdates</ignore>
<nodiff>/etc/ssl/private.key</nodiff>
</syscheck>
<rootcheck>
<disabled>no</disabled>
<check_files>yes</check_files>
<check_trojans>yes</check_trojans>
<check_dev>yes</check_dev>
<check_sys>yes</check_sys>
<check_pids>yes</check_pids>
<check_ports>yes</check_ports>
<check_if>yes</check_if>
<frequency>79200</frequency>
</rootcheck>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/messages</location>
</localfile>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/secure</location>
</localfile>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/auth.log</location>
</localfile>
<localfile>
<log_format>apache</log_format>
<location>/var/log/apache2/access.log</location>
</localfile>
<localfile>
<log_format>apache</log_format>
<location>/var/log/apache2/error.log</location>
</localfile>
</ossec_config>
Agent Management
Añadiendo agentes
# On OSSEC server - add agent
sudo /var/ossec/bin/manage_agents
# Interactive menu:
# A) Add an agent (A)
# Agent name: web-server-01
# Agent IP: 192.168.1.10
# Agent ID: 001
# Extract agent key
sudo /var/ossec/bin/manage_agents
# E) Extract key for an agent (E)
# Agent ID: 001
# On agent - import key
sudo /var/ossec/bin/manage_agents
# I) Import key from the server (I)
# Paste the key from server
# Restart OSSEC on both server and agent
sudo /var/ossec/bin/ossec-control restart
Administración de Agentes Automatizados
#!/bin/bash
# add-ossec-agent.sh
OSSEC_SERVER="192.168.1.100"
AGENT_NAME="$1"
AGENT_IP="$2"
if [ $# -ne 2 ]; then
echo "Usage: $0 <agent_name> <agent_ip>"
exit 1
fi
# Add agent on server
expect << EOF
spawn /var/ossec/bin/manage_agents
expect "Choose your action"
send "A\r"
expect "Agent name:"
send "$AGENT_NAME\r"
expect "Agent IP Address:"
send "$AGENT_IP\r"
expect "Agent ID:"
send "\r"
expect "Confirm adding it?"
send "y\r"
expect "Choose your action"
send "Q\r"
EOF
# Get agent ID
AGENT_ID=$(sudo /var/ossec/bin/manage_agents -l|grep "$AGENT_NAME"|awk '\\\\{print $2\\\\}'|sed 's/,//')
# Extract key
AGENT_KEY=$(expect << EOF
spawn /var/ossec/bin/manage_agents
expect "Choose your action"
send "E\r"
expect "Agent ID:"
send "$AGENT_ID\r"
expect "Choose your action"
send "Q\r"
EOF
)
echo "Agent added successfully!"
echo "Agent ID: $AGENT_ID"
echo "Use this key on the agent:"
echo "$AGENT_KEY"|grep -A 1 "Agent key information"
Supervisión del estado del agente
# List all agents
sudo /var/ossec/bin/agent_control -l
# Check specific agent status
sudo /var/ossec/bin/agent_control -i 001
# Get agent statistics
sudo /var/ossec/bin/agent_control -s
# Restart agent remotely
sudo /var/ossec/bin/agent_control -R 001
# Get last received events from agent
sudo /var/ossec/bin/agent_control -L -i 001
# Check agent configuration
sudo /var/ossec/bin/agent_control -i 001 -f
Análisis y seguimiento de los registros
Monitoreo de registros en tiempo real
# Monitor alerts in real-time
tail -f /var/ossec/logs/alerts/alerts.log
# Monitor specific alert levels
tail -f /var/ossec/logs/alerts/alerts.log|grep "Rule: "
# Monitor agent logs
tail -f /var/ossec/logs/ossec.log
# Monitor active response logs
tail -f /var/ossec/logs/active-responses.log
# Monitor firewall logs
tail -f /var/ossec/logs/firewall/firewall.log
Alert Analysis
# Search for specific alerts
grep "Authentication success" /var/ossec/logs/alerts/alerts.log
# Find failed login attempts
grep "Authentication failed" /var/ossec/logs/alerts/alerts.log
# Search by rule ID
grep "Rule: 5715" /var/ossec/logs/alerts/alerts.log
# Search by agent
grep "web-server-01" /var/ossec/logs/alerts/alerts.log
# Count alerts by type
grep -o "Rule: [0-9]*" /var/ossec/logs/alerts/alerts.log|sort|uniq -c|sort -nr
# Find high-level alerts
grep "Level: [89]" /var/ossec/logs/alerts/alerts.log
Estadísticas de registros
#!/bin/bash
# ossec-log-stats.sh
LOG_FILE="/var/ossec/logs/alerts/alerts.log"
DATE=$(date +%Y-%m-%d)
echo "OSSEC Alert Statistics for $DATE"
echo "=================================="
# Total alerts today
TOTAL_ALERTS=$(grep "$DATE" "$LOG_FILE"|wc -l)
echo "Total alerts today: $TOTAL_ALERTS"
# Alerts by level
echo -e "\nAlerts by level:"
grep "$DATE" "$LOG_FILE"|grep -o "Level: [0-9]*"|sort|uniq -c|sort -nr
# Top 10 rules
echo -e "\nTop 10 triggered rules:"
grep "$DATE" "$LOG_FILE"|grep -o "Rule: [0-9]*"|sort|uniq -c|sort -nr|head -10
# Top agents
echo -e "\nTop agents by alert count:"
grep "$DATE" "$LOG_FILE"|grep -o "Agent: [^)]*"|sort|uniq -c|sort -nr|head -10
# Authentication events
AUTH_SUCCESS=$(grep "$DATE" "$LOG_FILE"|grep -c "Authentication success")
AUTH_FAILED=$(grep "$DATE" "$LOG_FILE"|grep -c "Authentication failed")
echo -e "\nAuthentication events:"
echo "Successful logins: $AUTH_SUCCESS"
echo "Failed logins: $AUTH_FAILED"
Normas y Decodificadores personalizados
Reglas de aduana (/var/ossec/rules/local_rules.xml)
<group name="local,syslog,">
<rule id="100001" level="10">
<if_matched_sid>5716</if_matched_sid>
<same_source_ip />
<description>SSH brute force attack detected.</description>
<group>authentication_failures,pci_dss_10.2.4,pci_dss_10.2.5,</group>
</rule>
<rule id="100002" level="12">
<if_group>web</if_group>
<url>sql|union|select|insert|delete|drop|create|alter|exec|script</url>
<description>Web application attack detected.</description>
<group>attack,pci_dss_10.2.4,</group>
</rule>
<rule id="100003" level="7">
<if_group>syscheck</if_group>
<field name="file">/etc/passwd|/etc/shadow|/etc/sudoers</field>
<description>Critical system file modified.</description>
<group>syscheck,pci_dss_10.5.5,</group>
</rule>
<rule id="100004" level="8">
<if_group>rootcheck</if_group>
<match>Rootkit 'rk' detected</match>
<description>Rootkit detection alert.</description>
<group>rootcheck,</group>
</rule>
<rule id="100005" level="5">
<decoded_as>custom-app</decoded_as>
<field name="status">ERROR</field>
<description>Application error detected.</description>
<group>application,</group>
</rule>
<rule id="100006" level="6">
<if_group>firewall</if_group>
<field name="action">DENY</field>
<field name="dstport">22|23|3389</field>
<description>Blocked connection to administrative port.</description>
<group>firewall,access_denied,</group>
</rule>
<rule id="100007" level="9">
<if_group>authentication_success</if_group>
<time>22:00-06:00</time>
<description>After-hours login detected.</description>
<group>authentication_success,pci_dss_10.2.5,</group>
</rule>
</group>
Decodificadores personalizados (/var/ossec/etc/local_decoder.xml)
<decoder name="custom-app">
<program_name>myapp</program_name>
</decoder>
<decoder name="custom-app-details">
<parent>custom-app</parent>
<regex>^(\S+) \[(\S+)\] (\S+): (.+)$</regex>
<order>timestamp,level,status,message</order>
</decoder>
<decoder name="custom-firewall">
<program_name>firewall</program_name>
</decoder>
<decoder name="custom-firewall-details">
<parent>custom-firewall</parent>
<regex>^(\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+)$</regex>
<order>action,protocol,srcip,srcport,dstip,dstport,bytes</order>
</decoder>
<decoder name="mysql-custom">
<program_name>mysqld</program_name>
</decoder>
<decoder name="mysql-custom-details">
<parent>mysql-custom</parent>
<regex>^(\d+) (\S+) (\S+) (.+)$</regex>
<order>id,user,host,query</order>
</decoder>
Respuesta activa
Configuración de respuesta activa
<ossec_config>
<command>
<name>firewall-drop</name>
<executable>firewall-drop.sh</executable>
<expect>srcip</expect>
<timeout_allowed>yes</timeout_allowed>
</command>
<command>
<name>disable-account</name>
<executable>disable-account.sh</executable>
<expect>user</expect>
<timeout_allowed>yes</timeout_allowed>
</command>
<command>
<name>restart-service</name>
<executable>restart-service.sh</executable>
<expect>service</expect>
<timeout_allowed>no</timeout_allowed>
</command>
<active-response>
<disabled>no</disabled>
<command>firewall-drop</command>
<location>local</location>
<rules_id>100001</rules_id>
<timeout>600</timeout>
</active-response>
<active-response>
<disabled>no</disabled>
<command>disable-account</command>
<location>local</location>
<rules_id>5716</rules_id>
<timeout>1800</timeout>
</active-response>
<active-response>
<disabled>no</disabled>
<command>restart-service</command>
<location>server</location>
<rules_id>100005</rules_id>
</active-response>
</ossec_config>
Scripts de respuesta activa personalizada
#!/bin/bash
# /var/ossec/active-response/bin/firewall-drop.sh
LOCAL=`dirname $0`;
cd $LOCAL
cd ../
PWD=`pwd`
# Logging
echo "`date` $0 $1 $2 $3 $4 $5" >> $\\\\{PWD\\\\}/../logs/active-responses.log
# Getting action and IP
ACTION=$1
USER=$2
IP=$3
case "$\\\\{ACTION\\\\}" in
add)
# Block IP using iptables
/sbin/iptables -I INPUT -s $\\\\{IP\\\\} -j DROP
echo "`date` - Blocked IP $\\\\{IP\\\\}" >> $\\\\{PWD\\\\}/../logs/active-responses.log
;;
delete)
# Unblock IP
/sbin/iptables -D INPUT -s $\\\\{IP\\\\} -j DROP
echo "`date` - Unblocked IP $\\\\{IP\\\\}" >> $\\\\{PWD\\\\}/../logs/active-responses.log
;;
esac
exit 0;
#!/bin/bash
# /var/ossec/active-response/bin/disable-account.sh
LOCAL=`dirname $0`;
cd $LOCAL
cd ../
PWD=`pwd`
# Logging
echo "`date` $0 $1 $2 $3 $4 $5" >> $\\\\{PWD\\\\}/../logs/active-responses.log
# Getting action and user
ACTION=$1
USER=$2
IP=$3
case "$\\\\{ACTION\\\\}" in
add)
# Disable user account
/usr/sbin/usermod -L $\\\\{USER\\\\}
echo "`date` - Disabled account $\\\\{USER\\\\}" >> $\\\\{PWD\\\\}/../logs/active-responses.log
;;
delete)
# Enable user account
/usr/sbin/usermod -U $\\\\{USER\\\\}
echo "`date` - Enabled account $\\\\{USER\\\\}" >> $\\\\{PWD\\\\}/../logs/active-responses.log
;;
esac
exit 0;
#!/bin/bash
# /var/ossec/active-response/bin/restart-service.sh
LOCAL=`dirname $0`;
cd $LOCAL
cd ../
PWD=`pwd`
# Logging
echo "`date` $0 $1 $2 $3 $4 $5" >> $\\\\{PWD\\\\}/../logs/active-responses.log
# Getting action and service
ACTION=$1
USER=$2
IP=$3
SERVICE=$4
case "$\\\\{ACTION\\\\}" in
add)
# Restart service
/bin/systemctl restart $\\\\{SERVICE\\\\}
echo "`date` - Restarted service $\\\\{SERVICE\\\\}" >> $\\\\{PWD\\\\}/../logs/active-responses.log
;;
esac
exit 0;
Integración y automatización
ELK Stack Integration
#!/bin/bash
# ossec-to-elasticsearch.sh
OSSEC_LOG="/var/ossec/logs/alerts/alerts.log"
ELASTICSEARCH_URL="http://localhost:9200"
INDEX_NAME="ossec-$(date +%Y.%m.%d)"
# Function to parse OSSEC alert
parse_ossec_alert() \\\\{
local alert_file="$1"
python3 << EOF
import json
import re
from datetime import datetime
with open('$alert_file', 'r') as f:
content = f.read()
# Parse OSSEC alert format
alerts = content.split('** Alert')
for alert in alerts[1:]: # Skip first empty element
lines = alert.strip().split('\n')
alert_data = \\\\{\\\\}
for line in lines:
if 'Rule:' in line:
alert_data['rule_id'] = re.search(r'Rule: (\d+)', line).group(1)
alert_data['rule_level'] = re.search(r'level (\d+)', line).group(1)
elif 'Agent:' in line:
alert_data['agent'] = line.split('Agent: ')[1].split(' ')[0]
elif 'Location:' in line:
alert_data['location'] = line.split('Location: ')[1]
elif line.startswith('20'): # Timestamp line
alert_data['timestamp'] = line
# Send to Elasticsearch
if alert_data:
print(json.dumps(alert_data))
EOF
\\\\}
# Monitor and send alerts
tail -F "$OSSEC_LOG"|while read line; do
if [[ "$line" == "** Alert"* ]]; then
# Process complete alert
temp_file=$(mktemp)
echo "$line" > "$temp_file"
# Read until next alert or timeout
timeout 5 bash -c "
while read next_line; do
echo \"\$next_line\" >> \"$temp_file\"
if [[ \"\$next_line\" == \"** Alert\"* ]]; then
break
fi
done
"
# Parse and send to Elasticsearch
alert_json=$(parse_ossec_alert "$temp_file")
if [ -n "$alert_json" ]; then
curl -s -H "Content-Type: application/json" \
-X POST "$ELASTICSEARCH_URL/$INDEX_NAME/_doc" \
-d "$alert_json"
fi
rm "$temp_file"
fi
done
Splunk Integration
# /opt/splunk/etc/apps/ossec/local/inputs.conf
[monitor:///var/ossec/logs/alerts/alerts.log]
disabled = false
sourcetype = ossec:alert
index = security
[monitor:///var/ossec/logs/ossec.log]
disabled = false
sourcetype = ossec:system
index = security
[monitor:///var/ossec/logs/active-responses.log]
disabled = false
sourcetype = ossec:active_response
index = security
SIEM Integration Script
#!/usr/bin/env python3
# ossec-siem-integration.py
import re
import time
import json
import requests
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class OSSECLogHandler(FileSystemEventHandler):
def __init__(self, siem_endpoint, api_key):
self.siem_endpoint = siem_endpoint
self.api_key = api_key
self.current_alert = []
self.in_alert = False
def on_modified(self, event):
if event.src_path.endswith('alerts.log'):
self.process_alerts(event.src_path)
def process_alerts(self, log_path):
"""Process OSSEC alerts"""
try:
with open(log_path, 'r') as f:
f.seek(0, 2) # Go to end of file
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
if line.startswith('** Alert'):
if self.current_alert:
self.send_alert_to_siem(self.current_alert)
self.current_alert = [line.strip()]
self.in_alert = True
elif self.in_alert:
self.current_alert.append(line.strip())
# Check if alert is complete
if line.strip() == '' and len(self.current_alert) > 5:
self.send_alert_to_siem(self.current_alert)
self.current_alert = []
self.in_alert = False
except Exception as e:
print(f"Error processing alerts: \\\\{e\\\\}")
def parse_alert(self, alert_lines):
"""Parse OSSEC alert format"""
alert_data = \\\\{
'source': 'ossec',
'raw_alert': '\n'.join(alert_lines)
\\\\}
for line in alert_lines:
if 'Rule:' in line:
match = re.search(r'Rule: (\d+) \(level (\d+)\) -> (.+)', line)
if match:
alert_data['rule_id'] = match.group(1)
alert_data['rule_level'] = int(match.group(2))
alert_data['rule_description'] = match.group(3)
elif line.startswith('20'): # Timestamp
alert_data['timestamp'] = line
elif 'Agent:' in line:
match = re.search(r'Agent: ([^)]+)', line)
if match:
alert_data['agent'] = match.group(1)
elif 'Location:' in line:
alert_data['location'] = line.split('Location: ')[1]
elif 'User:' in line:
match = re.search(r'User: (\S+)', line)
if match:
alert_data['user'] = match.group(1)
elif 'Src IP:' in line:
match = re.search(r'Src IP: (\S+)', line)
if match:
alert_data['src_ip'] = match.group(1)
return alert_data
def send_alert_to_siem(self, alert_lines):
"""Send parsed alert to SIEM"""
try:
alert_data = self.parse_alert(alert_lines)
response = requests.post(
self.siem_endpoint,
json=alert_data,
headers=\\\\{
'Content-Type': 'application/json',
'Authorization': f'Bearer \\\\{self.api_key\\\\}'
\\\\},
timeout=5
)
response.raise_for_status()
print(f"Sent alert to SIEM: Rule \\\\{alert_data.get('rule_id', 'Unknown')\\\\}")
except requests.RequestException as e:
print(f"Error sending to SIEM: \\\\{e\\\\}")
except Exception as e:
print(f"Error processing alert: \\\\{e\\\\}")
def main():
log_directory = "/var/ossec/logs/alerts"
siem_endpoint = "https://your-siem.com/api/events"
api_key = "your-api-key"
event_handler = OSSECLogHandler(siem_endpoint, api_key)
observer = Observer()
observer.schedule(event_handler, log_directory, recursive=False)
observer.start()
print(f"Monitoring OSSEC alerts in \\\\{log_directory\\\\}")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == "__main__":
main()
Tuning y optimización del rendimiento
Tuning de rendimiento del servidor
<ossec_config>
<global>
<logall>no</logall>
<logall_json>no</logall_json>
<email_maxperhour>12</email_maxperhour>
<agents_disconnection_time>600</agents_disconnection_time>
<agents_disconnection_alert_time>0</agents_disconnection_alert_time>
</global>
<alerts>
<log_alert_level>3</log_alert_level>
<email_alert_level>7</email_alert_level>
<use_geoip>yes</use_geoip>
</alerts>
<logging>
<log_alert_level>1</log_alert_level>
<log_format>plain</log_format>
</logging>
</ossec_config>
Integración de bases de datos
# Install MySQL support
sudo apt install mysql-server mysql-client libmysqlclient-dev
# Recompile OSSEC with database support
cd ossec-hids-3.7.0
make setdb
sudo make install
# Configure database in ossec.conf
cat >> /var/ossec/etc/ossec.conf << 'EOF'
<database_output>
<hostname>localhost</hostname>
<username>ossec</username>
<password>ossec_password</password>
<database>ossec</database>
<type>mysql</type>
</database_output>
EOF
# Create database and tables
mysql -u root -p ``<< 'EOF'
CREATE DATABASE ossec;
CREATE USER 'ossec'@'localhost' IDENTIFIED BY 'ossec_password';
GRANT ALL PRIVILEGES ON ossec.* TO 'ossec'@'localhost';
FLUSH PRIVILEGES;
EOF
# Initialize database schema
mysql -u ossec -p ossec < /var/ossec/src/os_dbd/mysql.schema
Rotación de registros y gestión
# /etc/logrotate.d/ossec
/var/ossec/logs/alerts/alerts.log \\\{
daily
missingok
rotate 30
compress
delaycompress
notifempty
postrotate
/var/ossec/bin/ossec-control restart >`` /dev/null 2>&1||true
endscript
\\\\}
/var/ossec/logs/ossec.log \\\\{
weekly
missingok
rotate 12
compress
delaycompress
notifempty
postrotate
/var/ossec/bin/ossec-control restart > /dev/null 2>&1||true
endscript
\\\\}
/var/ossec/logs/active-responses.log \\\\{
weekly
missingok
rotate 12
compress
delaycompress
notifempty
\\\\}
Vigilancia y mantenimiento
Health Monitoring Script
#!/usr/bin/env python3
# ossec-health-monitor.py
import subprocess
import os
import time
from datetime import datetime, timedelta
class OSSECHealthMonitor:
def __init__(self):
self.ossec_dir = "/var/ossec"
self.log_dir = f"\\\\{self.ossec_dir\\\\}/logs"
self.alerts_log = f"\\\\{self.log_dir\\\\}/alerts/alerts.log"
self.ossec_log = f"\\\\{self.log_dir\\\\}/ossec.log"
def check_processes(self):
"""Check if OSSEC processes are running"""
try:
result = subprocess.run(['pgrep', '-f', 'ossec'],
capture_output=True, text=True)
processes = result.stdout.strip().split('\n') if result.stdout.strip() else []
return len(processes) > 0, f"Found \\\\{len(processes)\\\\} OSSEC processes"
except Exception as e:
return False, f"Error checking processes: \\\\{e\\\\}"
def check_log_freshness(self):
"""Check if logs are being generated"""
try:
if not os.path.exists(self.alerts_log):
return False, "Alerts log file not found"
mtime = datetime.fromtimestamp(os.path.getmtime(self.alerts_log))
if datetime.now() - mtime > timedelta(hours=1):
return False, "Alerts log appears stale"
return True, "Logs are fresh"
except Exception as e:
return False, f"Error checking log freshness: \\\\{e\\\\}"
def check_agent_connectivity(self):
"""Check agent connectivity"""
try:
result = subprocess.run([f'\\\\{self.ossec_dir\\\\}/bin/agent_control', '-l'],
capture_output=True, text=True)
if result.returncode != 0:
return False, "Unable to get agent list"
lines = result.stdout.strip().split('\n')
total_agents = 0
active_agents = 0
for line in lines:
if 'ID:' in line and 'Name:' in line:
total_agents += 1
if 'Active' in line:
active_agents += 1
return True, f"Agents: \\\\{active_agents\\\\}/\\\\{total_agents\\\\} active"
except Exception as e:
return False, f"Error checking agents: \\\\{e\\\\}"
def check_disk_space(self):
"""Check available disk space"""
try:
import shutil
total, used, free = shutil.disk_usage(self.log_dir)
free_percent = (free / total) * 100
if free_percent < 10:
return False, f"Low disk space: \\\\{free_percent:.1f\\\\}% free"
return True, f"Disk space OK: \\\\{free_percent:.1f\\\\}% free"
except Exception as e:
return False, f"Error checking disk space: \\\\{e\\\\}"
def get_recent_alerts(self):
"""Get count of recent alerts"""
try:
one_hour_ago = datetime.now() - timedelta(hours=1)
alert_count = 0
if os.path.exists(self.alerts_log):
with open(self.alerts_log, 'r') as f:
for line in f:
if line.startswith('** Alert'):
# Extract timestamp (simplified)
try:
timestamp_line = next(f, '')
if timestamp_line.startswith('20'):
# Parse OSSEC timestamp format
alert_count += 1
except:
continue
return alert_count
except Exception:
return 0
def run_health_check(self):
"""Run comprehensive health check"""
print(f"OSSEC Health Check - \\\\{datetime.now()\\\\}")
print("=" * 50)
# Process status
proc_status, proc_message = self.check_processes()
print(f"\\\\{'✓' if proc_status else '✗'\\\\} Processes: \\\\{proc_message\\\\}")
# Log freshness
log_status, log_message = self.check_log_freshness()
print(f"\\\\{'✓' if log_status else '✗'\\\\} Log freshness: \\\\{log_message\\\\}")
# Agent connectivity
agent_status, agent_message = self.check_agent_connectivity()
print(f"\\\\{'✓' if agent_status else '✗'\\\\} Agent connectivity: \\\\{agent_message\\\\}")
# Disk space
disk_status, disk_message = self.check_disk_space()
print(f"\\\\{'✓' if disk_status else '✗'\\\\} Disk space: \\\\{disk_message\\\\}")
# Recent alerts
alert_count = self.get_recent_alerts()
print(f"ℹ Recent alerts: \\\\{alert_count\\\\} in last hour")
print()
def main():
monitor = OSSECHealthMonitor()
while True:
try:
monitor.run_health_check()
time.sleep(300) # Check every 5 minutes
except KeyboardInterrupt:
print("Monitoring stopped")
break
except Exception as e:
print(f"Monitoring error: \\\\{e\\\\}")
time.sleep(60)
if __name__ == "__main__":
main()
Script de mantenimiento automatizado
#!/bin/bash
# ossec-maintenance.sh
OSSEC_DIR="/var/ossec"
LOG_DIR="$OSSEC_DIR/logs"
BACKUP_DIR="/var/backups/ossec"
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Function to backup configuration
backup_config() \\\\{
echo "Backing up OSSEC configuration..."
tar -czf "$BACKUP_DIR/ossec-config-$(date +%Y%m%d).tar.gz" \
-C "$OSSEC_DIR" etc rules
echo "Configuration backup completed"
\\\\}
# Function to clean old logs
clean_old_logs() \\\\{
echo "Cleaning old log files..."
find "$LOG_DIR" -name "*.log.*" -mtime +$RETENTION_DAYS -delete
find "$LOG_DIR" -name "alerts.log.*" -mtime +$RETENTION_DAYS -delete
echo "Old logs cleaned"
\\\\}
# Function to update rules
update_rules() \\\\{
echo "Updating OSSEC rules..."
# Backup current rules
tar -czf "$BACKUP_DIR/rules-backup-$(date +%Y%m%d).tar.gz" \
-C "$OSSEC_DIR" rules
# Download latest rules (if using external sources)
# wget -O /tmp/new_rules.xml https://example.com/ossec_rules.xml
# cp /tmp/new_rules.xml "$OSSEC_DIR/rules/custom_rules.xml"
# Test configuration
if $OSSEC_DIR/bin/ossec-control test; then
echo "Rule update successful"
$OSSEC_DIR/bin/ossec-control restart
else
echo "Rule update failed - restoring backup"
tar -xzf "$BACKUP_DIR/rules-backup-$(date +%Y%m%d).tar.gz" \
-C "$OSSEC_DIR"
fi
\\\\}
# Function to check agent status
check_agents() \\\\{
echo "Checking agent status..."
$OSSEC_DIR/bin/agent_control -l|grep -E "(Disconnected|Never connected)"|\
while read line; do
echo "WARNING: $line"
done
\\\\}
# Function to generate statistics
generate_stats() \\\\{
echo "Generating daily statistics..."
STATS_FILE="$BACKUP_DIR/stats-$(date +%Y%m%d).txt"
echo "OSSEC Daily Statistics - $(date)" > "$STATS_FILE"
echo "=================================" >> "$STATS_FILE"
# Alert statistics
echo "Alert Statistics:" >> "$STATS_FILE"
grep "$(date +%Y\ %b\ %d)" "$LOG_DIR/alerts/alerts.log"|\
grep -o "Rule: [0-9]*"|sort|uniq -c|sort -nr|head -10 >> "$STATS_FILE"
# Agent statistics
echo -e "\nAgent Statistics:" >> "$STATS_FILE"
$OSSEC_DIR/bin/agent_control -l >> "$STATS_FILE"
echo "Statistics saved to $STATS_FILE"
\\\\}
# Main execution
case "$1" in
backup)
backup_config
;;
clean)
clean_old_logs
;;
update)
update_rules
;;
check)
check_agents
;;
stats)
generate_stats
;;
all)
backup_config
clean_old_logs
check_agents
generate_stats
;;
*)
echo "Usage: $0 \\\\{backup|clean|update|check|stats|all\\\\}"
echo " backup - Backup configuration and rules"
echo " clean - Clean old log files"
echo " update - Update rules"
echo " check - Check agent status"
echo " stats - Generate statistics"
echo " all - Run all maintenance tasks"
exit 1
;;
esac
Buenas prácticas
Hardening de seguridad
<ossec_config>
<global>
<email_notification>yes</email_notification>
<email_maxperhour>12</email_maxperhour>
<agents_disconnection_time>300</agents_disconnection_time>
<agents_disconnection_alert_time>600</agents_disconnection_alert_time>
</global>
<alerts>
<log_alert_level>1</log_alert_level>
<email_alert_level>7</email_alert_level>
<use_geoip>yes</use_geoip>
</alerts>
<remote>
<connection>secure</connection>
<port>1514</port>
<protocol>udp</protocol>
<allowed-ips>192.168.1.0/24</allowed-ips>
</remote>
</ossec_config>
Optimización del rendimiento
# System-level optimizations
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
sysctl -p
# OSSEC process limits
echo 'ossec soft nofile 65536' >> /etc/security/limits.conf
echo 'ossec hard nofile 65536' >> /etc/security/limits.conf
Configuración de cumplimiento
<ossec_config>
<syscheck>
<frequency>79200</frequency>
<directories check_all="yes" realtime="yes">/etc,/usr/bin,/usr/sbin</directories>
<directories check_all="yes" realtime="yes">/bin,/sbin</directories>
<directories check_all="yes" realtime="yes">/var/www</directories>
</syscheck>
<rootcheck>
<disabled>no</disabled>
<check_files>yes</check_files>
<check_trojans>yes</check_trojans>
<check_dev>yes</check_dev>
<check_sys>yes</check_sys>
<check_pids>yes</check_pids>
<check_ports>yes</check_ports>
<check_if>yes</check_if>
<frequency>79200</frequency>
</rootcheck>
</ossec_config>
Solución de problemas
Cuestiones comunes
# Issue: Agent not connecting
# Check agent key
sudo /var/ossec/bin/manage_agents -l
# Check network connectivity
telnet ossec-server 1514
# Check agent logs
tail -f /var/ossec/logs/ossec.log
# Issue: High false positives
# Adjust alert levels
grep "log_alert_level" /var/ossec/etc/ossec.conf
# Add white list entries
echo "192.168.1.100" >> /var/ossec/etc/ossec.conf
# Issue: Missing alerts
# Check rule configuration
/var/ossec/bin/ossec-control test
# Verify log sources
grep "localfile" /var/ossec/etc/ossec.conf
# Issue: Performance problems
# Check process status
ps aux|grep ossec
# Monitor resource usage
top -p $(pgrep ossec)
Modo de depuración
# Enable debug mode
/var/ossec/bin/ossec-control enable debug
# Check debug logs
tail -f /var/ossec/logs/ossec.log
# Test specific rules
/var/ossec/bin/ossec-logtest
# Analyze configuration
/var/ossec/bin/ossec-control test
Recursos
- OSSEC Official Documentation
- OSSEC GitHub Repository
- OSSEC Rules Database
- OSSEC Community
- Wazuh (OSSEC Fork)
-...
*Esta hoja de trampa proporciona una guía completa para el despliegue y manejo de OSSEC para la detección de intrusión basada en el host. Las actualizaciones regulares de reglas y la configuración adecuada son esenciales para una vigilancia eficaz de la seguridad. *