<?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: Freemen HOUNGBEDJI</title>
    <description>The latest articles on DEV Community by Freemen HOUNGBEDJI (@freemen_tech).</description>
    <link>https://dev.to/freemen_tech</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3754857%2F0c8c529a-2768-4ce7-a55c-bcf97afa1345.jpg</url>
      <title>DEV Community: Freemen HOUNGBEDJI</title>
      <link>https://dev.to/freemen_tech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freemen_tech"/>
    <language>en</language>
    <item>
      <title>Why I built CyberEduc: open-source anti-phishing training that doesn't suck</title>
      <dc:creator>Freemen HOUNGBEDJI</dc:creator>
      <pubDate>Mon, 10 Aug 2026 10:41:22 +0000</pubDate>
      <link>https://dev.to/freemen_tech/why-i-built-cybereduc-open-source-anti-phishing-training-that-doesnt-suck-g95</link>
      <guid>https://dev.to/freemen_tech/why-i-built-cybereduc-open-source-anti-phishing-training-that-doesnt-suck-g95</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Why&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every corporate cybersecurity training I sat through taught me one thing: how to click "I understand" as fast as possible. None taught me to actually spot a phishing email.&lt;/p&gt;

&lt;p&gt;So I built CyberEduc, a free open-source anti-phishing training platform. The goal was simple: train pattern recognition through short lessons and hands-on exercises with realistic phishing scenarios.&lt;/p&gt;

&lt;p&gt;&lt;a href="//cybereduc.com"&gt;CyberEduc&lt;/a&gt;&lt;br&gt;
 &lt;a href="//github.com/FreemenTech/CyberEduc"&gt;Source&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's inside&lt;/strong&gt;&lt;br&gt;
7 short lessons on homograph attacks, URL shorteners, email spoofing, social engineering, email authentication (SPF/DKIM/DMARC), spear phishing, and incident response. Each ends with a quiz.&lt;br&gt;
A Red Flag Trainer where you face real phishing emails side by side with legitimate ones. Click every suspicious token before the timer runs out. Three difficulty levels.&lt;br&gt;
Progression system: XP, levels, badges. From Phish Spotter to Human Firewall.&lt;br&gt;
Auth: email/password with confirmation and password reset.&lt;br&gt;
Privacy first: no tracking, no analytics, no ads. Data encrypted at rest, EU-hosted.&lt;br&gt;
Tech stack&lt;/p&gt;

&lt;p&gt;Nothing exotic, but every choice was deliberate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Frontend : vanilla HTML/CSS/JS, no framework&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I hesitated on this a lot. React would have been faster to build. But CyberEduc is a security awareness site — hiding the frontend behind a bundler felt wrong. Anyone should be able to view-source and read what's happening. Vanilla JS made that transparent.&lt;/p&gt;

&lt;p&gt;Fonts: Inter (body), Instrument Serif (italic accents), JetBrains Mono (code/UI labels). The editorial look was inspired by publications like The Verge Redesign and modern SaaS landing pages.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Backend: FastAPI (Python)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Type hints via Pydantic, async by default, docs auto-generated at /docs. JWT auth issued server-side. REST API under /api. Total code: ~600 lines across auth, lessons, badges, and redflag routes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Data: Supabase&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL with Row Level Security for user data. Supabase Auth for the confirm-email and password-reset flows. Content (lessons + scenarios) lives as JSON files in data/, not in the database , makes contributions dead simple (PR a JSON file, done).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Email: Brevo SMTP&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Custom editorial HTML templates for confirmation and reset emails. Matches the site's black + green accent aesthetic.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deploy: Nginx on a Contabo VPS&lt;/em&gt;&lt;br&gt;
Static frontend + reverse proxy to FastAPI. Let's Encrypt for SSL. Systemd for the API service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design decisions I hesitated on&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JSON content vs a CMS. A CMS would have been more powerful but overkill for 7 lessons. JSON files in git means version-controlled content, dead-simple PRs, no admin panel to secure, no runtime dependency. Trade-off: no non-technical editors. Fine for now.&lt;/p&gt;

&lt;p&gt;No analytics. Zero tracking, zero heatmaps, zero funnel analysis. On principle, but also because I don't want to be the "anti-phishing site that fingerprints its users". If I need engagement data later, I'll add opt-in Plausible.&lt;/p&gt;

&lt;p&gt;Vanilla JS. Already covered. Wins on transparency and load time. Loses on velocity for complex features. If I ever need real interactivity beyond what's there, I might rewrite specific pages in Svelte. But not yet.&lt;/p&gt;

&lt;p&gt;Editorial design. Most cybersecurity products look like enterprise SaaS from 2015: gradients, stock photos of hackers in hoodies, "protect your business" copy. I went the opposite direction — magazine-like layout, Instrument Serif italic accents, black and one accent green. Wanted the site to feel like a place where you learn, not where you buy compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lessons learned building this&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build the boring parts first. I spent the first week on the Red Flag Trainer because it was fun. Then had to backtrack and build auth, sessions, JWT handling, email confirmation, password reset. If I could redo it, I'd start with the auth flow — it's what unlocks everything else.&lt;/p&gt;

&lt;p&gt;Emails are hard. Custom HTML emails that render correctly across Gmail web, Gmail iOS, Apple Mail, Outlook, and Thunderbird required table-based layouts, inline styles, and a lot of testing. Google Fonts import works in some clients and not others. Fallback stacks matter.&lt;/p&gt;

&lt;p&gt;Supabase RLS is powerful but tricky. Row Level Security is elegant when you get it, but the debug cycle is painful. Every "this insert fails silently" required checking policies twice. Worth it for the security guarantees.&lt;/p&gt;

&lt;p&gt;Free tiers stack. The entire production stack is on free tiers: Supabase (up to 500MB), Brevo (300 emails/day), Contabo VPS (~4€/month, not free but close). Total cost per month: less than a coffee. Solo indie budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's next&lt;/strong&gt;&lt;br&gt;
More lessons: OAuth phishing, MFA bypass, deepfake voice phishing&lt;br&gt;
i18n (French, Spanish)&lt;br&gt;
Team mode with aggregated stats for orgs training their employees&lt;br&gt;
Better mobile UX for the Red Flag Trainer (tokens are small on phone screens)&lt;br&gt;
Contribute&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything is MIT licensed. Contributions welcome:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New lessons: drop a JSON file in data/lessons/, follow the schema in CONTRIBUTING.md&lt;/li&gt;
&lt;li&gt;New Red Flag scenarios: same, in data/redflag/&lt;/li&gt;
&lt;li&gt;Bug reports and feature ideas: open an issue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="//cybereduc.com"&gt;Live&lt;/a&gt; &lt;br&gt;
&lt;a href="//github.com/FreemenTech/CyberEduc"&gt;Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy to answer questions in the comments about the stack, the design choices, or the content approach.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>cybersecurity</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a URL Threat Analyzer That Detects Phishing in Real-Time — Here's How It Works published</title>
      <dc:creator>Freemen HOUNGBEDJI</dc:creator>
      <pubDate>Sat, 09 May 2026 12:29:40 +0000</pubDate>
      <link>https://dev.to/freemen_tech/i-built-a-url-threat-analyzer-that-detects-phishing-in-real-time-heres-how-it-works-published-bhm</link>
      <guid>https://dev.to/freemen_tech/i-built-a-url-threat-analyzer-that-detects-phishing-in-real-time-heres-how-it-works-published-bhm</guid>
      <description>&lt;p&gt;&lt;em&gt;Every day, millions of people click malicious URLs without knowing it. Phishing pages look legitimate. Shortened links hide their destination. Freshly registered domains slip past blockers.&lt;br&gt;
I got tired of copy-pasting URLs into clunky online scanners and waiting 10 seconds for a result — so I built SnifURL.&lt;/em&gt;&lt;br&gt;
&lt;a href="//snifurl.online"&gt;Live&lt;/a&gt;&lt;br&gt;
&lt;a href="//github.com/FreemenTech/Snifurl"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is SnifURL?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SnifURL is a real-time URL threat analyzer. You paste a URL, it runs it through 13 heuristic checks in parallel, and returns a risk score from 0 to 100 with a full breakdown of every signal it found.&lt;br&gt;
No black box. No "we flagged it, trust us." Every point added or subtracted is explained.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "url": "https://paypa1-secure-login.tk/verify",&lt;br&gt;
  "score": 91,&lt;br&gt;
  "risk_level": "CRITICAL",&lt;br&gt;
  "recommendation": "Phishing almost certain — block immediately",&lt;br&gt;
  "details": [&lt;br&gt;
    "Suspicious TLD (.tk — Freenom free domain) (+18)",&lt;br&gt;
    "Brand impersonation detected: 'paypa1' looks like 'paypal' (+25)",&lt;br&gt;
    "Domain registered 3 days ago (+20)",&lt;br&gt;
    "Homograph character detected: '1' replacing 'l' (+15)",&lt;br&gt;
    "No valid SSL certificate (+13)"&lt;br&gt;
  ]&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Risk Score System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🟢 0–14 — &lt;strong&gt;SAFE&lt;/strong&gt; No significant indicators. The URL looks clean.&lt;br&gt;
🟡 15–34 — &lt;strong&gt;LOW&lt;/strong&gt; Probably safe, but worth a second look before clicking.&lt;br&gt;
🟠 35–54 — &lt;strong&gt;MEDIUM&lt;/strong&gt; Suspicious. Inspect manually before trusting it.&lt;br&gt;
🔴 55–74 — &lt;strong&gt;HIGH&lt;/strong&gt; Very suspicious — block it unless you're 100% sure of the source.&lt;br&gt;
🚨 75–100 — &lt;strong&gt;CRITICAL&lt;/strong&gt; Phishing almost certain. Block immediately.&lt;br&gt;
The score is additive: each indicator adds or subtracts points based on its confidence weight. This makes results explainable and debuggable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 13 Heuristic Indicators&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's exactly what SnifURL checks — and why each one matters.&lt;br&gt;
&lt;strong&gt;1. TLD Reputation&lt;/strong&gt;&lt;br&gt;
Free TLDs like .tk, .ml, .cf, .ga, .gq (Freenom) are massively over-represented in phishing campaigns. Crypto TLDs like .xyz, .top also rank high. High-risk ccTLDs are weighted accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Direct IP in URL&lt;/strong&gt;&lt;br&gt;
&lt;a href="http://192.168.1.1/login" rel="noopener noreferrer"&gt;http://192.168.1.1/login&lt;/a&gt; — no legitimate service asks you to log in via a raw IP address. This is a strong phishing signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Brand Impersonation&lt;/strong&gt;&lt;br&gt;
The engine scans the subdomain and path against a dictionary of major brands (paypal, google, apple, amazon, microsoft, netflix...) and checks for typosquatting variations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Homograph Attacks&lt;/strong&gt;&lt;br&gt;
Unicode lookalike characters are a sneaky attack vector. pаypal.com with a Cyrillic а looks identical to paypal.com. SnifURL detects non-ASCII characters and flags them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. SSL Certificate Validity&lt;/strong&gt;&lt;br&gt;
Checks if the certificate is valid and evaluates issuer trust. A self-signed cert on a "bank login" page? Red flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. WHOIS Domain Age&lt;/strong&gt;&lt;br&gt;
New domains are suspicious. A domain registered 2 days ago asking for your password is a massive red flag. SnifURL queries WHOIS and penalizes recently created domains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. DNS Resolution&lt;/strong&gt;&lt;br&gt;
If the domain doesn't even resolve — it's either dead or a trap. Simple check, non-zero value.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;URL Shorteners
bit.ly, tinyurl.com, t.co — shorteners hide the real destination. SnifURL flags them and encourages redirect inspection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;9. Double File Extensions&lt;/strong&gt;&lt;br&gt;
invoice.pdf.exe is a classic malware trick. The engine scans the URL path for chained extensions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. @ Character in URL&lt;/strong&gt;&lt;br&gt;
&lt;a href="http://legitimate.com@evil.com/phish" rel="noopener noreferrer"&gt;http://legitimate.com@evil.com/phish&lt;/a&gt; — browsers follow the part after @. This old trick still catches people off guard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11. Non-Standard Ports&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://mybank.com:8080/login" rel="noopener noreferrer"&gt;https://mybank.com:8080/login&lt;/a&gt; is a sign something is off. Legit services run on 443.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12. Excessive URL Encoding&lt;/strong&gt;&lt;br&gt;
%68%74%74%70%73%3A%2F%2F... — heavy encoding often signals an attempt to obfuscate a malicious destination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13. Subdomain Depth &amp;amp; Hyphens&lt;/strong&gt;&lt;br&gt;
secure-login-verify.paypal.accounts.malicious.com — deep subdomains and excessive hyphens are classic phishing patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the Parallel Analysis Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Network checks (DNS, WHOIS, SSL) are the slow part. Running them sequentially would add 3–5 seconds of latency. Instead, SnifURL runs them concurrently with Python's ThreadPoolExecutor:&lt;br&gt;
python# analyseur_url.py (simplified)&lt;br&gt;
from concurrent.futures import ThreadPoolExecutor, as_completed&lt;/p&gt;

&lt;p&gt;def analyze(url: str) -&amp;gt; dict:&lt;br&gt;
    results = {}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;with ThreadPoolExecutor(max_workers=4) as executor:
    futures = {
        executor.submit(check_ssl, url): "ssl",
        executor.submit(check_whois, url): "whois",
        executor.submit(check_dns, url): "dns",
        executor.submit(check_redirects, url): "redirects",
    }
    for future in as_completed(futures):
        key = futures[future]
        results[key] = future.result()

# Heuristic checks (no I/O — instant)
results["tld"] = check_tld(url)
results["homograph"] = check_homograph(url)
results["brand"] = check_brand_impersonation(url)
# ...

return scoring.compute(results)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Total analysis time on most URLs: under 2 seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Scoring Engine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;scoring.py takes the raw results and computes the final score. Each signal has a weight based on its phishing correlation strength:&lt;br&gt;
python# scoring.py (simplified)&lt;br&gt;
WEIGHTS = {&lt;br&gt;
    "suspicious_tld": 18,&lt;br&gt;
    "brand_impersonation": 25,&lt;br&gt;
    "homograph": 15,&lt;br&gt;
    "no_ssl": 13,&lt;br&gt;
    "recently_registered": 20,  # &amp;lt; 30 days&lt;br&gt;
    "direct_ip": 22,&lt;br&gt;
    "url_shortener": 10,&lt;br&gt;
    "double_extension": 15,&lt;br&gt;
    "at_char": 12,&lt;br&gt;
    "non_standard_port": 8,&lt;br&gt;
    "excessive_encoding": 10,&lt;br&gt;
    "subdomain_depth": 8,&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;def compute(results: dict) -&amp;gt; dict:&lt;br&gt;
    score = 50  # neutral start&lt;br&gt;
    details = []&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for key, weight in WEIGHTS.items():
    if results.get(key):
        score += weight
        details.append(f"{DESCRIPTIONS[key]} (+{weight})")

# Legitimate signals reduce the score
if results.get("ssl_valid"):
    score -= 10
if results.get("domain_age_days", 0) &amp;gt; 365:
    score -= 12
# ...

score = max(0, min(100, score))
return { "score": score, "risk_level": get_level(score), "details": details }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The weights were calibrated manually against a dataset of known phishing URLs from PhishTank and legitimate domains. It's not ML — it's deliberate, transparent logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything is accessible via a simple REST API:&lt;br&gt;
&lt;code&gt;curl -X POST https://snifurl.online/analyze \&lt;br&gt;
  -H "Content-Type: application/json" \&lt;br&gt;
  -d '{"url": "https://example.com"}'&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;code&gt;{&lt;br&gt;
  "url": "https://example.com",&lt;br&gt;
  "score": 12,&lt;br&gt;
  "risk_level": "SAFE",&lt;br&gt;
  "recommendation": "LEGITIMATE — No significant indicators",&lt;br&gt;
  "details": ["Known legitimate root domain (example.com) (-12)"],&lt;br&gt;
  "indicators": {&lt;br&gt;
    "uses_https": true,&lt;br&gt;
    "dns_exists": true,&lt;br&gt;
    "has_ip": false,&lt;br&gt;
    "suspicious_tld": null,&lt;br&gt;
    "recently_created": false,&lt;br&gt;
    "ssl_certificate": { "valid": true, "issuer_org": "DigiCert" },&lt;br&gt;
    "whois": { "age_days": 9862, "registrar": "..." }&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
You can integrate this into your own app, browser extension, or Slack bot to flag links before users click them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack &amp;amp; Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Backend → Python 3.11 / Flask&lt;br&gt;
Analysis engine → analyseur_url.py + scoring.py&lt;br&gt;
Network checks → dnspython, python-whois, ssl (parallel execution)&lt;br&gt;
Frontend → Vanilla HTML / CSS / JS&lt;br&gt;
Server → Vultr VPS / Ubuntu 22.04 / Nginx + Gunicorn&lt;/p&gt;

&lt;p&gt;No framework overhead on the frontend. The UI is intentionally lean — the value is in the analysis, not the interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run It Yourself&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/FreemenTech/Snifurl&lt;br&gt;
cd snifurl&lt;br&gt;
pip install -r requirements.txt&lt;br&gt;
python app.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt; — that's it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's Next&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few things I'm thinking about:&lt;/p&gt;

&lt;p&gt;Browser extension — flag URLs inline before you click&lt;br&gt;
Bulk analysis endpoint — scan a list of URLs in one request&lt;br&gt;
ML scoring layer — train a model on PhishTank data to complement the heuristics&lt;br&gt;
Redirect chain analysis — follow shorteners and score the final destination&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔗&lt;a href="//snifurl.online"&gt;Website&lt;/a&gt;&lt;br&gt;
Paste a suspicious URL you've received recently .I'd be curious what score it gets. Drop it in the comments.&lt;br&gt;
And if you find a false positive or a phishing URL that slips through open an issue. That's how the weights get better.&lt;/p&gt;

&lt;p&gt;Built by &lt;strong&gt;Freemen HOUNGBEDJI&lt;/strong&gt; — MIT License&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>python</category>
    </item>
    <item>
      <title>🔥 Building Vigilo: A 15MB File Integrity Monitor That Outperforms OSSEC</title>
      <dc:creator>Freemen HOUNGBEDJI</dc:creator>
      <pubDate>Fri, 06 Feb 2026 13:37:21 +0000</pubDate>
      <link>https://dev.to/freemen_tech/building-vigilo-a-15mb-file-integrity-monitor-that-outperforms-ossec-5g02</link>
      <guid>https://dev.to/freemen_tech/building-vigilo-a-15mb-file-integrity-monitor-that-outperforms-ossec-5g02</guid>
      <description>&lt;p&gt;🚨 The Night Everything Broke&lt;br&gt;
My former employer got hacked.&lt;/p&gt;

&lt;p&gt;At 3:07 AM, an attacker modified /etc/sudoers.&lt;br&gt;
No alerts.&lt;br&gt;
No logs reviewed.&lt;br&gt;
No alarms.&lt;/p&gt;

&lt;p&gt;We noticed it 3 days later.&lt;br&gt;
That night, I opened a blank Python file:&lt;br&gt;
   file_monitoring.py&lt;br&gt;
That file became Vigilo.&lt;/p&gt;

&lt;p&gt;❌ Why Existing Tools Failed Us&lt;br&gt;
We didn’t ignore security tools.&lt;br&gt;
We tried them.&lt;/p&gt;

&lt;p&gt;OSSEC&lt;br&gt;
❌ 200+ MB RAM on idle&lt;br&gt;
❌ 50+ lines of XML config for a single file&lt;br&gt;
❌ False positives drowning real alerts&lt;/p&gt;

&lt;p&gt;Wazuh&lt;br&gt;
❌ 30+ minutes installation&lt;br&gt;
❌ YAML + agents + dashboards&lt;br&gt;
❌ Massive overkill for &amp;lt; 50 servers&lt;/p&gt;

&lt;p&gt;What we needed was simple:&lt;/p&gt;

&lt;p&gt;“Tell me immediately when a critical file changes.&lt;br&gt;
Nothing more. Nothing less.”&lt;/p&gt;

&lt;p&gt;🛠️ What I Built Instead&lt;/p&gt;

&lt;p&gt;Vigilo is a lightweight File Integrity Monitor built for real-world ops teams.&lt;/p&gt;

&lt;p&gt;💾 &amp;lt; 15 MB RAM&lt;br&gt;
⚡ &amp;lt; 1 second alert latency&lt;br&gt;
🧠 Zero configuration hell&lt;br&gt;
🐍 100% Python, easy to hack &amp;amp; extend&lt;/p&gt;

&lt;p&gt;🎯 Core Design Principles&lt;/p&gt;

&lt;p&gt;Install in under 60 seconds&lt;br&gt;
Minimal memory footprint&lt;br&gt;
Readable, auditable code&lt;br&gt;
Production-ready from day one&lt;/p&gt;

&lt;p&gt;🧩 Technical Architecture&lt;br&gt;
vigilo/&lt;br&gt;
├── file_monitoring.py   # SHA-256 + metadata tracking&lt;br&gt;
├── FileWatcher.py       # inotify wrapper with smart filtering&lt;br&gt;
├── logger.py            # thread-safe persistent storage&lt;br&gt;
├── alert_manager.py     # system / future email / webhook alerts&lt;br&gt;
└── main.py              # CLI entrypoint&lt;/p&gt;

&lt;p&gt;⚡ Performance Optimizations That Matter&lt;br&gt;
1️⃣ In-Memory Baseline Cache&lt;br&gt;
Before (slow, disk-bound):&lt;br&gt;
def handle_event(path):&lt;br&gt;
    baseline = read_from_disk(path)&lt;/p&gt;

&lt;p&gt;After (fast, O(1)):&lt;br&gt;
def handle_event(path):&lt;br&gt;
    baseline = self.cache[path]&lt;br&gt;
📈 Result: 10× faster event processing.&lt;/p&gt;

&lt;p&gt;2️⃣ Atomic Writes (No Corrupted State)&lt;br&gt;
temp = "file_info.json.tmp"&lt;br&gt;
write_to(temp)&lt;br&gt;
os.replace(temp, "file_info.json")  # POSIX atomic&lt;/p&gt;

&lt;p&gt;Even a crash won’t break your baseline.&lt;/p&gt;

&lt;p&gt;3️⃣ Thread Safety (Because Events Are Brutal)&lt;br&gt;
_db_lock = threading.Lock()&lt;br&gt;
with _db_lock:&lt;br&gt;
    save_state()&lt;br&gt;
No race conditions. No silent corruption.&lt;/p&gt;

&lt;p&gt;📊 Benchmarks&lt;/p&gt;

&lt;p&gt;Test: Monitoring /etc/nginx/nginx.conf&lt;br&gt;
Load: 10 modifications / second&lt;/p&gt;

&lt;p&gt;Tool    CPU RAM False Positives&lt;br&gt;
Vigilo  0.8%    11 MB   0&lt;br&gt;
OSSEC   3.2%    187 MB  14&lt;br&gt;
Wazuh   5.1%    243 MB  23&lt;/p&gt;

&lt;p&gt;🚀 Usage&lt;/p&gt;

&lt;h1&gt;
  
  
  Install
&lt;/h1&gt;

&lt;p&gt;pip install -r requirements.txt&lt;/p&gt;

&lt;h1&gt;
  
  
  Add file to monitoring
&lt;/h1&gt;

&lt;p&gt;vigilo add /etc/nginx/nginx.conf --preset full --alert system&lt;/p&gt;

&lt;h1&gt;
  
  
  Start monitoring
&lt;/h1&gt;

&lt;p&gt;vigilo start&lt;br&gt;
Modify the file → desktop alert in &amp;lt; 1 second.&lt;/p&gt;

&lt;p&gt;🔐 Security First (Yes, Even the Tool)&lt;/p&gt;

&lt;p&gt;✅ Path whitelisting (no /etc/shadow)&lt;br&gt;
✅ Command injection protection (shlex.quote)&lt;br&gt;
✅ Strict file permissions (0o600)&lt;br&gt;
✅ Input validation on all CLI arguments&lt;/p&gt;

&lt;p&gt;🌙 Lessons Learned (The Hard Way)&lt;/p&gt;

&lt;p&gt;Night 1 — The Watchdog Spam&lt;br&gt;
One file triggered 1000+ events/min.&lt;br&gt;
👉 Fixed by filtering events before processing.&lt;/p&gt;

&lt;p&gt;Night 2 — The Performance Breakthrough&lt;br&gt;
Added in-memory cache.&lt;br&gt;
👉 Everything became 10× faster.&lt;/p&gt;

&lt;p&gt;Night 3 — The Security Obsession&lt;br&gt;
Found a command injection flaw in alert execution.&lt;br&gt;
👉 6 hours replacing everything with shlex.quote().&lt;/p&gt;

&lt;p&gt;Worth it.&lt;/p&gt;

&lt;p&gt;❌ When NOT to Use Vigilo&lt;br&gt;
You manage 1000+ servers&lt;br&gt;
You need advanced event correlation&lt;br&gt;
You require enterprise SLAs&lt;br&gt;
You must meet strict compliance (→ use Tripwire / Wazuh)&lt;br&gt;
✅ When Vigilo Is Perfect:&lt;br&gt;
&amp;lt; 100 servers&lt;br&gt;
You want something that just works&lt;br&gt;
You hate false positives&lt;br&gt;
You like tools you can actually read and modify&lt;/p&gt;

&lt;p&gt;🌍 Open Source&lt;br&gt;
🔗 GitHub: &lt;a href="https://github.com/FreemenTech/Vigilo" rel="noopener noreferrer"&gt;https://github.com/FreemenTech/Vigilo&lt;/a&gt;&lt;br&gt;
📄 License: MIT&lt;br&gt;
Contributions are welcome 🙌&lt;br&gt;
💬 Questions or feedback? Drop them below 👇&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
