Building a Mini SOC: A Complete Guide with Wazuh, Snort, and Zeek
In today’s threat landscape, organizations of all sizes need robust security monitoring capabilities. However, enterprise-grade Security Operations Centers (SOCs) often require significant budgets and specialized personnel. This guide demonstrates how to build a powerful mini SOC using three open-source tools: Wazuh for security information and event management (SIEM), Snort for intrusion detection, and Zeek for network traffic analysis.
What is a Mini SOC?
A mini SOC is a scaled-down security operations center that provides essential security monitoring, detection, and response capabilities without the overhead of enterprise solutions. It combines log management, intrusion detection, network analysis, and threat intelligence to give organizations visibility into their security posture.
Think of it as your organization’s security nerve center—continuously monitoring network traffic, analyzing logs, detecting threats, and alerting security teams to potential incidents.
Why These Three Tools?
Wazuh: The Central Nervous System
Wazuh is an open-source security platform that provides unified SIEM and extended detection and response (XDR) capabilities. It acts as your SOC’s central hub, collecting and correlating events from across your infrastructure.
Key capabilities:
- Host-based intrusion detection
- Log data analysis
- File integrity monitoring
- Vulnerability detection
- Security configuration assessment
- Regulatory compliance monitoring
Snort: The Perimeter Guard
Snort is a powerful network intrusion detection and prevention system (IDS/IPS) that analyzes network traffic in real-time, comparing it against known attack signatures and anomalous behavior patterns.
Key capabilities:
- Real-time traffic analysis
- Protocol analysis
- Content searching and matching
- Signature-based detection
- Anomaly detection
- Packet logging
Zeek: The Deep Inspector
Zeek (formerly Bro) is a network analysis framework that goes beyond simple packet inspection to provide comprehensive network visibility and security monitoring.
Key capabilities:
- Deep packet inspection
- Protocol analysis and decoding
- Network traffic logging
- Behavioral analysis
- File extraction from network traffic
- Custom scripting for detection logic
Architecture Overview
Our mini SOC architecture consists of several components working together:
┌─────────────────────────────────────────────────────────┐
│ Network Traffic │
└────────────────────┬────────────────────────────────────┘
│
┌────────────┴────────────┐
│ │
┌────▼─────┐ ┌─────▼────┐
│ Snort │ │ Zeek │
│ IDS │ │ Network │
│ │ │ Analysis │
└────┬─────┘ └─────┬────┘
│ │
│ ┌─────────────┐ │
└─────►│ Wazuh │◄──┘
│ Manager │
│ (SIEM) │
└──────┬──────┘
│
┌─────────────┼─────────────┐
│ │ │
┌────▼─────┐ ┌───▼────┐ ┌────▼─────┐
│ Wazuh │ │ Wazuh │ │ Wazuh │
│ Agent │ │ Agent │ │ Agent │
│ (Server) │ │ (Web) │ │(Endpoint)│
└──────────┘ └────────┘ └──────────┘
Hardware and System Requirements
Minimum Requirements
For a small network (up to 50 endpoints):
- Wazuh Manager: 4 CPU cores, 8GB RAM, 100GB storage
- Network Sensor (Snort + Zeek): 4 CPU cores, 8GB RAM, 500GB storage
- Wazuh Agents: 256MB RAM per agent
Recommended Setup
For better performance and scalability:
- Wazuh Manager: 8 CPU cores, 16GB RAM, 500GB SSD
- Network Sensor: 8 CPU cores, 16GB RAM, 1TB SSD
- Elasticsearch: 8 CPU cores, 16GB RAM, 1TB SSD
Network Requirements
- Dedicated management network for SOC components
- Network TAP or SPAN port for traffic monitoring
- Sufficient bandwidth for log transmission
Installation and Configuration
Step 1: Installing Wazuh
Wazuh can be deployed using several methods. We’ll use the all-in-one installation for simplicity.
Prerequisites:
# Update system
sudo apt update && sudo apt upgrade -y
# Install required dependencies
sudo apt install curl apt-transport-https lsb-release gnupg -y
Install Wazuh:
# Download and run the installation assistant
curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh
sudo bash ./wazuh-install.sh -a
# Save the credentials displayed after installation
# Default access: https://your-server-ip
Configure Wazuh Manager:
<!-- /var/ossec/etc/ossec.conf -->
<ossec_config>
<global>
<email_notification>yes</email_notification>
<email_to>security@yourcompany.com</email_to>
<smtp_server>smtp.yourcompany.com</smtp_server>
<email_from>wazuh@yourcompany.com</email_from>
</global>
<syslog_output>
<level>9</level>
<server>siem.yourcompany.com</server>
</syslog_output>
<alerts>
<log_alert_level>3</log_alert_level>
</alerts>
</ossec_config>
Deploy Wazuh Agents:
# On Linux endpoints
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add -
echo "deb https://packages.wazuh.com/4.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list
apt update
apt install wazuh-agent
# Configure agent to connect to manager
echo "WAZUH_MANAGER='your-manager-ip'" > /etc/wazuh-agent/wazuh-agent.conf
systemctl start wazuh-agent
Step 2: Installing Snort
Install Snort 3:
# Install dependencies
sudo apt install build-essential libpcap-dev libpcre3-dev \
libnet1-dev zlib1g-dev luajit hwloc libdnet-dev \
libdumbnet-dev bison flex liblzma-dev openssl libssl-dev \
pkg-config libhwloc-dev cmake cpputest libsqlite3-dev \
uuid-dev libcmocka-dev libnetfilter-queue-dev \
libmnl-dev autotools-dev libluajit-5.1-dev \
libunwind-dev -y
# Download and install DAQ
cd /tmp
wget https://www.snort.org/downloads/snortplus/libdaq-3.0.10.tar.gz
tar -xvzf libdaq-3.0.10.tar.gz
cd libdaq-3.0.10
./bootstrap
./configure
make
sudo make install
# Download and install Snort 3
cd /tmp
wget https://www.snort.org/downloads/snortplus/snort3-3.1.72.0.tar.gz
tar -xvzf snort3-3.1.72.0.tar.gz
cd snort3-3.1.72.0
./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc
cd build
make
sudo make install
Configure Snort:
-- /usr/local/etc/snort/snort.lua
-- Basic configuration
HOME_NET = '192.168.1.0/24'
EXTERNAL_NET = '!$HOME_NET'
-- Configure network interface
daq = {
module_dirs = { '/usr/local/lib/daq' },
modules = {
{
name = 'afpacket',
mode = 'inline',
variables = { 'eth0' }
}
}
}
-- Enable logging
alert_fast = {
file = true,
packet = false,
limit = 10
}
-- Configure output to Wazuh
alert_syslog = {
level = 'info'
}
Download Community Rules:
# Register for Snort account and get Oinkcode
cd /usr/local/etc/snort
wget https://www.snort.org/rules/snortrules-snapshot-31720.tar.gz -O rules.tar.gz
tar -xvzf rules.tar.gz
Step 3: Installing Zeek
Install Zeek:
# Add Zeek repository
echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /' | \
sudo tee /etc/apt/sources.list.d/security:zeek.list
curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_22.04/Release.key | \
gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null
sudo apt update
sudo apt install zeek -y
# Add Zeek to PATH
export PATH=/opt/zeek/bin:$PATH
echo 'export PATH=/opt/zeek/bin:$PATH' >> ~/.bashrc
Configure Zeek:
# Edit network configuration
sudo vim /opt/zeek/etc/node.cfg
# /opt/zeek/etc/node.cfg
[zeek]
type=standalone
host=localhost
interface=eth0
# Edit network settings
sudo vim /opt/zeek/etc/networks.cfg
# /opt/zeek/etc/networks.cfg
192.168.1.0/24 Private Network
10.0.0.0/8 Private Network
Install Zeek Packages:
# Initialize package manager
zkg autoconfig
# Install useful packages
zkg install zeek/corelight/bro-long-connections
zkg install zeek/corelight/bro-xor-exe-plugin
zkg install zeek/salesforce/ja3
Step 4: Integrating Everything
Configure Snort to Send Logs to Wazuh:
<!-- Add to /var/ossec/etc/ossec.conf -->
<localfile>
<log_format>snort-full</log_format>
<location>/var/log/snort/alert</location>
</localfile>
Configure Zeek to Send Logs to Wazuh:
# Create Zeek log monitoring script
cat > /opt/zeek/share/zeek/site/wazuh-integration.zeek << 'EOF'
@load base/frameworks/logging
event zeek_init() {
Log::add_filter(Conn::LOG, [
$name = "conn-wazuh",
$path = "/var/log/zeek/conn-wazuh",
$interv = 1min
]);
}
EOF
<!-- Add to /var/ossec/etc/ossec.conf -->
<localfile>
<log_format>json</log_format>
<location>/opt/zeek/logs/current/conn.log</location>
</localfile>
<localfile>
<log_format>json</log_format>
<location>/opt/zeek/logs/current/dns.log</location>
</localfile>
<localfile>
<log_format>json</log_format>
<location>/opt/zeek/logs/current/http.log</location>
</localfile>
Custom Detection Rules
Wazuh Custom Rules
<!-- /var/ossec/etc/rules/local_rules.xml -->
<group name="custom,">
<!-- Detect multiple failed SSH attempts -->
<rule id="100001" level="10">
<if_matched_sid>5716</if_matched_sid>
<same_source_ip />
<frequency>5</frequency>
<timeframe>360</timeframe>
<description>Multiple failed SSH login attempts</description>
<mitre>
<id>T1110</id>
</mitre>
</rule>
<!-- Detect port scanning -->
<rule id="100002" level="8">
<decoded_as>zeek</decoded_as>
<field name="zeek.conn.conn_state">^S0$</field>
<same_source_ip />
<frequency>20</frequency>
<timeframe>60</timeframe>
<description>Possible port scan detected</description>
<mitre>
<id>T1046</id>
</mitre>
</rule>
<!-- Detect suspicious outbound connections -->
<rule id="100003" level="9">
<decoded_as>zeek</decoded_as>
<field name="zeek.conn.dst_port">^(4444|31337|1337)$</field>
<description>Connection to suspicious port detected</description>
<mitre>
<id>T1571</id>
</mitre>
</rule>
</group>
Snort Custom Rules
# /usr/local/etc/snort/rules/local.rules
# Detect DNS tunneling attempts
alert udp any any -> any 53 (msg:"Possible DNS Tunneling - Long Query"; \
content:"|01 00|"; offset:2; depth:2; \
dsize:>100; sid:1000001; rev:1;)
# Detect SQL injection attempts
alert tcp any any -> any 80 (msg:"SQL Injection Attempt"; \
flow:to_server,established; \
content:"union"; nocase; content:"select"; nocase; \
sid:1000002; rev:1;)
# Detect ransomware communication patterns
alert tcp any any -> any any (msg:"Possible Ransomware C2 Communication"; \
content:".onion"; nocase; \
sid:1000003; rev:1;)
# Detect lateral movement
alert tcp $HOME_NET any -> $HOME_NET 445 (msg:"SMB Lateral Movement Attempt"; \
flow:to_server,established; \
content:"|ff|SMB"; offset:4; depth:4; \
threshold:type both, track by_src, count 10, seconds 60; \
sid:1000004; rev:1;)
Zeek Custom Scripts
# /opt/zeek/share/zeek/site/detect-beaconing.zeek
@load base/frameworks/notice
module BeaconDetection;
export {
redef enum Notice::Type += {
Beaconing_Detected
};
}
global beacon_tracker: table[addr] of table[addr] of count &create_expire=1hr;
event connection_established(c: connection) {
local orig = c$id$orig_h;
local resp = c$id$resp_h;
if (orig !in beacon_tracker)
beacon_tracker[orig] = table();
if (resp !in beacon_tracker[orig])
beacon_tracker[orig][resp] = 0;
beacon_tracker[orig][resp] += 1;
# Alert if more than 30 connections in an hour
if (beacon_tracker[orig][resp] > 30) {
NOTICE([$note=Beaconing_Detected,
$msg=fmt("Possible beaconing from %s to %s", orig, resp),
$src=orig,
$dst=resp]);
}
}
Dashboard and Visualization
Wazuh Dashboard Configuration
Access the Wazuh dashboard at https://your-server-ip and configure:
1. Create Custom Dashboards:
- Overview dashboard with key metrics
- Network security dashboard for Snort/Zeek events
- Compliance dashboard for regulatory requirements
- Threat intelligence dashboard
2. Set Up Key Visualizations:
- Top attacked hosts
- Attack timeline
- Geographic source of attacks
- MITRE ATT&CK framework mapping
- Vulnerability summary
3. Configure Alerts:
{
"name": "Critical Security Alert",
"severity": "high",
"conditions": {
"rule_level": ">=12"
},
"actions": [
{
"type": "email",
"recipients": ["security@company.com"]
},
{
"type": "webhook",
"url": "https://slack.com/api/webhook"
}
]
}
Operational Procedures
Daily Operations
Morning Checks:
- Review overnight alerts and security events
- Check system health and agent status
- Verify all data sources are reporting
- Review failed authentication attempts
- Check for signature/rule updates
Ongoing Monitoring:
- Monitor real-time alerts
- Investigate high-priority events
- Track incident response activities
- Update threat intelligence feeds
End of Day:
- Generate daily security report
- Document incidents and resolutions
- Plan follow-up actions
- Review system performance metrics
Weekly Maintenance
Security Hygiene:
- Update Snort rules and signatures
- Update Zeek packages and scripts
- Review and tune detection rules
- Analyze false positive rates
- Update Wazuh agent policies
Performance Tuning:
- Review system resource usage
- Optimize log retention policies
- Clean up old logs and archives
- Test backup and recovery procedures
Monthly Activities
Strategic Reviews:
- Analyze security trends and patterns
- Review detection coverage gaps
- Update security policies and procedures
- Conduct tabletop exercises
- Review and update runbooks
Compliance Activities:
- Generate compliance reports
- Review access controls
- Audit system configurations
- Update documentation
Threat Hunting with Your Mini SOC
Hunting Methodology
1. Hypothesis-Driven Hunting:
Hypothesis: Attackers may be using PowerShell for lateral movement
Wazuh Query:
rule.mitre.technique:T1059.001 AND
data.win.eventdata.commandLine:*-enc*
Zeek Analysis:
Look for SMB connections followed by process creation events
2. Baseline Anomaly Detection:
Establish normal patterns:
- Typical DNS query volumes per host
- Standard network connection patterns
- Regular authentication behaviors
Hunt for deviations using Wazuh queries:
agent.name:webserver AND
NOT (destination.ip:192.168.1.10 OR destination.ip:192.168.1.20)
3. Indicator-Based Hunting:
Search for known IOCs from threat intelligence:
Snort:
alert ip any any -> any any (msg:"Known Malicious IP"; \
content:"203.0.113.42"; sid:2000001;)
Zeek:
Look for specific user agents, JA3 hashes, or certificate fingerprints
Common Hunt Scenarios
Hunt for Data Exfiltration:
# Zeek - Unusual outbound data volumes
@load policy/protocols/conn/known-hosts
# Look for large outbound transfers
event connection_state_remove(c: connection) {
if (c$orig_bytes > 10485760) { # 10MB
print fmt("Large upload: %s -> %s (%d bytes)",
c$id$orig_h, c$id$resp_h, c$orig_bytes);
}
}
Hunt for Privilege Escalation:
# Wazuh query for unusual privilege changes
rule.groups:authentication AND
data.win.eventdata.targetUserName:Administrator AND
rule.level:>=7
Hunt for Persistence Mechanisms:
# Search for registry run key modifications
rule.groups:sysmon_event1 AND
data.win.eventdata.targetObject:(*\\Run\\* OR *\\RunOnce\\*)
Advanced Configurations
Threat Intelligence Integration
Configure MISP Integration:
<!-- /var/ossec/etc/ossec.conf -->
<integration>
<name>misp</name>
<hook_url>https://misp.yourcompany.com</hook_url>
<api_key>YOUR_API_KEY</api_key>
<level>10</level>
<alert_format>json</alert_format>
</integration>
Add Threat Feeds to Zeek:
# /opt/zeek/share/zeek/site/threat-intel.zeek
@load frameworks/intel/seen
redef Intel::read_files += {
"/opt/zeek/share/zeek/site/intel/malicious-ips.txt",
"/opt/zeek/share/zeek/site/intel/malicious-domains.txt"
};
Active Response
Configure Wazuh to automatically respond to threats:
<!-- /var/ossec/etc/ossec.conf -->
<active-response>
<command>firewall-drop</command>
<location>local</location>
<rules_id>100001</rules_id>
<timeout>600</timeout>
</active-response>
<active-response>
<command>disable-account</command>
<location>local</location>
<rules_id>100010</rules_id>
<timeout>7200</timeout>
</active-response>
Log Enrichment
Enhance detection with GeoIP and enrichment:
<!-- Enable GeoIP in Wazuh -->
<geoip>
<enabled>yes</enabled>
<database>/var/ossec/etc/GeoLite2-City.mmdb</database>
</geoip>
# Add custom fields in Zeek
@load policy/protocols/conn/mac-logging
@load policy/protocols/http/detect-sqli
redef record Conn::Info += {
# Add custom tracking fields
custom_tag: string &optional;
};
Performance Optimization
Wazuh Optimization
<!-- Tune log collection -->
<queue_size>131072</queue_size>
<log_collector>
<threads>4</threads>
</log_collector>
<!-- Optimize rule evaluation -->
<rules>
<decoder_order>yes</decoder_order>
</rules>
Snort Optimization
-- snort.lua performance tuning
daq = {
snaplen = 1518,
workers = 4
}
-- Optimize detection
detection = {
pcre_match_limit = 3500,
pcre_match_limit_recursion = 1500
}
-- Tune memory
stream = {
max_flows = 262144,
memcap = 8388608
}
Zeek Optimization
# /opt/zeek/etc/node.cfg
[manager]
type=manager
host=localhost
[proxy-1]
type=proxy
host=localhost
[worker-1]
type=worker
host=localhost
interface=eth0
lb_method=pf_ring
lb_procs=4
pin_cpus=0,1,2,3
Incident Response Playbooks
Playbook: Ransomware Detection
Detection Indicators:
- Mass file encryption activity
- Unusual file extensions (.encrypted, .locked)
- Ransom notes (README.txt files)
- Connections to known ransomware C2 servers
Response Steps:
- Isolate affected systems immediately
- Capture memory dumps and disk images
- Identify patient zero and lateral movement
- Check backups and restoration options
- Document timeline and indicators
- Engage law enforcement if required
Wazuh Query:
rule.groups:sysmon_event11 AND
(data.win.eventdata.targetFilename:*.encrypted OR
data.win.eventdata.targetFilename:*.locked)
Playbook: Brute Force Attack
Detection Indicators:
- Multiple failed authentication attempts
- Attempts from unusual geographic locations
- Automated, rapid login attempts
Response Steps:
- Block source IP addresses
- Implement rate limiting
- Force password resets for targeted accounts
- Enable MFA if not already active
- Review authentication logs for successful logins
- Update firewall rules
Wazuh Active Response:
<active-response>
<command>firewall-drop</command>
<location>local</location>
<rules_id>100001</rules_id>
<timeout>3600</timeout>
</active-response>
Cost Analysis
Total Cost of Ownership
Hardware/Infrastructure:
- Server hardware or cloud instances: $200-500/month
- Network TAP device: $200-2000 (one-time)
- Storage for log retention: $50-200/month
Software:
- All tools are open-source: $0
- Optional commercial support: $2000-10000/year
Personnel:
- Part-time SOC analyst: $30,000-60,000/year
- Training and certifications: $2000-5000/year
Total Annual Cost: $40,000-80,000
Compare this to enterprise SOC solutions that can cost $200,000-1,000,000+ annually.
Best Practices and Lessons Learned
Do’s
- Start simple and add complexity gradually
- Document everything from day one
- Automate repetitive tasks
- Regularly test detection rules
- Maintain baseline behavior profiles
- Keep systems and rules updated
- Conduct regular table-top exercises
Don’ts
- Don’t ignore false positives—tune them out
- Don’t collect logs you won’t analyze
- Don’t skip regular maintenance
- Don’t forget about system backups
- Don’t overlook insider threats
- Don’t neglect agent health monitoring
Common Pitfalls
Alert Fatigue: Tune your rules to reduce noise. It’s better to have 10 actionable alerts than 1000 false positives.
Log Storage Issues: Plan for log growth. Implement rotation and archival policies early.
Performance Degradation: Monitor system resources. Scale horizontally when needed.
Skill Gaps: Invest in training. Wazuh, Snort, and Zeek have excellent documentation and community resources.
Conclusion
Building a mini SOC with Wazuh, Snort, and Zeek provides organizations with enterprise-grade security monitoring capabilities at a fraction of the cost. This combination offers comprehensive visibility across endpoints, networks, and applications while remaining flexible and scalable.
The key to success lies in starting with solid fundamentals—proper installation, basic configuration, and essential detection rules—then progressively building more sophisticated capabilities as your team’s expertise grows.
Remember that tools are only as effective as the team operating them. Invest time in learning these platforms, developing custom detection rules for your environment, and establishing clear operational procedures.
Your mini SOC is not a set-it-and-forget-it solution. It requires ongoing maintenance, tuning, and adaptation to evolving threats. But with dedication and continuous improvement, you’ll have a powerful security operations capability that protects your organization from modern cyber threats.
The threat landscape continues to evolve, but with Wazuh, Snort, and Zeek working together, you have the visibility and detection capabilities needed to identify and respond to security incidents before they become breaches.
Ready to build your mini SOC? Start with the basics, learn continuously, and remember that every day of monitoring is a day of improved security posture. Your organization’s security journey begins now.