<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Linux on Zero-Entry</title>
    <link>https://zero-entry.co.za/tags/linux/</link>
    <description>Recent content in Linux on Zero-Entry</description>
    <generator>Hugo -- 0.147.7</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 24 Apr 2026 14:26:40 +0400</lastBuildDate>
    <atom:link href="https://zero-entry.co.za/tags/linux/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>WTH I&#39;m Doing RF Now: RTL-SDR &#43; HackRF One (and the dumb problems I hit)</title>
      <link>https://zero-entry.co.za/posts/wth-im-doing-rf-now/</link>
      <pubDate>Sun, 22 Feb 2026 00:00:00 +0200</pubDate>
      <guid>https://zero-entry.co.za/posts/wth-im-doing-rf-now/</guid>
      <description>First sessions with RTL-SDR and HackRF One: scanning 433 MHz, fixing udev permissions, building a passive logger, and the practical lessons from the first two hours.</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="/images/Pasted%20image%2020260219202312.png"></p>
<p>I&rsquo;ve started digging into RF, meaning anything noisy in the air that my SDR can see. This is a quick log of the first sessions using an RTL-SDR (cheap, RX-only) and a HackRF One (wider bandwidth, TX-capable, which stays off outside a legal setup).</p>
<p>This isn&rsquo;t a decoding write-up. The goal for now is observation: watch the spectrum, log activity, and build something useful.</p>
<h2 id="the-kit">The kit</h2>
<ul>
<li><strong>RTL-SDR</strong> (RTL2832U + R820T): cheap receive, wide community support, good for learning.</li>
<li><strong>HackRF One</strong>: wider tuning range, bigger bandwidth, better lab potential.</li>
</ul>
<p>Antennas matter more than most people want to admit. A random wire will pick something up, but it&rsquo;ll also mislead you.</p>
<h2 id="what-im-trying-to-do-v1">What I&rsquo;m trying to do (v1)</h2>
<p>Three things:</p>
<ol>
<li>Scan a band, starting with the 433 MHz junk drawer</li>
<li>Log energy and activity over time to CSV</li>
<li>Watch live when a remote is pressed or something triggers</li>
</ol>
<p>No demodulation, no protocol reversing yet. Just what&rsquo;s alive and when.</p>
<h2 id="rtl-sdr-first-scans-and-the-empty-csv-problem">RTL-SDR: first scans and the empty CSV problem</h2>
<p><code>rtl_power</code> is the right starting point for band surveys:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rtl_power -f 430M:440M:50k -i <span class="m">1</span> -g <span class="m">30</span> -e 15s /tmp/rtl_433_test.csv
</span></span><span class="line"><span class="cl">head -n <span class="m">3</span> /tmp/rtl_433_test.csv
</span></span></code></pre></div><p>Two things showed up immediately:</p>
<ul>
<li>Frequency hops, FFT bins, the tool doing its job.</li>
<li>This line:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[R82XX] PLL not locked!
</span></span></code></pre></div><p>It looks bad. In practice it&rsquo;s common with these dongles and the data is often usable anyway. If it looks broken, try adjusting the frequency range slightly, dropping the gain, swapping the USB port or cable, or ruling out power starvation.</p>
<p>The other thing: the numbers move even when you think nothing is happening. Your receiver sees something constantly. The job is separating signal from noise and logging it so you can compare runs over time.</p>
<h2 id="hackrf-the-access-denied-wall">HackRF: the access denied wall</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hackrf_info
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">hackrf_open() failed: Access denied (insufficient permissions) (-1000)
</span></span></code></pre></div><p>Linux has the hardware, you don&rsquo;t. Fix it with udev rules.</p>
<h3 id="the-fix">The fix</h3>
<p>Add yourself to the plugdev group:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo usermod -aG plugdev <span class="nv">$USER</span>
</span></span><span class="line"><span class="cl"><span class="c1"># log out and back in after this</span>
</span></span></code></pre></div><p>Check whether HackRF udev rules exist for your distro. If not, create them:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo nano /etc/udev/rules.d/53-hackrf.rules
</span></span></code></pre></div><p>Rule:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">SUBSYSTEM==&#34;usb&#34;, ATTR{idVendor}==&#34;1d50&#34;, ATTR{idProduct}==&#34;6089&#34;, MODE=&#34;0666&#34;
</span></span></code></pre></div><p>Reload:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo udevadm control --reload-rules
</span></span><span class="line"><span class="cl">sudo udevadm trigger
</span></span></code></pre></div><p>After that, <code>hackrf_info</code> works.</p>
<h2 id="driver-detach-and-reattach-noise">Driver detach and reattach noise</h2>
<p>RTL tools print this during normal operation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Detached kernel driver
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Reattached kernel driver
</span></span></code></pre></div><p>The SDR tooling takes temporary ownership of the USB device. It becomes a problem when another service grabs the device at the same time, or when you switch tools quickly and the reattach doesn&rsquo;t complete cleanly. Unplug and replug is a valid fix.</p>
<h2 id="current-workflow">Current workflow</h2>
<h3 id="1-quick-band-scan">1. Quick band scan</h3>
<p>Pick a known band, collect a short sample, inspect.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rtl_power -f 430M:440M:50k -i <span class="m">1</span> -g <span class="m">30</span> -e 60s ./rf_433_1min.csv
</span></span></code></pre></div><h3 id="2-trigger-devices-while-logging">2. Trigger devices while logging</h3>
<p>Press a remote, ring a doorbell, whatever you own and are allowed to test. Watch what shows up.</p>
<h3 id="3-passive-logger">3. Passive logger</h3>
<p>A script that samples a band, writes a CSV row with timestamp and strongest bins, and repeats for hours or days. The goal is trend visibility: activity spikes at these times, at these frequencies.</p>
<h3 id="4-long-runs-in-screen">4. Long runs in screen</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">screen -S rfwatch
</span></span><span class="line"><span class="cl"><span class="c1"># run your loop / script</span>
</span></span><span class="line"><span class="cl"><span class="c1"># detach: Ctrl+A then D</span>
</span></span><span class="line"><span class="cl">screen -r rfwatch
</span></span></code></pre></div><h2 id="lessons-from-the-first-two-hours">Lessons from the first two hours</h2>
<ul>
<li>Antenna placement matters more than gain settings. Move it 30cm and signal becomes noise.</li>
<li>Gain is not volume. Too much gain makes every bin look busy and kills your ability to compare runs.</li>
<li>433 MHz is crowded. Good for learning, bad for clean data.</li>
<li>A CSV you can graph beats ten live waterfall sessions.</li>
<li>Fix udev permissions before you need them, not during a session.</li>
</ul>
<h2 id="rtl-sdr-vs-hackrf">RTL-SDR vs HackRF</h2>
<p><strong>RTL-SDR</strong>: default always-on receiver. Cheap enough to leave plugged in and logging. Good for band surveys and learning.</p>
<p><strong>HackRF One</strong>: used for broader coverage and lab work. TX stays off unless the environment is controlled and the use is legal.</p>
<h2 id="whats-next">What&rsquo;s next</h2>
<ul>
<li>A 24-hour monitor for 433 MHz, then other bands</li>
<li>Lightweight analysis: top active frequencies, time-of-day patterns, spikes worth investigating</li>
<li>Mapping RF fingerprints in the environment: gates, remotes, alarms, sensors. What&rsquo;s constant vs what&rsquo;s event-driven.</li>
</ul>
<h2 id="legal">Legal</h2>
<p>I&rsquo;m monitoring what I&rsquo;m allowed to monitor, on equipment I own, in environments where I have permission. RF gets murky fast if you treat it like network recon without thinking about it first.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Why I Still Run My Own Infrastructure at Home</title>
      <link>https://zero-entry.co.za/posts/why-i-still-run-my-own-infrastructure-at-home/</link>
      <pubDate>Sun, 11 Jan 2026 20:30:00 +0200</pubDate>
      <guid>https://zero-entry.co.za/posts/why-i-still-run-my-own-infrastructure-at-home/</guid>
      <description>A walkthrough of a self-hosted homelab built around OPNsense, Docker, and deliberate design choices — media, monitoring, VPN containment, and the lessons it took to get there.</description>
      <content:encoded><![CDATA[<h1 id="home-lab-overview-alecto-and-friends">Home Lab Overview: Alecto and Friends</h1>
<p>I&rsquo;ve always enjoyed tinkering with operating systems and finding ways they improve day-to-day life. I&rsquo;m not a cloud hater. Cloud services are useful and I still use them. I self-host because it&rsquo;s fun.</p>
<p>With most SaaS tools, you&rsquo;re limited by design choices you had no part in. My biggest self-hosted system is a Plex machine. I watch what I want, how I want, for roughly the cost of electricity. There&rsquo;s also been a serious learning component: networking, security, general IT practice. That alone has made it worth running.</p>
<h2 id="topology">Topology</h2>
<p>Starting at the internet edge and working inward:</p>
<p><strong>Router / Firewall</strong> I settled on OPNsense. It met and exceeded what I needed. The box runs intrusion detection, Unbound DNS, and a handful of other security-focused services.</p>
<p><strong>Switching</strong> Traffic hits a 24-port unmanaged gigabit switch with SFP ports. Nothing exotic, but most ports are in use.</p>
<p><strong>Flat Network</strong> The network is currently flat, so traffic flows directly to access points, servers, Raspberry Pis, NVR systems, gaming consoles, and everything else.</p>
<p>The topology is simple. The interesting part is what the devices are doing, not how complex the diagram looks.</p>
<h2 id="core-infrastructure">Core Infrastructure</h2>
<h3 id="alecto">Alecto</h3>
<p><strong>Hardware</strong></p>
<ul>
<li>Ryzen 7 1700X</li>
<li>1 TB NVMe</li>
<li>4 TB HDD</li>
<li>GTX 1050 Ti</li>
</ul>
<p>Nothing exotic, but it handles everything I need with around 85% idle time.</p>
<p><strong>Software</strong> Ubuntu LTS as the host OS, Docker for everything else: media acquisition, media consumption, networking, local services, metrics, and automation.</p>
<p>Docker makes backing up and restoring critical services significantly easier, which is the main reason I keep everything containerised.</p>
<h2 id="services">Services</h2>
<h3 id="media-acquisition">Media Acquisition</h3>
<p>The pipeline follows a simple request, acquire, process, library chain.</p>
<ul>
<li>Overseerr</li>
<li>Prowlarr</li>
<li>Sonarr / Radarr</li>
<li>qBittorrent</li>
<li>Deluge</li>
<li>Unpackerr</li>
<li>cross-seed</li>
</ul>
<p><strong>Prowlarr</strong> manages indexers. Private trackers have far less fake or malicious content than public ones, which matters later in the chain.</p>
<p><strong>Sonarr</strong> and <strong>Radarr</strong> handle TV and movies. Quality profiles are simple: HD and 4K. That has covered everything so far. Both monitor RSS feeds from configured indexers and push matched torrents to the downloader automatically.</p>
<p>I run two download clients. <strong>qBittorrent</strong> handles the entire arr stack. <strong>Deluge</strong> handles manual downloads and non-media content. Dynamic save paths split movies and TV cleanly for Plex.</p>
<p><strong>Unpackerr</strong> handles automatic extraction for downloads that arrive as archives. <strong>cross-seed</strong> finds identical or near-identical torrents across trackers and advertises that I already have the data, which improves speeds and availability for others.</p>
<p>The only recurring issue is Sonarr or Radarr occasionally grabbing a fake title. Aggressive regex-based filters have mostly resolved it.</p>
<h3 id="media-consumption">Media Consumption</h3>
<ul>
<li>Plex</li>
<li>Tautulli</li>
<li>Overseerr</li>
<li>Homepage</li>
</ul>
<p><strong>Plex</strong> is the primary player. Mature, stable, available on every device, and accessible for non-technical users. I&rsquo;ve tested Jellyfin and like it, but haven&rsquo;t switched.</p>
<p><strong>Tautulli</strong> gives visibility into Plex usage: playback activity, per-user bandwidth, transcoding load. That data makes decisions around limits and capacity easier.</p>
<p><strong>Overseerr</strong> lets users request titles themselves rather than messaging me. Requests still require approval, but that takes seconds instead of a back-and-forth conversation.</p>
<p><strong>Homepage</strong> is a single customisable dashboard with a high-level view of everything running. It doesn&rsquo;t replace Zabbix or Grafana for monitoring, but it&rsquo;s useful for day-to-day glancing.</p>
<h3 id="networking-and-vpn-containment">Networking and VPN Containment</h3>
<p>Torrent clients are routed through <strong>Gluetun</strong>, a dedicated VPN container running WireGuard. The downloaders have never touched my LAN directly and never see my public IP.</p>
<p>Gluetun runs in strict kill-switch mode. If the VPN drops, traffic stops. There&rsquo;s no fallback to my home connection. Given the provider&rsquo;s SLA, this hasn&rsquo;t been an issue in practice.</p>
<p>No inbound ports need to be open, which reduces exposure further. Speed degradation from the VPN hasn&rsquo;t been noticeable.</p>
<h2 id="observability">Observability</h2>
<p>Prometheus, Node Exporter, cAdvisor, and Grafana cover system-level metrics: CPU load, memory usage, container behaviour. Critical alerts go to Telegram. I&rsquo;m refining thresholds so only actionable issues send a notification.</p>
<h2 id="automation">Automation</h2>
<p><strong>Watchtower</strong> handles container updates on a schedule at 03:00. If an update breaks something, rolling back means redeploying from the same configuration paths. Docker&rsquo;s stateless container model makes that straightforward.</p>
<p><strong>Portainer</strong> handles anything that needs a UI.</p>
<h2 id="network-edge">Network Edge</h2>
<h3 id="opnsense">OPNsense</h3>
<p>OPNsense sits between the internet and all internal systems. UPnP is disabled. No device exposes itself automatically. Only explicitly required services are permitted outbound or inbound.</p>
<p>All traffic is statefully inspected. DNS is forced through Unbound. Suricata monitors inbound and outbound traffic for known malicious patterns. Devices can&rsquo;t quietly phone home, bypass DNS filtering, or accept unsolicited inbound connections without generating an alert.</p>
<p>Services get published deliberately, not accidentally exposed.</p>
<h3 id="boreas">Boreas</h3>
<p>A Raspberry Pi running Nginx Proxy Manager and WireGuard. This started as a workaround for a previous router that lacked VPN support. After moving to OPNsense, the separation made enough sense to keep.</p>
<p>Boreas is my remote access point back into the LAN. Nginx Proxy Manager exposes Overseerr to friends and family outside the local network. Both services sit behind Cloudflare, primarily to obscure my real IP.</p>
<p>The throughput on the Pi is better than you&rsquo;d expect for the hardware.</p>
<h3 id="chronos">Chronos</h3>
<p>A Tor middle relay running as a small contribution to online privacy. No exit node: the ISP complaints and CAPTCHA overhead aren&rsquo;t worth it. A middle relay provides value without the operational noise. It&rsquo;s low-maintenance and largely invisible once configured.</p>
<h2 id="failures-and-lessons">Failures and Lessons</h2>
<p>In the past year, two things actually broke:</p>
<ul>
<li>Disks filled up from log spam. Entirely my fault. Log rotation is properly configured now.</li>
<li>Incorrect or fake titles downloaded. Better filters and denied extension lists resolved most of it.</li>
</ul>
<p>Beyond that, issues have been minor misconfigurations and occasional reboots.</p>
<h2 id="what-id-do-differently">What I&rsquo;d Do Differently</h2>
<p>I&rsquo;d spread services across more hosts if I could go back. Some hardening measures were probably over-engineered, but I don&rsquo;t regret that trade-off. Deploying the arr stack earlier would have saved time.</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p><strong>Hardware</strong>: managed switch, better access points, a more capable GPU for transcoding.</p>
<p><strong>Monitoring</strong>: a consolidated Zabbix dashboard with proper alerting.</p>
<p><strong>Networking</strong>: VLANs.</p>
<p>Self-hosted AI models aren&rsquo;t on the list. Cloud tools cover what I need without the overhead.</p>
<h2 id="closing">Closing</h2>
<p>Running this lab has mostly taught me patience. Getting multiple devices, containers, and services working together takes iteration. It&rsquo;s improved my understanding of networking and containerised systems more than any course I&rsquo;ve taken.</p>
<p>I keep running it because it&rsquo;s fun and I learn from it. That&rsquo;s enough reason.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
