Day 10: Final Project
Today's Goal
Put everything you have learned over the past nine days into practice by building a Security Operations Center (SOC) dashboard.
Project Overview
| Item | Details |
|---|---|
| Dashboard name | Security Operations Center (SOC) |
| Features | Threat detection, incident response, compliance reporting |
| Technologies used | SPL, dashboards, alerts, lookups, macros |
flowchart TB
subgraph SOC["SOC Dashboard"]
KPI["KPI Panels<br>Total events & alert count"]
Timeline["Timeline<br>Event trends"]
Threat["Threat Detection<br>Anomalous patterns"]
Detail["Detailed Analysis<br>Drilldown"]
end
style KPI fill:#3b82f6,color:#fff
style Timeline fill:#22c55e,color:#fff
style Threat fill:#ef4444,color:#fff
style Detail fill:#f59e0b,color:#fff
Step 1: Prepare Sample Data
Security Log Samples
Set up the following log sources for your SOC dashboard.
firewall.log
2026-01-30 10:00:01 action=allowed src_ip=192.168.1.10 dst_ip=10.0.0.1 dst_port=443 proto=TCP bytes=2048
2026-01-30 10:00:02 action=blocked src_ip=10.10.10.5 dst_ip=192.168.1.100 dst_port=22 proto=TCP bytes=0
2026-01-30 10:00:03 action=allowed src_ip=192.168.1.20 dst_ip=172.16.0.5 dst_port=80 proto=TCP bytes=4096
2026-01-30 10:00:05 action=blocked src_ip=203.0.113.50 dst_ip=192.168.1.100 dst_port=3389 proto=TCP bytes=0
2026-01-30 10:00:10 action=allowed src_ip=192.168.1.30 dst_ip=10.0.0.2 dst_port=53 proto=UDP bytes=128
auth.log
2026-01-30 10:00:01 action=login_success user=alice src_ip=192.168.1.10 method=password
2026-01-30 10:00:05 action=login_failed user=admin src_ip=203.0.113.50 method=password
2026-01-30 10:00:06 action=login_failed user=admin src_ip=203.0.113.50 method=password
2026-01-30 10:00:07 action=login_failed user=admin src_ip=203.0.113.50 method=password
2026-01-30 10:00:10 action=login_success user=bob src_ip=192.168.1.20 method=ssh_key
2026-01-30 10:00:15 action=login_failed user=root src_ip=198.51.100.10 method=password
2026-01-30 10:00:20 action=privilege_escalation user=alice src_ip=192.168.1.10 target=root
web_access.log
192.168.1.10 - alice [30/Jan/2026:10:00:01 +0900] "GET /admin HTTP/1.1" 200 2048
203.0.113.50 - - [30/Jan/2026:10:00:05 +0900] "GET /../../../../etc/passwd HTTP/1.1" 403 128
192.168.1.20 - bob [30/Jan/2026:10:00:10 +0900] "GET /api/users HTTP/1.1" 200 4096
198.51.100.10 - - [30/Jan/2026:10:00:15 +0900] "POST /api/login HTTP/1.1" 401 64
10.10.10.5 - - [30/Jan/2026:10:00:20 +0900] "GET /wp-admin HTTP/1.1" 404 128
Step 2: Lookup Tables
threat_intel.csv (Threat Intelligence)
ip_address,threat_type,severity,description
203.0.113.50,brute_force,high,Known brute force attacker
198.51.100.10,scanner,medium,Network scanner
10.10.10.5,botnet,critical,Botnet C2 server
asset_inventory.csv (Asset Inventory)
ip_address,hostname,department,criticality
192.168.1.10,ws-alice,Engineering,medium
192.168.1.20,ws-bob,Marketing,low
192.168.1.30,ws-charlie,Finance,high
192.168.1.100,srv-web01,IT,critical
10.0.0.1,srv-db01,IT,critical
Step 3: Search Macros
# macros.conf
# Detect threat IPs
[threat_detected]
definition = lookup threat_intel ip_address AS src_ip OUTPUT threat_type, severity, description AS threat_description | where isnotnull(threat_type)
# Classify event severity
[severity_classification]
definition = eval alert_severity=case(severity="critical", 4, severity="high", 3, severity="medium", 2, severity="low", 1, 1=1, 0)
# Detect authentication failures above a threshold
[auth_failures(1)]
args = threshold
definition = index=security sourcetype=auth_log action=login_failed | stats count by src_ip, user | where count >= $threshold$
Step 4: Alert Definitions
Brute Force Detection
index=security sourcetype=auth_log action=login_failed
| bin _time span=5m
| stats count by src_ip, _time
| where count >= 5
| `threat_detected`
Configuration:
- Schedule:
*/5 * * * * - Trigger: Number of Results > 0
- Suppress: 30 minutes per
src_ip - Actions: Email, Slack notification
Malicious Access Attempts
index=web sourcetype=access_combined
| rex field=uri "(?P<attack_pattern>(\.\./|etc/passwd|wp-admin|\.env|\.git))"
| where isnotnull(attack_pattern)
| stats count by clientip, attack_pattern
Step 5: SOC Dashboard
<dashboard theme="dark">
<label>Security Operations Center</label>
<description>Security monitoring dashboard</description>
<fieldset submitButton="false">
<input type="time" token="time">
<default>
<earliest>-24h@h</earliest>
<latest>now</latest>
</default>
</input>
<input type="dropdown" token="severity_filter">
<label>Severity</label>
<choice value="*">All</choice>
<choice value="critical">Critical</choice>
<choice value="high">High</choice>
<choice value="medium">Medium</choice>
<default>*</default>
</input>
</fieldset>
<!-- KPI row -->
<row>
<panel><title>Total Security Events</title>
<single>
<search>
<query>index=security OR index=web | stats count</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<option name="colorMode">block</option>
<option name="rangeColors">["0x22c55e","0xf59e0b","0xef4444"]</option>
<option name="rangeValues">[1000,5000]</option>
<option name="useColors">true</option>
</single>
</panel>
<panel><title>Threat Detections</title>
<single>
<search>
<query>
index=security OR index=web
| `threat_detected`
| stats dc(src_ip) AS threat_count
</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<option name="colorMode">block</option>
<option name="rangeColors">["0x22c55e","0xef4444"]</option>
<option name="rangeValues">[0]</option>
<option name="useColors">true</option>
</single>
</panel>
<panel><title>Failed Logins</title>
<single>
<search>
<query>index=security sourcetype=auth_log action=login_failed | stats count</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
</single>
</panel>
<panel><title>Blocked Connections</title>
<single>
<search>
<query>index=security sourcetype=firewall action=blocked | stats count</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
</single>
</panel>
</row>
<!-- Timeline -->
<row>
<panel><title>Security Events Timeline</title>
<chart>
<search>
<query>
index=security OR index=web
| eval event_type=case(
action="blocked", "Firewall Block",
action="login_failed", "Auth Failure",
status>=400, "Web Error",
1=1, "Other"
)
| timechart span=1h count by event_type
</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<option name="charting.chart">area</option>
<option name="charting.chart.stackMode">stacked</option>
<option name="charting.legend.placement">bottom</option>
</chart>
</panel>
</row>
<!-- Threat analysis -->
<row>
<panel><title>Threat Intelligence Matches</title>
<table>
<search>
<query>
index=security OR index=web
| `threat_detected`
| stats count, values(action) AS actions, latest(_time) AS last_seen by src_ip, threat_type, severity
| eval last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort -count
</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<option name="drilldown">row</option>
<drilldown>
<link target="_blank">/app/search/search?q=index%3Dsecurity%20src_ip%3D$row.src_ip$</link>
</drilldown>
</table>
</panel>
<panel><title>Top Blocked IPs</title>
<chart>
<search>
<query>
index=security sourcetype=firewall action=blocked
| stats count by src_ip
| sort -count
| head 10
</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<option name="charting.chart">bar</option>
</chart>
</panel>
</row>
<!-- Authentication analysis -->
<row>
<panel><title>Authentication Failures by User</title>
<chart>
<search>
<query>
index=security sourcetype=auth_log action=login_failed
| stats count by user
| sort -count
</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
<option name="charting.chart">pie</option>
</chart>
</panel>
<panel><title>Recent Security Events</title>
<table>
<search>
<query>
index=security
| eval severity=case(
action="privilege_escalation", "critical",
action="login_failed", "warning",
action="blocked", "info",
1=1, "low"
)
| table _time, sourcetype, action, user, src_ip, severity
| sort -_time
| head 20
</query>
<earliest>$time.earliest$</earliest>
<latest>$time.latest$</latest>
</search>
</table>
</panel>
</row>
</dashboard>
10-Day Recap
flowchart TB
D1["Day 1<br>Splunk Basics<br>Architecture"]
D2["Day 2<br>Data Ingestion<br>inputs.conf"]
D3["Day 3<br>Search Fundamentals<br>SPL Intro"]
D4["Day 4<br>Fields &<br>Filtering"]
D5["Day 5<br>Statistics &<br>Aggregation"]
D6["Day 6<br>Data Visualization<br>Dashboards"]
D7["Day 7<br>Advanced Search<br>lookup/join"]
D8["Day 8<br>Alerts &<br>Reports"]
D9["Day 9<br>Splunk Admin<br>Roles/Apps"]
D10["Day 10<br>Final Project"]
D1 --> D2 --> D3 --> D4 --> D5
D5 --> D6 --> D7 --> D8 --> D9 --> D10
style D1 fill:#3b82f6,color:#fff
style D2 fill:#3b82f6,color:#fff
style D3 fill:#22c55e,color:#fff
style D4 fill:#22c55e,color:#fff
style D5 fill:#22c55e,color:#fff
style D6 fill:#f59e0b,color:#fff
style D7 fill:#f59e0b,color:#fff
style D8 fill:#8b5cf6,color:#fff
style D9 fill:#8b5cf6,color:#fff
style D10 fill:#ef4444,color:#fff
| Day | Topic | Skills Acquired |
|---|---|---|
| 1 | Welcome to Splunk | Architecture, installation, Web UI |
| 2 | Data Ingestion | monitor, HEC, sourcetype, indexes |
| 3 | Search Fundamentals | SPL syntax, keyword/field search, pipes |
| 4 | Fields and Filtering | eval, where, rex |
| 5 | Statistics and Aggregation | stats, chart, timechart, top, eventstats |
| 6 | Data Visualization | Dashboards, Simple XML, drilldown |
| 7 | Advanced Search | Subsearches, lookup, join, transaction |
| 8 | Alerts and Reports | Scheduled searches, alerts, macros |
| 9 | Splunk Administration | Roles, index management, knowledge objects |
| 10 | Final Project | SOC dashboard build |
What to Learn Next
Now that you have a solid foundation in Splunk, here are some topics to explore next.
| Topic | Description |
|---|---|
| Splunk Enterprise Security (ES) | Full SIEM capabilities |
| Splunk SOAR | Security orchestration and automated response |
| SPL2 | The next-generation search language |
| Data Models and CIM | Common Information Model |
| Splunk Cloud | Cloud-hosted Splunk deployment |
| Splunk Certifications | Validate your skills professionally |
Splunk Certifications
| Certification | Level | Focus |
|---|---|---|
| Splunk Core Certified User | Foundation | Basic SPL operations |
| Splunk Core Certified Power User | Intermediate | Advanced SPL, dashboards |
| Splunk Core Certified Advanced Power User | Advanced | Data models, optimization |
| Splunk Enterprise Certified Admin | Administration | Infrastructure management, configuration |
Exercises
Exercise 1: Feature Addition
Use the iplocation command to add a map panel that shows the geographic origin of attack source IPs.
Exercise 2: Applied
Use eventstats to calculate the normal access frequency for each IP and write a query that detects anomalous activity (three times the average or higher).
Exercise 3: Challenge
Package the entire SOC dashboard as a standalone Splunk app. Include app.conf, navigation, dashboards, lookups, macros, and saved searches (alerts).
References
Congratulations! You have completed the 10-day Splunk fundamentals course. The knowledge you have built here -- from SPL basics to dashboard design, alerting, and administration -- forms a strong foundation for security operations, IT monitoring, data analysis, and any other domain where Splunk is used.