SEGMENT LEGEND4 VLANS · 1 TRUNK
VLAN 10 · TRUSTED
VLAN 20 · GUEST
VLAN 30 · SERVERS
VLAN 40 · DMZ
DIVISION 01 · CHERWOOD CORPORATION · LIVE BUILD

Four VLANs.
One rack.
Zero assumptions.

Cherwood Health is the operating scenario for a hands-on network engineering and security build — physical FortiGate and Cisco hardware, no simulator, every bug documented as it actually happened.

4
Segmented VLANs
2
Sites, RIP-routed
21/21
Build parts complete
0
Inbound ports besides VPN

Live cable run

VLAN10 Trusted VLAN20 Guest VLAN30 Servers VLAN40 DMZ Branch
Internet wan1 FortiGate 60E 10.10.x.1 / core Cisco 3560E Trunk 10/20/30/40 VLAN10 Trusted Staff AP · 10.10.10.0/24 VLAN20 Guest Portal + 10Mbps cap VLAN30 Servers Proxmox · Prometheus VLAN40 DMZ cherwood-dmz Cloudflare Tunnel — outbound only Cisco 1921 Branch RIPv2 · 10.10.99.0/30 Branch LAN 10.20.0.0/24 Remote Client SSL-VPN :10443
WHAT THIS PROVES

Not just configured — verified.

Every row below was built, then tested with real traffic, real logs, or a real deliberately-induced failure — not assumed to work because the config looked right.

RU 01

Segmentation

4 VLANs — Trusted, Guest, Servers, DMZ — each with explicit, logged firewall policy, not just implicit default-deny. Guest→Trusted isolation proven with real log evidence.

RU 02

Remote access

SSL-VPN on a non-default port, dynamic DNS via DuckDNS, tested end-to-end from real cellular data — including a 5-cause bug chain to get there.

RU 03

Site-to-site

A physically separate branch office, dynamically routed back to HQ over RIPv2, isolated from internal VLANs by policy, internet-only.

RU 04

Monitoring

Prometheus + Grafana, SNMP polling of every core device, live dashboards — with a documented, honestly-labeled limitation on containerized memory accounting.

RU 05

Automation

Bash + cron nightly diffing config backups on all three core devices, plus a config-drift isolation checker validated against a deliberately broken policy.

RU 06

Detection

A real reconnaissance simulation from the DMZ, confirmed blocked using a live FortiGate packet sniffer when standard log views came up empty.

CHRONOLOGICAL RECORD

Build log

Every part, in the order it was actually built. Full command-by-command detail lives in the repo's COMMAND-REFERENCE.md.

PART 00Foundation

Domain, DNS & brand structure

tarunc.com registered, nameservers moved to Cloudflare. Cherwood Corporation established as a parent brand, Cherwood Health as its first division.

Done
PART 01–03Foundation

Physical wiring & FortiGate admin access

FortiGate, switch, AP cabled. Admin GUI secured, internal1/internal2 split out of the default hardware switch.

Done
PART 04–05Segmentation

VLANs on the firewall & switch

VLAN 10/20/30 on the FortiGate; matching VLANs and trunk ports on the 3560E. Diagnosed a native-VLAN mismatch and a trunk-list-vs-VLAN-database gotcha.

Done
PART 06Wireless

Dual-SSID on Autonomous Cisco APs

Staff and Guest SSIDs mapped to VLANs 10/20. Hit a hard vendor limit — one guest-mode slot per radio — split across both radio bands.

Done
PART 07–09Enforcement

Firewall policy, captive portal, segmentation testing

Explicit ACCEPT/DENY per zone. Guest captive portal live. Isolation proven with a real blocked-traffic log entry before touching production.

Done
PART 10Production

Live migration + public DMZ site

Production Proxmox host moved onto the segmented network. DMZ stood up serving cherwood.tarunc.com via Cloudflare Tunnel — zero open inbound ports.

Done
PART 11Remote access

SSL-VPN, tested from real cellular data

A five-cause bug chain — cipher self-conflict, an unsaved port forward, a missing policy, a client-side VPN conflict — before a clean external connection.

Done
PART 12–13Site-to-site

Branch office, routed over RIPv2

A second physical site, dynamically routed back to HQ. Planned AP hardware turned out to be Lightweight firmware with unrecoverable credentials — substituted honestly.

Done
PART 14Observability

Prometheus + Grafana monitoring

SNMP polling of the firewall, switch, and branch router every 15 seconds. Live dashboards for interface throughput and host metrics.

Done
PART 15–16Automation

Config backups & drift detection

Nightly SSH config pulls with diffing. A custom isolation-check script, validated by deliberately disabling a real policy and confirming it got caught.

Done
PART 17Validation

Simulated attack & detection

A real reconnaissance attempt from DMZ into Trusted. Standard logs showed nothing — resolved with a live packet capture proving traffic was silently denied.

Done
PART 18Hardening

Guest bandwidth shaping

A shared 10 Mbps cap on Guest traffic, deprioritized under contention, verified via CLI against the saved config.

Done
PART 19–20Documentation

Architecture, command reference, troubleshooting log

Design rationale, every command used, every real bug with root cause and fix — documented honestly rather than cleaned up.

Done
PART 21Packaging

Sanitized configs, scripts & repo publication

Real device configs pulled and sanitized for all four devices, working scripts, a full screenshot set — audited before publishing.

Done
FAULT LOG

A few incidents, in brief

The full record — every bug, every root cause — lives in TROUBLESHOOTING-LOG.md. Four representative ones below.

PART 11 · SSL-VPN

A cipher list that banned its own requirements

SSL-VPN failed with a generic "SSL exit error." show full-configuration revealed the firewall had banned SHA256/SHA384 while its own cipher suite required them — zero valid ciphers left.

Fix: selectively un-banned the two hashes actually needed, left SHA1 excluded.

PART 11 · Client-side

The firewall wasn't the problem — a VPN client was

Every server-side fix still failed. The dominant cause: Tailscale on the test phone, competing with FortiClient for the device's VPN routing.

Fix: disabled the competing client. Immediate, clean connection.

PART 15/16 · Automation

A drift-detection script that couldn't detect drift

The isolation-checker passed every test — until validated against a real, intentionally-disabled policy. It missed it. The field that mattered was written before the anchor point it searched from.

Fix: rewrote to parse whole policy blocks, re-tested against the same real fault, confirmed caught.

PART 17 · Detection

Silence in the logs isn't proof of nothing happening

A real port scan from DMZ into Trusted was blocked — but produced zero entries in Forward Traffic, Local Traffic, or Security Events.

Fix: diagnose sniffer packet on the FortiGate CLI proved packets arrived and were silently denied — a logging distinction the GUI never surfaces.

DESIGN REFERENCE

Addressing scheme

Full rationale for every design decision lives in ARCHITECTURE.md, including an honest section on what would change for real production use.

SegmentSubnetGatewayPurpose
VLAN 10 — Trusted10.10.10.0/2410.10.10.1Staff devices, network admin access
VLAN 20 — Guest10.10.20.0/2410.10.20.1Public WiFi — isolated, bandwidth-capped
VLAN 30 — Servers10.10.30.0/2410.10.30.1Proxmox host, all internal service containers
VLAN 40 — DMZ10.10.40.0/2410.10.40.1Public-facing services only, fully isolated
Branch transit link10.10.99.0/30FG: .1 · 1921: .2Point-to-point HQ↔Branch routing
Branch LAN10.20.0.0/2410.20.0.1Branch office local network, internet-only
TOOLING

The stack

FortiGate 60ECisco Catalyst 3560ECisco 1921 ISRCisco Autonomous APsProxmox VEDebian LXCPrometheusGrafanaSNMP ExporterNode ExporterBash + cronCloudflare TunnelSSL-VPN / FortiClientRIPv2

Full documentation, every command, every bug.

The complete repo includes a command-by-command reference, the full troubleshooting log, and an interview-ready walkthrough of every design decision.