SIEM, SOC, and Threat Detection
- SIEM, SOC, and Threat Detection
Seeing the whole attack, not one log line
Security Information and Event Management (SIEM) systems aggregate, correlate, and alert on security events from across an environment. A Security Operations Center (SOC) is the team and process structure that uses SIEM, IDS/IPS, and EDR tools to detect, investigate, and respond to threats. This page covers the tooling and concepts that underpin threat detection operations.
ℹ️ The whole point of a SIEM is correlation: a single failed login is noise, but a failed login followed by a successful one, a new process, and an outbound connection is an attack chain. The detections here feed the response process on the Incident Response page.
SIEM
A SIEM ingests log data from servers, network devices, applications, and cloud services, then applies correlation rules and analytics to identify suspicious patterns that no single log source would reveal alone.
SIEM core functions
| Function | Description |
|---|---|
| Log aggregation | Collect logs from diverse sources into a central store |
| Normalization | Parse different log formats into a common schema |
| Correlation | Match events across sources to detect multi-stage attacks |
| Alerting | Generate alerts when rules match |
| Retention | Store logs for compliance and forensic investigation |
| Dashboards | Operational views of security posture |
Elastic Security (Elastic SIEM)
The Elastic Stack (Elasticsearch, Logstash, Kibana) is the most widely deployed open-source log management platform, and Elastic Security adds SIEM capabilities on top.
# Install Elasticsearch (single-node, for lab use)
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch \
| sudo gpg --dearmor -o /usr/share/keyrings/elastic-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] \
https://artifacts.elastic.co/packages/8.x/apt stable main" \
| sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update && sudo apt install elasticsearch kibana
sudo systemctl enable --now elasticsearch kibana
# Filebeat: ship logs to Elasticsearch
# /etc/filebeat/filebeat.yml (key sections)
filebeat.inputs:
- type: filestream
id: syslog-input
paths:
- /var/log/syslog
- /var/log/auth.log
tags: ["syslog", "linux"]
- type: filestream
id: nginx-input
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
tags: ["nginx"]
output.elasticsearch:
hosts: ["https://localhost:9200"]
username: "filebeat_writer"
password: "${FILEBEAT_PASSWORD}"
ssl.certificate_authorities: ["/etc/elasticsearch/certs/http_ca.crt"]
setup.kibana:
host: "localhost:5601"
# Enable Filebeat modules for common log formats
filebeat modules enable system nginx auditd
filebeat setup --dashboards # load pre-built Kibana dashboards
systemctl restart filebeat
# Python: query Elasticsearch for security events
from elasticsearch import Elasticsearch
from datetime import datetime, timedelta
es = Elasticsearch(
'https://localhost:9200',
basic_auth=('elastic', 'password'),
ca_certs='/etc/elasticsearch/certs/http_ca.crt',
)
# Find failed SSH logins in the last hour
query = {
"bool": {
"must": [
{"match": {"event.action": "ssh_login"}},
{"match": {"event.outcome": "failure"}},
{"range": {
"@timestamp": {
"gte": (datetime.utcnow() - timedelta(hours=1)).isoformat(),
"lte": "now"
}
}}
]
}
}
result = es.search(index='filebeat-*', query=query, size=100)
for hit in result['hits']['hits']:
src = hit['_source']
print(f"{src.get('@timestamp')}: Failed SSH from {src.get('source', {}).get('ip')} "
f"for user {src.get('user', {}).get('name')}")
Wazuh
Wazuh is an open-source security platform that combines SIEM, HIDS (Host-based Intrusion Detection), and compliance monitoring:
# Wazuh manager installation (single-node)
curl -sO https://packages.wazuh.com/4.9/wazuh-install.sh
sudo bash wazuh-install.sh -a
# Deploy Wazuh agent on Linux hosts
curl -sO https://packages.wazuh.com/4.9/wazuh-agent-linux-install.sh
WAZUH_MANAGER='wazuh.example.com' sudo bash wazuh-agent-linux-install.sh
sudo systemctl enable --now wazuh-agent
# Check agent connection status
sudo /var/ossec/bin/agent_control -l
Intrusion Detection and Prevention
IDS vs IPS
| Aspect | IDS (Detection) | IPS (Prevention) |
|---|---|---|
| Position | Out-of-band (mirror/tap) | Inline (traffic passes through) |
| Response | Alert only | Alert and block |
| Risk | No impact on traffic if fails | Can disrupt traffic if misconfigured |
| Use case | Monitoring, forensics | Active blocking of known threats |
Snort / Suricata (network IDS/IPS)
Suricata is the modern successor to Snort, supporting multi-threading and both IDS and IPS modes:
# Install Suricata
sudo apt install suricata
# Update rules (Emerging Threats open ruleset)
sudo suricata-update
# Run in IDS mode on an interface
sudo suricata -c /etc/suricata/suricata.yaml -i eth0
# Run in IPS mode (inline, drops matching packets)
sudo suricata --af-packet -c /etc/suricata/suricata.yaml
# Test configuration
sudo suricata -T -c /etc/suricata/suricata.yaml
# /etc/suricata/suricata.yaml key sections
vars:
address-groups:
HOME_NET: "[192.168.0.0/16,10.0.0.0/8]"
EXTERNAL_NET: "!$HOME_NET"
default-log-dir: /var/log/suricata/
outputs:
- eve-log:
enabled: yes
filetype: regular
filename: eve.json
types:
- alert
- http
- dns
- tls
- ssh
# Parse Suricata EVE JSON logs
import json
def parse_suricata_alerts(logfile: str):
with open(logfile) as f:
for line in f:
event = json.loads(line)
if event.get('event_type') == 'alert':
alert = event['alert']
print(
f"{event['timestamp']} "
f"[{alert['severity']}] {alert['signature']} "
f"({event.get('src_ip')}:{event.get('src_port')} → "
f"{event.get('dest_ip')}:{event.get('dest_port')})"
)
parse_suricata_alerts('/var/log/suricata/eve.json')
Falco (runtime container security)
Falco monitors system calls at runtime to detect anomalous behavior inside containers and on Linux hosts. It is the standard tool for Kubernetes runtime security.
# Install Falco
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] \
https://download.falco.org/packages/deb stable main" \
| sudo tee /etc/apt/sources.list.d/falcosecurity.list
sudo apt update && sudo apt install falco
sudo systemctl enable --now falco
# View alerts in real time
sudo journalctl -fu falco
# Custom Falco rule: alert on shell spawned inside a container
- rule: Shell Spawned in Container
desc: A shell was spawned inside a container — possible container escape or interactive backdoor
condition: >
spawned_process
and container
and proc.name in (shell_binaries)
and not proc.pname in (shell_binaries)
output: >
Shell spawned in container
(user=%user.name container=%container.name image=%container.image.repository
shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
priority: WARNING
tags: [container, shell, T1059]
- rule: Sensitive File Read
desc: A non-privileged process read a sensitive file
condition: >
open_read
and fd.name in (sensitive_files)
and not proc.name in (trusted_readers)
output: >
Sensitive file read (user=%user.name file=%fd.name proc=%proc.name)
priority: ERROR
# Falco in Kubernetes (DaemonSet)
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set falco.grpc.enabled=true \
--set falco.grpc_output.enabled=true
Log Analysis
Effective security monitoring depends on collecting the right logs, retaining them long enough, and being able to search them efficiently.
What to log
| Source | Key log types |
|---|---|
| Authentication | Login success/failure, MFA events, password changes, privilege escalation |
| Network | Firewall accepts/denies, DNS queries, proxy requests, VPN connections |
| Application | API access (method, path, status, user), errors, configuration changes |
| System | Package installations, cron job execution, kernel messages, service start/stop |
| Container | Image pulls, container start/stop, exec into container |
| Cloud | IAM API calls (CloudTrail), config changes (AWS Config), console logins |
Structured logging for security
Applications should emit structured (JSON) logs that are easily parsed by SIEM systems:
import logging
import json
import time
class SecurityLogger:
"""Emit structured security events to stdout (collected by log aggregator)."""
def __init__(self, service_name: str):
self.service = service_name
def _emit(self, level: str, event_type: str, **fields):
record = {
"timestamp": time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
"level": level,
"service": self.service,
"event_type": event_type,
**fields,
}
print(json.dumps(record), flush=True)
def auth_success(self, user_id: str, ip: str, method: str):
self._emit("INFO", "auth.success",
user_id=user_id, source_ip=ip, auth_method=method)
def auth_failure(self, username: str, ip: str, reason: str):
self._emit("WARN", "auth.failure",
username=username, source_ip=ip, reason=reason)
def privilege_escalation(self, user_id: str, from_role: str, to_role: str):
self._emit("WARN", "authz.privilege_change",
user_id=user_id, from_role=from_role, to_role=to_role)
def data_access(self, user_id: str, resource: str, action: str, outcome: str):
self._emit("INFO", "data.access",
user_id=user_id, resource=resource, action=action, outcome=outcome)
logger = SecurityLogger("payment-api")
logger.auth_failure("alice", "203.0.113.42", "invalid_password")
# Output: {"timestamp": "...", "level": "WARN", "service": "payment-api",
# "event_type": "auth.failure", "username": "alice",
# "source_ip": "203.0.113.42", "reason": "invalid_password"}
Log retention requirements
| Regulation / Standard | Minimum retention |
|---|---|
| PCI DSS | 1 year (3 months immediately available) |
| HIPAA | 6 years |
| SOC 2 | 1 year (common practice) |
| NIST SP 800-53 | 3 years (federal systems) |
| GDPR | Varies by data category |
Endpoint Detection and Response (EDR)
EDR tools provide continuous monitoring of endpoint activity — processes, network connections, file changes, registry modifications — and enable real-time response to threats.
EDR capabilities
| Capability | Description |
|---|---|
| Process monitoring | Record all process executions with parent-child relationships |
| Network monitoring | Log all outbound connections (IP, port, process) |
| File integrity monitoring | Alert on changes to critical system files |
| Memory analysis | Detect process injection, shellcode execution |
| Remote containment | Isolate a compromised host from the network |
| Forensic collection | Collect artifacts (memory dump, process list, network state) |
Auditd (Linux auditing framework)
Auditd is the Linux kernel audit subsystem. It records security-relevant system calls to a tamper-evident log.
# Install and enable
sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd
# View audit log
sudo ausearch -i # human-readable format
sudo ausearch -m LOGIN --start today # login events today
sudo ausearch -f /etc/passwd # access to /etc/passwd
sudo ausearch -x /bin/su # execution of su
# Generate a report
sudo aureport --summary
sudo aureport --auth # authentication report
sudo aureport --failed # failed events
# Audit rules: /etc/audit/rules.d/security.rules
# Monitor writes to /etc/passwd and /etc/shadow
-w /etc/passwd -p wa -k identity-files
-w /etc/shadow -p wa -k identity-files
-w /etc/sudoers -p wa -k privilege-escalation
# Monitor execution of su and sudo
-w /bin/su -p x -k privilege-escalation
-w /usr/bin/sudo -p x -k privilege-escalation
# Monitor network configuration changes
-w /etc/network/ -p wa -k network-config
-w /etc/hosts -p wa -k network-config
# Monitor all executions (high volume — use carefully)
-a always,exit -F arch=b64 -S execve -k exec-all
# Load rules
sudo augenrules --load
sudo auditctl -l # list active rules
SOAR (Security Orchestration, Automation, and Response)
SOAR platforms automate the repetitive tasks in security operations: enriching alerts, correlating data, assigning tickets, and executing response actions.
SOAR concepts
A SOAR playbook is an automated workflow triggered by a security event:
Alert: Failed SSH login from 203.0.113.42 (10 times in 5 minutes)
│
▼
Enrich: Look up IP in threat intelligence feeds
│
├── IP is in threat feed → Auto-block at firewall, create P1 ticket
│
└── IP not in threat feed
│
▼
Check: Is this a known developer IP?
│
├── Yes → Notify developer, close alert
│
└── No → Block temporarily, alert SOC analyst for review
Python-based SOAR automation
# Simple SOAR playbook: respond to failed SSH brute force
import requests
import subprocess
import json
from datetime import datetime
THREAT_INTEL_API = 'https://api.abuseipdb.com/api/v2/check'
ABUSEIPDB_KEY = 'your-api-key' # load from OpenBao in production
def check_threat_intel(ip: str) -> dict:
"""Check an IP against AbuseIPDB threat intelligence."""
resp = requests.get(
THREAT_INTEL_API,
headers={'Key': ABUSEIPDB_KEY, 'Accept': 'application/json'},
params={'ipAddress': ip, 'maxAgeInDays': 90},
)
return resp.json().get('data', {})
def block_ip_firewall(ip: str):
"""Add a firewall rule to block the IP."""
subprocess.run(
['iptables', '-A', 'INPUT', '-s', ip, '-j', 'DROP'],
check=True
)
print(f"[{datetime.now()}] Blocked {ip} at firewall")
def create_ticket(ip: str, abuse_score: int, event_count: int):
"""Create a ticket in the ticketing system (example: plain log)."""
ticket = {
'timestamp': datetime.now().isoformat(),
'title': f'SSH brute force from {ip}',
'priority': 'P1' if abuse_score > 50 else 'P2',
'details': {
'source_ip': ip,
'abuse_confidence_score': abuse_score,
'failed_logins': event_count,
}
}
print(f"TICKET: {json.dumps(ticket, indent=2)}")
def handle_ssh_brute_force(source_ip: str, event_count: int):
"""Main playbook: investigate and respond to SSH brute force."""
intel = check_threat_intel(source_ip)
abuse_score = intel.get('abuseConfidenceScore', 0)
is_known_attacker = abuse_score > 25
if is_known_attacker:
block_ip_firewall(source_ip)
create_ticket(source_ip, abuse_score, event_count)
elif event_count > 50:
# High volume even from unknown IP — block temporarily
block_ip_firewall(source_ip)
create_ticket(source_ip, abuse_score, event_count)
else:
print(f"[INFO] {source_ip}: {event_count} failures, score {abuse_score} — monitoring")
# Trigger from SIEM alert
handle_ssh_brute_force('203.0.113.42', event_count=75)
Alert types and severity
| Severity | Response time | Examples |
|---|---|---|
| Critical (P1) | Immediate (minutes) | Active ransomware, data exfiltration in progress, root compromise |
| High (P2) | Within 1 hour | Confirmed malware, credential stuffing success, lateral movement |
| Medium (P3) | Within 4 hours | Repeated failed logins, policy violation, suspicious reconnaissance |
| Low (P4) | Within 24 hours | Informational anomaly, single failed login, configuration drift |
Key takeaways
- A SIEM aggregates, normalizes, correlates, alerts on, and retains logs from across the environment — its value is finding multi-stage attacks no single source reveals. Elastic Security and Wazuh are the common open-source platforms.
- IDS detects, IPS prevents: out-of-band vs inline. Suricata covers the network; Falco watches syscalls for container/host runtime anomalies; auditd is the Linux kernel audit trail for files, privilege use, and
execve. - You can only detect what you log. Capture authentication, network, application, system, container, and cloud events; emit structured JSON so the SIEM can parse it; and retain per the applicable mandate (PCI 1yr, HIPAA 6yr, …).
- EDR adds endpoint depth — process trees, network/file/memory monitoring, remote containment, and forensic collection.
- SOAR automates the repetitive SOC work: a playbook enriches an alert (threat-intel lookup), decides, and acts (block, ticket, notify) — turning a flood of alerts into triaged, prioritized response (P1–P4).
References
- Elastic Security documentation. https://www.elastic.co/guide/en/security/current/index.html
- Wazuh documentation. https://documentation.wazuh.com/current/index.html
- Suricata documentation. https://docs.suricata.io/
- Falco documentation. https://falco.org/docs/
- Linux audit framework (
auditd) manual. https://man7.org/linux/man-pages/man8/auditd.8.html - MITRE ATT&CK framework. https://attack.mitre.org/
- NIST SP 800-92 — Guide to Computer Security Log Management. https://csrc.nist.gov/publications/detail/sp/800/92/final
Related course pages: Suricata IDS/IPS · Incident Response · Vulnerability Management
🛠️ Maintenance note: versions in the install snippets move — Elastic is on the 8.x APT repo (9.x exists), Wazuh paths here pin 4.9, and Falco’s repo/keyring URLs change. NIST SP 800-92 is under revision (a draft Rev. 1 is in progress). Re-verify the package repos, agent install scripts, and retention figures against current sources each term.