OSSEC Système de détection d'intrusion basé sur l'hôte
Aperçu général
OSSEC est un système de détection d'intrusion (HIDS) ouvert et complet qui fournit une analyse logarithmique, une surveillance de l'intégrité des fichiers, une surveillance des politiques, une détection rootkit, une alerte en temps réel et des capacités d'intervention active. Il fonctionne dans une architecture client-serveur et est largement utilisé pour la surveillance de la sécurité, la conformité et la détection d'incidents dans divers environnements informatiques, y compris les serveurs, les postes de travail et les appareils réseau.
C'est pas vrai. Note : OSSEC exige une configuration et un réglage appropriés pour minimiser les faux positifs. Il devrait être déployé avec des sources de registre appropriées et des politiques de surveillance pour assurer une couverture efficace de la sécurité.
Installation
Installation du serveur (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
Installation de l'agent
# 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
```_
### Installation du paquet
```bash
# 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
```_
### Installation Docker
```bash
# 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 .
Configuration de base
Configuration du serveur (/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>
Configuration de l'agent
<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>
Gestion des agents
Ajout d'agents
# 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
Gestion automatisée des agents
#!/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"
Surveillance de l'état des agents
# 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
Analyse et suivi des registres
Surveillance des journaux en temps réel
# 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
Analyse des alertes
# 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
Statistiques des journaux
#!/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"
Règles et décors personnalisés
Règles personnalisées (/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>
Décoders personnalisés (/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>
Réponse active
Configuration de la réponse active
<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 réponse active personnalisée
#!/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;
Intégration et automatisation
ELK Intégration des piles
#!/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
Intégration de spunk
# /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
Scénario d'intégration SIEM
#!/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 et optimisation des performances
Tuning des performances du serveur
<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>
Intégration des bases de données
# 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
Rotation et gestion du log
# /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
\\\\}
Surveillance et entretien
Scénario de surveillance de la santé
#!/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 maintenance automatisé
#!/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
Meilleures pratiques
Renforcement de la sécurité
<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>
Optimisation des performances
# 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
Configuration de conformité
<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>
Dépannage
Questions communes
# 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)
Mode de débogage
# 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
Ressources
- [Documentation officielle de l'OSSEC] (LINK_5)
- [Répertoire GitHub de l'OSSEC] (LINK_5)
- [Base de données des règles de l'OSSEC] (LINK_5)
- [Communauté OSSEC] (LINK_5)
- [Wazuh (Work de l'OSSEC)] (LINK_5)
*Cette feuille de triage fournit des conseils complets pour le déploiement et la gestion d'OSSEC pour la détection d'intrusion basée sur l'hôte. Des mises à jour régulières des règles et une configuration appropriée sont essentielles pour une surveillance efficace de la sécurité. *