Author SHA1 Message Date
venus 70134d2e00 added more samples and identified ideal candidates 2026-09-12 22:47:46 -05:00
venus f3ae84ad79 feat(samples): align split panel sample with canonical layout specs 2026-09-05 15:15:48 -05:00
venus 451fb34f52 feat(samples): align dual pane explorer with canonical system specs and logs 2026-09-05 15:15:46 -05:00
venus 9f4758039a feat(samples): align sample dashboard with canonical telemetry and metrics 2026-09-05 15:15:45 -05:00
venus 6a0f4347f9 feat(samples): align sample command center with canonical telemetry and nodes 2026-09-05 15:15:44 -05:00
venus 0ee5fae6be feat(samples): synchronize public services directory with canonical specs 2026-09-05 15:15:43 -05:00
venus be516f8848 feat(samples): update portfolio layout with canonical engineering projects 2026-09-05 15:15:41 -05:00
venus 59bac4bac9 feat(samples): expand samples catalog index with canonical layout showcase 2026-09-05 15:15:39 -05:00
venus e68322f182 feat(samples): update homepage sample with canonical metadata and layout updates 2026-09-05 15:15:38 -05:00
venus bf351e9755 feat(samples): align homelab specs and nodes with canonical dataset 2026-09-05 15:15:36 -05:00
venus 801ba3a533 feat(samples): update document flow layout with canonical dataset references 2026-09-05 15:15:35 -05:00
venus 65ad51560c feat(samples): update companion layout with canonical persona and links 2026-09-05 15:15:34 -05:00
venus 0f80bf4e9b feat(index): update tags and footer with canonical contact info and samples link 2026-09-05 15:15:33 -05:00
venus 424041a827 docs: add canonical sample content dataset 2026-09-05 15:15:29 -05:00
29 changed files with 12419 additions and 495 deletions
File diff suppressed because it is too large Load Diff
+780
View File
@@ -0,0 +1,780 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Blog Lander (Tiling Hero &amp; Feed)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered tile surface */
--border-color: #2b303b; /* Crisp 1px solid border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary active accent */
--accent-green: #00e676; /* Operational status indicator */
--accent-amber: #ffb700; /* Warning / highlight accent */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1120px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Status Header Bar (Gateway 3 Style) */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
.bar-link.active {
color: var(--text-primary);
border-bottom: 1px solid var(--accent-cyan);
}
/* Hero Tile: Section Declaration & Synopsis */
.hero-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 4px;
padding: 24px 28px;
display: flex;
flex-direction: column;
gap: 12px;
}
.hero-pretitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.hero-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.1rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
line-height: 1.2;
}
.hero-landing-text {
font-size: 0.98rem;
color: var(--text-primary);
line-height: 1.65;
max-width: 82ch;
}
.filter-pills-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-top: 4px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.filter-tag-btn {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
color: var(--text-muted);
padding: 3px 8px;
border-radius: 2px;
cursor: pointer;
transition: none;
}
.filter-tag-btn:hover {
border-color: var(--accent-cyan);
color: var(--text-primary);
background-color: var(--bg-elevated);
}
.filter-tag-btn.active {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
border-color: var(--accent-cyan);
font-weight: 700;
}
/* Asymmetric Split Grid */
.split-grid {
display: grid;
grid-template-columns: 1.25fr 0.75fr;
gap: 16px;
}
@media (max-width: 880px) {
.split-grid {
grid-template-columns: 1fr;
}
}
/* Standard Tile Container */
.tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}
.tile-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
}
.tile-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.92rem;
font-weight: 700;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 8px;
}
.tile-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
/* Featured Lead Article Card (Inside Tile) */
.featured-card-body {
display: flex;
flex-direction: column;
gap: 12px;
}
.featured-badge-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
flex-wrap: wrap;
gap: 8px;
}
.badge-pinned {
color: var(--accent-amber);
font-weight: 700;
}
.featured-article-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.35rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.3;
transition: none;
}
.featured-article-title:hover {
color: var(--accent-cyan);
}
.featured-prose {
font-size: 0.92rem;
color: var(--text-primary);
line-height: 1.6;
}
/* Terminal Code Block Component */
.terminal-code-box {
border: 1px solid var(--border-color);
border-radius: 3px;
background-color: var(--bg-canvas);
overflow: hidden;
font-family: 'JetBrains Mono', monospace;
}
.code-titlebar {
background-color: var(--bg-surface);
border-bottom: 1px solid var(--border-color);
padding: 6px 12px;
font-size: 0.74rem;
color: var(--text-muted);
display: flex;
justify-content: space-between;
}
.code-content {
padding: 12px;
font-size: 0.78rem;
overflow-x: auto;
color: var(--text-primary);
line-height: 1.5;
}
.featured-cta-row {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 10px;
border-top: 1px solid var(--border-color);
flex-wrap: wrap;
gap: 10px;
font-family: 'IBM Plex Mono', monospace;
}
.cta-button {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 6px 14px;
font-weight: 700;
font-size: 0.8rem;
text-decoration: none;
border-radius: 2px;
border: 1px solid var(--accent-cyan);
transition: none;
}
.cta-button:hover {
background-color: transparent;
color: var(--accent-cyan);
}
/* Sidebar Tile Elements */
.sidebar-stats-box {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
}
.stat-row {
display: flex;
justify-content: space-between;
}
.stat-val {
color: var(--text-primary);
font-weight: 700;
}
.topic-track-item {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 10px 12px;
display: flex;
flex-direction: column;
gap: 4px;
text-decoration: none;
transition: none;
}
.topic-track-item:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.topic-track-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.84rem;
font-weight: 700;
color: var(--text-primary);
}
.topic-track-item:hover .topic-track-title {
color: var(--accent-cyan);
}
.topic-track-desc {
font-size: 0.78rem;
color: var(--text-muted);
line-height: 1.4;
}
/* Full-Width Chronological Article Feed Tile */
.feed-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.feed-card {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px 18px;
display: flex;
flex-direction: column;
gap: 8px;
transition: none;
}
.feed-card:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.feed-meta-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
color: var(--text-muted);
}
.feed-date {
color: var(--accent-cyan);
}
.feed-heading {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.1rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
transition: none;
}
.feed-card:hover .feed-heading {
color: var(--accent-cyan);
}
.feed-excerpt {
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.6;
}
.feed-tags-row {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 6px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 6px;
}
.tag-cluster {
display: flex;
gap: 8px;
}
/* Global Footer Tile (Gateway 3 Standard) */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Global Status Bar (Gateway 3 Match) -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // BLOG &amp; RESEARCH ARCHIVE</span>
</div>
<nav class="bar-nav" aria-label="Quick Navigation">
<a href="service-gateway-tiling.html" class="bar-link">Gateway 3 ↗</a>
<a href="#" class="bar-link active">&gt; Dispatches</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="feed.xml" class="bar-link">RSS Feed</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Hero Tile: Blog Mission & Topic Filters -->
<section class="hero-tile" aria-label="Blog Mission & Overview">
<div class="hero-pretitle">TECHNICAL PUBLICATION REPOSITORY &bull; ~/NOTES/INDEX.MD</div>
<h1 class="hero-main-title">Engineering Notes, CTF Write-Ups &amp; Systems Architecture</h1>
<p class="hero-landing-text">
Documenting bare-metal systems, embedded hardware audits, and network isolation architectures. Writing zero-allocation POSIX scripts, reverse engineering production microcontrollers, and analyzing memory allocator exploitation primitives.
</p>
<div class="filter-pills-row">
<span style="color: var(--text-muted); margin-right: 4px;">TOPIC FILTER:</span>
<button class="filter-tag-btn active" onclick="filterTopic('all', this)">[All Dispatches (5)]</button>
<button class="filter-tag-btn" onclick="filterTopic('firmware', this)">[#firmware (1)]</button>
<button class="filter-tag-btn" onclick="filterTopic('homelab', this)">[#homelab (2)]</button>
<button class="filter-tag-btn" onclick="filterTopic('security', this)">[#security (3)]</button>
<button class="filter-tag-btn" onclick="filterTopic('posix-sh', this)">[#posix-sh (1)]</button>
</div>
</section>
<!-- Split Grid: Featured Article + Research Index -->
<div class="split-grid">
<!-- Left Column: Featured Article Tile -->
<section class="tile" aria-label="Featured Technical Article">
<div class="tile-header">
<div class="tile-title">
<span>// PINNED RESEARCH WRITE-UP</span>
</div>
<span class="tile-meta">SPI FLASH &bull; 8 MIN READ</span>
</div>
<div class="featured-card-body">
<div class="featured-badge-row">
<span class="badge-pinned">[FEATURED DEEP DIVE]</span>
<span style="color: var(--text-muted);">2026-07-20 &bull; ~/notes/iot-firmware-spi-extraction.md</span>
</div>
<h2 style="margin: 0;">
<a href="article-tiling-firmware.html" class="featured-article-title">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</h2>
<p class="featured-prose">
In security audits of embedded systems, retrieving firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.
</p>
<!-- Terminal Code Box -->
<div class="terminal-code-box">
<div class="code-titlebar">
<span>extract_firmware.sh</span>
<span>POSIX sh</span>
</div>
<div class="code-content">
<pre><code># Query the SPI flash details using flashrom via Bus Pirate
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
# Verify the integrity of the binary dump by comparing hashes
if [ $? -eq 0 ]; then
echo "Dump successful. Running md5sum..."
md5sum firmware_dump.bin
fi</code></pre>
</div>
</div>
<div class="featured-cta-row">
<div class="tag-cluster">
<span style="color: var(--text-muted); font-size: 0.75rem;">[#firmware] [#hardware] [#security] [#bus-pirate]</span>
</div>
<a href="article-tiling-firmware.html" class="cta-button">READ FULL WRITEUP &rarr;</a>
</div>
</div>
</section>
<!-- Right Column: Quick Research Tracks & Telemetry -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Publication Stats Tile -->
<section class="tile" aria-label="Archive Statistics">
<div class="tile-header">
<div class="tile-title">
<span>// ARCHIVE TELEMETRY</span>
</div>
<span class="tile-meta">STATIC HTML</span>
</div>
<div class="sidebar-stats-box">
<div class="stat-row">
<span>TOTAL ARTICLES:</span>
<span class="stat-val">5 PUBLISHED</span>
</div>
<div class="stat-row">
<span>TOTAL READING TIME:</span>
<span class="stat-val">51 MINUTES</span>
</div>
<div class="stat-row">
<span>ACTIVE TOPICS:</span>
<span class="stat-val">7 CATEGORIES</span>
</div>
<div class="stat-row">
<span>FORMAT COMPLIANCE:</span>
<span class="stat-val">IEEE STD 1003.1</span>
</div>
</div>
</section>
<!-- Curated Focus Tracks -->
<section class="tile" aria-label="Curated Topic Tracks">
<div class="tile-header">
<div class="tile-title">
<span>// RESEARCH TRACKS</span>
</div>
<span class="tile-meta">CURATED</span>
</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<a href="#" class="topic-track-item">
<div class="topic-track-title">&gt; Embedded &amp; Hardware Forensics</div>
<div class="topic-track-desc">Flash memory dumping, bus tapping, silicon pinout discovery.</div>
</a>
<a href="#" class="topic-track-item">
<div class="topic-track-title">&gt; Network Routing &amp; Homelab</div>
<div class="topic-track-desc">Traefik reverse proxying, WireGuard full-mesh, VLAN firewalls.</div>
</a>
<a href="#" class="topic-track-item">
<div class="topic-track-title">&gt; Low-Level Memory Exploitation</div>
<div class="topic-track-desc">glibc tcache safe-linking, heap corruption, House of Apple.</div>
</a>
</div>
</section>
</div>
</div>
<!-- Full-Width Article Feed Tile -->
<section class="tile" aria-label="Chronological Article Stream">
<div class="tile-header">
<div class="tile-title">
<span>// CHRONOLOGICAL DISPATCHES FEED</span>
</div>
<span class="tile-meta">ALL ARTICLES ORDERED BY DATE</span>
</div>
<div class="feed-list" id="feedList">
<!-- Post 2: Traefik -->
<article class="feed-card" data-tags="homelab networking">
<div class="feed-meta-row">
<time datetime="2026-07-15" class="feed-date">2026-07-15 &bull; 12 min read</time>
<span>~/notes/ha-traefik-docker.md</span>
</div>
<h3 style="margin: 0;">
<a href="article-tiling-traefik.html" class="feed-heading">&gt; Building a High-Availability Traefik Router with Docker Compose</a>
</h3>
<p class="feed-excerpt">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes on bare-metal infrastructure.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#homelab]</span>
<span>[#docker-traefik]</span>
<span>[#networking]</span>
</div>
<a href="article-tiling-traefik.html" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
<!-- Post 3: POSIX sh -->
<article class="feed-card" data-tags="posix-sh security">
<div class="feed-meta-row">
<time datetime="2026-07-10" class="feed-date">2026-07-10 &bull; 6 min read</time>
<span>~/notes/posix-sh-vs-bash.md</span>
</div>
<h3 style="margin: 0;">
<a href="#" class="feed-heading">&gt; POSIX sh vs. Bash: Portability in Modern Scripts</a>
</h3>
<p class="feed-excerpt">
Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#posix-sh]</span>
<span>[#shell]</span>
<span>[#unix]</span>
</div>
<a href="#" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
<!-- Post 4: Heap Exploitation -->
<article class="feed-card" data-tags="security">
<div class="feed-meta-row">
<time datetime="2026-06-28" class="feed-date">2026-06-28 &bull; 15 min read</time>
<span>~/notes/ctf-heap-glibc-2-35.md</span>
</div>
<h3 style="margin: 0;">
<a href="article-tiling-heap.html" class="feed-heading">&gt; CTF Write-up: Heap Exploitation in glibc 2.35</a>
</h3>
<p class="feed-excerpt">
Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking for arbitrary code execution.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#ctf]</span>
<span>[#binary-exploitation]</span>
<span>[#security]</span>
</div>
<a href="article-tiling-heap.html" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
<!-- Post 5: Zero-Trust WireGuard -->
<article class="feed-card" data-tags="networking security homelab">
<div class="feed-meta-row">
<time datetime="2026-06-14" class="feed-date">2026-06-14 &bull; 10 min read</time>
<span>~/notes/zero-trust-wireguard-opnsense.md</span>
</div>
<h3 style="margin: 0;">
<a href="#" class="feed-heading">&gt; Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
</h3>
<p class="feed-excerpt">
Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#networking]</span>
<span>[#wireguard]</span>
<span>[#security]</span>
</div>
<a href="#" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
</div>
</section>
<!-- Global Footer Tile (Matching Gateway 3 Exactly) -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="service-gateway-tiling.html" class="footer-btn">Gateway Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
function filterTopic(topic, btn) {
document.querySelectorAll('.filter-tag-btn').forEach(el => el.classList.remove('active'));
btn.classList.add('active');
const cards = document.querySelectorAll('#feedList .feed-card');
cards.forEach(card => {
if (topic === 'all') {
card.style.display = 'flex';
} else {
const tags = card.getAttribute('data-tags') || '';
if (tags.includes(topic)) {
card.style.display = 'flex';
} else {
card.style.display = 'none';
}
}
});
}
</script>
</body>
</html>
+81
View File
@@ -0,0 +1,81 @@
# Project Brief: Technical Web Architecture & Blog
**Project Type:** Personal Blog & Technical Documentation Site
**Design Philosophy:** High-signal, low-noise. Developer-centric minimalism.
**Vibe/Comparisons:** Zed Editor, Ghostty, Noctalia.dev.
**Strictly Avoid:** Raycast, Astro, Vercel-style "SaaS" aesthetics.
## 1. Executive Summary
This project requires a web interface that feels like a native development environment or terminal emulator, not a marketing page. The design must prioritize raw performance, keyboard navigability, and information density. It should evoke the craftsmanship of tiling window managers and modal text editors.
The content will heavily feature deep technical writing, including CTF write-ups, network routing diagrams, Docker/Traefik architectures, and raw code snippets (Lua, POSIX `sh`, and Python). The design must accommodate high-density information without visual clutter.
---
## 2. Global Rules & Anti-Patterns
To achieve the correct aesthetic, the designer must adhere to strict constraints.
> **The "Do Not Use" List**
> * **NO Glassmorphism:** Zero use of `backdrop-filter: blur()`, frosted glass, or translucent overlays.
> * **NO Glows or Drop Shadows:** Elements should not float, glow, or cast shadows. Depth is created through crisp 1px borders and distinct surface colors.
> * **NO Gradients:** Avoid sweeping linear or radial gradients. Stick to solid colors.
> * **NO Spring Animations:** Avoid floaty, delayed transitions.
> * **NO Rounded Blobs:** Keep border-radii minimal (0px to 4px max). Sharp corners are preferred.
---
## 3. Typography System
The typographical hierarchy is a hybrid system utilizing monospace fonts for structural elements and a clean sans-serif for long-form reading.
| Usage | Font Family Preference | Weight | Role |
| :--- | :--- | :--- | :--- |
| **Structural / UI** | IBM Plex Mono, JetBrains Mono | Regular (400), Medium (500) | Navigation links, metadata, dates, tags, timestamps, buttons. |
| **Code Blocks** | JetBrains Mono, Fira Code | Regular (400) | Inline code snippets, terminal command blocks, scripts. |
| **Body Prose** | Inter, Geist Sans, Roboto | Regular (400) | Standard article paragraphs, lists. |
| **Headings (H1-H3)**| IBM Plex Mono (or Sans variant) | Bold (700) | Article titles, section headers. |
**Typographical Constraints:**
* **Line Height:** `1.6` to `1.7` for prose.
* **Max Width:** Cap article text at `65ch` (characters) for optimal readability.
---
## 4. Color Palette (Dark Mode Native)
The site does not need a light mode. It should be built as a dark-mode native experience using a muted, low-saturation charcoal palette, mimicking a modern terminal or IDE.
* **Base Canvas (`#121417` or `#0d0f12`):** A deep slate/charcoal. Not pure black (`#000000`), which causes eye strain.
* **Surface / Card (`#1c1f26`):** Slightly lighter than the canvas for article blocks or terminal windows.
* **Borders & Dividers (`#2b303b`):** Subtle, low-contrast 1px solid lines used to define grids and separate content.
* **Primary Text (`#e0e6f0`):** Off-white/light ash for prose.
* **Muted Text (`#8a95a5`):** For timestamps, metadata, and non-essential UI text.
* **Accent Color (Designer's Choice):** One single, vibrant terminal color (e.g., ANSI Green, Amber, or Cyan) used sparingly for active states, link hovers, or terminal prompts (like `>`).
---
## 5. Layout & Component Architecture
The layout should be heavily grid-based, feeling structural and deliberate.
### Core Components Needed
1. **Terminal-Style Code Blocks:** Must support syntax highlighting. Should include a simple header (e.g., showing the filename like `config.lua` or `docker-compose.yml`) with a 1px border.
2. **Metadata Tags:** Small, monospaced inline blocks for categorizing posts (e.g., `[#homelab]`, `[#ctf]`, `[#hyprland]`).
3. **Keyboard Shortcut Hints:** Visual styling for `<kbd>` elements, rendering as crisp, bordered boxes (e.g., `Ctrl` + `K`).
4. **Index/Archive List:** A dense, tabular list for older posts, prioritized by date, title, and tags, rather than large image thumbnails.
### Spacing & Grid
* Use a rigid 4pt or 8pt baseline grid.
* Padding inside code blocks and cards should be dense but mathematically consistent.
* Full-bleed horizontal dividers (`<hr>`) should be used to separate major sections instead of large margins.
---
## 6. Interaction & Motion
Interactivity should mirror command-line interfaces: fast, binary, and unembellished.
* **Hover States:** Immediate state changes. Instead of fading a button's background over `300ms`, snap the background color instantly or invert the text/background colors.
* **Focus States:** Explicit, high-visibility 1px or 2px solid outlines (using the accent color) when navigating via the `Tab` key. Accessibility and keyboard navigation are paramount.
* **Active Elements:** Use structural indicators (like a `>` prepended to an active navigation link, or a solid left-border block) rather than changing font sizes or scaling elements up.
+592
View File
@@ -0,0 +1,592 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Homelab Gateway (Tiling Workspace)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered tile */
--border-color: #2b303b; /* Crisp 1px border */
--text-primary: #e0e6f0; /* Prose off-white */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary active accent */
--accent-green: #00e676; /* Online indicator */
--accent-amber: #ffb700; /* Warning / internal indicator */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1120px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Status Header Bar */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
/* Primary Hero Landing Tile (Main Focus of Homepage) */
.hero-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 4px;
padding: 28px 32px;
display: flex;
flex-direction: column;
gap: 16px;
}
.hero-pretitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.hero-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.2rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
line-height: 1.2;
}
.hero-landing-text {
font-size: 1.02rem;
color: var(--text-primary);
line-height: 1.7;
max-width: 80ch;
}
.hero-landing-text p {
margin-bottom: 14px;
}
.hero-landing-text p:last-child {
margin-bottom: 0;
}
.hero-directive-box {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 14px 18px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.84rem;
color: var(--text-muted);
line-height: 1.6;
}
.hero-directive-box strong {
color: var(--text-primary);
}
/* Tiling Grid Section: Split Columns */
.split-grid {
display: grid;
grid-template-columns: 1.15fr 0.85fr;
gap: 16px;
}
@media (max-width: 880px) {
.split-grid {
grid-template-columns: 1fr;
}
}
/* Tile Container Style */
.tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}
.tile-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
}
.tile-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
font-weight: 700;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 8px;
}
.tile-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
/* Featured Service Tile: The Blog */
.blog-service-feature {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px;
display: flex;
flex-direction: column;
gap: 10px;
}
.blog-feature-top {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.badge-core {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 2px 6px;
font-weight: 700;
border-radius: 2px;
}
.blog-feature-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.15rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
display: inline-block;
transition: none;
}
.blog-feature-title:hover {
color: var(--accent-cyan);
}
.blog-feature-desc {
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.5;
}
.blog-sublinks {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 4px;
border-top: 1px solid var(--border-color);
padding-top: 10px;
}
.blog-sublink-item {
display: flex;
justify-content: space-between;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--text-primary);
text-decoration: none;
padding: 4px 6px;
border-radius: 2px;
transition: none;
}
.blog-sublink-item:hover {
background-color: var(--bg-elevated);
color: var(--accent-cyan);
}
/* Homelab Services Grid */
.services-mini-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
@media (max-width: 540px) {
.services-mini-grid {
grid-template-columns: 1fr;
}
}
.service-tile-item {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 12px;
text-decoration: none;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 6px;
transition: none;
}
.service-tile-item:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.service-item-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.88rem;
font-weight: 700;
color: var(--text-primary);
}
.service-tile-item:hover .service-item-title {
color: var(--accent-cyan);
}
.service-item-tag {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: var(--text-muted);
}
.service-item-desc {
font-size: 0.8rem;
color: var(--text-muted);
line-height: 1.4;
}
/* Infrastructure Nodes Telemetry Tile */
.node-stat-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.node-name {
color: var(--text-primary);
font-weight: 700;
}
.node-load {
color: var(--accent-green);
}
/* Bottom Global Footer Tile */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Status Bar -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // NODE GATEWAY</span>
</div>
<nav class="bar-nav" aria-label="Quick Nav">
<a href="blog-lander-cards.html" class="bar-link">&gt; Blog &amp; Notes</a>
<a href="homelab.html" class="bar-link">Infrastructure</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Main Hero Landing Tile (Central Focus of Homepage) -->
<section class="hero-tile" aria-label="Homepage Mission & Landing Declaration">
<div class="hero-pretitle">SYSTEM DECLARATION &bull; RACK-01 NODE GATEWAY</div>
<h1 class="hero-main-title">Engineering Sovereign Infrastructure &amp; Technical Notes</h1>
<div class="hero-landing-text">
<p>
I am River Rooks, a cybersecurity engineering student at the University of Alabama. My work centers on network forensics, self-hosted system architecture, low-level firmware exploitation, and zero-allocation Unix utilities.
</p>
<p>
This website functions as the unified frontend for my physical homelab cluster. Rather than hosting projects on opaque third-party clouds, everything here runs on bare metal in my personal server rack—orchestrated through Proxmox VE, partitioned across isolated VLANs via OPNsense, and protected by point-to-point WireGuard cryptographic meshes.
</p>
<p>
<strong>Navigation Guide:</strong> If you are here to read technical research, the <strong>Engineering Blog</strong> is linked below with deep write-ups on firmware dumping, heap exploitation, and container routing. If you are here to use tools, the <strong>Public Services</strong> provide locally hosted instances of CyberChef, Stirling PDF, and Git.
</p>
</div>
<div class="hero-directive-box">
<strong>PRIMARY DESTINATIONS:</strong>
<span style="color: var(--accent-cyan); margin-left: 8px;">[1] Technical Blog (5 Articles)</span> &bull;
<span>[2] Forgejo Git Repos</span> &bull;
<span>[3] Public Cryptographic &amp; PDF Tools</span> &bull;
<span>[4] Cluster Telemetry</span>
</div>
</section>
<!-- Split Tiling Columns -->
<div class="split-grid">
<!-- Left Column: Featured Service (Blog) + Recent Articles -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Featured Service Tile: The Blog -->
<section class="tile" aria-label="Featured Service: Technical Blog">
<div class="tile-header">
<div class="tile-title">
<span>// PRIMARY SERVICE: THE TECHNICAL BLOG</span>
</div>
<span class="tile-meta">~/notes/ &bull; 5 ARTICLES</span>
</div>
<div class="blog-service-feature">
<div class="blog-feature-top">
<span class="badge-core">[CORE PUBLICATION SERVICE]</span>
<span style="color: var(--text-muted);">2026-07-20 LAST SYNC</span>
</div>
<a href="blog-lander-cards.html" class="blog-feature-title">&gt; River Rooks Technical Notes &amp; Research</a>
<p class="blog-feature-desc">
In-depth security post-mortems, CTF write-ups, shell portability benchmarks, and bare-metal homelab architecture guides.
</p>
<div class="blog-sublinks">
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>1. Reverse Engineering IoT Firmware (SPI Flash)</span>
<span style="color: var(--accent-cyan);">[8 min] &rarr;</span>
</a>
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>2. High-Availability Traefik with Docker Compose</span>
<span style="color: var(--accent-cyan);">[12 min] &rarr;</span>
</a>
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>3. POSIX sh vs. Bash: Portability in Modern Scripts</span>
<span style="color: var(--accent-cyan);">[6 min] &rarr;</span>
</a>
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>4. CTF Write-up: Heap Exploitation in glibc 2.35</span>
<span style="color: var(--accent-cyan);">[15 min] &rarr;</span>
</a>
</div>
</div>
</section>
</div>
<!-- Right Column: Homelab Hosted Services & Node Telemetry -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Hosted Services Tile -->
<section class="tile" aria-label="Homelab Services Directory">
<div class="tile-header">
<div class="tile-title">
<span>// HOMELAB SERVICES ROUTER</span>
</div>
<span class="tile-meta">4 PUBLIC TOOLS</span>
</div>
<div class="services-mini-grid">
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">Forgejo Git</div>
<div class="service-item-tag">git.rooks.dev:2222</div>
</div>
<p class="service-item-desc">Self-hosted code repositories &amp; dotfiles.</p>
</a>
<a href="https://chef.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">CyberChef</div>
<div class="service-item-tag">chef.rooks.dev:443</div>
</div>
<p class="service-item-desc">Hex decoding, cryptography &amp; forensics.</p>
</a>
<a href="https://pdf.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">Stirling PDF</div>
<div class="service-item-tag">pdf.rooks.dev:443</div>
</div>
<p class="service-item-desc">Private document OCR and manipulation.</p>
</a>
<a href="https://status.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">Uptime Kuma</div>
<div class="service-item-tag">status.rooks.dev:3001</div>
</div>
<p class="service-item-desc">Live synthetic latency &amp; uptime telemetry.</p>
</a>
</div>
</section>
<!-- Bare-Metal Node Telemetry Tile -->
<section class="tile" aria-label="Physical Hardware Nodes">
<div class="tile-header">
<div class="tile-title">
<span>// HARDWARE NODES (RACK-01)</span>
</div>
<span class="tile-meta">10GbE SFP+</span>
</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<div class="node-stat-row">
<div>
<span class="node-name">gw-node01.lan</span>
<span style="color: var(--text-muted); font-size: 0.72rem; margin-left: 6px;">OPNsense 24.7</span>
</div>
<span class="node-load">CPU: 18% | RAM: 32%</span>
</div>
<div class="node-stat-row">
<div>
<span class="node-name">pve-node02.lan</span>
<span style="color: var(--text-muted); font-size: 0.72rem; margin-left: 6px;">Proxmox VE (AMD 5900X)</span>
</div>
<span class="node-load">CPU: 42% | RAM: 68%</span>
</div>
<div class="node-stat-row">
<div>
<span class="node-name">nas-node03.lan</span>
<span style="color: var(--text-muted); font-size: 0.72rem; margin-left: 6px;">TrueNAS (48TB RaidZ2)</span>
</div>
<span class="node-load">CPU: 14% | RAM: 82%</span>
</div>
</div>
</section>
</div>
</div>
<!-- Global Footer Bar -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="blog-lander-cards.html" class="footer-btn">Blog Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
</body>
</html>
+10 -2
View File
@@ -250,6 +250,10 @@
<span class="tag">[#wireguard]</span>
<span class="tag">[#posix-sh]</span>
<span class="tag">[#python]</span>
<span class="tag">[#golang]</span>
<span class="tag">[#rust]</span>
<span class="tag">[#proxmox]</span>
<span class="tag">[#truenas]</span>
</div>
</section>
@@ -257,11 +261,15 @@
<!-- Piped Contact Footer -->
<footer class="footer-links">
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">GitHub</a>
<span class="pipe">|</span>
<a href="mailto:river@example.com" class="footer-link">Email</a>
<a href="mailto:river@rooks.dev" class="footer-link">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" class="footer-link">PGP Key</a>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-link">PGP Key</a>
<span class="pipe">|</span>
<a href="samples/index.html" class="footer-link">Spec Samples Catalog</a>
</footer>
</main>
File diff suppressed because it is too large Load Diff
+889
View File
@@ -0,0 +1,889 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CTF Write-up: Heap Exploitation in glibc 2.35 | River Rooks</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:ital,wght@0,400;0,500;0,700;1,400&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered surface */
--border-color: #2b303b; /* Crisp 1px border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Active accent */
--accent-green: #00e676; /* Success / online */
--accent-amber: #ffb700; /* Warning / highlight */
--accent-red: #ff5252; /* Critical alert */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.7;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1160px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Header Bar (Gateway 3 Standard) */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none;
}
.bar-link:hover {
color: var(--accent-cyan);
}
/* Article Workspace: 2-Column Split (Sidebar on Left) */
.article-workspace-grid {
display: grid;
grid-template-columns: 290px 1fr;
gap: 16px;
align-items: start;
}
@media (max-width: 960px) {
.article-workspace-grid {
grid-template-columns: 1fr;
}
}
/* Left Sidebar */
.article-sidebar {
display: flex;
flex-direction: column;
gap: 16px;
position: sticky;
top: 16px;
}
.sidebar-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 18px;
display: flex;
flex-direction: column;
gap: 12px;
}
.sidebar-heading {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
border-bottom: 1px solid var(--border-color);
padding-bottom: 8px;
display: flex;
justify-content: space-between;
align-items: center;
}
.toc-nav {
display: flex;
flex-direction: column;
gap: 4px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.toc-link {
color: var(--text-muted);
text-decoration: none;
padding: 4px 6px;
border-radius: 2px;
transition: none;
line-height: 1.4;
display: block;
}
.toc-link:hover {
background-color: var(--bg-elevated);
color: var(--accent-cyan);
}
.toc-link.active {
color: var(--accent-cyan);
background-color: var(--bg-canvas);
border-left: 2px solid var(--accent-cyan);
font-weight: 700;
}
.toc-sub {
padding-left: 14px;
color: var(--text-muted);
font-size: 0.74rem;
}
/* Collapsible Menu */
.collapsible-drawer {
border: 1px solid var(--border-color);
border-radius: 3px;
background-color: var(--bg-canvas);
overflow: hidden;
}
.collapsible-summary {
background-color: var(--bg-elevated);
padding: 8px 12px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
font-weight: 700;
color: var(--text-primary);
cursor: pointer;
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
user-select: none;
}
.collapsible-summary::-webkit-details-marker {
display: none;
}
.collapsible-summary::after {
content: "[+]";
color: var(--accent-cyan);
font-weight: 700;
}
.collapsible-drawer[open] .collapsible-summary::after {
content: "[-]";
}
.drawer-content {
padding: 10px;
display: flex;
flex-direction: column;
gap: 8px;
}
.related-card {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 2px;
padding: 8px 10px;
text-decoration: none;
display: flex;
flex-direction: column;
gap: 3px;
transition: none;
}
.related-card:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.related-date {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: var(--accent-cyan);
}
.related-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 700;
color: var(--text-primary);
line-height: 1.35;
}
.related-card:hover .related-title {
color: var(--accent-cyan);
}
/* Main Article Tile */
.article-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 36px 40px;
display: flex;
flex-direction: column;
gap: 24px;
}
@media (max-width: 600px) {
.article-tile {
padding: 24px 18px;
}
}
.article-header-block {
border-bottom: 1px solid var(--border-color);
padding-bottom: 24px;
display: flex;
flex-direction: column;
gap: 12px;
}
.article-breadcrumbs {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
display: flex;
align-items: center;
gap: 8px;
}
.article-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.3rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
line-height: 1.25;
}
@media (max-width: 768px) {
.article-main-title {
font-size: 1.8rem;
}
}
.article-meta-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 14px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--text-muted);
}
.tag-chip {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-muted);
}
/* Markdown Body */
.markdown-prose {
max-width: 68ch;
font-size: 1.02rem;
color: var(--text-primary);
line-height: 1.7;
}
.markdown-prose p {
margin-bottom: 18px;
}
.markdown-prose h2 {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.45rem;
font-weight: 700;
color: var(--text-primary);
margin: 36px 0 16px 0;
padding-bottom: 8px;
border-bottom: 1px solid var(--border-color);
}
.markdown-prose h3 {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.15rem;
font-weight: 700;
color: var(--text-primary);
margin: 28px 0 12px 0;
}
.markdown-prose code:not(pre code) {
font-family: 'JetBrains Mono', monospace;
font-size: 0.88rem;
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 2px 6px;
border-radius: 3px;
color: var(--accent-cyan);
}
/* Mathematical / Algorithm Formula Box */
.formula-card {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 3px;
padding: 14px 18px;
margin: 20px 0;
font-family: 'JetBrains Mono', monospace;
font-size: 0.88rem;
line-height: 1.6;
}
.formula-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
color: var(--text-muted);
text-transform: uppercase;
margin-bottom: 6px;
}
/* Code Block Containers */
.code-block-container {
margin: 22px 0;
border: 1px solid var(--border-color);
border-radius: 4px;
background-color: var(--bg-canvas);
overflow: hidden;
}
.code-block-header {
background-color: var(--bg-surface);
border-bottom: 1px solid var(--border-color);
padding: 6px 14px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
.copy-btn {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-muted);
padding: 2px 8px;
font-family: inherit;
font-size: 0.72rem;
cursor: pointer;
border-radius: 2px;
transition: none;
}
.copy-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.code-block-container pre {
padding: 14px 16px;
overflow-x: auto;
font-family: 'JetBrains Mono', monospace;
font-size: 0.82rem;
line-height: 1.5;
color: var(--text-primary);
}
/* GitHub-style Alerts */
.markdown-callout {
margin: 20px 0;
padding: 14px 18px;
border-radius: 3px;
border: 1px solid var(--border-color);
background-color: var(--bg-canvas);
font-size: 0.94rem;
line-height: 1.6;
}
.callout-caution {
border-left: 4px solid var(--accent-red);
}
.callout-note {
border-left: 4px solid var(--accent-cyan);
}
.callout-title {
font-family: 'IBM Plex Mono', monospace;
font-weight: 700;
font-size: 0.82rem;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.callout-caution .callout-title { color: var(--accent-red); }
.callout-note .callout-title { color: var(--accent-cyan); }
/* Tables */
.table-container {
width: 100%;
overflow-x: auto;
margin: 22px 0;
}
.markdown-table {
width: 100%;
border-collapse: collapse;
font-size: 0.84rem;
font-family: 'IBM Plex Mono', monospace;
text-align: left;
}
.markdown-table th {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 8px 12px;
color: var(--text-muted);
font-weight: 700;
}
.markdown-table td {
border: 1px solid var(--border-color);
padding: 8px 12px;
color: var(--text-primary);
}
/* Footnotes Section */
.footnotes-section {
margin-top: 36px;
padding-top: 20px;
border-top: 1px solid var(--border-color);
font-size: 0.84rem;
color: var(--text-muted);
}
.footnote-item {
margin-bottom: 8px;
}
/* Global Footer Tile (Gateway 3 Exact Match) */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Global Header Bar (Gateway 3 Standard) -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // CTF EXPLOITATION ARCHIVE</span>
</div>
<nav class="bar-nav" aria-label="Navigation">
<a href="service-gateway-tiling.html" class="bar-link">Gateway 3 ↗</a>
<a href="blog-tiling-lead.html" class="bar-link">&larr; Back to Blog Feed</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="feed.xml" class="bar-link">RSS</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Main Workspace: Sidebar TOC + Reading Canvas -->
<div class="article-workspace-grid">
<!-- Left Sidebar: Document Outline + Collapsible Series -->
<aside class="article-sidebar" aria-label="Table of Contents">
<!-- Outline Tile -->
<div class="sidebar-tile">
<div class="sidebar-heading">
<span>DOCUMENT OUTLINE</span>
<span style="color: var(--accent-cyan);">INDEX</span>
</div>
<nav class="toc-nav" aria-label="Table of Contents">
<a href="#challenge-intro" class="toc-link active">&gt; 1.0 Challenge Synopsis</a>
<a href="#safe-linking" class="toc-link">&gt; 2.0 Safe-Linking Pointer Mangling</a>
<a href="#mangling-math" class="toc-link toc-sub">2.1 Mathematical Derivation</a>
<a href="#gdb-session" class="toc-link">&gt; 3.0 GDB Memory Inspection</a>
<a href="#house-of-apple" class="toc-link">&gt; 4.0 House of Apple Hijacking</a>
<a href="#mitigation-matrix" class="toc-link">&gt; 5.0 Mitigation History</a>
<a href="#footnotes" class="toc-link">&gt; 6.0 References &amp; Notes</a>
</nav>
</div>
<!-- Collapsible Related Dispatches Tile -->
<div class="sidebar-tile">
<div class="sidebar-heading">
<span>SECURITY REPOSITORY</span>
<span>DRAWER</span>
</div>
<details class="collapsible-drawer" open>
<summary class="collapsible-summary">
<span>Security Dispatches (3)</span>
</summary>
<div class="drawer-content">
<a href="article-tiling-firmware.html" class="related-card">
<span class="related-date">2026-07-20 &bull; 8 min</span>
<span class="related-title">Reverse Engineering IoT Firmware: SPI Flash</span>
<span style="color: var(--text-muted); font-size: 0.7rem;">[#firmware] [#hardware]</span>
</a>
<a href="article-tiling-traefik.html" class="related-card">
<span class="related-date">2026-07-15 &bull; 12 min</span>
<span class="related-title">High-Availability Traefik Router with Docker</span>
<span style="color: var(--text-muted); font-size: 0.7rem;">[#homelab] [#networking]</span>
</a>
<a href="blog-tiling-lead.html" class="related-card">
<span class="related-date">2026-07-10 &bull; 6 min</span>
<span class="related-title">POSIX sh vs. Bash: Portability in Modern Scripts</span>
<span style="color: var(--text-muted); font-size: 0.7rem;">[#posix-sh] [#unix]</span>
</a>
</div>
</details>
</div>
<!-- Target Binary Info Tile -->
<div class="sidebar-tile" style="font-family: 'IBM Plex Mono', monospace; font-size: 0.76rem; color: var(--text-muted);">
<div style="display: flex; justify-content: space-between; margin-bottom: 6px;">
<span>ALLOCATOR:</span>
<span style="color: var(--accent-cyan); font-weight: 700;">GLIBC 2.35-0UBUNTU3</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 6px;">
<span>EXPLOIT PRIMITIVE:</span>
<span style="color: var(--accent-amber); font-weight: 700;">TCACHE POISONING</span>
</div>
<div style="display: flex; justify-content: space-between;">
<span>TARGET HOOK:</span>
<span style="color: var(--accent-green);">_IO_FILE VTABLE</span>
</div>
</div>
</aside>
<!-- Center Article Tile -->
<article class="article-tile">
<!-- Article Header Block -->
<header class="article-header-block">
<div class="article-breadcrumbs">
<span>~/notes/</span>
<span>&gt;</span>
<span style="color: var(--accent-cyan);">ctf-heap-glibc-2-35.md</span>
</div>
<h1 class="article-main-title">CTF Write-up: Heap Exploitation in glibc 2.35</h1>
<div class="article-meta-row">
<div><span style="color: var(--accent-cyan);">2026-06-28</span></div>
<span>&bull;</span>
<div><span>15 MIN READ</span></div>
<span>&bull;</span>
<div><span>AUTHOR: RIVER ROOKS</span></div>
<span>&bull;</span>
<div>
<span class="tag-chip">[#ctf]</span>
<span class="tag-chip">[#binary-exploitation]</span>
<span class="tag-chip">[#security]</span>
<span class="tag-chip">[#glibc]</span>
</div>
</div>
</header>
<!-- Markdown Prose Content -->
<div class="markdown-prose">
<h2 id="challenge-intro">1.0 Challenge Synopsis</h2>
<p>
During the DEFCON qualifier challenges, our team encountered a hardened 64-bit Linux binary linked against <code>glibc 2.35</code>. Standard legacy heap exploitation techniques—such as poisoning <code>__malloc_hook</code> or <code>__free_hook</code>—are rendered obsolete because upstream glibc maintainers removed all allocation hook pointer symbols entirely in version 2.34.
</p>
<p>
This write-up covers breaking modern <strong>tcache safe-linking pointer mangling</strong> and redirecting execution control flow using the <strong>House of Apple 2</strong> technique against the wide character vtable pointers inside <code>_IO_FILE</code> structures.
</p>
<h2 id="safe-linking">2.0 Safe-Linking Pointer Mangling</h2>
<p>
Introduced in glibc 2.32, safe-linking protects single-linked singly linked list pointers (such as entries inside the Thread Local Cache <code>tcache</code> and fastbins) against off-by-one overwrites and UAF corruption.
</p>
<h3 id="mangling-math">2.1 Mathematical Derivation</h3>
<!-- Formula Callout Box Showcase -->
<div class="formula-card">
<div class="formula-title">POINTER MANGLING FORMULA</div>
<div>Mangled_Pointer (P') = (Address_of_Chunk &gt;&gt; 12) ^ Target_Pointer (P)</div>
</div>
<p>
Since the lowest 12 bits of <code>Address_of_Chunk &gt;&gt; 12</code> are randomized by ASLR, overwriting <code>P'</code> directly without an address leak causes the kernel to dereference invalid virtual memory pages, aborting with <code>SIGSEGV</code>.
</p>
<p>
However, when an arbitrary read primitive leaks the mangled value of the terminal chunk in the tcache bin (where <code>Target_Pointer = NULL</code>), the equation simplifies:
</p>
<div class="formula-card">
<div>Leaked_Mangled = (Chunk_Addr &gt;&gt; 12) ^ 0x0 ==&gt; ASLR_Key = Leaked_Mangled</div>
</div>
<!-- Alert Callout Showcase -->
<div class="markdown-callout callout-caution">
<div class="callout-title">[!CAUTION] Pointer Alignment Constraints</div>
<p>
In glibc 2.35, chunks inserted into tcache bins must also adhere to strict 16-byte address alignment. Forging a fake chunk unaligned to a 16-byte boundary triggers <code>malloc(): unaligned tcache chunk detected</code> aborts.
</p>
</div>
<h2 id="gdb-session">3.0 GDB Memory Inspection</h2>
<p>
Attaching GDB with the <code>pwndbg</code> extension confirms the tcache bin layout and reveals the mangled pointer representation in memory:
</p>
<!-- Code Block Showcase -->
<div class="code-block-container">
<div class="code-block-header">
<div class="code-title">
<span>gdb-pwndbg stdout: heap inspection</span>
<span>GDB</span>
</div>
<button class="copy-btn" onclick="copySnippet(this)">Copy GDB</button>
</div>
<pre><code>pwndbg> tcachebins
tcachebins
0x40 [ 2]: 0x55555555a2a0 &rarr; 0x55555555a260
pwndbg> x/4gx 0x55555555a2a0
0x55555555a2a0: 0x0000555555550730 0x0000000000000000
0x55555555a2b0: 0x0000000000000000 0x0000000000000041
pwndbg> tele 0x55555555a2a0
00:0000 &boxv; 0x55555555a2a0 &rarr; 0x555555550730 (MANGLED POINTER: 0x55555555a260 ^ (0x55555555a >> 12))</code></pre>
</div>
<h2 id="house-of-apple">4.0 House of Apple Hijacking</h2>
<p>
With the ability to allocate chunks onto arbitrary memory addresses via tcache poisoning, we target <code>_IO_list_all</code>. When <code>exit()</code> or <code>abort()</code> is invoked by the runtime, the glibc standard I/O cleanup routine iterates through the <code>_IO_FILE</code> linked list and invokes <code>_IO_wfile_overflow()</code>:
</p>
<!-- C Exploit Snippet Showcase -->
<div class="code-block-container">
<div class="code-block-header">
<div class="code-title">
<span>house_of_apple_payload.c</span>
<span>C99</span>
</div>
<button class="copy-btn" onclick="copySnippet(this)">Copy C Code</button>
</div>
<pre><code>// Constructing fake _IO_FILE_plus structure
struct _IO_FILE_plus *fake_file = (struct _IO_FILE_plus *)payload;
fake_file->file._flags = 0x6873; // "sh" in ASCII
fake_file->file._mode = 1; // Force wide character stream mode
fake_file->vtable = (const struct _IO_jump_t *)wide_vtable_addr;
// Trigger call to system("/bin/sh") on stream flush
fake_file->file._wide_data->_wide_vtable->doallocate = (void *)system_addr;</code></pre>
</div>
<h2 id="mitigation-matrix">5.0 Glibc Heap Mitigation History</h2>
<p>
Tracking defensive hardening milestones across recent glibc releases:
</p>
<!-- Table Showcase -->
<div class="table-container">
<table class="markdown-table">
<thead>
<tr>
<th>glibc Version</th>
<th>Defensive Mitigation Added</th>
<th>Status</th>
<th>Impact on Attackers</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>2.26</code></td>
<td>Thread Cache (tcache) introduced</td>
<td>Active</td>
<td>Initially lacked double-free and count sanity checks.</td>
</tr>
<tr>
<td><code>2.29</code></td>
<td>tcache double-free check (key field)</td>
<td>Active</td>
<td>Stores pointer to tcache struct in chunk data.</td>
</tr>
<tr>
<td><code>2.32</code></td>
<td>Safe-Linking Pointer Mangling</td>
<td>Hardened</td>
<td>Requires ASLR heap base leak to forge pointers.</td>
</tr>
<tr>
<td><code>2.34</code></td>
<td>Removal of <code>__malloc_hook</code> / <code>__free_hook</code></td>
<td>Enforced</td>
<td>Forces targeting of <code>_IO_FILE</code> and stack frames.</td>
</tr>
<tr>
<td><code>2.35</code></td>
<td>Alignment verification on tcache chunks</td>
<td>Enforced</td>
<td>Eliminates misaligned chunk allocations entirely.</td>
</tr>
</tbody>
</table>
</div>
<!-- Footnotes Section Showcase -->
<div class="footnotes-section" id="footnotes">
<div class="footnote-item">
<sup>[1]</sup> Safe-Linking was first proposed by Eyal Itkin for memory allocators in modern operating systems.
</div>
<div class="footnote-item">
<sup>[2]</sup> House of Apple exploitation methodology authored by roderickchan, targeting wide character I/O functions.
</div>
</div>
</div>
</article>
</div>
<!-- Global Footer Tile (Gateway 3 Exact Match) -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="service-gateway-tiling.html" class="footer-btn">Gateway Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
function copySnippet(btn) {
const code = btn.closest('.code-block-container').querySelector('pre').innerText;
navigator.clipboard.writeText(code).then(() => {
const orig = btn.innerText;
btn.innerText = 'Copied!';
btn.style.color = 'var(--accent-green)';
btn.style.borderColor = 'var(--accent-green)';
setTimeout(() => {
btn.innerText = orig;
btn.style.color = '';
btn.style.borderColor = '';
}, 1800);
});
}
// ScrollSpy for TOC
window.addEventListener('DOMContentLoaded', () => {
const links = document.querySelectorAll('.toc-link');
const sections = [];
links.forEach(link => {
const targetId = link.getAttribute('href').substring(1);
const section = document.getElementById(targetId);
if (section) sections.push({ link, section });
});
window.addEventListener('scroll', () => {
const scrollPos = window.scrollY + 100;
for (let i = sections.length - 1; i >= 0; i--) {
if (sections[i].section.offsetTop <= scrollPos) {
links.forEach(l => l.classList.remove('active'));
sections[i].link.classList.add('active');
break;
}
}
});
});
</script>
</body>
</html>
+887
View File
@@ -0,0 +1,887 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Building a High-Availability Traefik Router with Docker Compose | River Rooks</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:ital,wght@0,400;0,500;0,700;1,400&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered surface */
--border-color: #2b303b; /* Crisp 1px border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Active accent */
--accent-green: #00e676; /* Success / online */
--accent-amber: #ffb700; /* Warning / highlight */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.7;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1160px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Header Bar (Gateway 3 Standard) */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
/* Right Sidebar Reading Workspace Grid: Content (Left) + Sidebar (Right) */
.article-workspace-grid {
display: grid;
grid-template-columns: 1fr 290px;
gap: 16px;
align-items: start;
}
@media (max-width: 960px) {
.article-workspace-grid {
grid-template-columns: 1fr;
}
.article-sidebar {
order: -1; /* Display TOC on top on mobile viewports */
}
}
/* Article Content Container Tile */
.article-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 36px 40px;
display: flex;
flex-direction: column;
gap: 24px;
}
@media (max-width: 600px) {
.article-tile {
padding: 24px 18px;
}
}
.article-header-block {
border-bottom: 1px solid var(--border-color);
padding-bottom: 24px;
display: flex;
flex-direction: column;
gap: 12px;
}
.article-breadcrumbs {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
display: flex;
align-items: center;
gap: 8px;
}
.article-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.3rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
line-height: 1.25;
}
@media (max-width: 768px) {
.article-main-title {
font-size: 1.8rem;
}
}
.article-meta-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 14px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--text-muted);
}
.tag-chip {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-muted);
}
/* Right Sidebar Components */
.article-sidebar {
display: flex;
flex-direction: column;
gap: 16px;
position: sticky;
top: 16px;
}
.sidebar-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 18px;
display: flex;
flex-direction: column;
gap: 12px;
}
.sidebar-heading {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
border-bottom: 1px solid var(--border-color);
padding-bottom: 8px;
display: flex;
justify-content: space-between;
align-items: center;
}
.toc-nav {
display: flex;
flex-direction: column;
gap: 4px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.toc-link {
color: var(--text-muted);
text-decoration: none;
padding: 4px 6px;
border-radius: 2px;
transition: none;
line-height: 1.4;
display: block;
}
.toc-link:hover {
background-color: var(--bg-elevated);
color: var(--accent-cyan);
}
.toc-link.active {
color: var(--accent-cyan);
background-color: var(--bg-canvas);
border-left: 2px solid var(--accent-cyan);
font-weight: 700;
}
.toc-sub {
padding-left: 14px;
color: var(--text-muted);
font-size: 0.74rem;
}
/* Collapsible Menu */
.collapsible-drawer {
border: 1px solid var(--border-color);
border-radius: 3px;
background-color: var(--bg-canvas);
overflow: hidden;
}
.collapsible-summary {
background-color: var(--bg-elevated);
padding: 8px 12px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
font-weight: 700;
color: var(--text-primary);
cursor: pointer;
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
user-select: none;
}
.collapsible-summary::-webkit-details-marker {
display: none;
}
.collapsible-summary::after {
content: "[+]";
color: var(--accent-cyan);
font-weight: 700;
}
.collapsible-drawer[open] .collapsible-summary::after {
content: "[-]";
}
.drawer-content {
padding: 10px;
display: flex;
flex-direction: column;
gap: 8px;
}
.related-card {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 2px;
padding: 8px 10px;
text-decoration: none;
display: flex;
flex-direction: column;
gap: 3px;
transition: none;
}
.related-card:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.related-date {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: var(--accent-cyan);
}
.related-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 700;
color: var(--text-primary);
line-height: 1.35;
}
.related-card:hover .related-title {
color: var(--accent-cyan);
}
/* Markdown Prose Elements */
.markdown-prose {
max-width: 68ch;
font-size: 1.02rem;
color: var(--text-primary);
line-height: 1.7;
}
.markdown-prose p {
margin-bottom: 18px;
}
.markdown-prose h2 {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.45rem;
font-weight: 700;
color: var(--text-primary);
margin: 36px 0 16px 0;
padding-bottom: 8px;
border-bottom: 1px solid var(--border-color);
}
.markdown-prose h3 {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.15rem;
font-weight: 700;
color: var(--text-primary);
margin: 28px 0 12px 0;
}
.markdown-prose code:not(pre code) {
font-family: 'JetBrains Mono', monospace;
font-size: 0.88rem;
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 2px 6px;
border-radius: 3px;
color: var(--accent-cyan);
}
/* ASCII Network Diagram Component */
.ascii-diagram-container {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 16px;
margin: 22px 0;
overflow-x: auto;
font-family: 'JetBrains Mono', monospace;
font-size: 0.78rem;
color: var(--accent-cyan);
line-height: 1.35;
}
/* Code Block Component */
.code-block-container {
margin: 22px 0;
border: 1px solid var(--border-color);
border-radius: 4px;
background-color: var(--bg-canvas);
overflow: hidden;
}
.code-block-header {
background-color: var(--bg-surface);
border-bottom: 1px solid var(--border-color);
padding: 6px 14px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
.copy-btn {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-muted);
padding: 2px 8px;
font-family: inherit;
font-size: 0.72rem;
cursor: pointer;
border-radius: 2px;
transition: none;
}
.copy-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.code-block-container pre {
padding: 14px 16px;
overflow-x: auto;
font-family: 'JetBrains Mono', monospace;
font-size: 0.82rem;
line-height: 1.5;
color: var(--text-primary);
}
/* Callout Boxes */
.markdown-callout {
margin: 20px 0;
padding: 14px 18px;
border-radius: 3px;
border: 1px solid var(--border-color);
background-color: var(--bg-canvas);
font-size: 0.94rem;
line-height: 1.6;
}
.callout-note {
border-left: 4px solid var(--accent-cyan);
}
.callout-tip {
border-left: 4px solid var(--accent-green);
}
.callout-title {
font-family: 'IBM Plex Mono', monospace;
font-weight: 700;
font-size: 0.82rem;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.callout-note .callout-title { color: var(--accent-cyan); }
.callout-tip .callout-title { color: var(--accent-green); }
/* Tables */
.table-container {
width: 100%;
overflow-x: auto;
margin: 22px 0;
}
.markdown-table {
width: 100%;
border-collapse: collapse;
font-size: 0.84rem;
font-family: 'IBM Plex Mono', monospace;
text-align: left;
}
.markdown-table th {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 8px 12px;
color: var(--text-muted);
font-weight: 700;
}
.markdown-table td {
border: 1px solid var(--border-color);
padding: 8px 12px;
color: var(--text-primary);
}
/* Global Footer Tile (Gateway 3 Exact Match) */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Global Header Bar (Gateway 3 Standard) -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // INFRASTRUCTURE ARCHIVE</span>
</div>
<nav class="bar-nav" aria-label="Navigation">
<a href="service-gateway-tiling.html" class="bar-link">Gateway 3 ↗</a>
<a href="blog-tiling-lead.html" class="bar-link">&larr; Back to Blog Feed</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="feed.xml" class="bar-link">RSS</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Right Sidebar Workspace Grid -->
<div class="article-workspace-grid">
<!-- Center / Left: Article Content -->
<article class="article-tile">
<!-- Article Header Block -->
<header class="article-header-block">
<div class="article-breadcrumbs">
<span>~/notes/</span>
<span>&gt;</span>
<span style="color: var(--accent-cyan);">ha-traefik-docker.md</span>
</div>
<h1 class="article-main-title">Building a High-Availability Traefik Router with Docker Compose</h1>
<div class="article-meta-row">
<div><span style="color: var(--accent-cyan);">2026-07-15</span></div>
<span>&bull;</span>
<div><span>12 MIN READ</span></div>
<span>&bull;</span>
<div><span>AUTHOR: RIVER ROOKS</span></div>
<span>&bull;</span>
<div>
<span class="tag-chip">[#homelab]</span>
<span class="tag-chip">[#docker-traefik]</span>
<span class="tag-chip">[#networking]</span>
</div>
</div>
</header>
<!-- Markdown Prose Body -->
<div class="markdown-prose">
<h2 id="architecture">1.0 Ingress Architecture &amp; Topologies</h2>
<p>
When running multi-tier web applications across self-hosted bare-metal clusters, an edge reverse proxy is indispensable. Managing static Nginx reverse proxy virtual host configs by hand becomes unmaintainable once container fleets scale past twenty services.
</p>
<p>
Traefik v3.1 solves this by inspecting the Docker socket daemon directly. When a new container is deployed, Traefik dynamically binds routing rules, attaches middlewares, and provisions automated wildcard TLS certificates without restarting the daemon.
</p>
<!-- ASCII Architecture Diagram Showcase -->
<div class="ascii-diagram-container">
<pre>+-------------------------------------------------------------------------+
| [INTERNET / WAN INGRESS] ==> Cloudflare DNS (DNS-01 ACME Challenge) |
+-------------------------------------------------------------------------+
||
\/
+-------------------------------------------------------------------------+
| gw-node01.lan (OPNsense 24.7 Gateway / NAT Port 443 Forwarding) |
+-------------------------------------------------------------------------+
||
\/ 10GbE VLAN 20 (Server DMZ)
+-------------------------------------------------------------------------+
| pve-node02.lan :: Traefik v3.1 Reverse Proxy Container (:443/:80) |
+-------------------------------------------------------------------------+
|| || ||
\/ (Docker Internal) \/ (Docker Internal) \/ (WireGuard)
+--------------------+ +--------------------+ +--------------------+
| Forgejo Git Server | | CyberChef Security | | Uptime Kuma Status |
+--------------------+ +--------------------+ +--------------------+
</pre>
</div>
<h2 id="dns-challenge">2.0 Automated DNS-01 ACME with Cloudflare</h2>
<p>
Standard HTTP-01 challenges require opening port <code>80/tcp</code> publicly to the internet, exposing unauthenticated ingress surfaces. By employing the <strong>DNS-01 challenge</strong>, Traefik proves domain ownership by creating temporary <code>_acme-challenge.rooks.dev</code> TXT records through the Cloudflare API.
</p>
<!-- Callout Showcase -->
<div class="markdown-callout callout-tip">
<div class="callout-title">[!TIP] Principle of Least Privilege</div>
<p>
Do not use your Global Cloudflare API Key. Instead, generate a scoped API Token with permissions restricted strictly to: <code>Zone.Zone:Read</code> and <code>Zone.DNS:Edit</code> scoped exclusively to your primary apex zone.
</p>
</div>
<h2 id="compose-spec">3.0 Complete Docker Compose Specification</h2>
<p>
Below is the production-tested <code>compose.yaml</code> definition. It mounts the Docker socket in read-only mode (<code>:ro</code>) and stores ACME certificate state inside an encrypted <code>acme.json</code> file with strict <code>0600</code> permissions:
</p>
<!-- Code Block Showcase -->
<div class="code-block-container">
<div class="code-block-header">
<div class="code-title">
<span>docker-compose.traefik.yml</span>
<span>YAML</span>
</div>
<button class="copy-btn" onclick="copySnippet(this)">Copy Compose</button>
</div>
<pre><code>services:
traefik:
image: traefik:v3.1.2
container_name: edge-traefik-proxy
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy-tier
ports:
- "80:80"
- "443:443"
environment:
- CF_DNS_API_TOKEN_FILE=/run/secrets/cf_token
secrets:
- cf_token
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/etc/traefik/traefik.yml:ro
- ./data/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`proxy.rooks.dev`)"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls.certresolver=cloudflare"
- "traefik.http.routers.api.service=api@internal"
secrets:
cf_token:
file: ./secrets/cloudflare_api_token.txt
networks:
proxy-tier:
external: true</code></pre>
</div>
<h2 id="configuration-matrix">4.0 Configuration Parameters Matrix</h2>
<p>
Key parameters governing the Traefik core engine:
</p>
<!-- Markdown Table Showcase -->
<div class="table-container">
<table class="markdown-table">
<thead>
<tr>
<th>Directive Parameter</th>
<th>Value</th>
<th>Scope</th>
<th>Behavior Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>providers.docker.exposedbydefault</code></td>
<td><code>false</code></td>
<td>Core Security</td>
<td>Prevents untagged backend containers from being routed.</td>
</tr>
<tr>
<td><code>entrypoints.web.http.redirections</code></td>
<td><code>to: websecure</code></td>
<td>HTTP &rarr; HTTPS</td>
<td>Enforces automatic HTTP 301 redirects to port 443.</td>
</tr>
<tr>
<td><code>certificatesresolvers.cf.acme.dnschallenge</code></td>
<td><code>cloudflare</code></td>
<td>Let's Encrypt</td>
<td>Uses Cloudflare DNS provider for wildcard propagation.</td>
</tr>
<tr>
<td><code>certificatesresolvers.cf.acme.storage</code></td>
<td><code>/acme.json</code></td>
<td>Persistent Storage</td>
<td>Encrypted JSON database for RSA/ECDSA key pairs.</td>
</tr>
</tbody>
</table>
</div>
<h2 id="verification">5.0 Verification &amp; Failover Testing</h2>
<p>
Verify TLS certificate issuance and HTTP/3 ALPN negotiation directly via <code>curl</code>:
</p>
<div class="code-block-container">
<div class="code-block-header">
<div class="code-title">
<span>terminal stdout: curl -Iv</span>
<span>Bash</span>
</div>
<button class="copy-btn" onclick="copySnippet(this)">Copy Output</button>
</div>
<pre><code>$ curl -Iv https://proxy.rooks.dev
* Server certificate:
* subject: CN=*.rooks.dev
* start date: Jul 15 00:00:00 2026 GMT
* expire date: Oct 13 23:59:59 2026 GMT
* issuer: C=US, O=Let's Encrypt, CN=R3
* SSL certificate verify ok.
&lt; HTTP/2 200 OK
&lt; server: traefik
&lt; strict-transport-security: max-age=63072000; includeSubDomains; preload</code></pre>
</div>
<p>
Zero downtime updates are achieved through rolling container health checks configured inside Traefik dynamic labels.
</p>
</div>
</article>
<!-- Right Sidebar: TOC & Collapsible Related Articles -->
<aside class="article-sidebar" aria-label="Table of Contents and Series">
<!-- Document Outline Tile -->
<div class="sidebar-tile">
<div class="sidebar-heading">
<span>DOCUMENT OUTLINE</span>
<span style="color: var(--accent-cyan);">INDEX</span>
</div>
<nav class="toc-nav" aria-label="Table of Contents">
<a href="#architecture" class="toc-link active">&gt; 1.0 Ingress Architecture</a>
<a href="#dns-challenge" class="toc-link">&gt; 2.0 DNS-01 ACME Setup</a>
<a href="#compose-spec" class="toc-link">&gt; 3.0 Compose Specification</a>
<a href="#configuration-matrix" class="toc-link">&gt; 4.0 Configuration Matrix</a>
<a href="#verification" class="toc-link">&gt; 5.0 Verification &amp; Testing</a>
</nav>
</div>
<!-- Collapsible Related Dispatches Tile -->
<div class="sidebar-tile">
<div class="sidebar-heading">
<span>RELATED DISPATCHES</span>
<span>DRAWER</span>
</div>
<details class="collapsible-drawer" open>
<summary class="collapsible-summary">
<span>Homelab Series (3)</span>
</summary>
<div class="drawer-content">
<a href="article-tiling-firmware.html" class="related-card">
<span class="related-date">2026-07-20 &bull; 8 min</span>
<span class="related-title">Reverse Engineering IoT Firmware: SPI Flash</span>
<span style="color: var(--text-muted); font-size: 0.7rem;">[#firmware] [#hardware]</span>
</a>
<a href="article-tiling-heap.html" class="related-card">
<span class="related-date">2026-06-28 &bull; 15 min</span>
<span class="related-title">CTF Write-up: Heap Exploitation in glibc 2.35</span>
<span style="color: var(--text-muted); font-size: 0.7rem;">[#ctf] [#security]</span>
</a>
<a href="blog-tiling-lead.html" class="related-card">
<span class="related-date">2026-06-14 &bull; 10 min</span>
<span class="related-title">Zero-Trust Network Isolation with WireGuard</span>
<span style="color: var(--text-muted); font-size: 0.7rem;">[#networking] [#wireguard]</span>
</a>
</div>
</details>
</div>
<!-- Runtime Metadata Tile -->
<div class="sidebar-tile" style="font-family: 'IBM Plex Mono', monospace; font-size: 0.76rem; color: var(--text-muted);">
<div style="display: flex; justify-content: space-between; margin-bottom: 6px;">
<span>TRAEFIK ENGINE:</span>
<span style="color: var(--accent-cyan); font-weight: 700;">v3.1.2 DOCKER</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 6px;">
<span>CERT PROVIDER:</span>
<span style="color: var(--accent-green); font-weight: 700;">ACME DNS-01</span>
</div>
<div style="display: flex; justify-content: space-between;">
<span>NODE TARGET:</span>
<span style="color: var(--text-primary);">pve-node02.lan</span>
</div>
</div>
</aside>
</div>
<!-- Global Footer Tile (Gateway 3 Exact Match) -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="service-gateway-tiling.html" class="footer-btn">Gateway Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
function copySnippet(btn) {
const code = btn.closest('.code-block-container').querySelector('pre').innerText;
navigator.clipboard.writeText(code).then(() => {
const orig = btn.innerText;
btn.innerText = 'Copied!';
btn.style.color = 'var(--accent-green)';
btn.style.borderColor = 'var(--accent-green)';
setTimeout(() => {
btn.innerText = orig;
btn.style.color = '';
btn.style.borderColor = '';
}, 1800);
});
}
// ScrollSpy for Right TOC
window.addEventListener('DOMContentLoaded', () => {
const links = document.querySelectorAll('.toc-link');
const sections = [];
links.forEach(link => {
const targetId = link.getAttribute('href').substring(1);
const section = document.getElementById(targetId);
if (section) sections.push({ link, section });
});
window.addEventListener('scroll', () => {
const scrollPos = window.scrollY + 100;
for (let i = sections.length - 1; i >= 0; i--) {
if (sections[i].section.offsetTop <= scrollPos) {
links.forEach(l => l.classList.remove('active'));
sections[i].link.classList.add('active');
break;
}
}
});
});
</script>
</body>
</html>
+629
View File
@@ -0,0 +1,629 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Field Notes &amp; Dispatches (Cards Lander)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Card background surface */
--bg-elevated: #1c1f26; /* Hovered card surface */
--border-color: #2b303b; /* Low-contrast 1px border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary terminal accent */
--accent-green: #00e676; /* Operational status indicator */
--accent-amber: #ffb700; /* Pinned badge accent */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.65;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 0 64px 0;
}
/* Top Sticky Header */
.top-navbar {
width: 100%;
background-color: var(--bg-canvas);
border-bottom: 1px solid var(--border-color);
position: sticky;
top: 0;
z-index: 100;
padding: 12px 24px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
}
.nav-brand {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
text-decoration: none;
font-weight: 700;
}
.status-dot {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.nav-links {
display: flex;
gap: 14px;
align-items: center;
}
.nav-item {
color: var(--text-muted);
text-decoration: none;
padding: 3px 6px;
transition: none; /* Instant snap */
}
.nav-item:hover {
color: var(--accent-cyan);
}
.nav-item.active {
color: var(--text-primary);
border-bottom: 1px solid var(--accent-cyan);
}
/* Page Container */
.page-container {
width: 100%;
max-width: 960px;
padding: 40px 20px 0 20px;
}
/* Hero Identity Header */
.hero-header {
margin-bottom: 36px;
padding-bottom: 24px;
border-bottom: 1px solid var(--border-color);
}
.hero-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.2rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
margin-bottom: 6px;
}
.hero-subtitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
color: var(--accent-cyan);
margin-bottom: 14px;
}
.hero-bio {
font-size: 0.98rem;
color: var(--text-primary);
max-width: 70ch;
margin-bottom: 18px;
}
.stack-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
}
.stack-tag {
color: var(--text-muted);
}
/* Featured Lead Card */
.featured-section {
margin-bottom: 44px;
}
.section-label {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.featured-card {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 24px;
display: flex;
flex-direction: column;
gap: 16px;
position: relative;
}
.featured-card:hover {
border-color: var(--accent-cyan);
}
.featured-badge-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
flex-wrap: wrap;
gap: 8px;
}
.badge-pinned {
color: var(--accent-amber);
font-weight: 700;
}
.featured-date {
color: var(--text-muted);
}
.featured-title-link {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.45rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.3;
transition: none;
}
.featured-title-link:hover {
color: var(--accent-cyan);
}
.featured-title-link:focus {
outline: 2px solid var(--accent-cyan);
}
.featured-abstract {
font-size: 0.95rem;
color: var(--text-primary);
line-height: 1.6;
}
/* Code Snippet in Lead Card */
.code-wrapper {
border: 1px solid var(--border-color);
border-radius: 3px;
background-color: var(--bg-canvas);
overflow: hidden;
font-family: 'JetBrains Mono', monospace;
}
.code-header {
background-color: var(--bg-surface);
border-bottom: 1px solid var(--border-color);
padding: 6px 12px;
font-size: 0.75rem;
color: var(--text-muted);
display: flex;
justify-content: space-between;
}
.code-body {
padding: 12px;
font-size: 0.8rem;
overflow-x: auto;
color: var(--text-primary);
}
.featured-footer {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
padding-top: 8px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
}
.cta-button {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 6px 14px;
font-family: 'IBM Plex Mono', monospace;
font-weight: 700;
font-size: 0.82rem;
text-decoration: none;
border-radius: 2px;
border: 1px solid var(--accent-cyan);
transition: none; /* Instant snap */
}
.cta-button:hover {
background-color: transparent;
color: var(--accent-cyan);
}
.cta-button:focus {
outline: 2px solid var(--accent-cyan);
}
/* Recent Dispatches Grid */
.cards-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-bottom: 48px;
}
@media (max-width: 720px) {
.cards-grid {
grid-template-columns: 1fr;
}
}
.dispatch-card {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 12px;
transition: none;
}
.dispatch-card:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.card-meta-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.75rem;
color: var(--text-muted);
}
.card-date {
color: var(--accent-cyan);
}
.card-heading-link {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.05rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
transition: none;
}
.dispatch-card:hover .card-heading-link {
color: var(--accent-cyan);
}
.card-heading-link:focus {
outline: 2px solid var(--accent-cyan);
}
.card-summary {
font-size: 0.88rem;
color: var(--text-primary);
line-height: 1.55;
}
.card-bottom-row {
display: flex;
justify-content: space-between;
align-items: baseline;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
padding-top: 10px;
border-top: 1px solid var(--border-color);
flex-wrap: wrap;
gap: 6px;
}
.card-tag-cluster {
display: flex;
flex-wrap: wrap;
gap: 6px;
color: var(--text-muted);
}
.read-more-link {
color: var(--accent-cyan);
text-decoration: none;
font-weight: 500;
}
.read-more-link:hover {
text-decoration: underline;
}
/* Bottom Site Footer */
.site-footer {
border-top: 1px solid var(--border-color);
padding-top: 24px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--text-muted);
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
}
.footer-links {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.footer-link {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-link:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.footer-link:focus {
outline: 2px solid var(--accent-cyan);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<!-- Sticky Top Navigation -->
<header class="top-navbar">
<a href="#" class="nav-brand">
<span class="status-dot"></span>
<span>ROOKS.DEV // NOTES</span>
</a>
<nav class="nav-links" aria-label="Site Navigation">
<a href="#" class="nav-item active">[Dispatches]</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="nav-item">Git</a>
<a href="feed.xml" class="nav-item">RSS</a>
<a href="index.html" class="nav-item">Catalog ↗</a>
</nav>
</header>
<main class="page-container">
<!-- Hero Identity Block -->
<section class="hero-header" aria-label="Author Profile">
<h1 class="hero-title">River Rooks</h1>
<div class="hero-subtitle">SYSTEMS ARCHITECTURE &amp; CYBERSECURITY • ALABAMA, USA</div>
<p class="hero-bio">
Cybersecurity student at the University of Alabama College of Engineering. Architecting high-throughput homelab networks, reverse engineering IoT firmware, and writing zero-allocation Unix utilities.
</p>
<div class="stack-tags">
<span class="stack-tag">[#network-forensics]</span>
<span class="stack-tag">[#docker-traefik]</span>
<span class="stack-tag">[#arch-linux]</span>
<span class="stack-tag">[#neovim]</span>
<span class="stack-tag">[#wireguard]</span>
<span class="stack-tag">[#posix-sh]</span>
<span class="stack-tag">[#python]</span>
<span class="stack-tag">[#rust]</span>
</div>
</section>
<!-- Featured Lead Story -->
<section class="featured-section" aria-label="Featured Technical Article">
<div class="section-label">
<span>// Pinned Technical Write-Up</span>
</div>
<article class="featured-card">
<div class="featured-badge-row">
<span class="badge-pinned">[PINNED WRITE-UP]</span>
<span class="featured-date">2026-07-20 • 8 min read</span>
</div>
<h2 class="featured-title">
<a href="#" class="featured-title-link">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</h2>
<p class="featured-abstract">
In security audits of embedded systems, retrieving the firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.
</p>
<!-- Code Snippet -->
<div class="code-wrapper">
<div class="code-header">
<span>extract_firmware.sh</span>
<span>POSIX sh</span>
</div>
<div class="code-body">
<pre><code># Query the SPI flash details using flashrom via Bus Pirate
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
# Verify the integrity of the binary dump by comparing hashes
if [ $? -eq 0 ]; then
echo "Dump successful. Running md5sum..."
md5sum firmware_dump.bin
fi</code></pre>
</div>
</div>
<div class="featured-footer">
<div class="stack-tags">
<span class="stack-tag">[#firmware]</span>
<span class="stack-tag">[#hardware]</span>
<span class="stack-tag">[#security]</span>
<span class="stack-tag">[#bus-pirate]</span>
</div>
<a href="#" class="cta-button">READ FULL WRITEUP [8 MIN] &rarr;</a>
</div>
</article>
</section>
<!-- Recent Dispatches Grid -->
<section class="recent-section" aria-label="Recent Technical Dispatches">
<div class="section-label">
<span>// Recent Dispatches &amp; Architecture Notes</span>
</div>
<div class="cards-grid">
<!-- Card 1: Traefik -->
<article class="dispatch-card">
<div>
<div class="card-meta-row">
<time datetime="2026-07-15" class="card-date">2026-07-15</time>
<span>12 min read</span>
</div>
<h3 style="margin: 10px 0 8px 0;">
<a href="#" class="card-heading-link">Building a High-Availability Traefik Router with Docker Compose</a>
</h3>
<p class="card-summary">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes.
</p>
</div>
<div class="card-bottom-row">
<div class="card-tag-cluster">
<span>[#homelab]</span>
<span>[#docker-traefik]</span>
</div>
<a href="#" class="read-more-link">Read &rarr;</a>
</div>
</article>
<!-- Card 2: POSIX sh -->
<article class="dispatch-card">
<div>
<div class="card-meta-row">
<time datetime="2026-07-10" class="card-date">2026-07-10</time>
<span>6 min read</span>
</div>
<h3 style="margin: 10px 0 8px 0;">
<a href="#" class="card-heading-link">POSIX sh vs. Bash: Portability in Modern Scripts</a>
</h3>
<p class="card-summary">
Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
</p>
</div>
<div class="card-bottom-row">
<div class="card-tag-cluster">
<span>[#posix-sh]</span>
<span>[#unix]</span>
</div>
<a href="#" class="read-more-link">Read &rarr;</a>
</div>
</article>
<!-- Card 3: Heap Exploitation -->
<article class="dispatch-card">
<div>
<div class="card-meta-row">
<time datetime="2026-06-28" class="card-date">2026-06-28</time>
<span>15 min read</span>
</div>
<h3 style="margin: 10px 0 8px 0;">
<a href="#" class="card-heading-link">CTF Write-up: Heap Exploitation in glibc 2.35</a>
</h3>
<p class="card-summary">
Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking.
</p>
</div>
<div class="card-bottom-row">
<div class="card-tag-cluster">
<span>[#ctf]</span>
<span>[#security]</span>
</div>
<a href="#" class="read-more-link">Read &rarr;</a>
</div>
</article>
<!-- Card 4: WireGuard OPNsense -->
<article class="dispatch-card">
<div>
<div class="card-meta-row">
<time datetime="2026-06-14" class="card-date">2026-06-14</time>
<span>10 min read</span>
</div>
<h3 style="margin: 10px 0 8px 0;">
<a href="#" class="card-heading-link">Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
</h3>
<p class="card-summary">
Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.
</p>
</div>
<div class="card-bottom-row">
<div class="card-tag-cluster">
<span>[#networking]</span>
<span>[#wireguard]</span>
</div>
<a href="#" class="read-more-link">Read &rarr;</a>
</div>
</article>
</div>
</section>
<!-- Site Footer -->
<footer class="site-footer">
<div>River Rooks &copy; 2026 • Node RACK-01</div>
<nav class="footer-links" aria-label="Footer Links">
<a href="feed.xml" class="footer-link">Feed</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">GitHub</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-link">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="PGP: 0x4A8E92F1C0B3D4E7" class="footer-link">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-link">Samples ↗</a>
</nav>
</footer>
</main>
</body>
</html>
+483
View File
@@ -0,0 +1,483 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Technical Notes &amp; Blog (Stream Lander)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Card surface background */
--bg-elevated: #1c1f26; /* Hovered / elevated state */
--border-color: #2b303b; /* Low-contrast 1px border */
--text-primary: #e0e6f0; /* Off-white prose */
--text-muted: #8a95a5; /* Monospaced metadata gray */
--accent-cyan: #00f0ff; /* Primary terminal accent */
--accent-green: #00e676; /* Operational indicator */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.65;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 48px 20px 64px 20px;
}
/* Reading container strictly capped at 65ch */
.stream-container {
width: 100%;
max-width: 65ch;
}
/* POSIX Path Top Banner */
.top-path-bar {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
margin-bottom: 24px;
padding-bottom: 10px;
border-bottom: 1px solid var(--border-color);
}
.path-display {
display: flex;
align-items: center;
gap: 8px;
}
.status-dot {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
flex-shrink: 0;
}
.status-badge {
color: var(--accent-green);
font-weight: 500;
}
/* Identity Section */
.author-name {
font-family: 'IBM Plex Mono', monospace;
font-size: 2rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
margin-bottom: 6px;
}
.author-role {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
color: var(--accent-cyan);
letter-spacing: 0.05em;
text-transform: uppercase;
margin-bottom: 16px;
}
.author-bio {
font-size: 0.98rem;
color: var(--text-primary);
margin-bottom: 24px;
}
/* Topic Filter Pills */
.filter-section {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
margin-bottom: 28px;
}
.filter-label {
color: var(--text-muted);
margin-right: 4px;
}
.filter-pill {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
color: var(--text-muted);
padding: 3px 8px;
border-radius: 3px;
cursor: pointer;
transition: none; /* Instant snap */
text-decoration: none;
}
.filter-pill:hover {
border-color: var(--accent-cyan);
color: var(--text-primary);
background-color: var(--bg-elevated);
}
.filter-pill.active {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
border-color: var(--accent-cyan);
font-weight: 700;
}
/* Section Divider */
.section-divider {
border: 0;
border-top: 1px solid var(--border-color);
margin: 28px 0;
}
/* Article Stream Entries */
.articles-stream {
display: flex;
flex-direction: column;
gap: 36px;
}
.article-entry {
display: flex;
flex-direction: column;
gap: 8px;
}
.article-entry.hidden {
display: none;
}
.article-meta {
display: flex;
align-items: center;
gap: 12px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
}
.article-date {
color: var(--accent-cyan);
}
.article-title-link {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.22rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
display: inline-block;
transition: none; /* Instant snap */
}
.article-title-link::before {
content: '> ';
color: var(--border-color);
transition: none;
}
.article-title-link:hover {
color: var(--accent-cyan);
}
.article-title-link:hover::before {
color: var(--accent-cyan);
}
.article-title-link:focus {
outline: 2px solid var(--accent-cyan);
outline-offset: 2px;
}
.article-abstract {
font-size: 0.94rem;
color: var(--text-primary);
line-height: 1.6;
}
.article-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.75rem;
margin-top: 4px;
}
.article-tag {
color: var(--text-muted);
}
.article-read-cta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
text-decoration: none;
align-self: flex-start;
margin-top: 2px;
transition: none;
}
.article-read-cta:hover {
text-decoration: underline;
}
/* Piped Footer */
.stream-footer {
margin-top: 48px;
padding-top: 24px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
color: var(--text-muted);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.footer-links {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.footer-link {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-link:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.footer-link:focus {
outline: 2px solid var(--accent-cyan);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="stream-container">
<!-- POSIX Path Top Banner -->
<header class="top-path-bar">
<div class="path-display">
<span class="status-dot" title="Cluster state: operational"></span>
<span>~/blog/notes/</span>
</div>
<div class="status-badge">[5 POSTS • FEED ONLINE]</div>
</header>
<!-- Identity & Bio -->
<section class="identity-section" aria-label="Author Identity">
<h1 class="author-name">River Rooks</h1>
<div class="author-role">Systems Architecture &amp; Cybersecurity</div>
<p class="author-bio">
Cybersecurity student at the University of Alabama College of Engineering, focusing on network forensics, self-hosted infrastructure, and bare-metal systems. Field notes, architecture specs, and low-level security research.
</p>
</section>
<!-- Quick Topic Filters -->
<nav class="filter-section" aria-label="Filter Articles by Topic">
<span class="filter-label">Filter:</span>
<button class="filter-pill active" data-filter="all" onclick="filterArticles('all', this)">[All (5)]</button>
<button class="filter-pill" data-filter="security" onclick="filterArticles('security', this)">[#security (3)]</button>
<button class="filter-pill" data-filter="homelab" onclick="filterArticles('homelab', this)">[#homelab (2)]</button>
<button class="filter-pill" data-filter="networking" onclick="filterArticles('networking', this)">[#networking (2)]</button>
<button class="filter-pill" data-filter="unix" onclick="filterArticles('unix', this)">[#unix (1)]</button>
</nav>
<hr class="section-divider">
<!-- Articles Stream (Reverse Chronological) -->
<section class="articles-stream" id="articlesStream" aria-label="Article Feed">
<!-- Post 1: Firmware -->
<article class="article-entry" data-category="security firmware">
<div class="article-meta">
<time datetime="2026-07-20" class="article-date">2026-07-20</time>
<span>•</span>
<span>8 min read</span>
<span>•</span>
<span>~/notes/iot-firmware-spi-extraction.md</span>
</div>
<h2 class="article-title">
<a href="#" class="article-title-link">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</h2>
<p class="article-abstract">
In security audits of embedded systems, retrieving the firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.
</p>
<div class="article-tags">
<span class="article-tag">[#firmware]</span>
<span class="article-tag">[#hardware]</span>
<span class="article-tag">[#security]</span>
<span class="article-tag">[#bus-pirate]</span>
</div>
<a href="#" class="article-read-cta">Read Writeup [8 min] &rarr;</a>
</article>
<!-- Post 2: Traefik Docker -->
<article class="article-entry" data-category="homelab networking">
<div class="article-meta">
<time datetime="2026-07-15" class="article-date">2026-07-15</time>
<span>•</span>
<span>12 min read</span>
<span>•</span>
<span>~/notes/ha-traefik-docker.md</span>
</div>
<h2 class="article-title">
<a href="#" class="article-title-link">Building a High-Availability Traefik Router with Docker Compose</a>
</h2>
<p class="article-abstract">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes on bare-metal infrastructure.
</p>
<div class="article-tags">
<span class="article-tag">[#homelab]</span>
<span class="article-tag">[#docker-traefik]</span>
<span class="article-tag">[#networking]</span>
</div>
<a href="#" class="article-read-cta">Read Writeup [12 min] &rarr;</a>
</article>
<!-- Post 3: POSIX sh -->
<article class="article-entry" data-category="unix">
<div class="article-meta">
<time datetime="2026-07-10" class="article-date">2026-07-10</time>
<span>•</span>
<span>6 min read</span>
<span>•</span>
<span>~/notes/posix-sh-vs-bash.md</span>
</div>
<h2 class="article-title">
<a href="#" class="article-title-link">POSIX sh vs. Bash: Portability in Modern Scripts</a>
</h2>
<p class="article-abstract">
Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
</p>
<div class="article-tags">
<span class="article-tag">[#posix-sh]</span>
<span class="article-tag">[#shell]</span>
<span class="article-tag">[#unix]</span>
</div>
<a href="#" class="article-read-cta">Read Writeup [6 min] &rarr;</a>
</article>
<!-- Post 4: Heap Exploitation -->
<article class="article-entry" data-category="security">
<div class="article-meta">
<time datetime="2026-06-28" class="article-date">2026-06-28</time>
<span>•</span>
<span>15 min read</span>
<span>•</span>
<span>~/notes/ctf-heap-glibc-2-35.md</span>
</div>
<h2 class="article-title">
<a href="#" class="article-title-link">CTF Write-up: Heap Exploitation in glibc 2.35</a>
</h2>
<p class="article-abstract">
Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking for arbitrary code execution.
</p>
<div class="article-tags">
<span class="article-tag">[#ctf]</span>
<span class="article-tag">[#binary-exploitation]</span>
<span class="article-tag">[#security]</span>
</div>
<a href="#" class="article-read-cta">Read Writeup [15 min] &rarr;</a>
</article>
<!-- Post 5: Zero Trust Network -->
<article class="article-entry" data-category="networking security homelab">
<div class="article-meta">
<time datetime="2026-06-14" class="article-date">2026-06-14</time>
<span>•</span>
<span>10 min read</span>
<span>•</span>
<span>~/notes/zero-trust-wireguard-opnsense.md</span>
</div>
<h2 class="article-title">
<a href="#" class="article-title-link">Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
</h2>
<p class="article-abstract">
Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.
</p>
<div class="article-tags">
<span class="article-tag">[#networking]</span>
<span class="article-tag">[#wireguard]</span>
<span class="article-tag">[#security]</span>
</div>
<a href="#" class="article-read-cta">Read Writeup [10 min] &rarr;</a>
</article>
</section>
<!-- Piped Footer -->
<footer class="stream-footer">
<div>River Rooks &copy; 2026</div>
<nav class="footer-links" aria-label="Footer Links">
<a href="feed.xml" class="footer-link">RSS Feed</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">GitHub</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-link">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="PGP: 0x4A8E92F1C0B3D4E7" class="footer-link">PGP Key</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-link">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
function filterArticles(category, btn) {
// Toggle active pill
document.querySelectorAll('.filter-pill').forEach(el => el.classList.remove('active'));
btn.classList.add('active');
const entries = document.querySelectorAll('.article-entry');
entries.forEach(entry => {
if (category === 'all') {
entry.classList.remove('hidden');
} else {
const cats = entry.getAttribute('data-category') || '';
if (cats.includes(category)) {
entry.classList.remove('hidden');
} else {
entry.classList.add('hidden');
}
}
});
}
</script>
</body>
</html>
+617
View File
@@ -0,0 +1,617 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Terminal Index Blog Lander</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Table & card surface */
--bg-elevated: #1c1f26; /* Selected row / elevated state */
--border-color: #2b303b; /* 1px solid low-contrast border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary terminal accent */
--accent-green: #00e676; /* Operational indicator */
--accent-amber: #ffb700; /* Warning / highlight */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'IBM Plex Mono', monospace;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 36px 16px 48px 16px;
}
.app-wrapper {
width: 100%;
max-width: 960px;
}
/* Terminal Window Frame */
.terminal-window {
border: 1px solid var(--border-color);
border-radius: 4px;
background-color: var(--bg-surface);
overflow: hidden;
}
/* Window Titlebar */
.terminal-titlebar {
background-color: var(--bg-canvas);
border-bottom: 1px solid var(--border-color);
padding: 8px 14px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.78rem;
color: var(--text-muted);
}
.window-controls {
display: flex;
gap: 6px;
align-items: center;
}
.window-dot {
width: 8px;
height: 8px;
background-color: var(--border-color);
display: inline-block;
}
.window-title {
color: var(--text-primary);
font-weight: 700;
}
/* Terminal Body */
.terminal-body {
padding: 20px;
}
/* System Header Info */
.system-header {
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid var(--border-color);
}
.system-identity {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: baseline;
gap: 8px;
margin-bottom: 8px;
}
.author-title {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
}
.author-role {
font-size: 0.8rem;
color: var(--accent-cyan);
}
.system-bio {
font-family: 'Inter', sans-serif;
font-size: 0.9rem;
color: var(--text-muted);
max-width: 75ch;
line-height: 1.5;
}
/* Command Prompt & Live Grep Filter */
.prompt-bar {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 10px 14px;
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.prompt-text {
color: var(--accent-cyan);
font-weight: 700;
font-size: 0.85rem;
white-space: nowrap;
}
.grep-label {
color: var(--text-muted);
font-size: 0.82rem;
}
.grep-input {
background: transparent;
border: none;
outline: none;
color: var(--text-primary);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
flex: 1;
min-width: 140px;
}
.grep-input::placeholder {
color: var(--text-muted);
opacity: 0.6;
}
.grep-count {
color: var(--accent-green);
font-size: 0.78rem;
}
/* Tabular Directory View */
.table-responsive {
width: 100%;
overflow-x: auto;
margin-bottom: 20px;
}
.directory-table {
width: 100%;
border-collapse: collapse;
font-size: 0.82rem;
text-align: left;
}
.directory-table th {
padding: 8px 12px;
border-bottom: 1px solid var(--border-color);
color: var(--text-muted);
font-weight: 500;
background-color: var(--bg-canvas);
white-space: nowrap;
}
.directory-table td {
padding: 10px 12px;
border-bottom: 1px solid var(--border-color);
color: var(--text-primary);
vertical-align: middle;
white-space: nowrap;
}
.directory-row {
cursor: pointer;
transition: none; /* Instant snap */
}
.directory-row:hover {
background-color: var(--bg-elevated);
}
.directory-row.active {
background-color: var(--bg-elevated);
border-left: 2px solid var(--accent-cyan);
}
.col-title {
white-space: normal !important;
min-width: 280px;
}
.entry-link {
color: var(--text-primary);
text-decoration: none;
font-weight: 500;
display: inline-block;
transition: none;
}
.directory-row:hover .entry-link,
.directory-row.active .entry-link {
color: var(--accent-cyan);
}
.tag-badge {
color: var(--text-muted);
font-size: 0.75rem;
}
.time-badge {
color: var(--text-muted);
font-size: 0.78rem;
}
.preview-indicator {
color: var(--accent-cyan);
font-size: 0.75rem;
text-decoration: none;
padding: 2px 6px;
border: 1px solid transparent;
}
.directory-row:hover .preview-indicator {
border-color: var(--accent-cyan);
}
/* Live Inspection / Preview Pane */
.preview-pane {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px;
margin-top: 12px;
display: flex;
flex-direction: column;
gap: 12px;
}
.preview-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color);
padding-bottom: 8px;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 8px;
}
.preview-filename {
color: var(--accent-cyan);
font-weight: 700;
}
.preview-abstract {
font-family: 'Inter', sans-serif;
font-size: 0.92rem;
color: var(--text-primary);
line-height: 1.6;
}
.preview-code-block {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
padding: 12px;
border-radius: 3px;
font-family: 'JetBrains Mono', monospace;
font-size: 0.78rem;
overflow-x: auto;
color: var(--text-primary);
}
.preview-actions {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 6px;
}
.read-btn {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
border: 1px solid var(--accent-cyan);
padding: 4px 10px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
font-weight: 700;
text-decoration: none;
border-radius: 2px;
cursor: pointer;
transition: none;
}
.read-btn:hover {
background-color: transparent;
color: var(--accent-cyan);
}
/* Terminal Status Bar at Bottom */
.terminal-statusbar {
background-color: var(--bg-canvas);
border-top: 1px solid var(--border-color);
padding: 8px 16px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.75rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 8px;
}
.footer-links {
display: flex;
gap: 12px;
align-items: center;
}
.footer-link {
color: var(--text-primary);
text-decoration: none;
padding: 1px 4px;
transition: none;
}
.footer-link:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.footer-link:focus {
outline: 2px solid var(--accent-cyan);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="app-wrapper">
<div class="terminal-window">
<!-- Titlebar -->
<div class="terminal-titlebar">
<div class="window-controls">
<span class="window-dot"></span>
<span class="window-dot"></span>
<span class="window-dot"></span>
<span class="window-title" style="margin-left: 6px;">rooks@sys: ~/articles</span>
</div>
<div>POSIX SH • UTF-8 • [READ-ONLY]</div>
</div>
<div class="terminal-body">
<!-- System Identity Header -->
<header class="system-header">
<div class="system-identity">
<h1 class="author-title">River Rooks // Articles Directory</h1>
<span class="author-role">[SYSTEMS ARCHITECTURE &amp; CYBERSECURITY]</span>
</div>
<p class="system-bio">
Field notes and technical write-ups covering embedded firmware reverse engineering, network forensics, low-level memory exploitation, and self-hosted infrastructure.
</p>
</header>
<!-- Command Prompt with Live Filter -->
<div class="prompt-bar" role="search">
<span class="prompt-text">dev-blog@system:~$</span>
<span class="grep-label">grep -i</span>
<input
type="text"
id="searchInput"
class="grep-input"
placeholder="filter by keyword, tag, or title..."
oninput="handleSearch(this.value)"
aria-label="Filter articles"
>
<span class="grep-count" id="matchCounter">5/5 matches</span>
</div>
<!-- Directory Listing Table -->
<div class="table-responsive">
<table class="directory-table" id="directoryTable" aria-label="Articles directory table">
<thead>
<tr>
<th scope="col">PERMS</th>
<th scope="col">DATE</th>
<th scope="col">PRIMARY TAG</th>
<th scope="col">ARTICLE TITLE / FILE</th>
<th scope="col">EST. TIME</th>
<th scope="col">ACTION</th>
</tr>
</thead>
<tbody id="tableBody">
<tr class="directory-row active" onclick="selectRow(0)" data-index="0" data-keywords="firmware hardware security bus-pirate spi flash extraction iot">
<td><span style="color: var(--text-muted);">-rw-r--r--</span></td>
<td><time datetime="2026-07-20" style="color: var(--accent-cyan);">2026-07-20</time></td>
<td><span class="tag-badge">[#firmware]</span></td>
<td class="col-title">
<a href="#" class="entry-link">&gt; Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</td>
<td><span class="time-badge">8 mins</span></td>
<td><span class="preview-indicator">[INSPECT]</span></td>
</tr>
<tr class="directory-row" onclick="selectRow(1)" data-index="1" data-keywords="homelab docker traefik networking proxy compose">
<td><span style="color: var(--text-muted);">-rw-r--r--</span></td>
<td><time datetime="2026-07-15" style="color: var(--accent-cyan);">2026-07-15</time></td>
<td><span class="tag-badge">[#homelab]</span></td>
<td class="col-title">
<a href="#" class="entry-link">&gt; Building a High-Availability Traefik Router with Docker Compose</a>
</td>
<td><span class="time-badge">12 mins</span></td>
<td><span class="preview-indicator">[INSPECT]</span></td>
</tr>
<tr class="directory-row" onclick="selectRow(2)" data-index="2" data-keywords="posix-sh shell unix portability scripts bashisms">
<td><span style="color: var(--text-muted);">-rw-r--r--</span></td>
<td><time datetime="2026-07-10" style="color: var(--accent-cyan);">2026-07-10</time></td>
<td><span class="tag-badge">[#posix-sh]</span></td>
<td class="col-title">
<a href="#" class="entry-link">&gt; POSIX sh vs. Bash: Portability in Modern Scripts</a>
</td>
<td><span class="time-badge">6 mins</span></td>
<td><span class="preview-indicator">[INSPECT]</span></td>
</tr>
<tr class="directory-row" onclick="selectRow(3)" data-index="3" data-keywords="ctf binary exploitation heap glibc 2.35 memory security">
<td><span style="color: var(--text-muted);">-rw-r--r--</span></td>
<td><time datetime="2026-06-28" style="color: var(--accent-cyan);">2026-06-28</time></td>
<td><span class="tag-badge">[#ctf]</span></td>
<td class="col-title">
<a href="#" class="entry-link">&gt; CTF Write-up: Heap Exploitation in glibc 2.35</a>
</td>
<td><span class="time-badge">15 mins</span></td>
<td><span class="preview-indicator">[INSPECT]</span></td>
</tr>
<tr class="directory-row" onclick="selectRow(4)" data-index="4" data-keywords="networking wireguard security zerotrust opnsense vlans">
<td><span style="color: var(--text-muted);">-rw-r--r--</span></td>
<td><time datetime="2026-06-14" style="color: var(--accent-cyan);">2026-06-14</time></td>
<td><span class="tag-badge">[#networking]</span></td>
<td class="col-title">
<a href="#" class="entry-link">&gt; Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
</td>
<td><span class="time-badge">10 mins</span></td>
<td><span class="preview-indicator">[INSPECT]</span></td>
</tr>
</tbody>
</table>
</div>
<!-- Live Inspection / Details Panel -->
<section class="preview-pane" id="previewPane" aria-label="Article Details Preview">
<div class="preview-header">
<span class="preview-filename" id="previewFilePath">~/notes/iot-firmware-spi-extraction.md</span>
<span id="previewMeta">2026-07-20 • 8 mins read • [#firmware] [#hardware] [#security]</span>
</div>
<p class="preview-abstract" id="previewAbstract">
In security audits of embedded systems, retrieving the firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.
</p>
<div class="preview-code-block" id="previewCode">
<pre><code># Query the SPI flash details using flashrom via Bus Pirate
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
# Verify the integrity of the binary dump by comparing hashes
if [ $? -eq 0 ]; then
echo "Dump successful. Running md5sum..."
md5sum firmware_dump.bin
fi</code></pre>
</div>
<div class="preview-actions">
<span style="font-size: 0.78rem; color: var(--text-muted);">Format: IEEE Std 1003.1 Markdown</span>
<a href="#" class="read-btn" id="previewReadBtn">READ COMPLETE WRITEUP &rarr;</a>
</div>
</section>
</div>
<!-- Bottom Statusbar -->
<footer class="terminal-statusbar">
<div>5 FILES INDEXED • 51m READING DURATION • STATUS: 0 (OK)</div>
<nav class="footer-links" aria-label="Terminal Footer Links">
<a href="feed.xml" class="footer-link">feed.xml</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link">git.rooks.dev</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">github</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-link">catalog ↗</a>
</nav>
</footer>
</div>
</main>
<script>
const articlesData = [
{
path: '~/notes/iot-firmware-spi-extraction.md',
date: '2026-07-20',
time: '8 mins read',
tags: '[#firmware] [#hardware] [#security] [#bus-pirate]',
abstract: 'In security audits of embedded systems, retrieving the firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.',
code: `# Query the SPI flash details using flashrom via Bus Pirate\nflashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin\n\n# Verify the integrity of the binary dump by comparing hashes\nif [ $? -eq 0 ]; then\n echo "Dump successful. Running md5sum..."\n md5sum firmware_dump.bin\nfi`
},
{
path: '~/notes/ha-traefik-docker.md',
date: '2026-07-15',
time: '12 mins read',
tags: '[#homelab] [#docker-traefik] [#networking]',
abstract: 'Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes on bare-metal infrastructure.',
code: `services:\n traefik:\n image: traefik:v3.1\n command:\n - "--providers.docker=true"\n - "--entrypoints.websecure.address=:443"\n - "--certificatesresolvers.cf.acme.dnschallenge=true"`
},
{
path: '~/notes/posix-sh-vs-bash.md',
date: '2026-07-10',
time: '6 mins read',
tags: '[#posix-sh] [#shell] [#unix]',
abstract: 'Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.',
code: `#!/bin/sh\n# Zero-allocation POSIX argument validation\n[ "$#" -ge 1 ] || { echo "Usage: $0 <target>" >&2; exit 1; }\ntarget="$1"\nprintf 'Configuring target node: %s\\n' "$target"`
},
{
path: '~/notes/ctf-heap-glibc-2-35.md',
date: '2026-06-28',
time: '15 mins read',
tags: '[#ctf] [#binary-exploitation] [#security]',
abstract: 'Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking for arbitrary code execution.',
code: `// glibc 2.35 tcache safe-linking pointer de-mangling\nuint64_t reveal_ptr(uint64_t mangled_ptr, uint64_t addr) {\n return mangled_ptr ^ (addr >> 12);\n}`
},
{
path: '~/notes/zero-trust-wireguard-opnsense.md',
date: '2026-06-14',
time: '10 mins read',
tags: '[#networking] [#wireguard] [#security]',
abstract: 'Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.',
code: `[Interface]\nPrivateKey = aGlkZGVuX2tleV9kYXRhX2hlcmU=\nAddress = 10.100.0.5/32\nDNS = 10.100.0.1\n\n[Peer]\nPublicKey = cGVlcl9wdWJsaWNfa2V5X2RhdGFfaGVyZQ==\nEndpoint = vpn.rooks.dev:51820\nAllowedIPs = 10.100.0.0/24`
}
];
function selectRow(index) {
document.querySelectorAll('.directory-row').forEach(row => row.classList.remove('active'));
const activeRow = document.querySelector(`.directory-row[data-index="${index}"]`);
if (activeRow) activeRow.classList.add('active');
const data = articlesData[index];
if (!data) return;
document.getElementById('previewFilePath').innerText = data.path;
document.getElementById('previewMeta').innerText = `${data.date} • ${data.time} • ${data.tags}`;
document.getElementById('previewAbstract').innerText = data.abstract;
document.getElementById('previewCode').innerHTML = `<pre><code>${escapeHtml(data.code)}</code></pre>`;
}
function handleSearch(query) {
const q = query.toLowerCase().trim();
const rows = document.querySelectorAll('.directory-row');
let visibleCount = 0;
rows.forEach(row => {
const text = (row.innerText + ' ' + (row.getAttribute('data-keywords') || '')).toLowerCase();
if (!q || text.includes(q)) {
row.style.display = '';
visibleCount++;
} else {
row.style.display = 'none';
}
});
document.getElementById('matchCounter').innerText = `${visibleCount}/5 matches`;
}
function escapeHtml(str) {
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
</script>
</body>
</html>
+661
View File
@@ -0,0 +1,661 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Blog Lander (Dual-Lead Grid &amp; Feed)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered tile surface */
--border-color: #2b303b; /* Crisp 1px border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary active accent */
--accent-green: #00e676; /* Operational status indicator */
--accent-amber: #ffb700; /* Highlight accent */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1120px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Header Bar (Gateway 3 Match) */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
.bar-link.active {
color: var(--text-primary);
border-bottom: 1px solid var(--accent-cyan);
}
/* Hero Section Tile */
.hero-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 4px;
padding: 24px 28px;
display: flex;
flex-direction: column;
gap: 12px;
}
.hero-pretitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.hero-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.1rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
}
.hero-landing-text {
font-size: 0.98rem;
color: var(--text-primary);
line-height: 1.65;
max-width: 84ch;
}
.hero-metadata-badges {
display: flex;
flex-wrap: wrap;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
margin-top: 4px;
}
.meta-badge {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
padding: 3px 8px;
border-radius: 2px;
color: var(--text-muted);
}
/* Dual-Lead Grid: 2 Side-by-Side Featured Cards */
.dual-lead-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
@media (max-width: 840px) {
.dual-lead-grid {
grid-template-columns: 1fr;
}
}
/* Tile Container Style */
.tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 14px;
}
.tile-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
}
.tile-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.88rem;
font-weight: 700;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 8px;
}
.tile-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
.lead-badge-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
}
.lead-heading {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.2rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
display: inline-block;
transition: none;
}
.lead-heading:hover {
color: var(--accent-cyan);
}
.lead-excerpt {
font-size: 0.88rem;
color: var(--text-primary);
line-height: 1.55;
}
/* Terminal Code Snippet */
.code-preview {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
font-family: 'JetBrains Mono', monospace;
font-size: 0.76rem;
overflow: hidden;
}
.code-preview-header {
background-color: var(--bg-elevated);
border-bottom: 1px solid var(--border-color);
padding: 4px 10px;
font-size: 0.72rem;
color: var(--text-muted);
display: flex;
justify-content: space-between;
}
.code-preview-body {
padding: 10px;
overflow-x: auto;
color: var(--text-primary);
line-height: 1.45;
}
.lead-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 10px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
flex-wrap: wrap;
gap: 8px;
}
.read-lead-btn {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 5px 12px;
font-weight: 700;
border-radius: 2px;
text-decoration: none;
transition: none;
}
.read-lead-btn:hover {
background-color: transparent;
color: var(--accent-cyan);
box-shadow: inset 0 0 0 1px var(--accent-cyan);
}
/* Archive Dispatches Feed Table */
.archive-feed-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}
.archive-table-wrapper {
width: 100%;
overflow-x: auto;
}
.archive-table {
width: 100%;
border-collapse: collapse;
font-size: 0.82rem;
text-align: left;
}
.archive-table th {
padding: 8px 12px;
background-color: var(--bg-canvas);
border-bottom: 1px solid var(--border-color);
color: var(--text-muted);
font-weight: 500;
white-space: nowrap;
font-family: 'IBM Plex Mono', monospace;
}
.archive-table td {
padding: 12px;
border-bottom: 1px solid var(--border-color);
vertical-align: middle;
white-space: nowrap;
}
.archive-row {
cursor: pointer;
transition: none;
}
.archive-row:hover {
background-color: var(--bg-elevated);
}
.archive-row.active {
background-color: var(--bg-elevated);
border-left: 2px solid var(--accent-cyan);
}
.archive-title-link {
font-family: 'IBM Plex Mono', monospace;
color: var(--text-primary);
text-decoration: none;
font-weight: 700;
}
.archive-row:hover .archive-title-link {
color: var(--accent-cyan);
}
/* Interactive Inline Inspection Pane */
.inspect-box {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px;
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 6px;
}
.inspect-head {
display: flex;
justify-content: space-between;
border-bottom: 1px solid var(--border-color);
padding-bottom: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
}
.inspect-prose {
font-family: 'Inter', sans-serif;
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.6;
}
/* Global Footer Tile (Gateway 3 Match) */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Global Bar (Gateway 3 Match) -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // DUAL-LEAD DISPATCH CATALOG</span>
</div>
<nav class="bar-nav" aria-label="Quick Navigation">
<a href="service-gateway-tiling.html" class="bar-link">Gateway 3 ↗</a>
<a href="#" class="bar-link active">&gt; Catalog</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="feed.xml" class="bar-link">RSS</a>
<a href="index.html" class="bar-link">Samples ↗</a>
</nav>
</header>
<!-- Hero Tile: Mission Statement & Metadata Badges -->
<section class="hero-tile" aria-label="Blog Declaration">
<div class="hero-pretitle">RESEARCH &bull; DISPATCHES &bull; SPECIFICATIONS</div>
<h1 class="hero-main-title">Systems Research &amp; Security Engineering Feed</h1>
<p class="hero-landing-text">
This catalog organizes field reports across two primary research vectors: hardware firmware reverse engineering and bare-metal self-hosted cloud infrastructure. Full source code, shell bootstrapping scripts, and network topology manifests are included.
</p>
<div class="hero-metadata-badges">
<span class="meta-badge">[NODE: gw-node01.lan]</span>
<span class="meta-badge">[5 CANONICAL DISPATCHES]</span>
<span class="meta-badge">[FORMAT: GHOSTTY / ZED MINIMALISM]</span>
<span class="meta-badge">[ENCRYPTED SYNC: WIREGUARD]</span>
</div>
</section>
<!-- Dual-Lead Grid: 2 Featured Stories Side-by-Side -->
<div class="dual-lead-grid">
<!-- Lead 1: Firmware Reversing -->
<section class="tile" aria-label="Lead Article 1">
<div class="tile-header">
<div class="tile-title">
<span>// LEAD: HARDWARE FORENSICS</span>
</div>
<span class="tile-meta">2026-07-20 &bull; 8 MIN</span>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;">
<div class="lead-badge-row">
<span style="color: var(--accent-amber); font-weight: 700; font-family: 'IBM Plex Mono', monospace;">[PINNED LEAD]</span>
<span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">~/notes/iot-firmware-spi-extraction.md</span>
</div>
<h2 style="margin: 0;">
<a href="#" class="lead-heading">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</h2>
<p class="lead-excerpt">
Extracting binary firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass locked-down UART/JTAG interfaces on production microcontrollers.
</p>
<div class="code-preview">
<div class="code-preview-header">
<span>extract_firmware.sh</span>
<span>POSIX sh</span>
</div>
<div class="code-preview-body">
<pre><code>flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M \
-r firmware_dump.bin && md5sum firmware_dump.bin</code></pre>
</div>
</div>
</div>
<div class="lead-footer">
<span style="color: var(--text-muted);">[#firmware] [#hardware]</span>
<a href="#" class="read-lead-btn">READ WRITEUP [8 MIN] &rarr;</a>
</div>
</section>
<!-- Lead 2: Traefik Infrastructure -->
<section class="tile" aria-label="Lead Article 2">
<div class="tile-header">
<div class="tile-title">
<span>// LEAD: INFRASTRUCTURE ROUTING</span>
</div>
<span class="tile-meta">2026-07-15 &bull; 12 MIN</span>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;">
<div class="lead-badge-row">
<span style="color: var(--accent-cyan); font-weight: 700; font-family: 'IBM Plex Mono', monospace;">[PINNED LEAD]</span>
<span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">~/notes/ha-traefik-docker.md</span>
</div>
<h2 style="margin: 0;">
<a href="#" class="lead-heading">High-Availability Traefik Router with Docker Compose</a>
</h2>
<p class="lead-excerpt">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover.
</p>
<div class="code-preview">
<div class="code-preview-header">
<span>docker-compose.traefik.yml</span>
<span>YAML</span>
</div>
<div class="code-preview-body">
<pre><code>services:
traefik:
image: traefik:v3.1
command: ["--providers.docker=true", "--entrypoints.websecure.address=:443"]</code></pre>
</div>
</div>
</div>
<div class="lead-footer">
<span style="color: var(--text-muted);">[#homelab] [#docker-traefik]</span>
<a href="#" class="read-lead-btn">READ WRITEUP [12 MIN] &rarr;</a>
</div>
</section>
</div>
<!-- Archive Dispatches Feed Tile with Interactive Inspector -->
<section class="archive-feed-tile" aria-label="Chronological Dispatches Archive">
<div class="tile-header">
<div class="tile-title">
<span>// CHRONOLOGICAL DISPATCHES ARCHIVE</span>
</div>
<span class="tile-meta">SELECT ROW TO INSPECT NOTES</span>
</div>
<div class="archive-table-wrapper">
<table class="archive-table" aria-label="Archive table">
<thead>
<tr>
<th scope="col">DATE</th>
<th scope="col">CATEGORY</th>
<th scope="col">TITLE / PATH</th>
<th scope="col">READ TIME</th>
<th scope="col">ACTION</th>
</tr>
</thead>
<tbody>
<tr class="archive-row active" onclick="inspectRow(0)">
<td><span style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace;">2026-07-10</span></td>
<td><span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">[#posix-sh]</span></td>
<td><a href="#" class="archive-title-link">&gt; POSIX sh vs. Bash: Portability in Modern Scripts</a></td>
<td><span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">6 min</span></td>
<td><span style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace;">[INSPECT &darr;]</span></td>
</tr>
<tr class="archive-row" onclick="inspectRow(1)">
<td><span style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace;">2026-06-28</span></td>
<td><span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">[#ctf]</span></td>
<td><a href="#" class="archive-title-link">&gt; CTF Write-up: Heap Exploitation in glibc 2.35</a></td>
<td><span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">15 min</span></td>
<td><span style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace;">[INSPECT &darr;]</span></td>
</tr>
<tr class="archive-row" onclick="inspectRow(2)">
<td><span style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace;">2026-06-14</span></td>
<td><span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">[#networking]</span></td>
<td><a href="#" class="archive-title-link">&gt; Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a></td>
<td><span style="color: var(--text-muted); font-family: 'IBM Plex Mono', monospace;">10 min</span></td>
<td><span style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace;">[INSPECT &darr;]</span></td>
</tr>
</tbody>
</table>
</div>
<!-- Inspection Details Box -->
<div class="inspect-box" id="inspectBox">
<div class="inspect-head">
<span id="inspectPath" style="color: var(--accent-cyan); font-weight: 700;">~/notes/posix-sh-vs-bash.md</span>
<span id="inspectMeta">2026-07-10 &bull; 6 MIN READ &bull; [#posix-sh] [#shell] [#unix]</span>
</div>
<p class="inspect-prose" id="inspectProse">
Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
</p>
<div style="display: flex; justify-content: flex-end;">
<a href="#" id="inspectReadBtn" class="read-lead-btn" style="padding: 4px 10px; font-size: 0.76rem;">OPEN ENTRY &rarr;</a>
</div>
</div>
</section>
<!-- Global Footer Tile (Matching Gateway 3 Exactly) -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="service-gateway-tiling.html" class="footer-btn">Gateway Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
const archiveData = [
{
path: '~/notes/posix-sh-vs-bash.md',
meta: '2026-07-10 • 6 MIN READ • [#posix-sh] [#shell] [#unix]',
prose: 'Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.'
},
{
path: '~/notes/ctf-heap-glibc-2-35.md',
meta: '2026-06-28 • 15 MIN READ • [#ctf] [#binary-exploitation] [#security]',
prose: 'Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking for arbitrary code execution.'
},
{
path: '~/notes/zero-trust-wireguard-opnsense.md',
meta: '2026-06-14 • 10 MIN READ • [#networking] [#wireguard] [#security]',
prose: 'Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.'
}
];
function inspectRow(idx) {
document.querySelectorAll('.archive-row').forEach(row => row.classList.remove('active'));
const activeRow = document.querySelectorAll('.archive-row')[idx];
if (activeRow) activeRow.classList.add('active');
const data = archiveData[idx];
if (data) {
document.getElementById('inspectPath').innerText = data.path;
document.getElementById('inspectMeta').innerText = data.meta;
document.getElementById('inspectProse').innerText = data.prose;
}
}
</script>
</body>
</html>
+780
View File
@@ -0,0 +1,780 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Blog Lander (Tiling Hero &amp; Feed)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered tile surface */
--border-color: #2b303b; /* Crisp 1px solid border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary active accent */
--accent-green: #00e676; /* Operational status indicator */
--accent-amber: #ffb700; /* Warning / highlight accent */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1120px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Status Header Bar (Gateway 3 Style) */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
.bar-link.active {
color: var(--text-primary);
border-bottom: 1px solid var(--accent-cyan);
}
/* Hero Tile: Section Declaration & Synopsis */
.hero-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 4px;
padding: 24px 28px;
display: flex;
flex-direction: column;
gap: 12px;
}
.hero-pretitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.hero-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.1rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
line-height: 1.2;
}
.hero-landing-text {
font-size: 0.98rem;
color: var(--text-primary);
line-height: 1.65;
max-width: 82ch;
}
.filter-pills-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-top: 4px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.filter-tag-btn {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
color: var(--text-muted);
padding: 3px 8px;
border-radius: 2px;
cursor: pointer;
transition: none;
}
.filter-tag-btn:hover {
border-color: var(--accent-cyan);
color: var(--text-primary);
background-color: var(--bg-elevated);
}
.filter-tag-btn.active {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
border-color: var(--accent-cyan);
font-weight: 700;
}
/* Asymmetric Split Grid */
.split-grid {
display: grid;
grid-template-columns: 1.25fr 0.75fr;
gap: 16px;
}
@media (max-width: 880px) {
.split-grid {
grid-template-columns: 1fr;
}
}
/* Standard Tile Container */
.tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}
.tile-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
}
.tile-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.92rem;
font-weight: 700;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 8px;
}
.tile-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
/* Featured Lead Article Card (Inside Tile) */
.featured-card-body {
display: flex;
flex-direction: column;
gap: 12px;
}
.featured-badge-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
flex-wrap: wrap;
gap: 8px;
}
.badge-pinned {
color: var(--accent-amber);
font-weight: 700;
}
.featured-article-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.35rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.3;
transition: none;
}
.featured-article-title:hover {
color: var(--accent-cyan);
}
.featured-prose {
font-size: 0.92rem;
color: var(--text-primary);
line-height: 1.6;
}
/* Terminal Code Block Component */
.terminal-code-box {
border: 1px solid var(--border-color);
border-radius: 3px;
background-color: var(--bg-canvas);
overflow: hidden;
font-family: 'JetBrains Mono', monospace;
}
.code-titlebar {
background-color: var(--bg-surface);
border-bottom: 1px solid var(--border-color);
padding: 6px 12px;
font-size: 0.74rem;
color: var(--text-muted);
display: flex;
justify-content: space-between;
}
.code-content {
padding: 12px;
font-size: 0.78rem;
overflow-x: auto;
color: var(--text-primary);
line-height: 1.5;
}
.featured-cta-row {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 10px;
border-top: 1px solid var(--border-color);
flex-wrap: wrap;
gap: 10px;
font-family: 'IBM Plex Mono', monospace;
}
.cta-button {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 6px 14px;
font-weight: 700;
font-size: 0.8rem;
text-decoration: none;
border-radius: 2px;
border: 1px solid var(--accent-cyan);
transition: none;
}
.cta-button:hover {
background-color: transparent;
color: var(--accent-cyan);
}
/* Sidebar Tile Elements */
.sidebar-stats-box {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
}
.stat-row {
display: flex;
justify-content: space-between;
}
.stat-val {
color: var(--text-primary);
font-weight: 700;
}
.topic-track-item {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 10px 12px;
display: flex;
flex-direction: column;
gap: 4px;
text-decoration: none;
transition: none;
}
.topic-track-item:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.topic-track-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.84rem;
font-weight: 700;
color: var(--text-primary);
}
.topic-track-item:hover .topic-track-title {
color: var(--accent-cyan);
}
.topic-track-desc {
font-size: 0.78rem;
color: var(--text-muted);
line-height: 1.4;
}
/* Full-Width Chronological Article Feed Tile */
.feed-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.feed-card {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px 18px;
display: flex;
flex-direction: column;
gap: 8px;
transition: none;
}
.feed-card:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.feed-meta-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
color: var(--text-muted);
}
.feed-date {
color: var(--accent-cyan);
}
.feed-heading {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.1rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
transition: none;
}
.feed-card:hover .feed-heading {
color: var(--accent-cyan);
}
.feed-excerpt {
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.6;
}
.feed-tags-row {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 6px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 6px;
}
.tag-cluster {
display: flex;
gap: 8px;
}
/* Global Footer Tile (Gateway 3 Standard) */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Global Status Bar (Gateway 3 Match) -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // BLOG &amp; RESEARCH ARCHIVE</span>
</div>
<nav class="bar-nav" aria-label="Quick Navigation">
<a href="service-gateway-tiling.html" class="bar-link">Gateway 3 ↗</a>
<a href="#" class="bar-link active">&gt; Dispatches</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="feed.xml" class="bar-link">RSS Feed</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Hero Tile: Blog Mission & Topic Filters -->
<section class="hero-tile" aria-label="Blog Mission & Overview">
<div class="hero-pretitle">TECHNICAL PUBLICATION REPOSITORY &bull; ~/NOTES/INDEX.MD</div>
<h1 class="hero-main-title">Engineering Notes, CTF Write-Ups &amp; Systems Architecture</h1>
<p class="hero-landing-text">
Documenting bare-metal systems, embedded hardware audits, and network isolation architectures. Writing zero-allocation POSIX scripts, reverse engineering production microcontrollers, and analyzing memory allocator exploitation primitives.
</p>
<div class="filter-pills-row">
<span style="color: var(--text-muted); margin-right: 4px;">TOPIC FILTER:</span>
<button class="filter-tag-btn active" onclick="filterTopic('all', this)">[All Dispatches (5)]</button>
<button class="filter-tag-btn" onclick="filterTopic('firmware', this)">[#firmware (1)]</button>
<button class="filter-tag-btn" onclick="filterTopic('homelab', this)">[#homelab (2)]</button>
<button class="filter-tag-btn" onclick="filterTopic('security', this)">[#security (3)]</button>
<button class="filter-tag-btn" onclick="filterTopic('posix-sh', this)">[#posix-sh (1)]</button>
</div>
</section>
<!-- Split Grid: Featured Article + Research Index -->
<div class="split-grid">
<!-- Left Column: Featured Article Tile -->
<section class="tile" aria-label="Featured Technical Article">
<div class="tile-header">
<div class="tile-title">
<span>// PINNED RESEARCH WRITE-UP</span>
</div>
<span class="tile-meta">SPI FLASH &bull; 8 MIN READ</span>
</div>
<div class="featured-card-body">
<div class="featured-badge-row">
<span class="badge-pinned">[FEATURED DEEP DIVE]</span>
<span style="color: var(--text-muted);">2026-07-20 &bull; ~/notes/iot-firmware-spi-extraction.md</span>
</div>
<h2 style="margin: 0;">
<a href="article-tiling-firmware.html" class="featured-article-title">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</h2>
<p class="featured-prose">
In security audits of embedded systems, retrieving firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.
</p>
<!-- Terminal Code Box -->
<div class="terminal-code-box">
<div class="code-titlebar">
<span>extract_firmware.sh</span>
<span>POSIX sh</span>
</div>
<div class="code-content">
<pre><code># Query the SPI flash details using flashrom via Bus Pirate
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
# Verify the integrity of the binary dump by comparing hashes
if [ $? -eq 0 ]; then
echo "Dump successful. Running md5sum..."
md5sum firmware_dump.bin
fi</code></pre>
</div>
</div>
<div class="featured-cta-row">
<div class="tag-cluster">
<span style="color: var(--text-muted); font-size: 0.75rem;">[#firmware] [#hardware] [#security] [#bus-pirate]</span>
</div>
<a href="article-tiling-firmware.html" class="cta-button">READ FULL WRITEUP &rarr;</a>
</div>
</div>
</section>
<!-- Right Column: Quick Research Tracks & Telemetry -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Publication Stats Tile -->
<section class="tile" aria-label="Archive Statistics">
<div class="tile-header">
<div class="tile-title">
<span>// ARCHIVE TELEMETRY</span>
</div>
<span class="tile-meta">STATIC HTML</span>
</div>
<div class="sidebar-stats-box">
<div class="stat-row">
<span>TOTAL ARTICLES:</span>
<span class="stat-val">5 PUBLISHED</span>
</div>
<div class="stat-row">
<span>TOTAL READING TIME:</span>
<span class="stat-val">51 MINUTES</span>
</div>
<div class="stat-row">
<span>ACTIVE TOPICS:</span>
<span class="stat-val">7 CATEGORIES</span>
</div>
<div class="stat-row">
<span>FORMAT COMPLIANCE:</span>
<span class="stat-val">IEEE STD 1003.1</span>
</div>
</div>
</section>
<!-- Curated Focus Tracks -->
<section class="tile" aria-label="Curated Topic Tracks">
<div class="tile-header">
<div class="tile-title">
<span>// RESEARCH TRACKS</span>
</div>
<span class="tile-meta">CURATED</span>
</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<a href="#" class="topic-track-item">
<div class="topic-track-title">&gt; Embedded &amp; Hardware Forensics</div>
<div class="topic-track-desc">Flash memory dumping, bus tapping, silicon pinout discovery.</div>
</a>
<a href="#" class="topic-track-item">
<div class="topic-track-title">&gt; Network Routing &amp; Homelab</div>
<div class="topic-track-desc">Traefik reverse proxying, WireGuard full-mesh, VLAN firewalls.</div>
</a>
<a href="#" class="topic-track-item">
<div class="topic-track-title">&gt; Low-Level Memory Exploitation</div>
<div class="topic-track-desc">glibc tcache safe-linking, heap corruption, House of Apple.</div>
</a>
</div>
</section>
</div>
</div>
<!-- Full-Width Article Feed Tile -->
<section class="tile" aria-label="Chronological Article Stream">
<div class="tile-header">
<div class="tile-title">
<span>// CHRONOLOGICAL DISPATCHES FEED</span>
</div>
<span class="tile-meta">ALL ARTICLES ORDERED BY DATE</span>
</div>
<div class="feed-list" id="feedList">
<!-- Post 2: Traefik -->
<article class="feed-card" data-tags="homelab networking">
<div class="feed-meta-row">
<time datetime="2026-07-15" class="feed-date">2026-07-15 &bull; 12 min read</time>
<span>~/notes/ha-traefik-docker.md</span>
</div>
<h3 style="margin: 0;">
<a href="article-tiling-traefik.html" class="feed-heading">&gt; Building a High-Availability Traefik Router with Docker Compose</a>
</h3>
<p class="feed-excerpt">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes on bare-metal infrastructure.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#homelab]</span>
<span>[#docker-traefik]</span>
<span>[#networking]</span>
</div>
<a href="article-tiling-traefik.html" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
<!-- Post 3: POSIX sh -->
<article class="feed-card" data-tags="posix-sh security">
<div class="feed-meta-row">
<time datetime="2026-07-10" class="feed-date">2026-07-10 &bull; 6 min read</time>
<span>~/notes/posix-sh-vs-bash.md</span>
</div>
<h3 style="margin: 0;">
<a href="#" class="feed-heading">&gt; POSIX sh vs. Bash: Portability in Modern Scripts</a>
</h3>
<p class="feed-excerpt">
Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#posix-sh]</span>
<span>[#shell]</span>
<span>[#unix]</span>
</div>
<a href="#" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
<!-- Post 4: Heap Exploitation -->
<article class="feed-card" data-tags="security">
<div class="feed-meta-row">
<time datetime="2026-06-28" class="feed-date">2026-06-28 &bull; 15 min read</time>
<span>~/notes/ctf-heap-glibc-2-35.md</span>
</div>
<h3 style="margin: 0;">
<a href="article-tiling-heap.html" class="feed-heading">&gt; CTF Write-up: Heap Exploitation in glibc 2.35</a>
</h3>
<p class="feed-excerpt">
Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking for arbitrary code execution.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#ctf]</span>
<span>[#binary-exploitation]</span>
<span>[#security]</span>
</div>
<a href="article-tiling-heap.html" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
<!-- Post 5: Zero-Trust WireGuard -->
<article class="feed-card" data-tags="networking security homelab">
<div class="feed-meta-row">
<time datetime="2026-06-14" class="feed-date">2026-06-14 &bull; 10 min read</time>
<span>~/notes/zero-trust-wireguard-opnsense.md</span>
</div>
<h3 style="margin: 0;">
<a href="#" class="feed-heading">&gt; Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
</h3>
<p class="feed-excerpt">
Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.
</p>
<div class="feed-tags-row">
<div class="tag-cluster">
<span>[#networking]</span>
<span>[#wireguard]</span>
<span>[#security]</span>
</div>
<a href="#" style="color: var(--accent-cyan); text-decoration: none;">Read Entry &rarr;</a>
</div>
</article>
</div>
</section>
<!-- Global Footer Tile (Matching Gateway 3 Exactly) -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="service-gateway-tiling.html" class="footer-btn">Gateway Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
function filterTopic(topic, btn) {
document.querySelectorAll('.filter-tag-btn').forEach(el => el.classList.remove('active'));
btn.classList.add('active');
const cards = document.querySelectorAll('#feedList .feed-card');
cards.forEach(card => {
if (topic === 'all') {
card.style.display = 'flex';
} else {
const tags = card.getAttribute('data-tags') || '';
if (tags.includes(topic)) {
card.style.display = 'flex';
} else {
card.style.display = 'none';
}
}
});
}
</script>
</body>
</html>
+711
View File
@@ -0,0 +1,711 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Blog Lander (Asymmetric 3-Tile Workspace)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered tile surface */
--border-color: #2b303b; /* Crisp 1px solid border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary active accent */
--accent-green: #00e676; /* Operational status indicator */
--accent-amber: #ffb700; /* Pinned highlight accent */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1120px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Header Bar (Gateway 3 Standard) */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
.bar-link.active {
color: var(--text-primary);
border-bottom: 1px solid var(--accent-cyan);
}
/* Hero Manifesto Tile */
.hero-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 4px;
padding: 24px 28px;
display: flex;
flex-direction: column;
gap: 12px;
}
.hero-pretitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.hero-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.1rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
}
.hero-prose {
font-size: 0.98rem;
color: var(--text-primary);
line-height: 1.65;
max-width: 84ch;
}
/* Interactive Grep Bar */
.grep-bar {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 8px 14px;
display: flex;
align-items: center;
gap: 10px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
}
.grep-prompt {
color: var(--accent-cyan);
font-weight: 700;
}
.grep-input {
background: transparent;
border: none;
outline: none;
color: var(--text-primary);
font-family: inherit;
font-size: 0.82rem;
flex: 1;
}
/* Main Asymmetric Split Grid */
.split-grid {
display: grid;
grid-template-columns: 1.25fr 0.75fr;
gap: 16px;
}
@media (max-width: 880px) {
.split-grid {
grid-template-columns: 1fr;
}
}
/* Standard Tile Container */
.tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}
.tile-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
}
.tile-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.92rem;
font-weight: 700;
color: var(--text-primary);
}
.tile-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
/* Featured Entry Card inside Primary Column */
.featured-entry {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px;
display: flex;
flex-direction: column;
gap: 10px;
}
.featured-entry:hover {
border-color: var(--accent-cyan);
}
.entry-badge-row {
display: flex;
justify-content: space-between;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.75rem;
}
.entry-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.2rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
transition: none;
}
.entry-title:hover {
color: var(--accent-cyan);
}
.entry-abstract {
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.6;
}
/* Code Preview Box */
.snippet-box {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 3px;
font-family: 'JetBrains Mono', monospace;
font-size: 0.76rem;
overflow: hidden;
}
.snippet-head {
background-color: var(--bg-canvas);
border-bottom: 1px solid var(--border-color);
padding: 4px 10px;
color: var(--text-muted);
display: flex;
justify-content: space-between;
font-size: 0.72rem;
}
.snippet-body {
padding: 10px;
overflow-x: auto;
color: var(--text-primary);
}
.entry-footer-row {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 8px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
}
.read-pill {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 4px 10px;
font-weight: 700;
border-radius: 2px;
text-decoration: none;
transition: none;
}
.read-pill:hover {
background-color: transparent;
color: var(--accent-cyan);
box-shadow: inset 0 0 0 1px var(--accent-cyan);
}
/* Right Column Component: Track Cards */
.track-tile-item {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 12px;
display: flex;
flex-direction: column;
gap: 6px;
text-decoration: none;
transition: none;
}
.track-tile-item:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.track-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
font-weight: 700;
color: var(--text-primary);
}
.track-tile-item:hover .track-title {
color: var(--accent-cyan);
}
.track-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.72rem;
color: var(--accent-cyan);
}
.track-desc {
font-size: 0.8rem;
color: var(--text-muted);
line-height: 1.45;
}
/* Right Column: Mini Feed Items */
.compact-feed-item {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 12px;
display: flex;
flex-direction: column;
gap: 6px;
}
.compact-feed-item:hover {
border-color: var(--accent-cyan);
}
.compact-date {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--accent-cyan);
}
.compact-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.92rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
line-height: 1.35;
}
.compact-title:hover {
color: var(--accent-cyan);
}
/* Global Footer Tile (Gateway 3 Match) */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Global Bar (Matching Gateway 3 Exactly) -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // TECHNICAL NOTES WORKSPACE</span>
</div>
<nav class="bar-nav" aria-label="Top Navigation">
<a href="service-gateway-tiling.html" class="bar-link">Gateway 3 ↗</a>
<a href="#" class="bar-link active">&gt; Field Notes</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="feed.xml" class="bar-link">RSS Feed</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Hero Tile: Mission Statement & Live Filter -->
<section class="hero-tile" aria-label="Notes Mission">
<div class="hero-pretitle">SYSTEM DISPATCHES &bull; KNOWLEDGE BASE</div>
<h1 class="hero-title">Technical Notes &amp; Systems Architecture</h1>
<p class="hero-prose">
Deep technical documentation on network forensics, self-hosted hypervisor infrastructure, embedded hardware exploitation, and minimal Unix tool design.
</p>
<div class="grep-bar">
<span class="grep-prompt">dev-blog@system:~$</span>
<span style="color: var(--text-muted);">grep -i</span>
<input
type="text"
id="liveFilterInput"
class="grep-input"
placeholder="filter dispatches by keyword, hardware, or ctf..."
oninput="filterArticles(this.value)"
>
<span id="matchStats" style="color: var(--accent-green); font-size: 0.74rem;">5 dispatches loaded</span>
</div>
</section>
<!-- Asymmetric Split Grid -->
<div class="split-grid">
<!-- Left Column: Featured Articles & Primary Feed -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Tile: Featured Article 1 (Hardware Lead) -->
<section class="tile article-container" data-keywords="firmware hardware security spi bus-pirate flash extraction" aria-label="Lead Article 1">
<div class="tile-header">
<div class="tile-title">
<span>// FEATURED WRITE-UP 01</span>
</div>
<span class="tile-meta">2026-07-20 &bull; 8 MIN READ</span>
</div>
<div class="featured-entry">
<div class="entry-badge-row">
<span style="color: var(--accent-amber); font-weight: 700;">[PINNED RESEARCH]</span>
<span style="color: var(--text-muted);">~/notes/iot-firmware-spi-extraction.md</span>
</div>
<h2 style="margin: 0;">
<a href="#" class="entry-title">&gt; Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</h2>
<p class="entry-abstract">
In security audits of embedded systems, retrieving the firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom.
</p>
<div class="snippet-box">
<div class="snippet-head">
<span>extract_firmware.sh</span>
<span>POSIX sh</span>
</div>
<div class="snippet-body">
<pre><code># Query the SPI flash details using flashrom via Bus Pirate
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
# Verify the integrity of the binary dump by comparing hashes
if [ $? -eq 0 ]; then
echo "Dump successful. Running md5sum..."
md5sum firmware_dump.bin
fi</code></pre>
</div>
</div>
<div class="entry-footer-row">
<span style="color: var(--text-muted);">[#firmware] [#hardware] [#security] [#bus-pirate]</span>
<a href="#" class="read-pill">READ WRITEUP [8 MIN] &rarr;</a>
</div>
</div>
</section>
<!-- Tile: Featured Article 2 (Infrastructure Lead) -->
<section class="tile article-container" data-keywords="homelab docker traefik networking compose proxy acme" aria-label="Lead Article 2">
<div class="tile-header">
<div class="tile-title">
<span>// FEATURED WRITE-UP 02</span>
</div>
<span class="tile-meta">2026-07-15 &bull; 12 MIN READ</span>
</div>
<div class="featured-entry">
<div class="entry-badge-row">
<span style="color: var(--accent-cyan); font-weight: 700;">[INFRASTRUCTURE SPEC]</span>
<span style="color: var(--text-muted);">~/notes/ha-traefik-docker.md</span>
</div>
<h2 style="margin: 0;">
<a href="#" class="entry-title">&gt; Building a High-Availability Traefik Router with Docker Compose</a>
</h2>
<p class="entry-abstract">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes on bare-metal infrastructure.
</p>
<div class="snippet-box">
<div class="snippet-head">
<span>traefik-compose.yml</span>
<span>YAML</span>
</div>
<div class="snippet-body">
<pre><code>services:
traefik:
image: traefik:v3.1
command:
- "--providers.docker=true"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.cf.acme.dnschallenge=true"</code></pre>
</div>
</div>
<div class="entry-footer-row">
<span style="color: var(--text-muted);">[#homelab] [#docker-traefik] [#networking]</span>
<a href="#" class="read-pill">READ WRITEUP [12 MIN] &rarr;</a>
</div>
</div>
</section>
<!-- Tile: Featured Article 3 (Unix Systems) -->
<section class="tile article-container" data-keywords="posix-sh shell unix portability alpine scripts bashisms" aria-label="Lead Article 3">
<div class="tile-header">
<div class="tile-title">
<span>// SYSTEMS &amp; SCRIPTING DISPATCH</span>
</div>
<span class="tile-meta">2026-07-10 &bull; 6 MIN READ</span>
</div>
<div class="featured-entry">
<div class="entry-badge-row">
<span style="color: var(--accent-green); font-weight: 700;">[STANDARDS &amp; COMPLIANCE]</span>
<span style="color: var(--text-muted);">~/notes/posix-sh-vs-bash.md</span>
</div>
<h2 style="margin: 0;">
<a href="#" class="entry-title">&gt; POSIX sh vs. Bash: Portability in Modern Scripts</a>
</h2>
<p class="entry-abstract">
Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
</p>
<div class="entry-footer-row">
<span style="color: var(--text-muted);">[#posix-sh] [#shell] [#unix]</span>
<a href="#" class="read-pill">READ WRITEUP [6 MIN] &rarr;</a>
</div>
</div>
</section>
</div>
<!-- Right Column: Curated Tracks & Additional Dispatches -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Curated Topic Tracks Tile -->
<section class="tile" aria-label="Curated Topic Tracks">
<div class="tile-header">
<div class="tile-title">
<span>// CURATED TRACKS</span>
</div>
<span class="tile-meta">SPECIALIZATIONS</span>
</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<a href="#" class="track-tile-item">
<div class="track-title">Embedded Silicon &amp; Hardware</div>
<div class="track-meta">[1 ARTICLE &bull; BUS PIRATE]</div>
<p class="track-desc">Physical chip extraction, UART/JTAG probing, SPI dump validation.</p>
</a>
<a href="#" class="track-tile-item">
<div class="track-title">Self-Hosted Infrastructure</div>
<div class="track-meta">[2 ARTICLES &bull; TRAEFIK &amp; WIREGUARD]</div>
<p class="track-desc">Automated edge routing, zero-trust overlay networks, VLAN firewalls.</p>
</a>
<a href="#" class="track-tile-item">
<div class="track-title">Low-Level Binary Exploitation</div>
<div class="track-meta">[1 ARTICLE &bull; GLIBC HEAP]</div>
<p class="track-desc">Memory allocator internals, tcache safe-linking mangling bypass.</p>
</a>
<a href="#" class="track-tile-item">
<div class="track-title">Zero-Allocation Tooling</div>
<div class="track-meta">[1 ARTICLE &bull; POSIX SH]</div>
<p class="track-desc">High-throughput logging, shell parser ASTs, minimalist runtimes.</p>
</a>
</div>
</section>
<!-- More Articles in Archive Tile -->
<section class="tile" aria-label="Additional Dispatches">
<div class="tile-header">
<div class="tile-title">
<span>// CTF &amp; SECURITY WIRE</span>
</div>
<span class="tile-meta">REPORTS</span>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;">
<!-- Post 4: Heap Exploitation -->
<div class="compact-feed-item article-container" data-keywords="ctf binary exploitation heap glibc 2.35 memory security">
<span class="compact-date">2026-06-28 &bull; 15 min read</span>
<a href="#" class="compact-title">&gt; CTF Write-up: Heap Exploitation in glibc 2.35</a>
<p style="font-size: 0.8rem; color: var(--text-muted); line-height: 1.45;">
Deconstructing tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking.
</p>
<div style="font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; color: var(--text-muted); margin-top: 4px;">
[#ctf] [#binary-exploitation]
</div>
</div>
<!-- Post 5: Zero-Trust WireGuard -->
<div class="compact-feed-item article-container" data-keywords="networking wireguard security zerotrust opnsense vlans">
<span class="compact-date">2026-06-14 &bull; 10 min read</span>
<a href="#" class="compact-title">&gt; Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
<p style="font-size: 0.8rem; color: var(--text-muted); line-height: 1.45;">
Designing strict zone-based firewall rules across isolated VLANs with point-to-point WireGuard cryptographic routing.
</p>
<div style="font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; color: var(--text-muted); margin-top: 4px;">
[#networking] [#wireguard]
</div>
</div>
</div>
</section>
</div>
</div>
<!-- Global Footer Tile (Matching Gateway 3 Exactly) -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="service-gateway-tiling.html" class="footer-btn">Gateway Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
<script>
function filterArticles(query) {
const q = query.toLowerCase().trim();
const items = document.querySelectorAll('.article-container');
let matches = 0;
items.forEach(item => {
const text = (item.innerText + ' ' + (item.getAttribute('data-keywords') || '')).toLowerCase();
if (!q || text.includes(q)) {
item.style.display = '';
matches++;
} else {
item.style.display = 'none';
}
});
document.getElementById('matchStats').innerText = `${matches} dispatches visible`;
}
</script>
</body>
</html>
+288
View File
@@ -0,0 +1,288 @@
# Canonical Content Dataset & Single Source of Truth for Design Samples
**Document Purpose:** Standardized dataset containing canonical profile data, active services, technical blog notes, engineering projects, hardware nodes, and interactive ASCII daemon assets. All design sample layouts (`homepage.html`, `split-panel.html`, `companion.html`, `document-flow.html`, `portfolio.html`, `homelab.html`, `public-services.html`, `sample-dashboard.html`, `sample-command-center.html`, `sample-dual-pane-explorer.html`) pull from this common material.
---
## 1. Persona & Identity (`whoami`)
| Field | Canonical Value |
| :--- | :--- |
| **Full Name** | `River Rooks` |
| **Primary Title** | `Systems Architecture & Cybersecurity` |
| **Academic / Institutional Role** | Cybersecurity student at the University of Alabama College of Engineering |
| **Specialization Areas** | Network forensics, self-hosted infrastructure, systems architecture, low-level tooling, bare-metal virtualization |
| **Physical Node Location** | Alabama, USA / `RACK-01` |
| **System Hostname Prompt** | `dev-blog@system:~$` / `agy --node-01` |
| **PGP Key Fingerprint** | `0x4A8E92F1C0B3D4E7` |
| **SSH Public Key Digest** | `SHA256:7uK+N04wP5rL/9z3Q8s1vX4dF6mK2pT8yB1wN0qZ8` |
| **Email Address** | `river@rooks.dev` (or `river@example.com`) |
| **Public Git Forge** | `https://git.rooks.dev` / `https://github.com` |
| **Matrix Chat Endpoint** | `@river:rooks.dev` |
### Biography Snippets
* **One-Line Meta:** `Cybersecurity student at UA College of Engineering focusing on network forensics, self-hosted infrastructure, and systems architecture.`
* **Extended Bio:** `Cybersecurity student and systems practitioner. Spends time architecting high-throughput homelab networks, reverse engineering IoT firmware, hardening FreeBSD/Linux hypervisors, and writing zero-allocation Unix utilities.`
### Active Tech Stack Tags
```text
[#network-forensics] [#docker-traefik] [#arch-linux] [#neovim] [#wireguard]
[#posix-sh] [#python] [#golang] [#rust] [#proxmox] [#truenas]
```
---
## 2. Services Directory & Infrastructure Catalog
### A. Core & Network Infrastructure
| Service Name | Category | Port / Protocol | Domain / Routing | Access | Description |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Traefik Proxy (v3.1)** | `#core` | `443/tcp` (TLS) | `https://proxy.rooks.dev` | `INTERNAL / ONLINE` | Edge HTTP reverse proxy and load balancer with dynamic Docker provider discovery and ACME Let's Encrypt TLS wildcard certificates. |
| **OPNsense Firewall (v24.7)** | `#core` | `VLAN 10 / Mgmt` | Gateway IP | `PROTECTED / ACTIVE` | Hardened FreeBSD firewall routing 10GbE traffic with VLAN isolation, Suricata IDS/IPS, and Unbound DNS resolvers. |
| **AdGuard Home** | `#dns` | `53/udp`, `853/tcp` | `https://dns.rooks.dev` | `INTERNAL / PROTECTED` | Network-wide DNS sinkhole filtering trackers and ad domains across all VLANs with DNS-over-HTTPS upstream security. |
| **WireGuard Mesh** | `#vpn` | `51820/udp` | Peer Mesh | `PUBLIC / 14 PEERS` | High-performance encrypted point-to-point VPN tunnel connecting remote laptops and mobile endpoints to homelab subnet. |
### B. Compute, Virtualization & Storage
| Service Name | Category | Port / Protocol | Domain / Routing | Access | Description |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Proxmox VE (v8.2)** | `#compute` | `8006/tcp` | `https://pve.rooks.dev` | `INTERNAL / ONLINE` | Enterprise hypervisor cluster hosting Debian LXC containers and KVM virtual machines with Ceph & ZFS backend. |
| **TrueNAS SCALE** | `#storage` | `NFS / SMB / 443` | `https://nas.rooks.dev` | `INTERNAL / ONLINE` | Primary network attached storage managing 48TB ZFS RaidZ2 array, dataset snapshots, NFS exports, and scrub jobs. |
| **Forgejo Git Server** | `#dev-git` | `3000/tcp`, `2222/ssh` | `https://git.rooks.dev` | `PUBLIC / OPEN` | Lightweight self-hosted Git forge hosting infrastructure-as-code repos, Ansible playbooks, dotfiles, and CTF archives. |
### C. Public Tools & Developer Utilities
| Service Name | Category | Port / Protocol | Domain / Routing | Access | Description |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **CyberChef Workbench** | `#security-tool` | `443/tcp` | `https://chef.rooks.dev` | `PUBLIC / OPEN` | Cyber Swiss Army Knife for hex decoding, Base64 operations, regex extraction, cryptographic hashing, and CTF payload analysis. |
| **Stirling PDF Studio** | `#pdf-tools` | `443/tcp` | `https://pdf.rooks.dev` | `PUBLIC / OPEN` | Self-hosted document processing suite for merging, splitting, OCR text extraction, password encryption, and PDF page manipulation. |
| **HedgeDoc Collaborative** | `#markdown` | `443/tcp` | `https://pad.rooks.dev` | `PUBLIC / OPEN` | Real-time collaborative Markdown editor for technical specs, RFC drafts, and collaborative meeting notes. |
### D. Media, Reading & Content Automation
| Service Name | Category | Port / Protocol | Domain / Routing | Access | Description |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Jellyfin Media Portal** | `#media-video` | `8096/tcp` | `https://watch.rooks.dev` | `AUTH REQUIRED` | FOSS media streaming engine leveraging Intel QuickSync GPU hardware acceleration for 4K HDR transcoding. |
| **Arr Automation Suite** | `#automation` | `8989 / 7878 / 9696` | `https://arr.rooks.dev` | `INTERNAL / RUNNING` | Automated content indexing, Prowlarr indexer management, Sonarr/Radarr pipeline, and SABnzbd queue downloader. |
| **Audiobookshelf** | `#media-audio` | `443/tcp` | `https://listen.rooks.dev` | `INVITE ONLY` | Self-hosted audiobook and podcast streaming server with continuous playback position synchronization across mobile clients. |
| **Calibre-Web Library** | `#ebooks` | `443/tcp` | `https://read.rooks.dev` | `PUBLIC READ` | E-book library catalog with e-reader OPDS feed integration and in-browser reading support. |
### E. Security, Telemetry & Communications
| Service Name | Category | Port / Protocol | Domain / Routing | Access | Description |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Vaultwarden** | `#secrets` | `443/tcp` (E2EE) | `https://vault.rooks.dev` | `2FA / AUTH` | Lightweight Rust implementation of the Bitwarden API hosting encrypted credentials, SSH keys, and TOTP tokens. |
| **Prometheus & Grafana** | `#telemetry` | `3000 / 9090` | `https://mon.rooks.dev` | `INTERNAL / SCRAPING` | Time-series metric collection with Node Exporter, Telegraf agents, and live cluster performance dashboards. |
| **Uptime Kuma** | `#status` | `3001/tcp` | `https://status.rooks.dev` | `PUBLIC / 100% HEALTH`| Synthetic HTTP, Ping, and TCP health monitor broadcasting real-time service uptime alerts to Discord webhooks. |
| **Matrix Synapse** | `#messaging` | `8448/tcp` | `https://matrix.rooks.dev` | `FEDERATED / OPEN` | Federated Matrix homeserver for encrypted messaging, public security channels, and cross-server communication. |
---
## 3. Technical Notes & Blog Articles
### Post 1: Featured Article (Full Writeup)
* **Title:** `Reverse Engineering IoT Firmware: SPI Flash Extraction`
* **File / Path:** `~/notes/iot-firmware-spi-extraction.md`
* **Publication Date:** `2026-07-20`
* **Reading Time:** `8 mins`
* **Tags:** `[#firmware]`, `[#hardware]`, `[#security]`, `[#bus-pirate]`
* **Abstract:** In security audits of embedded systems, retrieving the firmware is the critical first step. When over-the-air updates are encrypted and debug ports (UART, JTAG) are disabled in production silicon, dumping physical SPI Flash memory becomes necessary. This writeup covers extracting firmware from an 8-pin SOP SPI flash chip using a Bus Pirate and flashrom to bypass bootloader lockdowns.
* **Code Snippet (`extract_firmware.sh`):**
```bash
#!/bin/sh
# Query the SPI flash details using flashrom via Bus Pirate
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
# Verify the integrity of the binary dump by comparing hashes
if [ $? -eq 0 ]; then
echo "Dump successful. Running md5sum..."
md5sum firmware_dump.bin
else
echo "Failed to read flash memory." >&2
exit 1
fi
```
### Post 2: Traefik Docker Architecture
* **Title:** `Building a High-Availability Traefik Router with Docker Compose`
* **File / Path:** `~/notes/ha-traefik-docker.md`
* **Publication Date:** `2026-07-15`
* **Reading Time:** `12 mins`
* **Tags:** `[#homelab]`, `[#docker-traefik]`, `[#networking]`
* **Abstract:** Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and backend health-check failover routes.
### Post 3: Shell Portability
* **Title:** `POSIX sh vs. Bash: Portability in Modern Scripts`
* **File / Path:** `~/notes/posix-sh-vs-bash.md`
* **Publication Date:** `2026-07-10`
* **Reading Time:** `6 mins`
* **Tags:** `[#posix-sh]`, `[#shell]`, `[#unix]`
* **Abstract:** Analyzing edge-case incompatibilities, syntax overhead, eliminating bashisms, and writing fast, bulletproof bootstrapping scripts for Alpine and embedded targets conforming to IEEE Std 1003.1.
### Post 4: Low-Level CTF Exploitation
* **Title:** `CTF Write-up: Heap Exploitation in glibc 2.35`
* **File / Path:** `~/notes/ctf-heap-glibc-2-35.md`
* **Publication Date:** `2026-06-28`
* **Reading Time:** `15 mins`
* **Tags:** `[#ctf]`, `[#binary-exploitation]`, `[#security]`
* **Abstract:** Deconstructing modern glibc memory allocator defenses: tcache safe-linking pointer mangling, bypass primitives, and House of Apple file structure hijacking for arbitrary code execution.
### Post 5: Network Isolation
* **Title:** `Zero-Trust Network Isolation with WireGuard & OPNsense VLANs`
* **File / Path:** `~/notes/zero-trust-wireguard-opnsense.md`
* **Publication Date:** `2026-06-14`
* **Reading Time:** `10 mins`
* **Tags:** `[#networking]`, `[#wireguard]`, `[#security]`
* **Abstract:** Designing strict zone-based firewall rules across isolated VLANs (Management, Server DMZ, IoT, Trusted Clients) with point-to-point WireGuard cryptographic routing.
---
## 4. Engineering Projects & System Modules
### Module 1: Custom POSIX Shell Parser
* **Path / Identifier:** `/dev/posix-shell-parser`
* **Version:** `v1.2.0`
* **Primary Language:** `Lua`
* **Tags:** `[#lua]`, `[#ast-parser]`, `[#compilers]`
* **Summary:** A lightweight Lexer and AST parser written in Lua for parsing POSIX-compliant shell scripts. Optimized to avoid runtime heap allocations during tokenization, enabling real-time syntax coloring inside terminal buffers.
* **Code Snippet (`lexer.lua`):**
```lua
local function tokenize(src)
local tokens = {}
for pos, char in ipairs(src) do
if char == ";" or char == "|" then
table.insert(tokens, { type = "OPERATOR", value = char })
end
end
return tokens
end
```
### Module 2: WireGuard Mesh Topology Builder
* **Path / Identifier:** `/dev/wireguard-mesh`
* **Version:** `v0.8.4`
* **Primary Language:** `Python` / `POSIX sh`
* **Tags:** `[#networking]`, `[#wireguard]`, `[#automation]`
* **Summary:** Automated configuration generator that computes public/private key matrices and generates atomic configuration files for full-mesh WireGuard overlay networks spanning cloud VMs and homelab servers.
### Module 3: Zero-Allocation Logger (Go)
* **Path / Identifier:** `/dev/zero-alloc-logger`
* **Version:** `v2.1.1`
* **Primary Language:** `Go`
* **Tags:** `[#go]`, `[#performance]`, `[#systems]`
* **Summary:** A high-throughput structured JSON logger utilizing `sync.Pool` memory recycling to eliminate GC pause overhead during disk I/O (>500,000 log events/second).
### Module 4: Embedded Kernel Boot Strap
* **Path / Identifier:** `/dev/kernel-bootstrap`
* **Version:** `v0.1.0`
* **Primary Language:** `ARM Cortex Assembly` / `C`
* **Tags:** `[#arm-cortex]`, `[#assembly]`, `[#embedded]`
* **Summary:** Bare-metal boot sector and initial C runtime setup for ARM Cortex-M microcontrollers. Configures vector table offset registers, performs memory section copying, and initializes early UART debugging output.
### Module 5: Traefik Cloudflare Dynamic DNS Daemon
* **Path / Identifier:** `/dev/ddns-daemon`
* **Version:** `v1.0.2`
* **Primary Language:** `Python` / `Docker SDK`
* **Tags:** `[#docker]`, `[#traefik]`, `[#cloudflare]`
* **Summary:** Background controller daemon monitoring Docker container state transitions and synchronizing container label subdomains with Cloudflare DNS A/AAAA records.
---
## 5. Physical Hardware Nodes & Telemetry
```text
+-------------------+ 10GbE SFP+ +-------------------+
| gw-node01.lan | <==================> | pve-node02.lan |
| OPNsense 24.7 | | Proxmox VE 8.2 |
| Intel N100 (4C/4T)| | AMD 5900X (12C/24T|
+-------------------+ +-------------------+
|| ||
|| 10GbE Trunk || 10GbE NFS/SMB
\/ \/
+--------------------------------------------------------------+
| nas-node03.lan |
| TrueNAS SCALE (48TB RaidZ2 Pool) |
| Intel Core i5-12400 (6C/12T) / 64GB ECC |
+--------------------------------------------------------------+
```
| Hostname | Role / Operating System | Hardware Specifications | Nominal Load |
| :--- | :--- | :--- | :--- |
| **`gw-node01.lan`** | Edge Gateway / OPNsense 24.7 | Intel N100 (4C/4T), 16GB DDR5, 4x 2.5GbE I226-V | CPU: 18% \| RAM: 32% |
| **`pve-node02.lan`** | Hypervisor / Proxmox VE 8.2 | AMD Ryzen 9 5900X (12C/24T), 128GB ECC DDR4, 2x 2TB NVMe | CPU: 42% \| RAM: 68% |
| **`nas-node03.lan`** | Storage / TrueNAS SCALE | Intel Core i5-12400 (6C/12T), 64GB ECC, 6x 16TB Enterprise SAS | CPU: 14% \| RAM: 82% (ZFS ARC) |
---
## 6. ASCII Mascot & Daemon Artframes (`sys-daemon`)
### Frame 1: Idle / Scanning
```text
.-----------------.
/ ^ ^ ^ /|
/ (_) (_) (_) / |
/__________________/ |
| ___ ___ | |
| [o_o] [o_o] | |
| `-' `-' | |
| ______ | |
| / \ | /
| | -- | | /
| \____/ |/
`------------------'
```
### Frame 2: Active / Alert
```text
.-----------------.
/ ^ ^ ^ /|
/ (_) (_) (_) / |
/__________________/ |
| ___ ___ | |
| [-_-] [-_-] | |
| `-' `-' | |
| ______ | |
| / \ | /
| | O | | /
| \____/ |/
`------------------'
```
### Frame 3: Scroll-Tracker Cat Daemon
```text
/\___/\
( o o ) sys-daemon
( =^= ) [TRACKING]
(---)
```
---
## 7. Sample Pages Material Mapping Matrix
This matrix specifies which components and data entries from this canonical document are presented in each sample layout:
| Sample File | Layout Style | Persona / Bio | Services Included | Notes / Articles | Project Modules | Nodes & Telemetry | Mascot / Daemon |
| :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
| [`index.html`](file:///home/venus/code/blog/index.html) | Root Minimalist Business Card | Full whoami | — | — | Active Stack Tags | Terminal stdout | — |
| [`samples/homepage.html`](file:///home/venus/code/blog/samples/homepage.html) | Sample 1: Developer Homepage | Profile header | — | Post 1 (Full) + Archive Index (2,3,4) | — | — | — |
| [`samples/split-panel.html`](file:///home/venus/code/blog/samples/split-panel.html) | Sample 2: Split Panel Feed | — | — | — | Modules 1–5 | Status row | Frame 1/2 Animated |
| [`samples/companion.html`](file:///home/venus/code/blog/samples/companion.html) | Sample 3: Companion Layout | — | — | — | Modules 1–5 | Terminal card | Frame 3 Cat Daemon |
| [`samples/document-flow.html`](file:///home/venus/code/blog/samples/document-flow.html) | Sample 4: Continuous Document Flow | Header banner | — | Post 1 Snippets | Modules 1–5 in detail | — | Frame 3 Scroll Tracker |
| [`samples/portfolio.html`](file:///home/venus/code/blog/samples/portfolio.html) | Sample 5: Portfolio Card | Full whoami | — | — | Active Stack Tags | Terminal stdout | — |
| [`samples/homelab.html`](file:///home/venus/code/blog/samples/homelab.html) | Sample 6: Homelab Lander | Header banner | All Core & Compute (12 services) | — | — | Nodes 1–3 + ASCII Topology | Terminal logs |
| [`samples/public-services.html`](file:///home/venus/code/blog/samples/public-services.html) | Sample 7: Public Portal | Header banner | All Public Utilities (9 services) | — | — | Keys & PGP box | — |
| [`samples/sample-dashboard.html`](file:///home/venus/code/blog/samples/sample-dashboard.html) | Sample 8: 3-Tile Workspace | Center tile bio | Left tile services | Right tile archive | Center tile projects | Status bar | Vim command bar |
| [`samples/sample-command-center.html`](file:///home/venus/code/blog/samples/sample-command-center.html) | Sample 9: Tabbed Command Center | Tab 3 (Resume) | Tab 1 (Services) | Tab 2 (Blog Notes) | Tab 3 (Projects) | Tab 1 (Nodes) | Status dots |
| [`samples/sample-dual-pane-explorer.html`](file:///home/venus/code/blog/samples/sample-dual-pane-explorer.html) | Sample 10: Helix Tree Explorer | Sidebar links | Services subtree | Notes subtree | Modules subtree | Status bar | Sidebar companion |
| [`samples/blog-lander-stream.html`](file:///home/venus/code/blog/samples/blog-lander-stream.html) | Blog Lander 1: Minimalist Stream | Header & Bio | — | Posts 1–5 (Linear Feed & Topic Filter) | — | — | — |
| [`samples/blog-lander-terminal.html`](file:///home/venus/code/blog/samples/blog-lander-terminal.html) | Blog Lander 2: Terminal Directory Index | Header & Subtitle | — | Posts 1–5 (Dense Tabular Index & Code Inspection) | — | Terminal Status Bar | — |
| [`samples/blog-lander-cards.html`](file:///home/venus/code/blog/samples/blog-lander-cards.html) | Blog Lander 3: Curated Dispatch & Cards | Profile & Bio | — | Post 1 (Pinned Lead Card) + Posts 2–5 (Cards Grid) | — | — | — |
| [`samples/service-gateway-manifesto.html`](file:///home/venus/code/blog/samples/service-gateway-manifesto.html) | Gateway Lander 1: Manifesto & System Hub | Hero Manifesto & Bio | 6 Core/Public Services | Posts 1–3 Excerpts | — | Status banner | — |
| [`samples/service-gateway-terminal.html`](file:///home/venus/code/blog/samples/service-gateway-terminal.html) | Gateway Lander 2: Host Console & MOTD Router | MOTD Narrative & Specs | 6 Tabular Services | Posts 1–5 Log Lines | — | Hardware summary | — |
| [`samples/service-gateway-tiling.html`](file:///home/venus/code/blog/samples/service-gateway-tiling.html) | Gateway Lander 3: Tiling Workspace Hub | Hero Landing Tile | 5 Grid Services (Blog Core Tile) | Posts 1–4 Sublinks | — | Nodes 1–3 Live Telemetry | — |
| [`samples/blog-tiling-lead.html`](file:///home/venus/code/blog/samples/blog-tiling-lead.html) | Tiling Blog 1: Hero Dispatch & Dual Stream | Hero Tile & Topic Filter | — | Post 1 (Lead with Code) + Posts 2–5 (Feed) | — | Archive Telemetry | — |
| [`samples/blog-tiling-split.html`](file:///home/venus/code/blog/samples/blog-tiling-split.html) | Tiling Blog 2: Asymmetric 3-Tile Workspace | Hero Tile & Grep Bar | — | Posts 1–3 (Featured) + Posts 4–5 (Wire) | — | Curated Tracks | — |
| [`samples/blog-tiling-catalog.html`](file:///home/venus/code/blog/samples/blog-tiling-catalog.html) | Tiling Blog 3: Dual-Lead Grid & Inspection Feed | Hero Tile & Badges | — | Posts 1–2 (Dual Leads) + Posts 3–5 (Table) | — | Inline Note Inspector | — |
| [`samples/article-tiling-firmware.html`](file:///home/venus/code/blog/samples/article-tiling-firmware.html) | Article 1: IoT Firmware Extraction | Header & Meta | — | Post 1 (Full Markdown, Code, Tables, Alerts) | — | Winbond 25Q64 specs | — |
| [`samples/article-tiling-traefik.html`](file:///home/venus/code/blog/samples/article-tiling-traefik.html) | Article 2: HA Traefik Router | Header & Meta | — | Post 2 (Full Markdown, Compose YAML, ASCII Diagram) | — | pve-node02.lan specs | — |
| [`samples/article-tiling-heap.html`](file:///home/venus/code/blog/samples/article-tiling-heap.html) | Article 3: CTF Heap Exploitation | Header & Meta | — | Post 4 (Full Markdown, GDB session, C payload, Formula) | — | glibc 2.35 runtime | — |
+18 -13
View File
@@ -345,6 +345,11 @@
<a href="companion.html" class="nav-link active">Sample 3</a>
<a href="document-flow.html" class="nav-link">Sample 4</a>
<a href="portfolio.html" class="nav-link">Sample 5</a>
<a href="homelab.html" class="nav-link">Sample 6</a>
<a href="public-services.html" class="nav-link">Sample 7</a>
<a href="sample-dashboard.html" class="nav-link">Sample 8</a>
<a href="sample-command-center.html" class="nav-link">Sample 9</a>
<a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10</a>
</nav>
</header>
@@ -354,53 +359,53 @@
<!-- Left Pane: Scrollable Project Cards -->
<main class="left-pane" aria-label="Project Feed">
<div class="scroll-content">
<h2 class="section-title">System Modules</h2>
<h2 class="section-title">River Rooks // System Modules</h2>
<div class="card-list">
<!-- Card 1 -->
<div class="project-card" tabindex="0" data-target="/dev/posix-shell-parser">
<h3 class="card-title">Custom POSIX Shell Parser</h3>
<h3 class="card-title">Custom POSIX Shell Parser <span style="font-size: 0.8rem; font-weight: 400; color: var(--text-muted);">[v1.2.0 • #lua]</span></h3>
<p class="card-description">
A lightweight Lexer and AST parser written in Lua for parsing POSIX-compliant shell scripts. Highly optimized for syntax coloring inside modal environments.
A lightweight Lexer and AST parser written in Lua for parsing POSIX-compliant shell scripts. Highly optimized for syntax coloring inside modal environments without runtime heap allocations.
</p>
</div>
<!-- Card 2 -->
<div class="project-card" tabindex="0" data-target="/dev/wireguard-mesh">
<h3 class="card-title">WireGuard Mesh Topology Builder</h3>
<h3 class="card-title">WireGuard Mesh Topology Builder <span style="font-size: 0.8rem; font-weight: 400; color: var(--text-muted);">[v0.8.4 • #wireguard]</span></h3>
<p class="card-description">
Automated configuration generator for setting up full-mesh WireGuard private overlays across cloud instances and local homelab nodes.
Automated configuration generator for computing key matrices and setting up full-mesh WireGuard private overlays across cloud instances and local homelab nodes.
</p>
</div>
<!-- Card 3 -->
<div class="project-card" tabindex="0" data-target="/dev/zero-alloc-logger">
<h3 class="card-title">Zero-Allocation Logger (Go)</h3>
<h3 class="card-title">Zero-Allocation Logger (Go) <span style="font-size: 0.8rem; font-weight: 400; color: var(--text-muted);">[v2.1.1 • #golang]</span></h3>
<p class="card-description">
A high-performance JSON structure logger that uses sync.Pool buffers to avoid memory allocation overhead during intensive disk operations.
A high-performance JSON structure logger that uses sync.Pool buffers to avoid memory allocation overhead during intensive disk operations (>500k ops/sec).
</p>
</div>
<!-- Card 4 -->
<div class="project-card" tabindex="0" data-target="/dev/kernel-bootstrap">
<h3 class="card-title">Embedded Kernel Boot Strap</h3>
<h3 class="card-title">Embedded Kernel Boot Strap <span style="font-size: 0.8rem; font-weight: 400; color: var(--text-muted);">[v0.1.0 • #arm-cortex]</span></h3>
<p class="card-description">
Minimalist boot sector and initial kernel bootstrap for ARM Cortex-M microcontrollers to handle memory map initialization and early UART status printouts.
Minimalist boot sector and initial kernel bootstrap for ARM Cortex-M microcontrollers to handle vector table offset mapping and early UART status printouts.
</p>
</div>
<!-- Card 5 -->
<div class="project-card" tabindex="0" data-target="/dev/ddns-daemon">
<h3 class="card-title">Traefik Cloudflare DDNS Daemon</h3>
<h3 class="card-title">Traefik Cloudflare DDNS Daemon <span style="font-size: 0.8rem; font-weight: 400; color: var(--text-muted);">[v1.0.2 • #docker-traefik]</span></h3>
<p class="card-description">
Background controller daemon designed to sync Docker container network labels with Cloudflare DNS records to route traffic to local homelab subdomains.
Background controller daemon designed to sync Docker container network labels with Cloudflare DNS records to route traffic to local homelab subdomains dynamically.
</p>
</div>
</div>
<footer class="pane-footer">
<span>Companion Spec Sample</span>
<span>© 2026 Developer System</span>
<span>Sample 3: Companion Layout</span>
<span>© 2026 River Rooks</span>
</footer>
</div>
</main>
+8 -3
View File
@@ -379,6 +379,11 @@
<a href="companion.html" class="nav-link">Sample 3</a>
<a href="document-flow.html" class="nav-link active">Sample 4</a>
<a href="portfolio.html" class="nav-link">Sample 5</a>
<a href="homelab.html" class="nav-link">Sample 6</a>
<a href="public-services.html" class="nav-link">Sample 7</a>
<a href="sample-dashboard.html" class="nav-link">Sample 8</a>
<a href="sample-command-center.html" class="nav-link">Sample 9</a>
<a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10</a>
</nav>
</header>
@@ -407,9 +412,9 @@
<!-- Document Header -->
<header class="document-header">
<h1 class="doc-title">Engineering Architecture & Portfolio</h1>
<h1 class="doc-title">River Rooks // Systems &amp; Architecture</h1>
<p class="doc-subtitle">
A high-density technical reading flow. Pinned left pane contains an automated terminal tracker daemon observing scroll depth across sections.
A high-density technical reading flow. Pinned left pane contains an automated terminal tracker daemon observing scroll depth across system modules.
</p>
</header>
@@ -536,7 +541,7 @@ end</code></pre>
<footer class="pane-footer">
<span>Sample 4: Document Flow Layout</span>
<span>© 2026 Developer System</span>
<span>© 2026 River Rooks</span>
</footer>
</div>
+12 -10
View File
@@ -512,6 +512,10 @@
<a href="document-flow.html" class="nav-link">Sample 4</a>
<a href="portfolio.html" class="nav-link">Sample 5</a>
<a href="homelab.html" class="nav-link active">Sample 6 (Homelab)</a>
<a href="public-services.html" class="nav-link">Sample 7</a>
<a href="sample-dashboard.html" class="nav-link">Sample 8</a>
<a href="sample-command-center.html" class="nav-link">Sample 9</a>
<a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10</a>
</nav>
</header>
@@ -771,9 +775,9 @@
<tr>
<td class="node-hostname">nas-node03.lan</td>
<td>TrueNAS SCALE</td>
<td>Intel Xeon E-2278G (8C/16T) | 64GB ECC | 6x16TB ZFS</td>
<td><span class="metric-bar">[██░░░░░░░░]</span> 24%</td>
<td><span class="metric-bar">[████████░░]</span> 81%</td>
<td>Intel Core i5-12400 (6C/12T) | 64GB ECC | 6x 16TB RaidZ2</td>
<td><span class="metric-bar">[██░░░░░░░░]</span> 14%</td>
<td><span class="metric-bar">[████████░░]</span> 82%</td>
</tr>
</tbody>
</table>
@@ -800,7 +804,7 @@
│
▼
┌─────────────────────────┐
│ Traefik v3 Reverse Proxy│ (Auto TLS Certs / Authelia 2FA)
│ Traefik v3 Reverse Proxy│ (Auto TLS Certs / Dynamic Docker)
└───────────┬─────────────┘
│
┌─────────┴───────────────────────┬─────────────────────────┐
@@ -808,7 +812,7 @@
┌─────────────────────────┐ ┌───────────────────────┐ ┌─────────────────────────┐
│ VLAN 10: Management │ │ VLAN 20: Services │ │ VLAN 30: Storage Pool │
│ • Proxmox VE (8006) │ │ • Grafana (3000) │ │ • TrueNAS ZFS (SMB/NFS) │
│ • AdGuard Home (53) │ │ • Jellyfin Media │ │ • MinIO S3 Bucket │
│ • AdGuard Home (53) │ │ • Jellyfin Media │ │ • Forgejo Git (3000) │
└─────────────────────────┘ └───────────────────────┘ └─────────────────────────┘
</div>
</section>
@@ -819,13 +823,11 @@
<footer class="footer-links">
<a href="index.html" class="footer-link">Spec Catalog</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">GitHub</a>
<a href="https://git.rooks.dev" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="mailto:river@example.com" class="footer-link">Email</a>
<a href="mailto:river@rooks.dev" class="footer-link">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" class="footer-link">PGP Key</a>
<span class="pipe">|</span>
<span style="font-size:0.78rem; color:var(--text-muted);">HOSTED ON SELF-HEALED K3S CLUSTER</span>
<span style="font-size:0.78rem; color:var(--text-muted);">CLUSTER ONLINE • 48TB ZFS POOL • 10GbE SFP+ BACKBONE</span>
</footer>
</main>
+29 -30
View File
@@ -356,40 +356,33 @@
<!-- Sidebar Navigation -->
<aside class="sidebar">
<div class="profile-title">[node-01]</div>
<div class="profile-title">River Rooks</div>
<div class="profile-subtitle">dev-blog@system:~$</div>
<nav>
<ul class="nav-list">
<li class="nav-item">
<a href="homepage.html" class="nav-link active">Home</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link">Posts</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link">Projects</a>
</li>
<li class="nav-item">
<a href="index.html" class="nav-link">Spec Catalog</a>
</li>
<li class="nav-item"><a href="index.html" class="nav-link">Catalog</a></li>
<li class="nav-item"><a href="homepage.html" class="nav-link active">Sample 1 (Home)</a></li>
<li class="nav-item"><a href="split-panel.html" class="nav-link">Sample 2 (Split)</a></li>
<li class="nav-item"><a href="companion.html" class="nav-link">Sample 3 (Daemon)</a></li>
<li class="nav-item"><a href="document-flow.html" class="nav-link">Sample 4 (Doc Flow)</a></li>
<li class="nav-item"><a href="portfolio.html" class="nav-link">Sample 5 (Portfolio)</a></li>
<li class="nav-item"><a href="homelab.html" class="nav-link">Sample 6 (Homelab)</a></li>
<li class="nav-item"><a href="public-services.html" class="nav-link">Sample 7 (Services)</a></li>
<li class="nav-item"><a href="sample-dashboard.html" class="nav-link">Sample 8 (Dashboard)</a></li>
<li class="nav-item"><a href="sample-command-center.html" class="nav-link">Sample 9 (Command)</a></li>
<li class="nav-item"><a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10 (Explorer)</a></li>
</ul>
</nav>
<!-- Keybindings Panel Widget -->
<div class="keybindings-panel">
<div class="keybindings-title">Keyboard Shortcuts</div>
<div class="keybinding-row">
<span>Search posts</span>
<kbd>Ctrl</kbd> + <kbd>K</kbd>
</div>
<div class="keybinding-row">
<span>Go to Catalog</span>
<kbd>g</kbd> + <kbd>c</kbd>
</div>
<div class="keybinding-row">
<span>Toggle Terminal</span>
<kbd>~</kbd>
<div class="keybindings-title">Active Stack</div>
<div style="font-size: 0.75rem; color: var(--text-muted); line-height: 1.6;">
[#network-forensics]<br>
[#docker-traefik]<br>
[#arch-linux] [#neovim]<br>
[#wireguard] [#posix-sh]
</div>
</div>
</aside>
@@ -410,6 +403,7 @@
<a href="#" class="tag">[#firmware]</a>
<a href="#" class="tag">[#hardware]</a>
<a href="#" class="tag">[#security]</a>
<a href="#" class="tag">[#bus-pirate]</a>
</div>
<p>
@@ -436,7 +430,7 @@ flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
echo <span class="syn-string">"Dump successful. Running md5sum..."</span>
md5sum firmware_dump.bin
<span class="syn-keyword">else</span>
echo <span class="syn-string">"Failed to read flash memory."</span> >&2
echo <span class="syn-string">"Failed to read flash memory."</span> &gt;&amp;2
<span class="syn-keyword">exit</span> 1
<span class="syn-keyword">fi</span></code></pre>
</div>
@@ -451,7 +445,7 @@ flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
<!-- Tabular Archive Index Section -->
<section>
<h2>Recent Writes & Archive</h2>
<h2>Recent Writes &amp; Archive</h2>
<p style="color: var(--text-muted); font-size: 0.9rem; margin-bottom: 20px;">
Dense, terminal-style index of prior posts. Press <kbd>Tab</kbd> to focus and navigate rows instantly.
</p>
@@ -473,21 +467,26 @@ flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
<tr onclick="location.href='#'">
<td class="post-date">2026-07-10</td>
<td><a href="#">POSIX sh vs. Bash: Portability in Modern Scripts</a></td>
<td><span style="color: var(--accent);">[#shell]</span></td>
<td><span style="color: var(--accent);">[#posix-sh]</span></td>
</tr>
<tr onclick="location.href='#'">
<td class="post-date">2026-06-28</td>
<td><a href="#">CTF Write-up: Heap Exploitation in glibc 2.35</a></td>
<td><span style="color: var(--accent);">[#ctf]</span></td>
</tr>
<tr onclick="location.href='#'">
<td class="post-date">2026-06-14</td>
<td><a href="#">Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a></td>
<td><span style="color: var(--accent);">[#networking]</span></td>
</tr>
</tbody>
</table>
</section>
<!-- Footer -->
<footer>
<span>© 2026 Developer Blog</span>
<span>Built with Design-Specification.md</span>
<span>© 2026 River Rooks</span>
<span>Aligned with Canonical-Sample-Content.md</span>
</footer>
</div>
+780 -240
View File
File diff suppressed because it is too large Load Diff
+15 -4
View File
@@ -282,6 +282,11 @@
<a href="companion.html" class="nav-link">Sample 3</a>
<a href="document-flow.html" class="nav-link">Sample 4</a>
<a href="portfolio.html" class="nav-link active">Sample 5</a>
<a href="homelab.html" class="nav-link">Sample 6</a>
<a href="public-services.html" class="nav-link">Sample 7</a>
<a href="sample-dashboard.html" class="nav-link">Sample 8</a>
<a href="sample-command-center.html" class="nav-link">Sample 9</a>
<a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10</a>
</nav>
</header>
@@ -310,7 +315,7 @@
<div class="terminal-body">
<div class="cmd-line"><span class="prompt">$</span> cat /var/log/status.txt</div>
<div class="cmd-output">
Under construction. Full site infrastructure is currently being provisioned. Routing traffic to temporary landing page...<span class="cursor-block"></span>
Provisioning 10GbE homelab cluster. Routing traffic through Traefik v3 edge proxy...<span class="cursor-block"></span>
</div>
</div>
</div>
@@ -320,7 +325,7 @@
<section class="bio-section">
<h2 class="section-title">whoami</h2>
<p class="bio-text">
Cybersecurity student at the University of Alabama College of Engineering, focusing on network forensics, self-hosted infrastructure, and systems architecture.
Cybersecurity student at the University of Alabama College of Engineering, focusing on network forensics, self-hosted infrastructure, systems architecture, and low-level Unix tooling.
</p>
</section>
@@ -335,6 +340,10 @@
<span class="tag">[#wireguard]</span>
<span class="tag">[#posix-sh]</span>
<span class="tag">[#python]</span>
<span class="tag">[#golang]</span>
<span class="tag">[#rust]</span>
<span class="tag">[#proxmox]</span>
<span class="tag">[#truenas]</span>
</div>
</section>
@@ -342,11 +351,13 @@
<!-- E. Footer (Contact & Links) -->
<footer class="footer-links">
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">GitHub</a>
<span class="pipe">|</span>
<a href="mailto:river@example.com" class="footer-link">Email</a>
<a href="mailto:river@rooks.dev" class="footer-link">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" class="footer-link">PGP Key</a>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-link">PGP: 0x4A8E92F1...</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-link">Spec Catalog</a>
</footer>
+12 -11
View File
@@ -545,6 +545,9 @@
<a href="portfolio.html" class="nav-link">Sample 5</a>
<a href="homelab.html" class="nav-link">Sample 6</a>
<a href="public-services.html" class="nav-link active">Sample 7 (Public Services)</a>
<a href="sample-dashboard.html" class="nav-link">Sample 8</a>
<a href="sample-command-center.html" class="nav-link">Sample 9</a>
<a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10</a>
</nav>
</header>
@@ -797,10 +800,10 @@
<div class="key-row">
<div>
<span class="key-label">PGP Key Fingerprint:</span><br>
<span class="key-value">3F8A B29C 7D1E 4056 9912 A8B0 C4D3 E2F1 8091 22A4</span>
<span class="key-label">PGP Key ID / Fingerprint:</span><br>
<span class="key-value">0x4A8E92F1C0B3D4E7 • 3F8A B29C 7D1E 4056 9912 A8B0 C4D3 E2F1 8091 22A4</span>
</div>
<button class="copy-btn" onclick="navigator.clipboard.writeText('3F8AB29C7D1E40569912A8B0C4D3E2F1809122A4')">Copy Key Fingerprint</button>
<button class="copy-btn" onclick="navigator.clipboard.writeText('0x4A8E92F1C0B3D4E7')">Copy Key ID</button>
</div>
<div class="key-row">
@@ -813,10 +816,10 @@
<div class="key-row">
<div>
<span class="key-label">Public SSH Key:</span><br>
<span class="key-value">ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8q882a... river@rooks.dev</span>
<span class="key-label">Public SSH Key Digest:</span><br>
<span class="key-value">SHA256:7uK+N04wP5rL/9z3Q8s1vX4dF6mK2pT8yB1wN0qZ8 (river@rooks.dev)</span>
</div>
<button class="copy-btn" onclick="navigator.clipboard.writeText('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8q882aZ9kX1m2pL3vN4qR5sT6uV7wX8yZ9river@rooks.dev')">Copy Public Key</button>
<button class="copy-btn" onclick="navigator.clipboard.writeText('SHA256:7uK+N04wP5rL/9z3Q8s1vX4dF6mK2pT8yB1wN0qZ8')">Copy Digest</button>
</div>
</div>
@@ -828,13 +831,11 @@
<footer class="footer-links">
<a href="index.html" class="footer-link">Spec Catalog</a>
<span class="pipe">|</span>
<a href="https://github.com" target="_blank" rel="noopener" class="footer-link">GitHub</a>
<a href="https://git.rooks.dev" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="mailto:river@example.com" class="footer-link">Email Contact</a>
<a href="mailto:river@rooks.dev" class="footer-link">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" class="footer-link">Download PGP Key</a>
<span class="pipe">|</span>
<span style="font-size:0.78rem; color:var(--text-muted);">PUBLIC SERVICES PORTAL v2.4</span>
<span style="font-size:0.78rem; color:var(--text-muted);">PUBLIC SERVICES PORTAL • RIVER ROOKS</span>
</footer>
</main>
+85 -49
View File
@@ -290,7 +290,7 @@
<header class="app-header">
<div class="brand-title">
<span class="status-dot"></span>
RIVER ROOKS // COMMAND CENTER
<a href="index.html" style="color: var(--text-primary); text-decoration: none;">RIVER ROOKS // COMMAND CENTER</a>
</div>
<nav class="nav-tabs">
@@ -308,56 +308,80 @@
<div class="panel">
<div class="panel-header">
<span>/etc/services.d/manifest.json</span>
<span>4 SERVICES OPERATIONAL</span>
<span>6 CANONICAL SERVICES</span>
</div>
<div class="panel-body">
<div class="services-grid">
<div class="service-box">
<div class="service-title">
<a href="https://grafana.local" target="_blank">grafana.homelab</a>
<a href="https://proxy.rooks.dev" target="_blank">Traefik Proxy (v3.1)</a>
<span class="badge-status badge-online">ONLINE</span>
</div>
<p class="service-desc">Real-time metrics, Prometheus scraping, &amp; homelab telemetry dashboards.</p>
<p class="service-desc">Edge HTTP reverse proxy with dynamic ACME Let's Encrypt TLS wildcard certificates.</p>
<div class="service-stats">
<span>PING: 4ms</span>
<span>TRAEFIK HTTPS</span>
<span>PORT: 443/tcp</span>
<span>#core</span>
</div>
</div>
<div class="service-box">
<div class="service-title">
<a href="https://vault.local" target="_blank">vault.homelab</a>
<a href="https://nas.rooks.dev" target="_blank">TrueNAS SCALE</a>
<span class="badge-status badge-online">ONLINE</span>
</div>
<p class="service-desc">HashiCorp Vault secret storage, certificate authority, &amp; mTLS renewal.</p>
<p class="service-desc">Primary storage pool managing 48TB ZFS RaidZ2 array with daily scrub jobs.</p>
<div class="service-stats">
<span>PING: 2ms</span>
<span>SEALED: FALSE</span>
<span>NFS / SMB</span>
<span>#storage</span>
</div>
</div>
<div class="service-box">
<div class="service-title">
<a href="https://nextcloud.local" target="_blank">cloud.homelab</a>
<span class="badge-status badge-online">ONLINE</span>
<a href="https://vault.rooks.dev" target="_blank">Vaultwarden Secrets</a>
<span class="badge-status badge-online">E2EE</span>
</div>
<p class="service-desc">Encrypted private cloud file storage &amp; automated system backup target.</p>
<p class="service-desc">Rust implementation of Bitwarden API hosting credentials, SSH keys, &amp; 2FA.</p>
<div class="service-stats">
<span>PING: 6ms</span>
<span>STORAGE: 1.2TB</span>
<span>2FA / AUTH</span>
<span>#secrets</span>
</div>
</div>
<div class="service-box">
<div class="service-title">
<a href="https://wireguard.local" target="_blank">wireguard.homelab</a>
<span class="badge-status badge-internal">INTERNAL</span>
<a href="https://git.rooks.dev" target="_blank">Forgejo Git Forge</a>
<span class="badge-status badge-online">PUBLIC</span>
</div>
<p class="service-desc">WireGuard mesh VPN gateway connecting cloud VPS instances to homelab node.</p>
<p class="service-desc">Self-hosted Git platform for dotfiles, playbooks, and CTF binary writeups.</p>
<div class="service-stats">
<span>PING: 12ms</span>
<span>PEERS: 6 ACTIVE</span>
<span>PORT: 3000</span>
<span>#dev-git</span>
</div>
</div>
<div class="service-box">
<div class="service-title">
<a href="https://chef.rooks.dev" target="_blank">CyberChef Workbench</a>
<span class="badge-status badge-online">PUBLIC</span>
</div>
<p class="service-desc">Hex decoding, Base64 operations, regex extraction, &amp; payload analysis.</p>
<div class="service-stats">
<span>OPEN WEB</span>
<span>#security-tool</span>
</div>
</div>
<div class="service-box">
<div class="service-title">
<a href="https://pve.rooks.dev" target="_blank">Proxmox VE (v8.2)</a>
<span class="badge-status badge-online">ONLINE</span>
</div>
<p class="service-desc">Hypervisor cluster hosting Debian LXC containers &amp; KVM virtual machines.</p>
<div class="service-stats">
<span>PORT: 8006</span>
<span>#compute</span>
</div>
</div>
@@ -371,7 +395,7 @@
<div class="panel">
<div class="panel-header">
<span>/var/log/articles.index</span>
<span>POST COUNT: 4</span>
<span>POST COUNT: 5</span>
</div>
<div class="panel-body" style="padding: 0;">
<table class="blog-table">
@@ -385,28 +409,34 @@
</thead>
<tbody>
<tr>
<td>2026-08-02</td>
<td><a href="#" class="post-link">Hardening Traefik Ingress with HashiCorp Vault mTLS</a></td>
<td><span class="tag-badge">[#homelab] [#traefik]</span></td>
<td>2026-07-20</td>
<td><a href="#" class="post-link">Reverse Engineering IoT Firmware: SPI Flash Extraction</a></td>
<td><span class="tag-badge">[#firmware] [#hardware]</span></td>
<td>8 min</td>
</tr>
<tr>
<td>2026-07-18</td>
<td><a href="#" class="post-link">DEFCON CTF Qualifier: Memory Corruption &amp; Heap Exploitation</a></td>
<td>2026-07-15</td>
<td><a href="#" class="post-link">Building a High-Availability Traefik Router with Docker Compose</a></td>
<td><span class="tag-badge">[#homelab] [#traefik]</span></td>
<td>12 min</td>
</tr>
<tr>
<td>2026-07-10</td>
<td><a href="#" class="post-link">POSIX sh vs. Bash: Portability in Modern Scripts</a></td>
<td><span class="tag-badge">[#posix-sh] [#unix]</span></td>
<td>6 min</td>
</tr>
<tr>
<td>2026-06-28</td>
<td><a href="#" class="post-link">CTF Write-up: Heap Exploitation in glibc 2.35</a></td>
<td><span class="tag-badge">[#ctf] [#binary]</span></td>
<td>14 min</td>
<td>15 min</td>
</tr>
<tr>
<td>2026-06-29</td>
<td><a href="#" class="post-link">Custom Linux Kernel Compilation for BPF Network Tracing</a></td>
<td><span class="tag-badge">[#linux] [#ebpf]</span></td>
<td>11 min</td>
</tr>
<tr>
<td>2026-05-14</td>
<td><a href="#" class="post-link">Minimalist Dotfiles &amp; Hyprland Keybindings Optimization</a></td>
<td><span class="tag-badge">[#hyprland] [#dots]</span></td>
<td>5 min</td>
<td>2026-06-14</td>
<td><a href="#" class="post-link">Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a></td>
<td><span class="tag-badge">[#networking] [#wireguard]</span></td>
<td>10 min</td>
</tr>
</tbody>
</table>
@@ -424,25 +454,31 @@
<div class="panel-body">
<div class="conf-block">
<span class="conf-comment"># Identity &amp; System Purpose</span><br>
<span class="conf-comment"># Identity &amp; Systems Architecture</span><br>
<span class="conf-key">AUTHOR</span> = <span class="conf-val">"River Rooks"</span><br>
<span class="conf-key">ROLE</span> = <span class="conf-val">"Systems Architect &amp; Cybersecurity Researcher"</span><br>
<span class="conf-key">AFFILIATION</span> = <span class="conf-val">"University of Alabama College of Engineering"</span><br><br>
<span class="conf-key">ROLE</span> = <span class="conf-val">"Systems Architecture &amp; Cybersecurity"</span><br>
<span class="conf-key">AFFILIATION</span> = <span class="conf-val">"University of Alabama College of Engineering"</span><br>
<span class="conf-key">PGP_KEY</span> = <span class="conf-val">"0x4A8E92F1C0B3D4E7"</span><br><br>
<span class="conf-comment"># Active Skillset Matrix</span><br>
<span class="conf-key">DOMAINS</span> = [<span class="conf-val">"Network Forensics"</span>, <span class="conf-val">"Self-Hosted Infrastructure"</span>, <span class="conf-val">"Linux Kernel Hardening"</span>]<br>
<span class="conf-key">LANGUAGES</span> = [<span class="conf-val">"POSIX sh"</span>, <span class="conf-val">"Python"</span>, <span class="conf-val">"C"</span>, <span class="conf-val">"Lua"</span>]<br>
<span class="conf-key">TOOLS</span> = [<span class="conf-val">"Docker"</span>, <span class="conf-val">"Traefik"</span>, <span class="conf-val">"WireGuard"</span>, <span class="conf-val">"Neovim"</span>, <span class="conf-val">"Arch Linux"</span>]
<span class="conf-key">DOMAINS</span> = [<span class="conf-val">"Network Forensics"</span>, <span class="conf-val">"Self-Hosted Infrastructure"</span>, <span class="conf-val">"Bare-Metal Virtualization"</span>]<br>
<span class="conf-key">LANGUAGES</span> = [<span class="conf-val">"POSIX sh"</span>, <span class="conf-val">"Python"</span>, <span class="conf-val">"Go"</span>, <span class="conf-val">"Lua"</span>, <span class="conf-val">"ARM Assembly"</span>]<br>
<span class="conf-key">STACK</span> = [<span class="conf-val">"Traefik v3"</span>, <span class="conf-val">"WireGuard"</span>, <span class="conf-val">"Proxmox VE"</span>, <span class="conf-val">"TrueNAS"</span>, <span class="conf-val">"Neovim"</span>]
</div>
<p style="font-size: 0.92rem; margin-bottom: 16px;">
Focused on building resilient, zero-trust network architectures and low-noise self-hosted environments.
Proven CTF participant and open-source dotfiles maintainer.
</p>
<h3 style="font-family: 'IBM Plex Mono', monospace; font-size: 0.95rem; margin-bottom: 12px;">System Modules:</h3>
<ul style="font-size: 0.88rem; color: var(--text-muted); line-height: 1.8; margin-bottom: 20px; list-style-position: inside;">
<li><strong style="color: var(--accent-cyan);">/dev/posix-shell-parser</strong> (v1.2.0 • Lua) — Zero-allocation AST lexer</li>
<li><strong style="color: var(--accent-cyan);">/dev/wireguard-mesh</strong> (v0.8.4 • Python) — Full-mesh overlay provisioner</li>
<li><strong style="color: var(--accent-cyan);">/dev/zero-alloc-logger</strong> (v2.1.1 • Go) — High-throughput sync.Pool logger</li>
<li><strong style="color: var(--accent-cyan);">/dev/kernel-bootstrap</strong> (v0.1.0 • ARM ASM) — Bare-metal boot setup</li>
<li><strong style="color: var(--accent-cyan);">/dev/ddns-daemon</strong> (v1.0.2 • Docker API) — Dynamic Cloudflare DNS sync</li>
</ul>
<div style="display: flex; gap: 12px;">
<a href="#" class="btn-action">Download Resume (.PDF)</a>
<a href="#" class="btn-action">Fetch PGP Key</a>
<a href="mailto:river@rooks.dev" class="btn-action">Email: river@rooks.dev</a>
<a href="https://git.rooks.dev" class="btn-action">Git Repositories ↗</a>
<a href="index.html" class="btn-action">Spec Catalog ↗</a>
</div>
</div>
+85 -45
View File
@@ -268,13 +268,25 @@
<!-- Top Status Navigation -->
<header class="top-bar">
<div>
<div style="display: flex; align-items: center; gap: 12px;">
<span class="mode-tag">NORMAL</span>
<span class="filepath">/home/river/dashboard.workspace</span>
<span style="color: var(--border-color);">|</span>
<nav style="display: flex; gap: 8px; font-size: 0.78rem;">
<a href="index.html" style="color: var(--text-primary); text-decoration: none;">Catalog</a>
<span style="color: var(--border-color);">/</span>
<a href="homelab.html" style="color: var(--text-muted); text-decoration: none;">Homelab</a>
<span style="color: var(--border-color);">/</span>
<a href="public-services.html" style="color: var(--text-muted); text-decoration: none;">Services</a>
<span style="color: var(--border-color);">/</span>
<a href="sample-command-center.html" style="color: var(--text-muted); text-decoration: none;">Command</a>
<span style="color: var(--border-color);">/</span>
<a href="sample-dual-pane-explorer.html" style="color: var(--text-muted); text-decoration: none;">Explorer</a>
</nav>
</div>
<div class="status-group">
<span><span class="status-dot"></span> TRAEFIK: MESH_OK</span>
<span>SYS_LOAD: 0.14</span>
<span><span class="status-dot"></span> TRAEFIK: V3.1 OK</span>
<span>CLUSTER: 10GbE SFP+</span>
<span>UPTIME: 99.98%</span>
</div>
</header>
@@ -282,59 +294,71 @@
<!-- Main 3-Tile Dashboard -->
<main class="dashboard-grid">
<!-- Left Tile: Homelab Services Directory -->
<!-- Left Tile: Homelab & Public Services Directory -->
<section class="tile">
<div class="tile-header">
<span>/etc/services</span>
<span>[4 ACTIVE]</span>
<span>[CANONICAL SERVICES]</span>
</div>
<div class="tile-body">
<div class="service-card">
<div class="service-head">
<a href="https://grafana.local" target="_blank">grafana.homelab</a>
<a href="https://proxy.rooks.dev" target="_blank">Traefik Proxy (v3.1)</a>
<span class="badge-online">[ONLINE]</span>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Telemetry & Prometheus monitoring dashboards.</p>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Edge HTTP reverse proxy with dynamic ACME wildcard TLS.</p>
<div class="service-meta">
<span>PORT: :3000</span>
<span>HTTPS</span>
<span>PORT: 443/tcp</span>
<span>#core</span>
</div>
</div>
<div class="service-card">
<div class="service-head">
<a href="https://vault.local" target="_blank">vault.homelab</a>
<a href="https://nas.rooks.dev" target="_blank">TrueNAS SCALE</a>
<span class="badge-online">[ONLINE]</span>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">HashiCorp Vault secret storage & certificates.</p>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Primary storage pool managing 48TB ZFS RaidZ2 array.</p>
<div class="service-meta">
<span>PORT: :8200</span>
<span>mTLS</span>
<span>NFS / SMB</span>
<span>#storage</span>
</div>
</div>
<div class="service-card">
<div class="service-head">
<a href="https://nextcloud.local" target="_blank">cloud.homelab</a>
<span class="badge-online">[ONLINE]</span>
<a href="https://vault.rooks.dev" target="_blank">Vaultwarden Secrets</a>
<span class="badge-online">[E2EE]</span>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Private encrypted document & data storage.</p>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Lightweight Rust Bitwarden API hosting credentials &amp; 2FA.</p>
<div class="service-meta">
<span>PORT: :443</span>
<span>HTTPS</span>
<span>2FA / AUTH</span>
<span>#secrets</span>
</div>
</div>
<div class="service-card">
<div class="service-head">
<a href="https://wireguard.local" target="_blank">vpn.homelab</a>
<span class="badge-internal">[INTERNAL]</span>
<a href="https://git.rooks.dev" target="_blank">Forgejo Git Forge</a>
<span class="badge-online">[PUBLIC]</span>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">WireGuard mesh overlay network ingress.</p>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Self-hosted Git platform for dotfiles, playbooks &amp; CTF code.</p>
<div class="service-meta">
<span>UDP: :51820</span>
<span>VPN</span>
<span>PORT: 3000</span>
<span>#dev-git</span>
</div>
</div>
<div class="service-card">
<div class="service-head">
<a href="https://chef.rooks.dev" target="_blank">CyberChef Workbench</a>
<span class="badge-online">[PUBLIC]</span>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 6px;">Hex decoding, Base64, hashing &amp; CTF payload analysis.</p>
<div class="service-meta">
<span>OPEN WEB</span>
<span>#security-tool</span>
</div>
</div>
@@ -349,11 +373,11 @@
</div>
<div class="tile-body">
<h1 class="hero-title">River Rooks</h1>
<div class="subtitle">SYSTEMS ARCHITECT &amp; CYBERSECURITY RESEARCHER</div>
<div class="subtitle">SYSTEMS ARCHITECTURE &amp; CYBERSECURITY</div>
<p class="bio-prose">
Computer Science &amp; Cybersecurity student at the University of Alabama College of Engineering.
Specializing in low-level network forensics, self-hosted infrastructure resilience, and hardened Linux kernel configurations.
Cybersecurity student at the University of Alabama College of Engineering.
Focusing on network forensics, self-hosted infrastructure resilience, bare-metal virtualization, and low-level Unix tooling.
</p>
<h2 class="section-title">active_stack</h2>
@@ -365,22 +389,32 @@
<span>[#wireguard]</span>
<span>[#posix-sh]</span>
<span>[#python]</span>
<span>[#hashicorp-vault]</span>
<span>[#golang]</span>
<span>[#rust]</span>
<span>[#proxmox]</span>
<span>[#truenas]</span>
</div>
<h2 class="section-title">featured_projects</h2>
<h2 class="section-title">featured_modules</h2>
<div class="project-card">
<div class="project-title">mesh-topology-builder</div>
<div class="project-title">/dev/posix-shell-parser <span style="font-size: 0.75rem; color: var(--text-muted);">[v1.2.0 • #lua]</span></div>
<p style="font-size: 0.85rem; color: var(--text-primary);">
Automated WireGuard mesh network provisioner written in POSIX shell and Python. Generates deterministic keypairs and Traefik routing rules.
Zero-allocation Lexer and AST parser written in Lua for parsing POSIX shell scripts inside modal terminal buffers.
</p>
</div>
<div class="project-card">
<div class="project-title">pcap-forensics-parser</div>
<div class="project-title">/dev/wireguard-mesh <span style="font-size: 0.75rem; color: var(--text-muted);">[v0.8.4 • #wireguard]</span></div>
<p style="font-size: 0.85rem; color: var(--text-primary);">
High-throughput PCAP packet analyzer built for CTF competitions to detect anomalous TCP handshake flags and hidden ICMP payloads.
Automated configuration generator computing key matrices and provisioning full-mesh WireGuard private overlays across cloud and homelab nodes.
</p>
</div>
<div class="project-card">
<div class="project-title">/dev/zero-alloc-logger <span style="font-size: 0.75rem; color: var(--text-muted);">[v2.1.1 • #golang]</span></div>
<p style="font-size: 0.85rem; color: var(--text-primary);">
High-throughput structured JSON logger utilizing sync.Pool byte buffers to eliminate heap allocation GC overhead (>500k ops/sec).
</p>
</div>
@@ -396,27 +430,33 @@
<div class="tile-body">
<div class="article-item">
<div class="article-date">2026-08-02 | #HOMELAB</div>
<a href="#" class="article-link">Hardening Traefik Ingress with HashiCorp Vault mTLS</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Zero-trust certificate auto-renewal pipeline configuration.</p>
<div class="article-date">2026-07-20 | #FIRMWARE</div>
<a href="#" class="article-link">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Dumping SPI flash chips via Bus Pirate &amp; flashrom to bypass locked bootloaders.</p>
</div>
<div class="article-item">
<div class="article-date">2026-07-18 | #CTF</div>
<a href="#" class="article-link">DEFCON CTF Qualifier: Memory Corruption &amp; Heap Exploitation</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Deconstructing glibc malloc chunk metadata manipulation.</p>
<div class="article-date">2026-07-15 | #HOMELAB</div>
<a href="#" class="article-link">Building a High-Availability Traefik Router with Docker Compose</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Dynamic Docker provider discovery &amp; Let's Encrypt automated TLS wildcard routing.</p>
</div>
<div class="article-item">
<div class="article-date">2026-06-29 | #LINUX</div>
<a href="#" class="article-link">Custom Linux Kernel Compilation for BPF Network Tracing</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Configuring eBPF probe hooks for real-time socket inspection.</p>
<div class="article-date">2026-07-10 | #POSIX-SH</div>
<a href="#" class="article-link">POSIX sh vs. Bash: Portability in Modern Scripts</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Eliminating bashisms and adhering to IEEE Std 1003.1 for high-speed bootstrapping.</p>
</div>
<div class="article-item">
<div class="article-date">2026-05-14 | #HYPRLAND</div>
<a href="#" class="article-link">Minimalist Dotfiles &amp; Hyprland Keybindings Optimization</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Ergonomic modal editing &amp; window tiling configuration setup.</p>
<div class="article-date">2026-06-28 | #CTF</div>
<a href="#" class="article-link">CTF Write-up: Heap Exploitation in glibc 2.35</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Tcache safe-linking bypass and House of Apple file structure hijacking primitives.</p>
</div>
<div class="article-item">
<div class="article-date">2026-06-14 | #NETWORKING</div>
<a href="#" class="article-link">Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
<p style="font-size: 0.78rem; color: var(--text-muted);">Segregating untrusted IoT devices, homelab servers, and management networks.</p>
</div>
</div>
@@ -427,7 +467,7 @@
<!-- Interactive Terminal Footer Bar -->
<footer class="cmd-footer">
<span class="prompt-symbol">$</span>
<input type="text" class="cmd-input" placeholder="Type :help, :open <service>, or press Ctrl+K for commands..." readonly>
<input type="text" class="cmd-input" placeholder="River Rooks Workspace • Type :help or click links to navigate..." readonly>
</footer>
</body>
+148 -68
View File
@@ -207,12 +207,24 @@
<!-- Top Breadcrumbs Bar -->
<header class="top-nav">
<div>
<div style="display: flex; align-items: center; gap: 12px;">
<span class="status-dot"></span>
<span>RIVER ROOKS // TREE EXPLORER</span>
<span style="font-weight: 700;">RIVER ROOKS // TREE EXPLORER</span>
<span style="color: var(--border-color);">|</span>
<nav style="display: flex; gap: 8px; font-size: 0.78rem;">
<a href="index.html" style="color: var(--text-primary); text-decoration: none;">Catalog</a>
<span style="color: var(--border-color);">/</span>
<a href="homepage.html" style="color: var(--text-muted); text-decoration: none;">Sample 1</a>
<span style="color: var(--border-color);">/</span>
<a href="homelab.html" style="color: var(--text-muted); text-decoration: none;">Homelab</a>
<span style="color: var(--border-color);">/</span>
<a href="public-services.html" style="color: var(--text-muted); text-decoration: none;">Services</a>
<span style="color: var(--border-color);">/</span>
<a href="sample-dashboard.html" style="color: var(--text-muted); text-decoration: none;">Dashboard</a>
</nav>
</div>
<div>
<span>POSITION: /home/river/services/grafana.md</span>
<span style="color: var(--text-muted);">HOST: pve-node02.lan [10GbE]</span>
</div>
</header>
@@ -225,13 +237,22 @@
<div class="tree-view">
<div class="tree-folder">▾ /services/</div>
<div class="tree-item active" onclick="selectItem(this, 'grafana')">grafana.md <span>[SVC]</span></div>
<div class="tree-item" onclick="selectItem(this, 'vault')">vault.md <span>[SVC]</span></div>
<div class="tree-item" onclick="selectItem(this, 'wireguard')">wireguard.md <span>[SVC]</span></div>
<div class="tree-item active" onclick="selectItem(this, 'traefik')">traefik.md <span>[SVC]</span></div>
<div class="tree-item" onclick="selectItem(this, 'truenas')">truenas.md <span>[SVC]</span></div>
<div class="tree-item" onclick="selectItem(this, 'vaultwarden')">vaultwarden.md <span>[SVC]</span></div>
<div class="tree-item" onclick="selectItem(this, 'forgejo')">forgejo.md <span>[SVC]</span></div>
<div class="tree-item" onclick="selectItem(this, 'cyberchef')">cyberchef.md <span>[SVC]</span></div>
<div class="tree-folder">▾ /notes/</div>
<div class="tree-item" onclick="selectItem(this, 'traefik-note')">traefik-mtls.md <span>[BLOG]</span></div>
<div class="tree-item" onclick="selectItem(this, 'ctf-note')">defcon-ctf.md <span>[BLOG]</span></div>
<div class="tree-item" onclick="selectItem(this, 'spi-flash')">spi-flash.md <span>[BLOG]</span></div>
<div class="tree-item" onclick="selectItem(this, 'ha-traefik')">ha-traefik.md <span>[BLOG]</span></div>
<div class="tree-item" onclick="selectItem(this, 'posix-sh')">posix-sh.md <span>[BLOG]</span></div>
<div class="tree-item" onclick="selectItem(this, 'ctf-heap')">ctf-heap.md <span>[BLOG]</span></div>
<div class="tree-folder">▾ /modules/</div>
<div class="tree-item" onclick="selectItem(this, 'shell-parser')">shell-parser.lua <span>[DEV]</span></div>
<div class="tree-item" onclick="selectItem(this, 'mesh-builder')">wireguard-mesh.py <span>[DEV]</span></div>
<div class="tree-item" onclick="selectItem(this, 'zero-logger')">zero-logger.go <span>[DEV]</span></div>
<div class="tree-folder">▾ /resume/</div>
<div class="tree-item" onclick="selectItem(this, 'whoami')">whoami.md <span>[CV]</span></div>
@@ -253,31 +274,34 @@
<main class="main-pane">
<div class="doc-container" id="doc-view">
<!-- Default Content: Grafana Service -->
<div class="doc-path">file:///home/river/services/grafana.md</div>
<h1 class="doc-title">Service: grafana.homelab</h1>
<!-- Default Content: Traefik Proxy -->
<div class="doc-path">file:///home/river/services/traefik.md</div>
<h1 class="doc-title">Service: Traefik Proxy (v3.1)</h1>
<p>
Primary telemetry and Prometheus monitoring dashboard. Aggregates host node resource usage, Docker container stats, and Traefik router throughput.
Edge HTTP reverse proxy and load balancer with dynamic Docker provider discovery and ACME Let's Encrypt TLS wildcard certificate management.
</p>
<div class="code-block">
<div class="code-header">docker-compose.yml</div>
<div class="code-header">traefik.yml</div>
<div class="code-content">
<span style="color: var(--accent-cyan);">services:</span>
<span style="color: var(--accent-cyan);">grafana:</span>
image: grafana/grafana-oss:latest
container_name: homelab_grafana
ports:
- "3000:3000"
restart: unless-stopped
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
cloudflare:
acme:
dnsChallenge:
provider: cloudflare
</div>
</div>
<div class="tag-cluster">
<span>[#homelab]</span>
<span>[#prometheus]</span>
<span>[#telemetry]</span>
<span>[#core]</span>
<span>[#docker-traefik]</span>
<span>[PORT: 443/tcp]</span>
<span>[STATUS: ONLINE]</span>
</div>
@@ -289,79 +313,135 @@
<!-- Bottom Status Bar -->
<footer class="status-bar">
<div>UTF-8 | LF | POSIX Shell</div>
<div>Use Arrow Keys / Mouse to inspect workspace items</div>
<div>River Rooks • Canonical Content Dataset Compliant</div>
</footer>
<script>
const docs = {
'grafana': `
<div class="doc-path">file:///home/river/services/grafana.md</div>
<h1 class="doc-title">Service: grafana.homelab</h1>
<p>Primary telemetry and Prometheus monitoring dashboard. Aggregates host node resource usage, Docker container stats, and Traefik router throughput.</p>
'traefik': `
<div class="doc-path">file:///home/river/services/traefik.md</div>
<h1 class="doc-title">Service: Traefik Proxy (v3.1)</h1>
<p>Edge HTTP reverse proxy and load balancer with dynamic Docker provider discovery and ACME Let's Encrypt TLS wildcard certificate management.</p>
<div class="code-block">
<div class="code-header">docker-compose.yml</div>
<div class="code-header">traefik.yml</div>
<div class="code-content">
<span style="color: var(--accent-cyan);">services:</span>
<span style="color: var(--accent-cyan);">grafana:</span>
image: grafana/grafana-oss:latest
container_name: homelab_grafana
ports:
- "3000:3000"
restart: unless-stopped
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
cloudflare:
acme:
dnsChallenge:
provider: cloudflare
</div>
</div>
<div class="tag-cluster"><span>[#homelab]</span><span>[#prometheus]</span><span>[#telemetry]</span><span>[STATUS: ONLINE]</span></div>
<div class="tag-cluster"><span>[#core]</span><span>[#docker-traefik]</span><span>[PORT: 443/tcp]</span><span>[STATUS: ONLINE]</span></div>
`,
'vault': `
<div class="doc-path">file:///home/river/services/vault.md</div>
<h1 class="doc-title">Service: vault.homelab</h1>
<p>HashiCorp Vault cluster managing secrets, SSH keys, internal PKI certificates, and mTLS auto-renewal for homelab nodes.</p>
'truenas': `
<div class="doc-path">file:///home/river/services/truenas.md</div>
<h1 class="doc-title">Service: TrueNAS SCALE</h1>
<p>Primary storage pool managing 48TB ZFS RaidZ2 array across 6x 16TB enterprise SAS drives with daily snapshots and NFS/SMB exports.</p>
<div class="tag-cluster"><span>[#storage]</span><span>[#zfs]</span><span>[PORT: NFS / SMB]</span><span>[STATUS: ONLINE]</span></div>
`,
'vaultwarden': `
<div class="doc-path">file:///home/river/services/vaultwarden.md</div>
<h1 class="doc-title">Service: Vaultwarden Secrets</h1>
<p>Lightweight Rust implementation of the Bitwarden API hosting encrypted credentials, SSH keys, and TOTP authentication tokens.</p>
<div class="tag-cluster"><span>[#secrets]</span><span>[#security]</span><span>[PORT: 443/tcp]</span><span>[STATUS: 2FA/AUTH]</span></div>
`,
'forgejo': `
<div class="doc-path">file:///home/river/services/forgejo.md</div>
<h1 class="doc-title">Service: Forgejo Git Forge</h1>
<p>Self-hosted Git forge hosting homelab infrastructure-as-code repos, Ansible playbooks, dotfiles, and CTF binary writeup scripts.</p>
<div class="tag-cluster"><span>[#dev-git]</span><span>[#git]</span><span>[PORT: 3000/tcp]</span><span>[STATUS: PUBLIC]</span></div>
`,
'cyberchef': `
<div class="doc-path">file:///home/river/services/cyberchef.md</div>
<h1 class="doc-title">Service: CyberChef Workbench</h1>
<p>Web-based data transformation Swiss Army knife for hex decoding, Base64 operations, regex extraction, and CTF payload analysis.</p>
<div class="tag-cluster"><span>[#security-tool]</span><span>[#crypto]</span><span>[STATUS: PUBLIC]</span></div>
`,
'spi-flash': `
<div class="doc-path">file:///home/river/notes/iot-firmware-spi-extraction.md</div>
<h1 class="doc-title">Reverse Engineering IoT Firmware: SPI Flash Extraction</h1>
<p>Physical hardware-level dumping of SPI flash memory chips using Bus Pirate and flashrom to bypass locked bootloaders.</p>
<div class="code-block">
<div class="code-header">vault-config.hcl</div>
<div class="code-header">extract_firmware.sh</div>
<div class="code-content">
storage "file" { path = "/vault/file" }
listener "tcp" { address = "0.0.0.0:8200" tls_disable = 0 }
ui = true
flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=1M -r firmware_dump.bin
md5sum firmware_dump.bin
</div>
</div>
<div class="tag-cluster"><span>[#vault]</span><span>[#security]</span><span>[#mtls]</span><span>[STATUS: ONLINE]</span></div>
<div class="tag-cluster"><span>[#firmware]</span><span>[#hardware]</span><span>[#security]</span><span>[DATE: 2026-07-20]</span></div>
`,
'wireguard': `
<div class="doc-path">file:///home/river/services/wireguard.md</div>
<h1 class="doc-title">Service: wireguard.homelab</h1>
<p>Encrypted WireGuard mesh network ingress connecting offsite cloud VPS nodes directly to the internal homelab network.</p>
<div class="tag-cluster"><span>[#networking]</span><span>[#wireguard]</span><span>[#vpn]</span><span>[STATUS: INTERNAL]</span></div>
'ha-traefik': `
<div class="doc-path">file:///home/river/notes/ha-traefik-docker.md</div>
<h1 class="doc-title">Building a High-Availability Traefik Router</h1>
<p>Architecting automated TLS wildcard certificate propagation and dynamic Docker container discovery failover routing.</p>
<div class="tag-cluster"><span>[#homelab]</span><span>[#docker-traefik]</span><span>[DATE: 2026-07-15]</span></div>
`,
'traefik-note': `
<div class="doc-path">file:///home/river/notes/traefik-mtls.md</div>
<h1 class="doc-title">Hardening Traefik Ingress with HashiCorp Vault mTLS</h1>
<p>Technical write-up detailing zero-trust certificate auto-renewal pipelines using Vault PKI backend and Traefik dynamic configuration reloads.</p>
<div class="tag-cluster"><span>[#blog]</span><span>[#traefik]</span><span>[#security]</span><span>[DATE: 2026-08-02]</span></div>
'posix-sh': `
<div class="doc-path">file:///home/river/notes/posix-sh-vs-bash.md</div>
<h1 class="doc-title">POSIX sh vs. Bash: Portability in Modern Scripts</h1>
<p>Eliminating bashisms and adhering to IEEE Std 1003.1 for high-speed bootstrapping in Alpine and embedded targets.</p>
<div class="tag-cluster"><span>[#posix-sh]</span><span>[#unix]</span><span>[DATE: 2026-07-10]</span></div>
`,
'ctf-note': `
<div class="doc-path">file:///home/river/notes/defcon-ctf.md</div>
<h1 class="doc-title">DEFCON CTF Qualifier: Memory Corruption Write-Up</h1>
<p>Deep-dive analysis on exploitation techniques involving glibc malloc heap metadata corruption and arbitrary write primitives.</p>
<div class="tag-cluster"><span>[#ctf]</span><span>[#binary]</span><span>[#pwn]</span><span>[DATE: 2026-07-18]</span></div>
'ctf-heap': `
<div class="doc-path">file:///home/river/notes/ctf-heap-glibc-2-35.md</div>
<h1 class="doc-title">CTF Write-up: Heap Exploitation in glibc 2.35</h1>
<p>Tcache safe-linking bypass and House of Apple file structure hijacking primitives for arbitrary code execution.</p>
<div class="tag-cluster"><span>[#ctf]</span><span>[#binary-exploitation]</span><span>[DATE: 2026-06-28]</span></div>
`,
'shell-parser': `
<div class="doc-path">file:///home/river/modules/posix-shell-parser.lua</div>
<h1 class="doc-title">Module: Custom POSIX Shell Parser (v1.2.0)</h1>
<p>Zero-allocation Lexer and AST parser written in Lua for real-time syntax coloring in modal editors.</p>
<div class="code-block">
<div class="code-header">lexer.lua</div>
<div class="code-content">
local function tokenize(src)
local tokens = {}
for pos, char in ipairs(src) do
if char == ";" or char == "|" then table.insert(tokens, { type = "OPERATOR", value = char }) end
end
return tokens
end
</div>
</div>
<div class="tag-cluster"><span>[#lua]</span><span>[#ast-parser]</span><span>[VERSION: v1.2.0]</span></div>
`,
'mesh-builder': `
<div class="doc-path">file:///home/river/modules/wireguard-mesh.py</div>
<h1 class="doc-title">Module: WireGuard Mesh Topology Builder (v0.8.4)</h1>
<p>Matrix topology generator creating atomic configuration files and key pairings across multi-cloud and homelab nodes.</p>
<div class="tag-cluster"><span>[#networking]</span><span>[#wireguard]</span><span>[VERSION: v0.8.4]</span></div>
`,
'zero-logger': `
<div class="doc-path">file:///home/river/modules/zero-alloc-logger.go</div>
<h1 class="doc-title">Module: Zero-Allocation Logger (Go v2.1.1)</h1>
<p>High-throughput structured JSON logger utilizing sync.Pool byte buffers to eliminate heap allocations (>500k ops/sec).</p>
<div class="tag-cluster"><span>[#golang]</span><span>[#performance]</span><span>[VERSION: v2.1.1]</span></div>
`,
'whoami': `
<div class="doc-path">file:///home/river/resume/whoami.md</div>
<h1 class="doc-title">River Rooks - Biography</h1>
<p>Cybersecurity student at the University of Alabama College of Engineering, focusing on network forensics, self-hosted infrastructure, and hardened kernel configs.</p>
<div class="tag-cluster"><span>[#cs]</span><span>[#cybersecurity]</span><span>[#resume]</span></div>
<h1 class="doc-title">River Rooks - Systems Architecture &amp; Cybersecurity</h1>
<p>Cybersecurity student at the University of Alabama College of Engineering, focusing on network forensics, self-hosted infrastructure, and bare-metal virtualization.</p>
<div class="tag-cluster"><span>[#cybersecurity]</span><span>[#systems]</span><span>[UA COLLEGE OF ENGINEERING]</span></div>
`,
'stack': `
<div class="doc-path">file:///home/river/resume/active_stack.conf</div>
<h1 class="doc-title">Active Engineering Stack</h1>
<p>System configuration & tech stack specifications:</p>
<div class="code-block">
<div class="code-header">stack.conf</div>
<div class="code-content">
LANGUAGES="POSIX sh, Python, C, Lua"
TOOLS="Docker, Traefik, WireGuard, HashiCorp Vault, Neovim"
OS="Arch Linux / POSIX Compliance"
DOMAINS="Network Forensics, Self-Hosted Infrastructure, Linux Kernel Hardening"
LANGUAGES="POSIX sh, Python, Go, Rust, Lua, ARM Assembly"
STACK="Traefik v3, WireGuard, Proxmox VE, TrueNAS SCALE, Neovim"
</div>
</div>
<div class="tag-cluster"><span>[#arch-linux]</span><span>[#neovim]</span><span>[#wireguard]</span></div>
`
};
+587
View File
@@ -0,0 +1,587 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Node Gateway &amp; System Hub</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Card surface background */
--bg-elevated: #1c1f26; /* Hovered surface */
--border-color: #2b303b; /* Low-contrast 1px border */
--text-primary: #e0e6f0; /* Off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary terminal accent */
--accent-green: #00e676; /* Operational indicator */
--accent-amber: #ffb700; /* Internal / protected warning */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.65;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 20px 64px 20px;
}
.hub-container {
width: 100%;
max-width: 780px;
}
/* Top Breadcrumb & Status Bar */
.top-status-bar {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
padding-bottom: 12px;
margin-bottom: 28px;
border-bottom: 1px solid var(--border-color);
flex-wrap: wrap;
gap: 10px;
}
.node-identifier {
display: flex;
align-items: center;
gap: 8px;
}
.status-dot {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
flex-shrink: 0;
}
.status-pill {
color: var(--accent-green);
font-weight: 500;
}
/* Main Landing Narrative Section (Primary Focus) */
.landing-hero {
margin-bottom: 36px;
}
.author-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.2rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
margin-bottom: 6px;
}
.author-tagline {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
color: var(--accent-cyan);
margin-bottom: 20px;
letter-spacing: 0.04em;
}
.manifesto-prose {
font-size: 1.02rem;
color: var(--text-primary);
line-height: 1.7;
margin-bottom: 20px;
}
.manifesto-prose p {
margin-bottom: 16px;
}
.callout-block {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 3px;
padding: 14px 18px;
font-size: 0.9rem;
color: var(--text-muted);
margin-bottom: 24px;
font-family: 'IBM Plex Mono', monospace;
line-height: 1.55;
}
.callout-block strong {
color: var(--text-primary);
}
/* 1px Solid Section Divider */
.section-divider {
border: 0;
border-top: 1px solid var(--border-color);
margin: 36px 0;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 16px;
}
.section-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
font-weight: 700;
color: var(--text-primary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.section-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
color: var(--text-muted);
}
/* Direction to Services Router */
.services-router {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 40px;
}
.service-card {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 16px 20px;
display: flex;
flex-direction: column;
gap: 8px;
text-decoration: none;
color: inherit;
transition: none; /* Instant snap */
}
.service-card:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.service-card:focus {
outline: 2px solid var(--accent-cyan);
outline-offset: -1px;
}
/* Highlighted Blog Service Card */
.service-card.service-primary {
border-left: 3px solid var(--accent-cyan);
}
.service-top-row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
}
.service-name-group {
display: flex;
align-items: center;
gap: 10px;
}
.service-name {
font-size: 1.05rem;
font-weight: 700;
color: var(--text-primary);
}
.service-card:hover .service-name {
color: var(--accent-cyan);
}
.service-badge {
font-size: 0.72rem;
padding: 2px 6px;
border-radius: 2px;
font-weight: 500;
}
.badge-blog {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
font-weight: 700;
}
.badge-public {
border: 1px solid var(--accent-green);
color: var(--accent-green);
}
.badge-internal {
border: 1px solid var(--accent-amber);
color: var(--accent-amber);
}
.service-endpoint {
color: var(--text-muted);
font-size: 0.76rem;
}
.service-desc {
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.5;
}
.service-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
margin-top: 4px;
}
/* Recent Articles Feed Section */
.articles-preview-list {
display: flex;
flex-direction: column;
gap: 16px;
}
.article-item {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 14px 18px;
display: flex;
flex-direction: column;
gap: 6px;
}
.article-item:hover {
border-color: var(--accent-cyan);
}
.article-meta-row {
display: flex;
justify-content: space-between;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.75rem;
color: var(--text-muted);
}
.article-date {
color: var(--accent-cyan);
}
.article-heading {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.98rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
transition: none;
}
.article-heading:hover {
color: var(--accent-cyan);
}
.article-summary-text {
font-size: 0.88rem;
color: var(--text-primary);
line-height: 1.5;
}
/* Footer */
.hub-footer {
margin-top: 48px;
padding-top: 24px;
border-top: 1px solid var(--border-color);
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--text-muted);
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
}
.footer-links {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
}
.footer-link {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-link:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="hub-container">
<!-- Top Status Line -->
<header class="top-status-bar">
<div class="node-identifier">
<span class="status-dot"></span>
<span>node: gw-node01.lan [RACK-01 / ALABAMA]</span>
</div>
<div class="status-pill">[SYSTEMS OPERATIONAL • 10GbE]</div>
</header>
<!-- Main Landing Narrative (Core Focus) -->
<section class="landing-hero" aria-label="System Introduction & Landing Manifesto">
<h1 class="author-title">River Rooks</h1>
<div class="author-tagline">SYSTEMS ARCHITECTURE &bull; CYBERSECURITY &bull; SELF-HOSTED CLUSTER</div>
<div class="manifesto-prose">
<p>
Welcome to my personal computing node and technical gateway. I am an engineering student at the University of Alabama specializing in network forensics, bare-metal hypervisors, and security systems.
</p>
<p>
This server is not a commercial landing page or marketing platform. It is a sovereign, self-hosted operational command hub operating from a dedicated 10GbE home rack. All services below run on hardened local hypervisors (Proxmox VE, OPNsense, TrueNAS) routed through an automated Traefik reverse proxy with WireGuard zero-trust mesh peering.
</p>
<p>
Use this landing portal to navigate the ecosystem. The <strong>Technical Blog</strong> contains deep-dive research notes and CTF post-mortems. The <strong>Public Services</strong> are live, free-to-use developer and cryptographic utilities available to the public, while the <strong>Internal Infrastructure</strong> links route directly to cluster monitoring and orchestration consoles.
</p>
</div>
<div class="callout-block">
<strong>ROUTING NOTICE:</strong> External ingress is authenticated and monitored via OPNsense Suricata IDS/IPS. Public utilities are open for interactive use without registration.
</div>
</section>
<hr class="section-divider">
<!-- Direction to Services (With Blog as Primary Endpoint) -->
<section aria-label="Homelab Services Directory">
<div class="section-header">
<h2 class="section-title">Directory of Hosted Services &amp; Tools</h2>
<span class="section-meta">Select a destination &rarr;</span>
</div>
<div class="services-router">
<!-- Service 1: The Blog (Primary Service) -->
<a href="blog-lander-stream.html" class="service-card service-primary" title="Go to Technical Blog & Dispatches">
<div class="service-top-row">
<div class="service-name-group">
<span class="service-name">&gt; Technical Notes &amp; Engineering Blog</span>
<span class="service-badge badge-blog">[BLOG / DISPATCHES]</span>
</div>
<span class="service-endpoint">~/blog/notes/ &bull; rooks.dev/notes</span>
</div>
<p class="service-desc">
The core writing repository. Reverse-chronological feed of technical articles covering IoT SPI flash extraction, glibc 2.35 heap exploitation, high-availability Traefik routing, and POSIX shell engineering.
</p>
<div class="service-tags">
<span>[#ctf-writeups]</span>
<span>[#firmware-reversing]</span>
<span>[#traefik-docker]</span>
<span>[#posix-sh]</span>
<span style="color: var(--accent-cyan); font-weight: 500;">[OPEN BLOG FEED &rarr;]</span>
</div>
</a>
<!-- Service 2: Forgejo Git Server -->
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="service-card" title="Open Self-Hosted Git Forge">
<div class="service-top-row">
<div class="service-name-group">
<span class="service-name">Forgejo Git Server</span>
<span class="service-badge badge-public">[PUBLIC FORGE]</span>
</div>
<span class="service-endpoint">https://git.rooks.dev &bull; :2222/ssh</span>
</div>
<p class="service-desc">
Lightweight, independent Git forge hosting infrastructure-as-code playbooks, dotfiles, POSIX shell parser modules, and bare-metal kernel bootstrap code.
</p>
<div class="service-tags">
<span>[#iac]</span>
<span>[#ansible]</span>
<span>[#cortex-m]</span>
<span>[#git]</span>
</div>
</a>
<!-- Service 3: CyberChef Workbench -->
<a href="https://chef.rooks.dev" target="_blank" rel="noopener" class="service-card" title="Open CyberChef Workbench">
<div class="service-top-row">
<div class="service-name-group">
<span class="service-name">CyberChef Security Workbench</span>
<span class="service-badge badge-public">[PUBLIC TOOL]</span>
</div>
<span class="service-endpoint">https://chef.rooks.dev &bull; :443</span>
</div>
<p class="service-desc">
Client-side cryptographic Swiss Army knife for hex decoding, Base64 operations, XOR decryption, hashing algorithms, and CTF payload deconstruction.
</p>
<div class="service-tags">
<span>[#cryptography]</span>
<span>[#forensics]</span>
<span>[#ctf-toolkit]</span>
</div>
</a>
<!-- Service 4: Stirling PDF Studio -->
<a href="https://pdf.rooks.dev" target="_blank" rel="noopener" class="service-card" title="Open Stirling PDF Suite">
<div class="service-top-row">
<div class="service-name-group">
<span class="service-name">Stirling PDF Studio</span>
<span class="service-badge badge-public">[PUBLIC TOOL]</span>
</div>
<span class="service-endpoint">https://pdf.rooks.dev &bull; :443</span>
</div>
<p class="service-desc">
Locally hosted private document toolkit for OCR text extraction, PDF merging, splitting, sanitization, and password encryption without external cloud telemetry.
</p>
<div class="service-tags">
<span>[#pdf-tools]</span>
<span>[#ocr]</span>
<span>[#privacy-first]</span>
</div>
</a>
<!-- Service 5: Proxmox VE & TrueNAS Cluster Management -->
<a href="homelab.html" class="service-card" title="Inspect Homelab Infrastructure">
<div class="service-top-row">
<div class="service-name-group">
<span class="service-name">Homelab Cluster &amp; Storage</span>
<span class="service-badge badge-internal">[INTERNAL / HYPERVISOR]</span>
</div>
<span class="service-endpoint">https://pve.rooks.dev &bull; 48TB ZFS</span>
</div>
<p class="service-desc">
Hypervisor cluster with AMD Ryzen 9 5900X (12C/24T), 128GB ECC RAM, and TrueNAS SCALE RaidZ2 storage pool. View node topology and live resource utilization telemetry.
</p>
<div class="service-tags">
<span>[#proxmox-ve]</span>
<span>[#truenas]</span>
<span>[#10gbe-mesh]</span>
</div>
</a>
<!-- Service 6: Uptime Kuma System Telemetry -->
<a href="https://status.rooks.dev" target="_blank" rel="noopener" class="service-card" title="Open Status Dashboard">
<div class="service-top-row">
<div class="service-name-group">
<span class="service-name">Uptime Kuma Health Monitor</span>
<span class="service-badge badge-public">[STATUS / TELEMETRY]</span>
</div>
<span class="service-endpoint">https://status.rooks.dev &bull; :3001</span>
</div>
<p class="service-desc">
Continuous synthetic HTTP, TCP, and ICMP health checks broadcasting real-time cluster uptime, DNS resolution latencies, and service availability.
</p>
<div class="service-tags">
<span>[#uptime-100%]</span>
<span>[#telemetry]</span>
<span>[#prometheus]</span>
</div>
</a>
</div>
</section>
<hr class="section-divider">
<!-- Recent Technical Writing (Direct Excerpts from the Blog) -->
<section aria-label="Latest Blog Dispatches">
<div class="section-header">
<h2 class="section-title">Latest Technical Dispatches From the Blog</h2>
<a href="blog-lander-stream.html" style="color: var(--accent-cyan); font-family: 'IBM Plex Mono', monospace; font-size: 0.78rem; text-decoration: none;">View all 5 entries &rarr;</a>
</div>
<div class="articles-preview-list">
<article class="article-item">
<div class="article-meta-row">
<time datetime="2026-07-20" class="article-date">2026-07-20 &bull; 8 min read</time>
<span>[#firmware] [#hardware]</span>
</div>
<a href="blog-lander-stream.html" class="article-heading">&gt; Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
<p class="article-summary-text">
Bypassing bootloader lockdowns by dumping physical SPI Flash memory from an 8-pin SOP chip using a Bus Pirate and flashrom.
</p>
</article>
<article class="article-item">
<div class="article-meta-row">
<time datetime="2026-07-15" class="article-date">2026-07-15 &bull; 12 min read</time>
<span>[#homelab] [#docker-traefik]</span>
</div>
<a href="blog-lander-stream.html" class="article-heading">&gt; Building a High-Availability Traefik Router with Docker Compose</a>
<p class="article-summary-text">
Architecting automated TLS wildcard certificate propagation, Docker provider label routing, zero-downtime container updates, and health checks.
</p>
</article>
<article class="article-item">
<div class="article-meta-row">
<time datetime="2026-07-10" class="article-date">2026-07-10 &bull; 6 min read</time>
<span>[#posix-sh] [#unix]</span>
</div>
<a href="blog-lander-stream.html" class="article-heading">&gt; POSIX sh vs. Bash: Portability in Modern Scripts</a>
<p class="article-summary-text">
Eliminating bashisms and writing bulletproof, zero-allocation bootstrapping scripts for minimal Alpine and embedded Linux environments.
</p>
</article>
</div>
</section>
<!-- Footer -->
<footer class="hub-footer">
<div>River Rooks &bull; Cluster gw-node01.lan</div>
<nav class="footer-links" aria-label="Portal Footer Navigation">
<a href="blog-lander-stream.html" class="footer-link">Blog</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-link">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link">Git Forge</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-link">Email</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-link">PGP Key</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-link">Samples Catalog &rarr;</a>
</nav>
</footer>
</main>
</body>
</html>
+609
View File
@@ -0,0 +1,609 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Homelab Host Console &amp; Service Router</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Table & card surface */
--bg-elevated: #1c1f26; /* Selected row / elevated state */
--border-color: #2b303b; /* Low-contrast 1px border */
--text-primary: #e0e6f0; /* Light off-white prose */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary terminal accent */
--accent-green: #00e676; /* Operational status indicator */
--accent-amber: #ffb700; /* Internal / protected warning */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'IBM Plex Mono', monospace;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 32px 16px 56px 16px;
}
.terminal-container {
width: 100%;
max-width: 920px;
}
/* Terminal Window Shell */
.terminal-shell {
border: 1px solid var(--border-color);
border-radius: 4px;
background-color: var(--bg-surface);
overflow: hidden;
}
.shell-titlebar {
background-color: var(--bg-canvas);
border-bottom: 1px solid var(--border-color);
padding: 8px 16px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.78rem;
color: var(--text-muted);
}
.window-dots {
display: flex;
align-items: center;
gap: 6px;
}
.dot {
width: 8px;
height: 8px;
background-color: var(--border-color);
display: inline-block;
}
.shell-body {
padding: 24px;
}
/* MOTD / Welcome Landing Narrative (Primary Focus) */
.motd-banner {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 20px;
margin-bottom: 28px;
}
.motd-header {
font-size: 0.8rem;
color: var(--accent-cyan);
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 8px;
}
.motd-title {
font-size: 1.4rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 6px;
letter-spacing: -0.02em;
}
.motd-subtitle {
font-size: 0.82rem;
color: var(--text-muted);
margin-bottom: 14px;
}
.motd-prose {
font-family: 'Inter', sans-serif;
font-size: 0.94rem;
color: var(--text-primary);
line-height: 1.65;
}
.motd-prose p {
margin-bottom: 12px;
}
.motd-prose p:last-child {
margin-bottom: 0;
}
.motd-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid var(--border-color);
font-size: 0.76rem;
color: var(--text-muted);
}
.stat-val {
color: var(--text-primary);
font-weight: 700;
}
/* Command Prompt Separator */
.cmd-bar {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
font-size: 0.86rem;
}
.cmd-prompt {
color: var(--accent-cyan);
font-weight: 700;
}
.cmd-text {
color: var(--text-primary);
}
/* Services Routing Table */
.services-table-wrapper {
width: 100%;
overflow-x: auto;
margin-bottom: 36px;
}
.services-table {
width: 100%;
border-collapse: collapse;
font-size: 0.82rem;
text-align: left;
}
.services-table th {
padding: 8px 12px;
background-color: var(--bg-canvas);
border-bottom: 1px solid var(--border-color);
color: var(--text-muted);
font-weight: 500;
white-space: nowrap;
}
.services-table td {
padding: 10px 12px;
border-bottom: 1px solid var(--border-color);
vertical-align: middle;
white-space: nowrap;
}
.service-row {
transition: none; /* Instant snap */
}
.service-row:hover {
background-color: var(--bg-elevated);
}
.service-row.highlight-blog {
border-left: 2px solid var(--accent-cyan);
background-color: rgba(0, 240, 255, 0.03);
}
.service-link {
color: var(--text-primary);
text-decoration: none;
font-weight: 700;
display: inline-flex;
align-items: center;
gap: 6px;
}
.service-row:hover .service-link {
color: var(--accent-cyan);
}
.badge-status {
font-size: 0.72rem;
padding: 1px 6px;
border-radius: 2px;
}
.badge-online {
border: 1px solid var(--accent-green);
color: var(--accent-green);
}
.badge-blog-highlight {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
font-weight: 700;
border: 1px solid var(--accent-cyan);
}
.badge-protected {
border: 1px solid var(--accent-amber);
color: var(--accent-amber);
}
.action-btn {
color: var(--accent-cyan);
text-decoration: none;
font-size: 0.76rem;
padding: 2px 6px;
border: 1px solid transparent;
display: inline-block;
transition: none;
}
.service-row:hover .action-btn {
border-color: var(--accent-cyan);
}
/* Articles Stream Section */
.articles-section {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 20px;
}
.articles-header {
display: flex;
justify-content: space-between;
align-items: baseline;
padding-bottom: 10px;
border-bottom: 1px solid var(--border-color);
margin-bottom: 16px;
flex-wrap: wrap;
gap: 8px;
}
.articles-title {
font-size: 0.95rem;
font-weight: 700;
color: var(--text-primary);
}
.articles-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.article-row {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: 6px 0;
border-bottom: 1px solid rgba(43, 48, 59, 0.4);
flex-wrap: wrap;
gap: 8px;
}
.article-row:last-child {
border-bottom: none;
}
.article-row-left {
display: flex;
align-items: baseline;
gap: 12px;
}
.article-date-mono {
color: var(--accent-cyan);
font-size: 0.78rem;
}
.article-title-click {
color: var(--text-primary);
text-decoration: none;
font-weight: 500;
font-size: 0.88rem;
}
.article-title-click:hover {
color: var(--accent-cyan);
text-decoration: underline;
}
.article-tags-mono {
color: var(--text-muted);
font-size: 0.74rem;
}
/* Status Bar Footer */
.shell-footer {
background-color: var(--bg-canvas);
border-top: 1px solid var(--border-color);
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.75rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 8px;
}
.footer-nav {
display: flex;
gap: 10px;
align-items: center;
}
.footer-link-item {
color: var(--text-primary);
text-decoration: none;
padding: 1px 4px;
}
.footer-link-item:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="terminal-container">
<div class="terminal-shell">
<!-- Shell Window Bar -->
<div class="shell-titlebar">
<div class="window-dots">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span style="color: var(--text-primary); font-weight: 700; margin-left: 6px;">dev-blog@system: ~/gateway</span>
</div>
<div>SESSION: TTY1 &bull; 10GbE TRUNK &bull; UPTIME: 99.98%</div>
</div>
<div class="shell-body">
<!-- MOTD / Landing Narrative (Main Focus of Homepage) -->
<section class="motd-banner" aria-label="System Message Of The Day and Landing Introduction">
<div class="motd-header">
<span>/etc/motd &bull; BROADCAST MESSAGE</span>
<span>NODE: gw-node01.lan [RACK-01]</span>
</div>
<h1 class="motd-title">River Rooks // Homelab Gateway &amp; Service Router</h1>
<div class="motd-subtitle">Systems Architecture &bull; Network Forensics &bull; Bare-Metal Infrastructure</div>
<div class="motd-prose">
<p>
Welcome to the entrypoint for my self-hosted environment. I am a cybersecurity and systems student at the University of Alabama College of Engineering. This portal acts as the root router for both my external public services and internal virtualization infrastructure.
</p>
<p>
Rather than relying on commercial cloud silos, every application listed below runs directly on physical hardware housed in my home lab. Network traffic is segmented across dedicated VLANs (Management, Server DMZ, IoT) and shielded behind an OPNsense firewall with Suricata intrusion prevention and an automated Traefik reverse proxy handling Let's Encrypt TLS wildcard certificates.
</p>
<p>
<strong>Looking for technical writing?</strong> The <a href="blog-lander-terminal.html" style="color: var(--accent-cyan); text-decoration: underline;">Technical Notes &amp; Blog</a> service is where I document firmware reverse engineering, CTF binary exploitation, and zero-trust routing architectures. All public utilities (CyberChef, Stirling PDF, Git Forge) are open and ready for immediate use.
</p>
</div>
<div class="motd-stats-grid">
<div>GATEWAY: <span class="stat-val">OPNsense 24.7 (Intel N100)</span></div>
<div>COMPUTE: <span class="stat-val">Proxmox VE 8.2 (AMD 5900X)</span></div>
<div>STORAGE: <span class="stat-val">TrueNAS SCALE (48TB ZFS)</span></div>
<div>SECURITY: <span class="stat-val">WireGuard Full-Mesh</span></div>
</div>
</section>
<!-- Command Execution Bar -->
<div class="cmd-bar">
<span class="cmd-prompt">dev-blog@system:~$</span>
<span class="cmd-text">route-service --list-all --highlight=blog</span>
</div>
<!-- Directory of Hosted Services (Routing) -->
<div class="services-table-wrapper">
<table class="services-table" aria-label="Homelab Services Routing Table">
<thead>
<tr>
<th scope="col">SERVICE IDENTIFIER</th>
<th scope="col">ROUTING DOMAIN / PATH</th>
<th scope="col">ACCESS LEVEL</th>
<th scope="col">DESCRIPTION</th>
<th scope="col">DISPATCH</th>
</tr>
</thead>
<tbody>
<!-- Blog Service (Highlighted) -->
<tr class="service-row highlight-blog">
<td>
<a href="blog-lander-terminal.html" class="service-link">
<span>&gt; Technical Notes &amp; Blog</span>
</a>
</td>
<td style="color: var(--accent-cyan);">~/notes/ &bull; rooks.dev/notes</td>
<td><span class="badge-status badge-blog-highlight">[FEATURED BLOG]</span></td>
<td style="color: var(--text-primary); font-family: 'Inter', sans-serif;">
Technical writing on firmware reversing, heap exploitation, and networking.
</td>
<td><a href="blog-lander-terminal.html" class="action-btn">[OPEN BLOG &rarr;]</a></td>
</tr>
<!-- Forgejo Git -->
<tr class="service-row">
<td>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="service-link">
<span>Forgejo Git Forge</span>
</a>
</td>
<td style="color: var(--text-muted);">git.rooks.dev:2222</td>
<td><span class="badge-status badge-online">[PUBLIC OPEN]</span></td>
<td style="color: var(--text-primary); font-family: 'Inter', sans-serif;">
Self-hosted repositories: Ansible IaC, dotfiles, and POSIX parser modules.
</td>
<td><a href="https://git.rooks.dev" target="_blank" rel="noopener" class="action-btn">[VISIT FORGE]</a></td>
</tr>
<!-- CyberChef -->
<tr class="service-row">
<td>
<a href="https://chef.rooks.dev" target="_blank" rel="noopener" class="service-link">
<span>CyberChef Suite</span>
</a>
</td>
<td style="color: var(--text-muted);">chef.rooks.dev:443</td>
<td><span class="badge-status badge-online">[PUBLIC TOOL]</span></td>
<td style="color: var(--text-primary); font-family: 'Inter', sans-serif;">
Client-side decoding, hex analysis, hashing, and CTF payload processing.
</td>
<td><a href="https://chef.rooks.dev" target="_blank" rel="noopener" class="action-btn">[OPEN CHEF]</a></td>
</tr>
<!-- Stirling PDF -->
<tr class="service-row">
<td>
<a href="https://pdf.rooks.dev" target="_blank" rel="noopener" class="service-link">
<span>Stirling PDF Studio</span>
</a>
</td>
<td style="color: var(--text-muted);">pdf.rooks.dev:443</td>
<td><span class="badge-status badge-online">[PUBLIC TOOL]</span></td>
<td style="color: var(--text-primary); font-family: 'Inter', sans-serif;">
Local document manipulation: OCR, PDF merge, split, and sanitize.
</td>
<td><a href="https://pdf.rooks.dev" target="_blank" rel="noopener" class="action-btn">[LAUNCH PDF]</a></td>
</tr>
<!-- Uptime Kuma -->
<tr class="service-row">
<td>
<a href="https://status.rooks.dev" target="_blank" rel="noopener" class="service-link">
<span>Uptime Kuma Telemetry</span>
</a>
</td>
<td style="color: var(--text-muted);">status.rooks.dev:3001</td>
<td><span class="badge-status badge-online">[PUBLIC METRICS]</span></td>
<td style="color: var(--text-primary); font-family: 'Inter', sans-serif;">
Live latency metrics, cluster ping monitors, and real-time SLA status.
</td>
<td><a href="https://status.rooks.dev" target="_blank" rel="noopener" class="action-btn">[VIEW STATS]</a></td>
</tr>
<!-- Proxmox VE -->
<tr class="service-row">
<td>
<a href="homelab.html" class="service-link">
<span>Proxmox Hypervisor</span>
</a>
</td>
<td style="color: var(--text-muted);">pve.rooks.dev:8006</td>
<td><span class="badge-status badge-protected">[INTERNAL AUTH]</span></td>
<td style="color: var(--text-primary); font-family: 'Inter', sans-serif;">
KVM VMs and LXC container cluster on AMD Ryzen 9 5900X (12C/24T).
</td>
<td><a href="homelab.html" class="action-btn">[CLUSTER VIEW]</a></td>
</tr>
</tbody>
</table>
</div>
<!-- Command Execution Bar for Articles -->
<div class="cmd-bar">
<span class="cmd-prompt">dev-blog@system:~$</span>
<span class="cmd-text">tail -n 5 ~/notes/dispatches.log</span>
</div>
<!-- Articles Digest Section -->
<section class="articles-section" aria-label="Articles Feed">
<div class="articles-header">
<div class="articles-title">~/notes/dispatches.log &bull; RECENT TECHNICAL WRITING</div>
<a href="blog-lander-terminal.html" style="color: var(--accent-cyan); text-decoration: none; font-size: 0.78rem;">Full Archive &rarr;</a>
</div>
<div class="articles-list">
<div class="article-row">
<div class="article-row-left">
<span class="article-date-mono">2026-07-20</span>
<a href="blog-lander-terminal.html" class="article-title-click">Reverse Engineering IoT Firmware: SPI Flash Extraction</a>
</div>
<span class="article-tags-mono">[#firmware] [#hardware] &bull; 8m</span>
</div>
<div class="article-row">
<div class="article-row-left">
<span class="article-date-mono">2026-07-15</span>
<a href="blog-lander-terminal.html" class="article-title-click">Building a High-Availability Traefik Router with Docker Compose</a>
</div>
<span class="article-tags-mono">[#homelab] [#docker-traefik] &bull; 12m</span>
</div>
<div class="article-row">
<div class="article-row-left">
<span class="article-date-mono">2026-07-10</span>
<a href="blog-lander-terminal.html" class="article-title-click">POSIX sh vs. Bash: Portability in Modern Scripts</a>
</div>
<span class="article-tags-mono">[#posix-sh] [#unix] &bull; 6m</span>
</div>
<div class="article-row">
<div class="article-row-left">
<span class="article-date-mono">2026-06-28</span>
<a href="blog-lander-terminal.html" class="article-title-click">CTF Write-up: Heap Exploitation in glibc 2.35</a>
</div>
<span class="article-tags-mono">[#ctf] [#binary-exploitation] &bull; 15m</span>
</div>
<div class="article-row">
<div class="article-row-left">
<span class="article-date-mono">2026-06-14</span>
<a href="blog-lander-terminal.html" class="article-title-click">Zero-Trust Network Isolation with WireGuard &amp; OPNsense VLANs</a>
</div>
<span class="article-tags-mono">[#networking] [#wireguard] &bull; 10m</span>
</div>
</div>
</section>
</div>
<!-- Footer -->
<footer class="shell-footer">
<div>STATUS: 0 (OK) &bull; TLS: ACME WILDCARD &bull; NODE RACK-01</div>
<nav class="footer-nav" aria-label="Terminal Navigation Footer">
<a href="blog-lander-terminal.html" class="footer-link-item">Blog Lander</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-link-item">Forgejo Git</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-link-item">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-link-item">Catalog ↗</a>
</nav>
</footer>
</div>
</main>
</body>
</html>
+592
View File
@@ -0,0 +1,592 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>River Rooks | Homelab Gateway (Tiling Workspace)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400&family=Inter:wght@400;500;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
:root {
--bg-canvas: #0d0f12; /* Deep slate/charcoal canvas */
--bg-surface: #121417; /* Tile surface */
--bg-elevated: #1c1f26; /* Hovered tile */
--border-color: #2b303b; /* Crisp 1px border */
--text-primary: #e0e6f0; /* Prose off-white */
--text-muted: #8a95a5; /* Monospace metadata */
--accent-cyan: #00f0ff; /* Primary active accent */
--accent-green: #00e676; /* Online indicator */
--accent-amber: #ffb700; /* Warning / internal indicator */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-canvas);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 24px 16px 48px 16px;
}
.tiling-layout {
width: 100%;
max-width: 1120px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Global Status Header Bar */
.global-bar {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
flex-wrap: wrap;
gap: 10px;
}
.brand-group {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-primary);
font-weight: 700;
}
.status-indicator {
width: 8px;
height: 8px;
background-color: var(--accent-green);
display: inline-block;
}
.bar-nav {
display: flex;
gap: 14px;
align-items: center;
}
.bar-link {
color: var(--text-muted);
text-decoration: none;
transition: none; /* Instant snap */
}
.bar-link:hover {
color: var(--accent-cyan);
}
/* Primary Hero Landing Tile (Main Focus of Homepage) */
.hero-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
border-radius: 4px;
padding: 28px 32px;
display: flex;
flex-direction: column;
gap: 16px;
}
.hero-pretitle {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.hero-main-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 2.2rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.02em;
line-height: 1.2;
}
.hero-landing-text {
font-size: 1.02rem;
color: var(--text-primary);
line-height: 1.7;
max-width: 80ch;
}
.hero-landing-text p {
margin-bottom: 14px;
}
.hero-landing-text p:last-child {
margin-bottom: 0;
}
.hero-directive-box {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 14px 18px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.84rem;
color: var(--text-muted);
line-height: 1.6;
}
.hero-directive-box strong {
color: var(--text-primary);
}
/* Tiling Grid Section: Split Columns */
.split-grid {
display: grid;
grid-template-columns: 1.15fr 0.85fr;
gap: 16px;
}
@media (max-width: 880px) {
.split-grid {
grid-template-columns: 1fr;
}
}
/* Tile Container Style */
.tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}
.tile-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
}
.tile-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
font-weight: 700;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 8px;
}
.tile-meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
color: var(--text-muted);
}
/* Featured Service Tile: The Blog */
.blog-service-feature {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 16px;
display: flex;
flex-direction: column;
gap: 10px;
}
.blog-feature-top {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.badge-core {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
padding: 2px 6px;
font-weight: 700;
border-radius: 2px;
}
.blog-feature-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 1.15rem;
font-weight: 700;
color: var(--text-primary);
text-decoration: none;
display: inline-block;
transition: none;
}
.blog-feature-title:hover {
color: var(--accent-cyan);
}
.blog-feature-desc {
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.5;
}
.blog-sublinks {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 4px;
border-top: 1px solid var(--border-color);
padding-top: 10px;
}
.blog-sublink-item {
display: flex;
justify-content: space-between;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--text-primary);
text-decoration: none;
padding: 4px 6px;
border-radius: 2px;
transition: none;
}
.blog-sublink-item:hover {
background-color: var(--bg-elevated);
color: var(--accent-cyan);
}
/* Homelab Services Grid */
.services-mini-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
@media (max-width: 540px) {
.services-mini-grid {
grid-template-columns: 1fr;
}
}
.service-tile-item {
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 12px;
text-decoration: none;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 6px;
transition: none;
}
.service-tile-item:hover {
border-color: var(--accent-cyan);
background-color: var(--bg-elevated);
}
.service-item-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.88rem;
font-weight: 700;
color: var(--text-primary);
}
.service-tile-item:hover .service-item-title {
color: var(--accent-cyan);
}
.service-item-tag {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: var(--text-muted);
}
.service-item-desc {
font-size: 0.8rem;
color: var(--text-muted);
line-height: 1.4;
}
/* Infrastructure Nodes Telemetry Tile */
.node-stat-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
background-color: var(--bg-canvas);
border: 1px solid var(--border-color);
border-radius: 3px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
}
.node-name {
color: var(--text-primary);
font-weight: 700;
}
.node-load {
color: var(--accent-green);
}
/* Bottom Global Footer Tile */
.footer-tile {
background-color: var(--bg-surface);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
color: var(--text-muted);
flex-wrap: wrap;
gap: 10px;
}
.footer-links-cluster {
display: flex;
gap: 12px;
align-items: center;
}
.footer-btn {
color: var(--text-primary);
text-decoration: none;
padding: 2px 4px;
transition: none;
}
.footer-btn:hover {
background-color: var(--accent-cyan);
color: var(--bg-canvas);
}
.pipe {
color: var(--border-color);
}
</style>
</head>
<body>
<main class="tiling-layout">
<!-- Top Status Bar -->
<header class="global-bar">
<div class="brand-group">
<span class="status-indicator"></span>
<span>RIVER ROOKS // NODE GATEWAY</span>
</div>
<nav class="bar-nav" aria-label="Quick Nav">
<a href="blog-lander-cards.html" class="bar-link">&gt; Blog &amp; Notes</a>
<a href="homelab.html" class="bar-link">Infrastructure</a>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="bar-link">Git Forge</a>
<a href="index.html" class="bar-link">Catalog ↗</a>
</nav>
</header>
<!-- Main Hero Landing Tile (Central Focus of Homepage) -->
<section class="hero-tile" aria-label="Homepage Mission & Landing Declaration">
<div class="hero-pretitle">SYSTEM DECLARATION &bull; RACK-01 NODE GATEWAY</div>
<h1 class="hero-main-title">Engineering Sovereign Infrastructure &amp; Technical Notes</h1>
<div class="hero-landing-text">
<p>
I am River Rooks, a cybersecurity engineering student at the University of Alabama. My work centers on network forensics, self-hosted system architecture, low-level firmware exploitation, and zero-allocation Unix utilities.
</p>
<p>
This website functions as the unified frontend for my physical homelab cluster. Rather than hosting projects on opaque third-party clouds, everything here runs on bare metal in my personal server rack—orchestrated through Proxmox VE, partitioned across isolated VLANs via OPNsense, and protected by point-to-point WireGuard cryptographic meshes.
</p>
<p>
<strong>Navigation Guide:</strong> If you are here to read technical research, the <strong>Engineering Blog</strong> is linked below with deep write-ups on firmware dumping, heap exploitation, and container routing. If you are here to use tools, the <strong>Public Services</strong> provide locally hosted instances of CyberChef, Stirling PDF, and Git.
</p>
</div>
<div class="hero-directive-box">
<strong>PRIMARY DESTINATIONS:</strong>
<span style="color: var(--accent-cyan); margin-left: 8px;">[1] Technical Blog (5 Articles)</span> &bull;
<span>[2] Forgejo Git Repos</span> &bull;
<span>[3] Public Cryptographic &amp; PDF Tools</span> &bull;
<span>[4] Cluster Telemetry</span>
</div>
</section>
<!-- Split Tiling Columns -->
<div class="split-grid">
<!-- Left Column: Featured Service (Blog) + Recent Articles -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Featured Service Tile: The Blog -->
<section class="tile" aria-label="Featured Service: Technical Blog">
<div class="tile-header">
<div class="tile-title">
<span>// PRIMARY SERVICE: THE TECHNICAL BLOG</span>
</div>
<span class="tile-meta">~/notes/ &bull; 5 ARTICLES</span>
</div>
<div class="blog-service-feature">
<div class="blog-feature-top">
<span class="badge-core">[CORE PUBLICATION SERVICE]</span>
<span style="color: var(--text-muted);">2026-07-20 LAST SYNC</span>
</div>
<a href="blog-lander-cards.html" class="blog-feature-title">&gt; River Rooks Technical Notes &amp; Research</a>
<p class="blog-feature-desc">
In-depth security post-mortems, CTF write-ups, shell portability benchmarks, and bare-metal homelab architecture guides.
</p>
<div class="blog-sublinks">
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>1. Reverse Engineering IoT Firmware (SPI Flash)</span>
<span style="color: var(--accent-cyan);">[8 min] &rarr;</span>
</a>
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>2. High-Availability Traefik with Docker Compose</span>
<span style="color: var(--accent-cyan);">[12 min] &rarr;</span>
</a>
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>3. POSIX sh vs. Bash: Portability in Modern Scripts</span>
<span style="color: var(--accent-cyan);">[6 min] &rarr;</span>
</a>
<a href="blog-lander-cards.html" class="blog-sublink-item">
<span>4. CTF Write-up: Heap Exploitation in glibc 2.35</span>
<span style="color: var(--accent-cyan);">[15 min] &rarr;</span>
</a>
</div>
</div>
</section>
</div>
<!-- Right Column: Homelab Hosted Services & Node Telemetry -->
<div style="display: flex; flex-direction: column; gap: 16px;">
<!-- Hosted Services Tile -->
<section class="tile" aria-label="Homelab Services Directory">
<div class="tile-header">
<div class="tile-title">
<span>// HOMELAB SERVICES ROUTER</span>
</div>
<span class="tile-meta">4 PUBLIC TOOLS</span>
</div>
<div class="services-mini-grid">
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">Forgejo Git</div>
<div class="service-item-tag">git.rooks.dev:2222</div>
</div>
<p class="service-item-desc">Self-hosted code repositories &amp; dotfiles.</p>
</a>
<a href="https://chef.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">CyberChef</div>
<div class="service-item-tag">chef.rooks.dev:443</div>
</div>
<p class="service-item-desc">Hex decoding, cryptography &amp; forensics.</p>
</a>
<a href="https://pdf.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">Stirling PDF</div>
<div class="service-item-tag">pdf.rooks.dev:443</div>
</div>
<p class="service-item-desc">Private document OCR and manipulation.</p>
</a>
<a href="https://status.rooks.dev" target="_blank" rel="noopener" class="service-tile-item">
<div>
<div class="service-item-title">Uptime Kuma</div>
<div class="service-item-tag">status.rooks.dev:3001</div>
</div>
<p class="service-item-desc">Live synthetic latency &amp; uptime telemetry.</p>
</a>
</div>
</section>
<!-- Bare-Metal Node Telemetry Tile -->
<section class="tile" aria-label="Physical Hardware Nodes">
<div class="tile-header">
<div class="tile-title">
<span>// HARDWARE NODES (RACK-01)</span>
</div>
<span class="tile-meta">10GbE SFP+</span>
</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<div class="node-stat-row">
<div>
<span class="node-name">gw-node01.lan</span>
<span style="color: var(--text-muted); font-size: 0.72rem; margin-left: 6px;">OPNsense 24.7</span>
</div>
<span class="node-load">CPU: 18% | RAM: 32%</span>
</div>
<div class="node-stat-row">
<div>
<span class="node-name">pve-node02.lan</span>
<span style="color: var(--text-muted); font-size: 0.72rem; margin-left: 6px;">Proxmox VE (AMD 5900X)</span>
</div>
<span class="node-load">CPU: 42% | RAM: 68%</span>
</div>
<div class="node-stat-row">
<div>
<span class="node-name">nas-node03.lan</span>
<span style="color: var(--text-muted); font-size: 0.72rem; margin-left: 6px;">TrueNAS (48TB RaidZ2)</span>
</div>
<span class="node-load">CPU: 14% | RAM: 82%</span>
</div>
</div>
</section>
</div>
</div>
<!-- Global Footer Bar -->
<footer class="footer-tile">
<div>River Rooks &bull; University of Alabama College of Engineering</div>
<nav class="footer-links-cluster" aria-label="Global Footer Links">
<a href="blog-lander-cards.html" class="footer-btn">Blog Lander</a>
<span class="pipe">|</span>
<a href="feed.xml" class="footer-btn">RSS</a>
<span class="pipe">|</span>
<a href="https://git.rooks.dev" target="_blank" rel="noopener" class="footer-btn">Forgejo</a>
<span class="pipe">|</span>
<a href="mailto:river@rooks.dev" class="footer-btn">river@rooks.dev</a>
<span class="pipe">|</span>
<a href="#" title="Fingerprint: 0x4A8E92F1C0B3D4E7" class="footer-btn">PGP</a>
<span class="pipe">|</span>
<a href="index.html" class="footer-btn">Catalog ↗</a>
</nav>
</footer>
</main>
</body>
</html>
+21 -16
View File
@@ -296,6 +296,11 @@
<a href="companion.html" class="nav-link">Sample 3</a>
<a href="document-flow.html" class="nav-link">Sample 4</a>
<a href="portfolio.html" class="nav-link">Sample 5</a>
<a href="homelab.html" class="nav-link">Sample 6</a>
<a href="public-services.html" class="nav-link">Sample 7</a>
<a href="sample-dashboard.html" class="nav-link">Sample 8</a>
<a href="sample-command-center.html" class="nav-link">Sample 9</a>
<a href="sample-dual-pane-explorer.html" class="nav-link">Sample 10</a>
</nav>
</header>
@@ -326,15 +331,15 @@
<div class="status-panel">
<div class="status-row">
<span class="status-label">Target:</span>
<span class="status-value">AGY-Node-A2</span>
<span class="status-value">pve-node02.lan</span>
</div>
<div class="status-row">
<span class="status-label">Status:</span>
<span class="status-value" style="color: var(--accent);">ANIMATING</span>
</div>
<div class="status-row">
<span class="status-label">Engine:</span>
<span class="status-value">Vanilla JS</span>
<span class="status-label">Cluster:</span>
<span class="status-value">10GbE SFP+</span>
</div>
</div>
</div>
@@ -343,7 +348,7 @@
<!-- Right Pane - Scrollable List of Cards -->
<main class="right-pane">
<div class="scroll-content">
<h2 class="section-title">Developer Workspace Projects</h2>
<h2 class="section-title">River Rooks // System Modules</h2>
<div class="tile-list">
@@ -351,10 +356,10 @@
<a href="#" class="tile">
<div class="tile-header">
<h3 class="tile-title">Custom POSIX Shell Parser</h3>
<span class="tile-meta">v1.2.0</span>
<span class="tile-meta">v1.2.0 • [#lua]</span>
</div>
<p class="tile-description">
A lightweight Lexer and AST parser written in Lua for parsing POSIX compliant shell scripts. Highly optimized for syntax coloring inside modal environments.
A lightweight Lexer and AST parser written in Lua for parsing POSIX-compliant shell scripts. Highly optimized for syntax coloring inside modal environments without runtime heap allocations.
</p>
</a>
@@ -362,10 +367,10 @@
<a href="#" class="tile">
<div class="tile-header">
<h3 class="tile-title">WireGuard Mesh Topology Builder</h3>
<span class="tile-meta">v0.8.4</span>
<span class="tile-meta">v0.8.4 • [#wireguard]</span>
</div>
<p class="tile-description">
Automated configuration generator for setting up full-mesh WireGuard private overlays across cloud instances and local homelab nodes.
Automated configuration generator for computing key matrices and setting up full-mesh WireGuard private overlays across cloud instances and local homelab nodes.
</p>
</a>
@@ -373,10 +378,10 @@
<a href="#" class="tile">
<div class="tile-header">
<h3 class="tile-title">Zero-Allocation Logger (Go)</h3>
<span class="tile-meta">v2.1.1</span>
<span class="tile-meta">v2.1.1 • [#golang]</span>
</div>
<p class="tile-description">
A high-performance JSON structure logger that uses sync.Pool buffers to avoid memory allocation overhead during intensive disk operations.
A high-performance JSON structure logger that uses sync.Pool buffers to avoid memory allocation overhead during intensive disk operations (>500k ops/sec).
</p>
</a>
@@ -384,10 +389,10 @@
<a href="#" class="tile">
<div class="tile-header">
<h3 class="tile-title">Embedded Kernel Boot Strap</h3>
<span class="tile-meta">v0.1.0</span>
<span class="tile-meta">v0.1.0 • [#arm-cortex]</span>
</div>
<p class="tile-description">
Minimalist boot sector and initial kernel bootstrap for ARM Cortex-M microcontrollers to handle memory map initialization and early UART status printouts.
Minimalist boot sector and initial kernel bootstrap for ARM Cortex-M microcontrollers to handle vector table offset mapping and early UART status printouts.
</p>
</a>
@@ -395,18 +400,18 @@
<a href="#" class="tile">
<div class="tile-header">
<h3 class="tile-title">Traefik Cloudflare Dynamic DNS Daemon</h3>
<span class="tile-meta">v1.0.2</span>
<span class="tile-meta">v1.0.2 • [#docker-traefik]</span>
</div>
<p class="tile-description">
Background controller daemon designed to sync Docker container network labels with Cloudflare DNS records to route traffic to local homelab subdomains.
Background controller daemon designed to sync Docker container network labels with Cloudflare DNS records to route traffic to local homelab subdomains dynamically.
</p>
</a>
</div>
<footer class="pane-footer">
<span>Split Panel Spec Sample</span>
<span>© 2026 Developer System</span>
<span>Sample 2: Split Panel Layout</span>
<span>© 2026 River Rooks</span>
</footer>
</div>
</main>