Cherwood Health is a fictional regional clinic group used as the operating scenario for a hands-on network engineering and security portfolio project — physical Fortinet and Cisco gear, no simulator, every bug documented as it actually happened.
Every layer below was built, then verified with real traffic, real logs, or a real deliberately-induced failure — not assumed to work because the config looked right.
Trusted, Guest, Servers, and DMZ — each with explicit, logged firewall policy, not just implicit default-deny. Guest→Trusted isolation proven with real log evidence.
Non-default port, dynamic DNS via DuckDNS, tested end-to-end from real cellular data — including a 5-cause bug chain to get there.
A physically separate branch office, dynamically routed back to HQ, isolated from internal VLANs by policy, internet-only.
SNMP polling of every core device, live dashboards, host metrics — with a documented, honestly-labeled limitation on containerized memory accounting.
Nightly diffing config backups on all three core devices, plus a config-drift isolation checker — validated by deliberately breaking a real policy and confirming it got caught.
A real reconnaissance simulation from the DMZ, confirmed blocked using a live FortiGate packet sniffer when standard log views came up empty.
Every part, in the order it was actually built. Full command-by-command detail lives in the repo's COMMAND-REFERENCE.md.
tarunc.com registered, nameservers moved to Cloudflare. Cherwood Corporation established as a parent holding brand, with Cherwood Health as its first division — reusable for future homelab projects.
FortiGate, switch, AP all cabled. Admin GUI secured, internal1/internal2 split out of the default hardware switch to become independently configurable.
VLAN 10/20/30 created on the FortiGate; matching VLANs and trunk ports configured on the 3560E. Diagnosed a native-VLAN mismatch and a "trunk allowed list ≠ VLAN database entry" gotcha along the way.
Staff and Guest SSIDs mapped to VLANs 10/20. Hit a hard vendor limit — one guest-mode slot per radio — and split the SSIDs across both radio bands to resolve it.
Explicit ACCEPT and DENY policies for every zone. Guest captive portal live. Isolation proven — not assumed — with a real blocked-traffic log entry before touching any production system.
Production Proxmox host and its Kindle/RSS pipeline moved onto the segmented network. DMZ stood up serving cherwood.tarunc.com via Cloudflare Tunnel — zero open inbound ports for the public site.
A five-cause bug chain — cipher self-conflict, a silently-unsaved port forward, a missing firewall policy, and a client-side VPN client conflict — before a clean connection from outside the network.
A second physical site, dynamically routed back to HQ, isolated by policy the same way Guest is. Planned AP hardware turned out to be Lightweight firmware with unrecoverable credentials — documented and substituted honestly.
SNMP polling of the firewall, switch, and branch router every 15 seconds. Live dashboards for interface throughput and host metrics.
Nightly SSH-based config pulls with diffing on all three core devices. A custom isolation-check script, validated by deliberately disabling a real firewall policy and confirming the script caught it.
A real reconnaissance attempt from the DMZ against the Trusted VLAN. Standard logs showed nothing — resolved with a live packet capture proving the traffic was actually being silently denied.
A shared 10 Mbps cap on Guest traffic, deprioritized under contention, verified via CLI against the saved config.
Full write-up of the design rationale, every command used across the build, and every real bug encountered with its root cause and fix — documented honestly rather than cleaned up to look flawless.
Real device configs pulled and sanitized for all four network devices, working automation scripts, and a full screenshot set — audited for accidental credential or key exposure before publishing.
The full record — every bug, every root cause — lives in TROUBLESHOOTING-LOG.md. Four representative ones below.
SSL-VPN failed with a generic "SSL exit error," visible in no abbreviated config view. show full-configuration revealed the firewall had banned SHA256/SHA384 while its own configured cipher suite required them — zero valid ciphers left to negotiate.
Fix: selectively un-banned the two hashes actually needed, leaving the genuinely weak SHA1 excluded.
After every server-side fix, connections still failed. The actual dominant cause: Tailscale running on the test phone, competing with FortiClient for the device's own VPN routing.
Fix: disabled the competing client. Immediate, clean connection.
The isolation-checker passed every test — until deliberately validated against a real, intentionally-disabled policy. It missed it. The field that mattered was written before the anchor point the script searched from.
Fix: rewrote to parse whole policy blocks, re-tested against the same real fault, confirmed caught.
A real port scan from DMZ into Trusted was clearly blocked — but produced zero entries in Forward Traffic, Local Traffic, or Security Events.
Fix: diagnose sniffer packet directly on the FortiGate CLI proved packets were arriving and being silently denied — a logging-category distinction the GUI never surfaces.
Full rationale for every design decision lives in ARCHITECTURE.md, including an honest section on what would change for real production use.
| Segment | Subnet | Gateway | Purpose |
|---|---|---|---|
| VLAN 10 — Trusted | 10.10.10.0/24 | 10.10.10.1 | Staff devices, network admin access |
| VLAN 20 — Guest | 10.10.20.0/24 | 10.10.20.1 | Public WiFi — isolated, bandwidth-capped |
| VLAN 30 — Servers | 10.10.30.0/24 | 10.10.30.1 | Proxmox host, all internal service containers |
| VLAN 40 — DMZ | 10.10.40.0/24 | 10.10.40.1 | Public-facing services only, fully isolated |
| Branch transit link | 10.10.99.0/30 | FG: .1 · 1921: .2 | Point-to-point HQ↔Branch routing |
| Branch LAN | 10.20.0.0/24 | 10.20.0.1 | Branch office local network, internet-only |
The complete repo includes a command-by-command reference, the full troubleshooting log, and an interview-ready walkthrough of every design decision.