Files
blog/samples/service-gateway-terminal.html
T

610 lines
20 KiB
HTML

<!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>