{"id":193,"date":"2023-07-29T09:00:00","date_gmt":"2023-07-29T09:00:00","guid":{"rendered":"http:\/\/justruss.tech\/index.php\/2023\/07\/29\/upgrading-my-home-lab-adding-a-siem-stack-on-a-budget\/"},"modified":"2026-05-13T12:59:35","modified_gmt":"2026-05-13T12:59:35","slug":"upgrading-my-home-lab-adding-a-siem-stack-on-a-budget","status":"publish","type":"post","link":"https:\/\/justruss.tech\/index.php\/2023\/07\/29\/upgrading-my-home-lab-adding-a-siem-stack-on-a-budget\/","title":{"rendered":"Upgrading My Home Lab: Adding a SIEM Stack on a Budget"},"content":{"rendered":"<p>This covers the build-out of a functional threat hunting and DFIR lab running on a single repurposed server. The focus is on realistic log volume, proper network segmentation, and having the right tools available for each phase of an<br \/>\ninvestigation.<\/p>\n<h3>Hardware baseline<\/h3>\n<p>The lab runs on a Dell PowerEdge R730 (2x Xeon E5-2640v4, 128GB RAM, 4x 1TB SAS in RAID10). A minimum viable setup for this work is 32GB RAM \u2014 enough to run 4-5 VMs simultaneously without constant swapping. The storage minimum is approximately<br \/>\n500GB to hold OS images, snapshots, and log data without constant cleanup.<\/p>\n<h3>Network topology<\/h3>\n<pre>Internet\n    |\n[Home Router - 192.168.1.0\/24]\n    |\n[Lab Switch - VLAN aware]\n    |\n    +-- VLAN 10 (172.16.10.0\/24) -- Management\n    |     - Velociraptor server\n    |     - SIEM (Elastic)\n    |     - Zeek sensor\n    |\n    +-- VLAN 20 (172.16.20.0\/24) -- Attack\n    |     - Kali Linux\n    |\n    +-- VLAN 30 (172.16.30.0\/24) -- Targets\n          - Windows 10 (patched)\n          - Windows 10 (vulnerable - no EDR)\n          - Windows Server 2019 (DC)\n          - Ubuntu 22.04 (web target)<\/pre>\n<p>VLAN 20 (Attack) can reach VLAN 30 (Targets). VLAN 10 (Management) can reach both. Internet access from VLAN 20 routes through a Zeek tap so all attack tool downloads and C2 callbacks are logged. Targets have no direct internet access.<\/p>\n<h3>SIEM stack \u2014 Docker Compose<\/h3>\n<pre>version: \"3\"\nservices:\n  elasticsearch:\n    image: docker.elastic.co\/elasticsearch\/elasticsearch:8.11.0\n    environment:\n      - discovery.type=single-node\n      - ES_JAVA_OPTS=-Xms4g -Xmx4g\n      - xpack.security.enabled=true\n      - ELASTIC_PASSWORD=changeme\n    volumes:\n      - esdata:\/usr\/share\/elasticsearch\/data\n    ports:\n      - \"9200:9200\"\n\n  kibana:\n    image: docker.elastic.co\/kibana\/kibana:8.11.0\n    environment:\n      - ELASTICSEARCH_URL=http:\/\/elasticsearch:9200\n      - ELASTICSEARCH_USERNAME=kibana_system\n      - ELASTICSEARCH_PASSWORD=changeme\n    ports:\n      - \"5601:5601\"\n    depends_on:\n      - elasticsearch\n\n  fleet-server:\n    image: docker.elastic.co\/beats\/elastic-agent:8.11.0\n    environment:\n      - FLEET_SERVER_ENABLE=true\n      - FLEET_SERVER_ELASTICSEARCH_HOST=http:\/\/elasticsearch:9200\n      - FLEET_SERVER_SERVICE_TOKEN=&lt;generate_via_kibana&gt;\n    ports:\n      - \"8220:8220\"\n\nvolumes:\n  esdata:<\/pre>\n<p>Start with <code>docker compose up -d<\/code>. Kibana is available at port 5601. First login: create the kibana_system password via the elasticsearch container:<\/p>\n<pre>docker exec -it elastic_elasticsearch_1 \\\n  bin\/elasticsearch-reset-password -u kibana_system<\/pre>\n<h3>Sysmon configuration<\/h3>\n<p>The SwiftOnSecurity config is a solid starting point but needs additions for a lab:<\/p>\n<pre># Download base config\nInvoke-WebRequest -Uri https:\/\/raw.githubusercontent.com\/SwiftOnSecurity\/sysmon-config\/master\/sysmonconfig-export.xml -OutFile sysmon.xml\n\n# Install Sysmon with config\n.\\Sysmon64.exe -accepteula -i sysmon.xml\n\n# Verify\nGet-WinEvent -LogName \"Microsoft-Windows-Sysmon\/Operational\" -MaxEvents 5 | Select TimeCreated, Id, Message<\/pre>\n<p>Additional rules to add for the lab (add inside the appropriate EventFiltering sections):<\/p>\n<pre>&lt;!-- Log all LSASS access regardless of source --&gt;\n&lt;ProcessAccess onmatch=\"include\"&gt;\n  &lt;TargetImage condition=\"is\"&gt;C:\\Windows\\System32\\lsass.exe&lt;\/TargetImage&gt;\n&lt;\/ProcessAccess&gt;\n\n&lt;!-- Log all DNS queries --&gt;\n&lt;DnsQuery onmatch=\"exclude\"&gt;\n  &lt;QueryName condition=\"end with\"&gt;.microsoft.com&lt;\/QueryName&gt;\n  &lt;QueryName condition=\"end with\"&gt;.windows.com&lt;\/QueryName&gt;\n&lt;\/DnsQuery&gt;<\/pre>\n<h3>Elastic Agent deployment to Windows targets<\/h3>\n<pre># In Kibana: Fleet &gt; Agent Policies &gt; Create policy \"Lab Windows\"\n# Add integrations: Windows (event logs), Sysmon\n\n# On Windows target - download the agent from Fleet UI\n# Then install:\n.\\elastic-agent.exe install --url=https:\/\/172.16.10.10:8220 `\n  --enrollment-token=&lt;token_from_fleet_ui&gt; `\n  --insecure  # lab only - use proper certs in production<\/pre>\n<p>After enrollment, events appear in Kibana under Discover within about 30 seconds. The Sysmon integration auto-parses all field mappings \u2014 process names, hashes, network connections \u2014 without manual index template configuration.<\/p>\n<h3>Zeek on the network tap<\/h3>\n<pre># Interface ens4 is the span\/tap port receiving all lab traffic\nzeekctl deploy\nzeekctl status\n\n# Verify logs are writing\ntail -f \/opt\/zeek\/logs\/current\/conn.log | python3 -m json.tool<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>After running a basic VM setup for a year, how I stood up<br \/>\nElastic SIEM without spending money on hardware I did not need.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-193","post","type-post","status-publish","format-standard","hentry","category-home-lab"],"_links":{"self":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/comments?post=193"}],"version-history":[{"count":2,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/193\/revisions"}],"predecessor-version":[{"id":235,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/193\/revisions\/235"}],"wp:attachment":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/media?parent=193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/categories?post=193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/tags?post=193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}