<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Homelab - Tag - Arsh Imtiaz</title>
        <link>https://arshimtiaz.github.io/tags/homelab/</link>
        <description>Homelab - Tag - Arsh Imtiaz</description>
        <generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sun, 09 Nov 2025 00:00:00 &#43;0000</lastBuildDate><atom:link href="https://arshimtiaz.github.io/tags/homelab/" rel="self" type="application/rss+xml" /><item>
    <title>When Red Teaming Meets Car Hacking: Building a Virtual Vehicle Pentest Lab on My Laptop</title>
    <link>https://arshimtiaz.github.io/posts/when-red-teaming-meets-car-hacking-building-a-virtual-vehicle-pentest-lab-on-my-laptop/</link>
    <pubDate>Sun, 09 Nov 2025 00:00:00 &#43;0000</pubDate>
    <author>Arsh Imtiaz</author>
    <guid>https://arshimtiaz.github.io/posts/when-red-teaming-meets-car-hacking-building-a-virtual-vehicle-pentest-lab-on-my-laptop/</guid>
    <description><![CDATA[<div style="text-align: center;">
  
  <small>How does one emulate cars at home?</small>
</div>
<p>Every car hacking tool I have come across required expensive ECUs, adapters or even full test benches. Having worked with test cars before, I got an insight into how time consuming and expensive, if not difficult it is to set a working HIL (Hardware-In-Loop) setup.
I didn&rsquo;t want to wait for hardware to understand how automotive networks behave - I wanted to simulate it.</p>
<p>So, I built my own virtual car hacking network using Linux tools, a bit of Python, and some creative problem solving.</p>
<hr>
<h2 id="background">Background</h2>
<p>Automotive Cybersecurity is fascinating. Being extremely niche, it isn&rsquo;t the first thing that comes to mind when someone thinks of <em>cybersecurity</em>. They imagine computers, massive server farms and a network that connects them all. But what is a modern car, if not a network of highly powerful computers, on wheels.</p>
<p>Working with cars as a pentester has had me dealing with security at the intersection of software and hardware - but I wanted to explore the same logic on my own terms.</p>
<p>A vehicle&rsquo;s network is split into three specific interfaces:</p>
<ol>
<li><strong>CAN</strong> (Controller Area Network) - the most widely used</li>
<li><strong>LIN</strong> (Local Interconnect Network) - for low-speed/low-cost devices</li>
<li><strong>Automotive Ethernet</strong> (100BASE-T1, 1000BASE-T1, etc.) - higher bandwidth, growing adoption</li>
</ol>
<p>Infotainment Systems, Sensors, ECUs, they all talk over these buses. Setting these up requires a lot of specialized hardware and software. This includes purchasing an expensive license with the already expensive hardware which is designed to simulate and control such networks. (Yes <a href="https://www.vector.com" target="_blank" rel="noopener noreffer "><em>Vector</em></a>, I&rsquo;m talking about you). These tools are brilliant, but they&rsquo;re practically out of reach when you&rsquo;re hacking solo and not backed by a corporation.</p>
<p>So: emulate it.</p>
<hr>
<h2 id="the-idea">The Idea</h2>
<p>If network penetration testers can simulate servers and routers, why can&rsquo;t car hackers simulate ECUs? After all, ECUs are basically computers that run a <em>specific</em> piece of software or a <em>specific</em> operating system on them, designed to only perform <em>specific</em> tasks.</p>
<p>In a world where we have virtual machines helping us run multiple computers on one, I started brainstorming if it was possible to create ECUs digitally, without all the fancy expensive hardware. What would you possibly need? GPS? Wi-Fi? Bluetooth? A platform to run apps and scripts? A logger? All of this already exists on a standard laptop. The only thing that stood out to me was the communication interfaces. CAN is not used anywhere apart from automotive networks. Neither is LIN or 100Base-T1 (<em>Automotive</em> Ethernet for a reason). This made me research even more. What could possibly help me <strong>simulate</strong> CAN?</p>
<blockquote>
<p>&ldquo;If there&rsquo;s a will, there is a way.&rdquo;
~ some wise person</p>
</blockquote>
<hr>
<h2 id="the-build">The Build</h2>
<p>After a bit of research, I came across <a href="https://docs.kernel.org/networking/can.html" target="_blank" rel="noopener noreffer ">SocketCAN</a>. It&rsquo;s a Linux kernel subsystem that exposes CAN interfaces like any other network device. Think CAN, but now it runs pretty much anywhere.  It allows us to create virtual CAN interfaces on Linux, or connect to physical CAN networks present on an actual car.</p>
<p>It doesn&rsquo;t have anything to do with what flavour you choose as it is built into the kernel. It is only a matter flipping the switch and enabling it:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo modprobe vcan
</span></span></code></pre></td></tr></table>
</div>
</div><p>This will help enable the vcan (virtual CAN) interface module.</p>
<p>After this, you can create the virtual CAN interface:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ip link add dev vcan0 <span class="nb">type</span> vcan
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> up vcan0
</span></span></code></pre></td></tr></table>
</div>
</div><p>Run this to confirm if you&rsquo;ve got it:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ifconfig
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">vcan0: flags=193&lt;UP,RUNNING,NOARP&gt;  mtu 72
</span></span><span class="line"><span class="cl">        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
</span></span><span class="line"><span class="cl">        RX packets 0  bytes 0 (0.0 B)
</span></span><span class="line"><span class="cl">        RX errors 0  dropped 0  overruns 0  frame 0
</span></span><span class="line"><span class="cl">        TX packets 0  bytes 0 (0.0 B)
</span></span><span class="line"><span class="cl">        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
</span></span></code></pre></td></tr></table>
</div>
</div><p>And voila! You now have a virtual CAN interface, ready to read and transmit CAN frames.</p>
<hr>
<h3 id="sending-packets">Sending packets</h3>
<p>What&rsquo;s the point of creating an interface if you&rsquo;re not going to use it?
To send packets on this interface, we have a set of can tools that you can install on pretty much any Linux machine as well.</p>
<p>I use the <a href="https://www.blackarch.org/downloads.html#install-repo" target="_blank" rel="noopener noreffer ">Blackarch repository</a> on my Arch Linux machine. If you&rsquo;re on Debian, you can use <a href="https://www.kali.org/docs/general-use/kali-linux-sources-list-repositories/" target="_blank" rel="noopener noreffer ">Kali Linux&rsquo;s repository</a> for the same. Both of them contain the package we want to install.</p>
<p><small> Fedora users please don&rsquo;t come after me </small></p>
<p>Arch Linux:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -Syu
</span></span><span class="line"><span class="cl">sudo pacman -S can-utils <span class="c1"># tools for working with CAN</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Debian:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt-get update <span class="o">&amp;&amp;</span> apt-get upgrade
</span></span><span class="line"><span class="cl">sudo apt-get install can-utils
</span></span></code></pre></td></tr></table>
</div>
</div><p>This will give you access to these tools:</p>
<ol>
<li>candump</li>
<li>cansend</li>
<li>canplayer</li>
<li>cansniffer</li>
</ol>
<p>&hellip;and more.</p>
<p>To send packets on the virtual bus (vcan0), use this command:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cansend vcan0 123#AABBCCDDEEFF
</span></span></code></pre></td></tr></table>
</div>
</div><p>If it doesn&rsquo;t output anything, congratulations! You&rsquo;ve sent your first CAN frame using Linux!</p>
<p>But&hellip; how do we know that it got sent?
We can use <code>candump</code>, which continuously listens for any CAN messages being transmitted on the bus you specify to it as an argument.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">candump vcan0
</span></span></code></pre></td></tr></table>
</div>
</div><p>While this is running, send the example CAN frame with <code>cansend</code> from another terminal again. This time, you&rsquo;ll see it pop up on the listener as a properly formatted CAN frame:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">vcan0  <span class="m">123</span>   <span class="o">[</span>6<span class="o">]</span>  AA BB CC DD EE FF
</span></span></code></pre></td></tr></table>
</div>
</div><p>Brilliant. You&rsquo;ve now mastered the art of sending CAN frames on a bus using Linux, and only Linux.</p>
<p>What makes this fun is you can also build your own custom logger and transmitter using Python, with the <a href="https://python-can.readthedocs.io/en/stable/" target="_blank" rel="noopener noreffer ">python-can</a> library. It can both send and listen for CAN frames on any CAN interface.</p>
<p>Here&rsquo;s one if you want to try it out:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env python3</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">can</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">threading</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">receiver</span><span class="p">(</span><span class="n">bus</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Receive and print CAN messages.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;[Receiver] Listening for CAN messages...&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">msg</span> <span class="ow">in</span> <span class="n">bus</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;[Received] ID: </span><span class="si">{</span><span class="n">msg</span><span class="o">.</span><span class="n">arbitration_id</span><span class="si">:</span><span class="s2">#04x</span><span class="si">}</span><span class="s2">, Data: </span><span class="si">{</span><span class="n">msg</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">hex</span><span class="p">()</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">sender</span><span class="p">(</span><span class="n">bus</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Send CAN messages periodically.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;[Sender] Starting message transmission...&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">msg</span> <span class="o">=</span> <span class="n">can</span><span class="o">.</span><span class="n">Message</span><span class="p">(</span><span class="n">arbitration_id</span><span class="o">=</span><span class="mh">0x123</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">[</span><span class="mh">0x11</span><span class="p">,</span> <span class="mh">0x22</span><span class="p">,</span> <span class="mh">0x33</span><span class="p">,</span> <span class="mh">0x44</span><span class="p">],</span> <span class="n">is_extended_id</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">bus</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;[Sent] ID: </span><span class="si">{</span><span class="n">msg</span><span class="o">.</span><span class="n">arbitration_id</span><span class="si">:</span><span class="s2">#04x</span><span class="si">}</span><span class="s2">, Data: </span><span class="si">{</span><span class="n">msg</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">hex</span><span class="p">()</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="n">can</span><span class="o">.</span><span class="n">CanError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;[Error] Message not sent&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Connect to virtual CAN interface</span>
</span></span><span class="line"><span class="cl">    <span class="n">bus</span> <span class="o">=</span> <span class="n">can</span><span class="o">.</span><span class="n">interface</span><span class="o">.</span><span class="n">Bus</span><span class="p">(</span><span class="n">channel</span><span class="o">=</span><span class="s2">&#34;vcan0&#34;</span><span class="p">,</span> <span class="n">bustype</span><span class="o">=</span><span class="s2">&#34;socketcan&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Start receiver in background thread</span>
</span></span><span class="line"><span class="cl">    <span class="n">recv_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">receiver</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">bus</span><span class="p">,),</span> <span class="n">daemon</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">recv_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Start sending messages</span>
</span></span><span class="line"><span class="cl">    <span class="n">sender</span><span class="p">(</span><span class="n">bus</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">main</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>This simple program lets you prototype virtual ECUs that send/receive frames — perfect for building test scenarios.</p>
<hr>
<h2 id="reflection">Reflection</h2>
<p>My reflection on this piece of work includes this:</p>
<ol>
<li>If I create ECUs built on either C or C++, using the same logic that a standard ECU would, I could have it generate CAN frames for specific functions and accept CAN frames to perform specific functions. This completely virtualizes the test bench and makes it portable.</li>
<li>The presence of Python (python-can) allows us to craft custom CAN packets, which opens doors to creating a <strong>fuzzer</strong> that mutates CAN frames randomly.</li>
<li>All of this put together gives us a basic, but robust virtual car, which can be used to practice pentesting and diagnostics(Enter, UDS).</li>
<li>I can safely test security features without messing with actual hardware(did I tell you it was very expensive?).</li>
<li>I can practice IDS detection in Wazuh or Suricata by integrating the CAN logs.</li>
<li>Train myself and others without physical ECUs.</li>
</ol>
<p>Hacking isn&rsquo;t about fancy gear. It&rsquo;s about creativity. By virtualizing this challenge, I learned more about CAN networks, Linux Networking, and the hacker mindset in itself.</p>
<p>If you are into automotive cybersecurity but don&rsquo;t know where to start, start by simulating - the best labs are the ones you build yourself.</p>
<hr>
<h2 id="whats-next">What&rsquo;s Next?</h2>
<ol>
<li>Create an instrument cluster/infotainment system next and connect it to my virtual network to simulate a more complete in-vehicle setup.</li>
<li>Setup UDS (Unified Diagnostics Services) request/response handling in a virtual ECU</li>
</ol>
<hr>
<p>Thanks for reading — I’ll keep posting updates as I build the next pieces (infotainment mock, UDS handlers, and a tiny fuzzer). If you want the example scripts or a reproducible repo structure, tell me and I’ll publish them on GitHub.</p>
]]></description>
</item>
<item>
    <title>Docker to Detection: Setting Up Wazuh SIEM for Beginners</title>
    <link>https://arshimtiaz.github.io/posts/docker-to-detection-setting-up-wazuh-siem-for-beginners/</link>
    <pubDate>Sat, 14 Jun 2025 00:00:00 &#43;0100</pubDate>
    <author>Arsh Imtiaz</author>
    <guid>https://arshimtiaz.github.io/posts/docker-to-detection-setting-up-wazuh-siem-for-beginners/</guid>
    <description><![CDATA[<p></p>
<p>Setting up a SIEM (Security Information and Event Management) system might sound intimidating if you’re just getting started, but it’s a rewarding project that gives you real insight into how cybersecurity professionals monitor and detect threats. I recently built a Wazuh-based SIEM entirely with Docker and connected my personal Linux workstation as an agent. In this post, I’ll walk you through the process with practical commands for both Arch Linux and Debian users.</p>
<hr>
<blockquote>
<p><strong>Wazuh</strong> started as a fork of OSSEC, one of the first open-source host-based intrusion detection systems, but has evolved into a full-blown security platform with log analysis, vulnerability detection, and compliance monitoring.</p>
</blockquote>
<hr>
<h2 id="system-overview">System Overview</h2>
<p>Here’s what I used:</p>
<ul>
<li>Host OS: Arch Linux (but I include Debian commands too, since many readers might be on either)</li>
<li>Deployment method: Docker (because containers make complex stacks easier to manage)</li>
<li>Architecture: Single-node setup running Manager, Indexer, and Dashboard on one machine</li>
<li>Agent: My own Linux workstation</li>
<li>Use case: Personal monitoring and vulnerability detection in a home lab</li>
</ul>
<hr>
<h2 id="step-1-installing-docker-and-docker-compose">Step 1: Installing Docker and Docker Compose</h2>
<p>Before we get started, make sure Docker is installed and running. If you don’t have it, here’s how:</p>
<p><strong>On Arch Linux:</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S docker docker-compose
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now docker
</span></span><span class="line"><span class="cl">sudo usermod -aG docker <span class="nv">$USER</span>
</span></span><span class="line"><span class="cl">newgrp docker
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>On Debian or Ubuntu:</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install docker.io docker-compose
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now docker
</span></span><span class="line"><span class="cl">sudo usermod -aG docker <span class="nv">$USER</span>
</span></span><span class="line"><span class="cl">newgrp docker
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<blockquote>
<p>Docker was originally released in 2013 and revolutionized how developers package and deploy applications. Today, it’s an essential tool in cybersecurity labs for simulating complex environments quickly.</p>
</blockquote>
<hr>
<h2 id="step-2-cloning-the-wazuh-docker-repository">Step 2: Cloning the Wazuh Docker Repository</h2>
<p>Wazuh maintains an official Docker repository with all the configurations needed for different deployments. Grab the single-node setup like this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://github.com/wazuh/wazuh-docker -b v4.12.0
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> wazuh-docker/single-node
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="step-3-generating-ssl-certificates">Step 3: Generating SSL Certificates</h2>
<p>To secure communication between the components, you’ll need to generate SSL certificates. First, create the directory:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p config/wazuh_indexer_ssl_certs/
</span></span></code></pre></td></tr></table>
</div>
</div><p>Next, create the configuration files. Here’s the <strong>config/certs.yml</strong> file content:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">wazuh.indexer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">indexer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">wazuh.manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">wazuh.dashboard</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">dashboard</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>And the <strong>generate-indexer-certs.yml</strong> file:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;3.3&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">generator</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">wazuh/wazuh-certs-generator:0.0.2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">wazuh-certs-generator</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./config/wazuh_indexer_ssl_certs/:/certificates/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./config/certs.yml:/config/certs.yml</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>Then run:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker-compose -f generate-indexer-certs.yml run --rm generator
</span></span></code></pre></td></tr></table>
</div>
</div><p>If you get errors about overwriting files, just clear the folder and try again:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rm -rf config/wazuh_indexer_ssl_certs/*
</span></span><span class="line"><span class="cl">docker-compose -f generate-indexer-certs.yml run --rm generator
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="step-4-starting-the-wazuh-stack">Step 4: Starting the Wazuh Stack</h2>
<p>With everything set, launch the whole Wazuh environment:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker-compose up -d
</span></span></code></pre></td></tr></table>
</div>
</div><p>This will bring up the manager, indexer, and dashboard.</p>
<hr>
<h2 id="step-5-accessing-the-web-dashboard">Step 5: Accessing the Web Dashboard</h2>
<p>Open your browser and head to:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">https://&lt;your-server-ip&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>This would be localhost if you&rsquo;re setting it up locally.</p>
<hr>
<p>The default login credentials are:</p>
<ul>
<li>Username: <code>admin</code></li>
<li>Password: <code>SecretPassword</code> (or check the <code>.env</code> file in the repo)</li>
</ul>
<p>Expect a warning about the self-signed certificate. This is normal. You can safely proceed for now.</p>
<hr>
<h2 id="adding-your-own-machine-as-an-agent">Adding Your Own Machine as an Agent</h2>
<p>Wazuh’s strength lies in monitoring endpoints. I connected my Arch Linux workstation as an agent, but these steps work the same on Debian.</p>
<h3 id="download-and-install-the-agent">Download and install the agent:</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sO https://packages.wazuh.com/4.12/wazuh-agent-4.12.0-linux-x86_64.tar.gz
</span></span><span class="line"><span class="cl">tar -xvzf wazuh-agent-4.12.0-linux-x86_64.tar.gz
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> wazuh-agent-4.12.0
</span></span><span class="line"><span class="cl">sudo ./install.sh
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="register-the-agent-with-the-manager">Register the agent with the manager:</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo /var/ossec/bin/agent-auth -m &lt;wazuh-manager-ip&gt;
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now wazuh-agent
</span></span></code></pre></td></tr></table>
</div>
</div><p>After a short while, your agent will show up in the dashboard, forwarding logs and security events.</p>
<hr>
<blockquote>
<p>The first version of Wazuh was released in 2015, and it has since become one of the most widely used open-source security platforms worldwide.</p>
</blockquote>
<p><strong>You&rsquo;re now done!</strong> You should be able to explore the dashboard and learn all the features Wazuh has to offer.</p>
<hr>
<h2 id="real-world-detection-cve-2025-4598">Real-World Detection: CVE-2025-4598</h2>
<p>Shortly after getting everything running, Wazuh’s Vulnerability Detector flagged a real systemd vulnerability on my machine (CVE-2025-4598). This was a practical example of how such tools help spot risks before attackers do.</p>
<p><em>Don’t worry, I patched it right away. Wouldn’t want to make it too easy for you hackers, right?</em></p>
<hr>
<h2 id="why-this-matters">Why This Matters</h2>
<p>Setting this up wasn’t just an academic exercise. I now have a hands-on understanding of log collection, normalization, and alerting. In fields like automotive cybersecurity, knowing what’s happening on endpoints and spotting anomalies early is crucial—and this kind of setup lets you practice those skills.</p>
<hr>
<h2 id="whats-next">What’s Next?</h2>
<p>Here are some things you can try for yourself now that you&rsquo;ve got the hang of setting it up:</p>
<ul>
<li>Crafting custom detection rules tailored to your environment</li>
<li>Simulating attacks to validate your alerts</li>
<li>Adding Windows or other OS agents</li>
<li>Expanding to multi-node deployments for scalability</li>
</ul>
<hr>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Wazuh is a fantastic project for anyone looking to deepen their cybersecurity skills. Using Docker simplifies the setup, and the dashboard delivers meaningful insights out of the box. Whether you’re a beginner or an experienced professional, experimenting with Wazuh builds a solid foundation for real-world security monitoring.</p>
<p>Thanks for reading! Feel free to reach out if you want to discuss or share your own setups.</p>
]]></description>
</item>
</channel>
</rss>
