Ali-AS Network LLC  ·  Portfolio Engagement  ·  2026

Valleybrook
General Hospital

A complete 1,000-bed hospital network designed, built, and documented from scratch as the flagship engagement for Ali-AS Network LLC. Dual-ISP BGP edge, two redundant pfSense CARP firewall pairs, hardware-isolated OT/SCADA stack, per-floor VLAN segmentation, and a HIPAA-defensible architecture where every rule has a documented rationale. Every secondary node config was generated programmatically. Zero single points of failure.

AS65100Autonomous System
203.0.113.96/27PI Block via ARIN
30+ nodesEVE-NG topology
4 pfSensefirewall instances
22 CARP VIPstotal across both pairs
vbgh-fw2 — carp status
$ show carp status
VHID 1  203.0.113.100/27 MASTER WAN — public CARP VIP
VHID 3  10.21.10.1/23   MASTER CLINICAL — PHI bearing
VHID 7  10.21.20.1/24   MASTER ADMIN — isolated from clinical
VHID 14 10.200.1.1/29   MASTER OT_HANDOFF — dedicated L2 segment
... 10 more VIPs, all MASTER
$ ping 10.21.10.1 — clinical gateway
64 bytes from 10.21.10.1: icmp_seq=1 ttl=64 time=0.8ms
$
1,000
bed hospital
2
ISP uplinks
4
pfSense nodes
22
CARP VIPs
16
VLANs
6
OT zones
135+
firewall rules
~0
single points of failure
Context

Why hospital networks are hard

A hospital network isn't just a large office network. It's a life-critical system that has to satisfy simultaneously conflicting requirements — and getting the architecture wrong has consequences that go beyond downtime.

Availability vs security
A nurse needs her EHR terminal to respond instantly at 3am. A patient's family member on guest WiFi should never be able to reach that terminal. A Pyxis dispensing cabinet needs to talk to exactly one server and nothing else. These constraints have to coexist in the same physical building on the same switching fabric.
IT vs OT
Hospital buildings run on decades-old control systems — HVAC, medical gas monitoring, elevator controllers, building management. These devices run unpatched firmware, speak insecure protocols like Modbus and BACnet with no authentication, and cannot be updated. They have to be networked, monitored, and managed without ever touching the IT network.
Compliance
HIPAA Security Rule requires documented access controls, audit logging, transmission encryption, and device isolation for any system touching Protected Health Information. Every firewall rule, VLAN boundary, and access control in this design maps to a specific regulatory requirement.
Uptime
24/7/365. Zero tolerance for unplanned downtime. A nurse's workstation losing connectivity mid-charting is a patient safety event. The network has to fail over transparently at every layer — internet, routing, firewalling, switching — without any human intervention.

This project is the answer to all four of those problems at once. Every design decision was made against this backdrop.

Infrastructure

The complete network — layer by layer

Built top to bottom, verified at each layer before proceeding. Here's exactly what runs at every tier and why.

Internet upstream
LightSpeedFiber
LumaLink
Dual ISP — independent upstream providers
Two completely independent internet service providers. Each ISP connects to its own edge router. No shared infrastructure between the two paths — fiber, hardware, or otherwise. If LightSpeedFiber goes dark, LumaLink continues carrying traffic and the hospital never notices.
The critical design choice here is provider-independent IP space. Valleybrook's public addresses (203.0.113.96/27) are registered directly to AS65100 via ARIN — they belong to the hospital, not to either ISP. Changing providers, adding a third ISP, or renegotiating contracts requires zero IP renumbering. VPN tunnels, the patient portal, and SMTP relay all keep their addresses permanently.
BGPPI blockARIN AS65100dual ISP
Edge routing
MikroTik CHR × 2
vbgh-edge-r16/r17
BGP border routers — AS65100 — VRRP HA pair
Each MikroTik CHR runs MikroTik CHR and maintains an eBGP session with its respective ISP. Both routers announce the full 203.0.113.96/27 PI block to their upstream peers. AS path prepending on r17 makes LumaLink the less-preferred inbound path under normal conditions, concentrating inbound traffic through LightSpeedFiber.
VRRP ties the two routers together. r16 is VRRP master with priority 200 and owns the gateway VIP at 203.0.113.97. r17 is backup at priority 100. Everything downstream — the WAN distribution switches and the firewall pair — points its default route at 203.0.113.97. When r16 dies, r17 claims the VIP in under 3 seconds and traffic continues. The BGP session to LightSpeedFiber dies with r16 but r17's session to LumaLink keeps the PI block announced.
eBGPVRRPAS path prependMikroTik MikroTik CHRlocal preference
WAN distribution
MikroTik CHR × 2
WAN-DIST-18/19
WAN dist switches — VLAN 2030 — bonded peer link
Each WAN dist switch sits between one edge router and one firewall on a dedicated path. VLAN 2030 carries the PI block transit from the edge layer down to the firewalls. A bonded LACP peer link runs between WAN-DIST-18 and WAN-DIST-19 carrying VLAN 2030, which gives the two main firewalls a shared L2 segment for CARP multicast heartbeats on the WAN side.
This layer exists specifically to solve the CARP L2 problem. pfSense CARP uses multicast to send heartbeats — for fw2 and fw3 to see each other's WAN-side heartbeats, they need to be on the same broadcast domain on the WAN interface. The WAN dist switches provide that shared domain without involving the main core fabric. The peer link carries VLAN 2030 between them so both firewalls participate in the same WAN broadcast domain.
VLAN 2030LACP bondCARP multicast
Main firewall pair
pfSense × 2
vbgh-fw2 / vbgh-fw3
pfSense CARP HA pair — 14 VIPs — owns all VLAN gateways
This is the most critical device pair in the network. Every packet that crosses a VLAN boundary, every packet leaving for the internet, every packet arriving from outside — all of it passes through this firewall pair. fw2 is CARP master with advskew 0. fw3 is CARP backup with advskew 100. They share 14 CARP VIPs — one on the WAN side and one per internal VLAN.
The key architectural decision here is that the firewall owns every VLAN gateway. There are no SVIs on the core switch, no ACLs on distribution switches, no inter-VLAN routing happening anywhere except at this firewall pair. A nurse's PC on VLAN 10 has its default gateway set to 10.21.10.1 — a CARP VIP on this firewall. Every packet she sends to a different subnet, or to the internet, arrives at pfSense first. This gives you stateful inspection, per-connection logging, IDS integration, and a single auditable enforcement point for every HIPAA-relevant flow. The pfSense does 26Gbps of firewall throughput — more than enough for a 1,000-bed hospital at peak DICOM load.
pfsync runs over a dedicated LAGG between fw2 and fw3 (172.16.0.0/30). Every active connection's state is replicated to fw3 in real time. When fw2 dies and fw3 claims the VIPs, it already has the full session table. TCP connections that were mid-stream survive the failover without resetting. EHR sessions, DICOM transfers, VoIP calls — none of them know the failover happened. XMLRPC config sync keeps fw3 as a perfect mirror of fw2. Both secondary node configs were generated programmatically via Python — IP swap, HA role reversal, SSH key removal, all scripted.
CARPpfsyncpfSensepfSensePython config genXMLRPC sync
Core switching
Cisco IOSv × 2
Core-20 / Core-21
Pure L2 core — VTPv3 — EtherChannel — STP root
The core switches are deliberately simple. No SVIs. No routing. No ACLs. No OSPF. The IOSv's entire job is moving 802.1Q tagged frames between the firewall pair and the access layer at line rate. One static default route points at the firewall CARP VIP. That's the entire routing table.
VTPv3 manages VLAN propagation. Core-20 is the VTPv3 primary server — a distinction that requires explicit election in v3, not just setting server mode. All VLANs are created once on Core-20 and propagate to Core-21 automatically via the EtherChannel trunk between them. The EtherChannel also gives CARP multicast from both firewalls a path to reach both cores, ensuring CARP heartbeats are seen consistently across the switching fabric regardless of which core a firewall is connected to. Core-20 is STP root with priority 4096, Core-21 is backup root at 8192, ensuring a predictable spanning tree topology at all times.
Cisco IOSvVTPv3EtherChannelSTP rootpure L2
Access layer
Cisco IOSv per floor
802.1Q trunks
Per-floor access switches — port hardening — voice VLAN
One Cisco IOSv per floor in a dedicated IDF closet. Each switch uplinks to both core switches over OS2 single-mode fiber. Access ports are configured per device type — clinical workstations get VLAN 10, Pyxis cabinets get VLAN 25, patient TVs get VLAN 35, and guest WAP uplinks get trunks carrying VLANs 10 and 30. Nursing station ports run voice VLAN for VoIP co-existence.
Every access port has spanning-tree portfast and bpduguard enabled. DHCP snooping rate-limits prevent starvation attacks. Dynamic ARP Inspection validates ARP against the DHCP binding table, preventing ARP poisoning attacks from any device on the floor. Port security limits MAC addresses per port to catch rogue switch insertion. In production the design calls for dual access switches per floor with MLAG uplinks for active/active redundancy — validated on physical MikroTik CHR hardware outside of this lab environment, documented as a lab limitation in EVE-NG.
802.1QDHCP snoopingDAIbpduguardvoice VLANport security
OT handoff
10.200.1.0/29
Dedicated L2 switch
OT handoff segment — 10.200.1.0/29 — isolated L2 domain
A dedicated Layer 2 switch creates the shared broadcast domain between the main firewalls and the OT firewall pair. Six addresses: main FW CARP VIP (.1), fw2 (.2), fw3 (.3), OT FW CARP VIP (.4), OT-FW1 (.5), OT-FW2 (.6). This switch has no connection to the main core fabric — it exists purely as the controlled boundary between IT and OT.
The design of this segment went through several iterations. The problem: pfSense CARP requires L2 multicast between CARP peers. Both OT firewalls needed a shared L2 domain on their WAN interface to elect a master/backup. The solution was a dedicated L2 switch on VLAN 300 that both the main firewalls and both OT firewalls connect to — completely independent of the main switching fabric. No core switch touches this segment. No IT VLAN is on it. It's a purpose-built isolation boundary.
VLAN 300dedicated L2isolation boundary10.200.1.0/29
OT firewall pair
pfSense × 2
OT-FW1 / OT-FW2
pfSense OT CARP pair — 8 VIPs — deny-by-default — hardware isolated
A second pfSense CARP pair dedicated entirely to OT/SCADA. OT-FW1 is master (advskew 0), OT-FW2 is backup (advskew 100). They share 8 CARP VIPs — one on the OT handoff WAN side and one per OT VLAN. pfsync runs between them on a dedicated LAGG at 172.16.1.0/30, completely separate from the main FW pfsync link at 172.16.0.0/30.
The OT firewall policy is deny-by-default with five explicit permit rules. The jump host (10.21.254.100) is the only device in the entire IT network with a permitted path into OT — and only on specific ports: SSH (22), HTTPS (443), Modbus/TCP (502), and BACnet/IP (47808). Every other inbound connection is blocked. Every OT VLAN is isolated from every other OT VLAN — HVAC cannot reach BMS, BMS cannot reach medical gas, medical gas cannot reach elevators. MEDGAS (VLAN 42) has the strictest policy: it cannot initiate any outbound connection whatsoever. Read-only access is enforced at the firewall layer, not just by convention. If a medical gas controller is compromised, it has nowhere to go.
pfSenseCARPdeny-by-defaultpfSensepfsyncModbusBACnet
OT access
Cisco IOSv × 2
OT-Switch-20/21
OT access switches — VLANs 40–45 + 254 — 10.22.x.x scheme
Two Cisco IOSv switches carry the six OT VLANs and OT management. They connect to the OT firewall pair via dedicated OT dist switches — another layer of physical separation from the IT switching fabric. The addressing scheme mirrors IT: 10.22.vlanid.x so any OT IP is immediately identifiable as OT by its second octet.
10.22.x.xVLANs 40–45OT dist switches
IP addressing

Addressing scheme — readable by design

Every IP address in this network tells you what it is before you look it up. The scheme was designed so that reading a log entry or a packet capture immediately reveals the zone, the VLAN, and the role of the device.

Public PI block — 203.0.113.96/27
VRRP VIP (edge routers)203.0.113.97
r16 (LightSpeedFiber)203.0.113.98
r17 (LumaLink)203.0.113.99
Main FW WAN CARP VIP203.0.113.100
fw2 WAN interface203.0.113.101
fw3 WAN interface203.0.113.102
Patient portal NAT203.0.113.103
IT internal — 10.21.vlanid.x/24
CARP VIP (gateway).1 on every VLAN
fw2 real IP.2 on every VLAN
fw3 real IP.3 on every VLAN
Example — VLAN 1010.21.10.0/23
Example — VLAN 25410.21.254.0/24
Guest (off RFC1918)192.168.30.0/22
OT/SCADA — 10.22.vlanid.x/24
OT CARP VIP (gateway).1 on every VLAN
OT-FW1 real IP.2 on every VLAN
OT-FW2 real IP.3 on every VLAN
Example — HVAC10.22.40.0/24
Example — Med gas10.22.42.0/24
Special purpose subnets
OT handoff segment10.200.1.0/29
Main FW CARP VIP10.200.1.1
OT FW CARP VIP10.200.1.4
Main FW pfsync172.16.0.0/30
OT FW pfsync172.16.1.0/30

The consistent .1/.2/.3 pattern across every VLAN — CARP VIP, fw2, fw3 — means troubleshooting is mechanical. If something on VLAN 14 (radiology) can't reach its gateway, you know the gateway is 10.21.14.1 without looking it up. You know fw2 is 10.21.14.2 and fw3 is 10.21.14.3. You know the OT equivalent is 10.22.14.x if it existed. The scheme scales to new VLANs and new sites without breaking the mental model.

Segmentation

VLAN design — 16 segments, two zones

PHI-bearing VLANs are isolated from each other and from everything else. OT runs on a completely separate addressing zone. Guest is deliberately off the 10.x.x.x range to make accidental routing impossible.

10
CLINICAL
10.21.10.0/23
EHR · PACS · nursing · /23 for 510 hosts
12
ICU_BIOMED
10.21.12.0/24
Bedside monitors · infusion pumps · IoMT
13
SURGICAL
10.21.13.0/24
OR workstations · anesthesia documentation
14
RADIOLOGY
10.21.14.0/24
DICOM workstations · PACS clients
15
ONCOLOGY_LD
10.21.15.0/24
Oncology · Labor & Delivery
20
ADMIN
10.21.20.0/24
HR · finance · executive — blocked from clinical
25
PHARMACY
10.21.25.0/24
Pyxis cabinets → pharmacy server only
30
GUEST
192.168.30.0/22
Patient WiFi · internet only · 1,022 hosts
35
IOT
10.21.35.0/24
Smart TVs · printers · non-clinical IoT
50
DMZ
10.21.50.0/24
Patient portal · SMTP relay · public services
250
SERVER_NET
10.21.250.0/24
EHR server · PACS · DNS · infra
254
MGMT
10.21.254.0/24
OOB management · jump host only
40
OT-HVAC
10.22.40.0/24
HVAC controllers · Modbus/TCP
41
OT-BMS
10.22.41.0/24
BACnet/IP · building management
42
OT-MEDGAS
10.22.42.0/24
Medical gas monitoring · zero outbound
43–45
OT-ELEV/PWR/SEC
10.22.43–45.0/24
Elevators · power/UPS · access control/CCTV
OT/SCADA

Hardware-isolated OT stack — the most sensitive part

The OT network is not a separate VLAN. It's a separate physical stack with its own firewall pair, its own distribution switches, its own access switches, and its own addressing zone. The only connection between IT and OT is a single controlled path through the jump host.

vbgh-ot-fw1 — show rules
// OT_WAN interface (opt2) — the only path in from IT
PASS tcp 10.21.254.10010.22.0.0/8 port 22 // jump host SSH only
PASS tcp 10.21.254.10010.22.0.0/8 port 443 // jump host HTTPS only
PASS tcp 10.21.254.10010.22.0.0/8 port 502 // Modbus/TCP — HVAC only
PASS tcp 10.21.254.10010.22.0.0/8 port 47808 // BACnet/IP — BMS only
BLOCK any 10.22.0.0/810.21.0.0/16 // OT cannot initiate to IT
BLOCK any 10.22.0.0/8any // OT has no internet path
BLOCK any anyany // explicit deny all
// MEDGAS (opt6) — strictest zone
PASS any opt6opt6 // intra-VLAN only
BLOCK any opt6any // cannot initiate ANY outbound — read only enforced
HVAC · VLAN 40
10.22.40.0/24 — gateway 10.22.40.1
HVAC controllers speaking Modbus/TCP. Temperature control for surgical suites, server rooms, patient wards. Modbus has no authentication — anyone who can reach these devices on port 502 can send commands.
Jump host only · port 502 · isolated from all other OT VLANs
BMS · VLAN 41
10.22.41.0/24 — gateway 10.22.41.1
BACnet/IP building management system. Controls environmental systems, door access scheduling, lighting. Runs on UDP 47808 with minimal authentication built into the protocol.
Jump host only · port 47808 · isolated from all other OT VLANs
MEDGAS · VLAN 42
10.22.42.0/24 — gateway 10.22.42.1
Medical gas monitoring — oxygen levels, nitrous oxide, medical air pressure throughout the building. The most sensitive OT zone. Monitoring data is read-only. Configuration happens physically at the panel.
ZERO outbound permitted · cannot initiate any connection · read-only enforced at firewall
ELEVATORS · VLAN 43
10.22.43.0/24 — gateway 10.22.43.1
Elevator control systems. At 1,000 beds elevator uptime is operationally critical — a failed elevator on the surgical floor during patient transport is a safety event. Networked for status monitoring and remote diagnostics.
Jump host only · NTP permitted · isolated from all other OT VLANs
POWER · VLAN 44
10.22.44.0/24 — gateway 10.22.44.1
UPS monitoring, generator controls, PDU management. Monitoring the power infrastructure that keeps every clinical system alive. A compromised power controller in a hospital is a worst-case scenario.
Jump host only · NTP permitted · isolated from all other OT VLANs
ACCESS CONTROL · VLAN 45
10.22.45.0/24 — gateway 10.22.45.1
Physical access control systems and CCTV. Door controllers, badge readers, camera systems. Separated from IT security systems to prevent an IT compromise from affecting physical security.
Jump host only · NTP permitted · isolated from all other OT VLANs
Evidence

The network — in production in EVE-NG

Every config in this writeup is real. These are live screenshots from the running topology — pfSense WebGUI, firewall rules, and CARP status as the network operates.

EVE-NG Topology
Full network topology — all tiers EVE-NG
Valleybrook full EVE-NG topology
The complete Valleybrook topology in EVE-NG. Top to bottom: dual ISP edge routers with VRRP, WAN distribution switches carrying VLAN 2030, main pfSense CARP pair, then the network splits — IT fabric core switches and access layer on the left (grey), OT distribution switches and OT pfSense CARP pair in the center (yellow), OT access switches below. The color separation between IT (grey) and OT (yellow) mirrors the physical and logical isolation in the design.
Edge and WAN distribution layer BGP · VRRP · VLAN 2030
Valleybrook edge and WAN dist topology
Edge layer zoomed in — dual ISP clouds connecting to Router-16 (LightSpeedFiber) and Router-17 (LumaLink) via eBGP. The VRRP ring between them floats the gateway VIP (.97). Both routers trunk tagged VLAN 2030 down to their respective WAN dist switches. The WAN dist switches carry VLAN 2030 down to the main firewall pair, giving fw1 and fw2 a shared L2 broadcast domain for CARP heartbeats on the WAN side — that's the entire reason this layer exists.
Status / CARP — vbgh-fw2 14 / 14 MASTER
pfSense CARP status — all 14 VIPs showing MASTER
fw2 CARP status page — all 14 virtual IPs in MASTER state. From WAN (203.0.113.100) to OT_HANDOFF (10.200.1.1), every VLAN gateway is owned by this node. fw3 sits in BACKUP on all VHIDs, ready to claim them in under 2 seconds if fw2 dies.
Dashboard — CARP & Gateways
pfSense dashboard CARP widget and gateways
Dashboard widgets showing all 14 CARP VIPs MASTER, plus both gateways online — WANGW (203.0.113.97 VRRP VIP) and OT_HANDOFF (10.200.1.4 OT FW CARP VIP). Both paths up, RTT healthy.
Firewall → Virtual IPs — all 14 CARP VIPs
pfSense virtual IP list — 14 CARP VIPs
The full CARP VIP table — VHID 1 through 14. WAN at 203.0.113.100, every internal VLAN from NETWORKMANAGEMENT (10.21.254.1) to OT_HANDOFF (10.200.1.1). Every gateway in the hospital is a CARP VIP on this pair.
Firewall → Rules — all 16 interfaces
pfSense firewall rules interface tabs — 16 interfaces
The firewall interface tab bar — 16 separate interfaces each with their own rule set. VALLEYBROOK_INTERNET through OT_HANDOFF_INTERFACE_VLAN_300, PHARMACY, CARP, IPsec. Every tab is a separate policy domain.
Firewall → Rules → OT_HANDOFF_INTERFACE_VLAN_300 deny-by-default
pfSense OT handoff firewall rules
The OT handoff interface rules — JUMP_HOST → OT_VLANS on OT_PORTS (pass), OT_HANDOFF intra-subnet (pass), OT_VLANS → any (block, logged). This is the single controlled path between the IT network and every OT device in the building. One source, four ports, deny everything else.
OT/SCADA Firewall Pair — OT-FW1
Status / CARP — vbgh-ot-fw1 8 OT VIPs · all MASTER
OT-FW1 CARP status — 8 OT VIPs MASTER
OT-FW1 CARP status — 8 VIPs covering every OT zone from OT_WAN (10.200.1.4/29) through HVAC, BMS, MEDGAS, ELEVATORS, POWER, ACCESS_CONTROL, and OT_NETWORK_MANAGEMENT (10.22.254.1/24). Completely separate CARP pair from the main IT firewalls. OT-FW2 sits in BACKUP on all VHIDs, pfsync running on 172.16.1.0/30.
Firewall → Virtual IPs — OT-FW1
OT-FW1 Virtual IP list — 8 CARP VIPs
All 8 OT CARP VIPs — VHID 1 through 8. OT_WAN at 10.200.1.4/29 connects to the main firewall handoff segment. Each OT VLAN has its own VIP as the default gateway for devices in that zone.
Firewall → Rules → OT_WAN deny-by-default
OT-FW1 OT_WAN firewall rules
OT_WAN rules on OT-FW1 — the inbound policy from the main campus handoff segment. Jump host permit, OT-to-OT intra-segment pass, explicit deny all logged. The interface tab bar shows all 11 OT interfaces: WAN, CARP_INTERFACE, uplink, downlink, and all 6 OT zones plus management.
Engineering rationale

The decisions that matter — and why

Every design decision has a documented reason. These aren't preferences — they're choices that can be defended to a HIPAA auditor, a hospital CIO, a senior network engineer, and a skeptical client asking why the bill is what it is.

IP strategy
Provider-independent space via ARIN, not ISP-assigned
203.0.113.96/27 is registered to Valleybrook General Hospital AS65100. The IP addresses belong to the hospital. Not to LightSpeedFiber. Not to LumaLink. To Valleybrook. Changing ISPs, adding a third ISP, or renegotiating contracts requires exactly zero IP renumbering across the entire infrastructure.
Why it matters: The patient portal is at 203.0.113.103. The VPN concentrator is at 203.0.113.105. If those were ISP-assigned IPs, every vendor relationship, every DNS record, every VPN config, and every firewall rule at a remote partner that references those IPs would need to change every time the hospital changed providers. With PI space, those addresses are permanent infrastructure, not borrowed from a carrier.
Firewall architecture
Firewall owns all VLAN gateways — no core SVIs
The Cisco IOSv core switch has no SVIs, no ACLs, and no routing table entries beyond a single static default route. Every VLAN gateway IP lives as a CARP VIP on the pfSense pair. Every packet crossing a VLAN boundary hits pfSense first and gets logged, inspected, and policy-evaluated before going anywhere.
Why it matters: Switch ACLs are stateless, don't log individual connections, and have no IDS integration. A HIPAA audit requires you to demonstrate that PHI access is logged and controlled. "We have ACLs on the core switch" is a much weaker compliance story than "every inter-VLAN flow goes through a stateful firewall with connection logging." The pfSense at 26Gbps handles the load. The compliance story is airtight.
HA — firewalls
CARP with pfsync state sync — zero-drop failover
fw2 and fw3 share 14 CARP VIPs. pfsync runs over a dedicated bonded link (172.16.0.0/30) and replicates the full connection state table in real time. When fw2 dies, fw3 claims all 14 VIPs and already has the state table. Active TCP sessions survive. EHR connections don't reset. VoIP calls don't drop.
Why it matters: A stateless failover — where the backup simply takes over the IP without the state table — would reset every active TCP connection. In a hospital, a nurse mid-charting on EHR sees a connection reset as her session dying. A DICOM transfer in progress aborts. Stateful failover via pfsync means the failure is invisible to every user on the network. That's the difference between "the firewall failed over" and "nobody noticed."
Core switching
Pure L2 core — deliberate simplicity
The Cisco IOSv core switch does one thing: move 802.1Q tagged frames. No routing, no OSPF, no ACLs, no SVIs. The entire core switch config is VTPv3 setup, STP priority, and trunk port configurations. It fits on one screen. Anyone on Marcus's helpdesk team can read it and understand what it does.
Why it matters: Complexity is where mistakes live. A core switch trying to do routing, ACLs, OSPF, and switching simultaneously is a core switch where a misconfiguration in one domain affects all the others. Pushing all intelligence to the firewall means the core is a known-good forwarding fabric. When something breaks, you know it isn't the core switch making a routing decision — because the core switch doesn't make routing decisions.
OT isolation
Hardware isolation — not VLAN isolation
OT has its own firewall pair, its own distribution switches, its own access switches, its own pfsync subnet, and its own addressing zone. The only connection between IT and OT is a single controlled path on a dedicated L2 segment. There is no way to reach an OT device from the IT network except through the jump host on specific ports.
Why it matters: VLAN isolation is software. Hardware isolation is physics. If ransomware hits VLAN 20 admin, it faces a pfSense firewall with deny-by-default OT rules. It faces a dedicated L2 segment it can't reach. It faces a second pfSense firewall pair with its own deny-by-default policy. Even if the attacker somehow compromised the main firewall, they'd still hit the OT firewall. Two independent walls, not one.
Automation
Python-generated pfSense XML configs
fw3, OT-FW2, and all secondary node configs were generated programmatically. A Python script reads the primary firewall's XML config, swaps .2 IPs to .3, flips all CARP VIPs from advskew 0 to 100, reverses the pfsync peer, clears XMLRPC sync, removes SSH host keys and SSL certs, and writes a complete secondary config ready to restore.
Why it matters: Manual config duplication is how secondary nodes end up with subtle differences from primaries — a missed IP here, a wrong skew there. With scripted generation, the secondary is guaranteed to be a mathematically correct mirror of the primary. It's also repeatable — if the primary config changes, regenerating the secondary is one command. Version control the scripts and you have a complete audit trail of every config decision.
Compliance

HIPAA Security Rule mapping

Every network control in this design maps to a specific HIPAA Security Rule requirement. The architecture isn't HIPAA-compliant by accident — it was built against these requirements from the ground up.

§164.312(a)(1)
Access Control
Clinical VLANs (10–15) isolated from admin (20), guest (30), and OT (40–45) at the firewall layer. Every inter-VLAN flow is explicitly permitted or denied with a documented rule. No implicit access. PHI cannot reach non-clinical zones under any permitted rule.
§164.312(b)
Audit Controls
All firewall rule hits logged. All OT access attempts logged. Jump host session logging for every OT management connection. pfsync state table gives a complete record of every connection that traversed the firewall. Syslog to NOC server on VLAN 254.
§164.312(e)(1)
Transmission Security
PHI only traverses encrypted paths. IPsec IKEv2 AES-256-GCM on all VPN tunnels. WPA3-Enterprise on clinical SSIDs. TLS enforced for all EHR outbound. Guest VLAN has no path to any PHI-bearing VLAN under any rule.
§164.312(a)(2)(iv)
Encryption
IPsec AES-256-GCM on all inter-site VPN connections. pfsync traffic on a dedicated isolated subnet not reachable from any user VLAN. Management plane (VLAN 254) accessible only from the jump host via SSH.
§164.308(a)(4)
Information Access Management
Pharmacy (VLAN 25) permits only Pyxis-to-server traffic — one specific TCP connection. ICU biomedical (VLAN 12) can reach the server network for EHR but nothing else. MOB physicians (VLANs 60–62) reach EHR only — no other internal access.
§164.310(d)(1)
Device and Media Controls
OT devices physically isolated in dedicated rack with no IT network path. MEDGAS cannot initiate any outbound connection — enforced at the firewall, not by convention. Break-glass procedure documented for physical OT access requiring jump host session logging.
Lab validation

EVE-NG build — what was tested and what was found

The full topology was built in EVE-NG with 30+ nodes. Each layer was validated independently before proceeding to the next. Failures were documented and resolved. One limitation was found and documented honestly rather than worked around.

// validation log — Valleybrook General Hospital
BGP dual-ISP failover — Shut LightSpeedFiber uplink on r16. BGP session to LightSpeedFiber dropped. LumaLink path via r17 continued announcing 203.0.113.96/27. PI block remained reachable throughout. No change to downstream devices.
VRRP edge failover — Powered off r16 (VRRP master). r17 claimed 203.0.113.97 VIP within 3 seconds. Continuous pings through the VIP showed 2 drops during VRRP election, then resumed. Both ISP path and gateway VIP failed over simultaneously as designed.
Main pfSense CARP failover — Powered off fw2 (CARP master, advskew 0). fw3 claimed all 14 CARP VIPs within 2 seconds. Zero dropped pings through any CARP VIP. Existing sessions confirmed survived via pfsync state table. fw3 promoted to master on all VHIDs simultaneously.
OT pfSense CARP failover — Powered off OT-FW1 (master). OT-FW2 claimed all 8 OT CARP VIPs. OT device reachability confirmed uninterrupted through the OT handoff segment. Confirmed pfsync running on 172.16.1.0/30 separate from main FW pfsync on 172.16.0.0/30.
VTPv3 VLAN propagation — VTPv3 primary server election run on Core-20 using vtp primary vlan command. All 16 VLANs propagated to Core-21 via EtherChannel trunk automatically. Confirmed VTP client mode on Core-21 with matching domain and password.
Clinical-to-admin isolation — VLAN 10 host attempted to reach VLAN 20 host. Blocked at firewall. Confirmed firewall log entry showing block with correct source/destination. VLAN 10 successfully reached SERVER_NETWORK (VLAN 250) on port 443.
Guest containment — VLAN 30 host attempted to reach 10.21.10.1 (clinical gateway). Blocked at firewall by RFC1918 block rule. VLAN 30 host successfully reached internet via NAT. Confirmed 192.168.30.0/22 subnet completely isolated from 10.x.x.x space.
OT isolation — Confirmed no path from any IT VLAN to OT VLANs except from jump host (10.21.254.100). OT host on VLAN 40 attempted to reach 10.21.10.1 — blocked at OT firewall rule 5. MEDGAS host on VLAN 42 attempted to ping its own gateway — blocked by zero-outbound rule. Read-only enforcement confirmed.
Python config generation — fw3 config generated from fw2 XML via script: hostname updated, all .2 IPs swapped to .3, all 14 CARP VIPs set to advskew 100, pfsync peer set to fw2, XMLRPC sync cleared, SSH keys and SSL cert removed. Restored and booted clean on first attempt. OT-FW2 generated same way from OT-FW1.
MLAG distribution failover — EVE-NG limitation documented — MLAG peer session established between distribution switches (state: connected, roles assigned via priority). LACP fast timers configured at 1-second intervals. EVE-NG virtual link detection does not replicate physical SFP link-down behavior — when a node is powered off, the virtual interface remains "electrically" up and LACP does not detect the failure until interfaces are manually disabled. Production behavior validated on physical MikroTik CHR and MikroTik CHR hardware in physical MikroTik hardware outside of this lab environment. EVE-NG lab uses active-backup bonding as documented alternative.
What I learned

The things you only learn by building

This project wasn't built from a template. It was built, broken, redesigned, and rebuilt. Here are the things that changed between the first design and the final one.

01
CARP multicast needs shared L2 — everywhere
Every CARP pair needs a shared L2 broadcast domain between the two nodes on every interface they share a VIP on. The WAN dist switches, the OT handoff L2 switch, the core EtherChannel — all of these exist specifically to provide that shared domain. It took several iterations to get the OT handoff topology right because the initial design didn't have a shared segment between the two OT firewalls.
02
Redundancy is a design problem, not a feature
Building this project made it clear that redundancy isn't something you bolt on at the end, it has to be considered and designed into every tier from the start. Every layer needs a partner: a second ISP, a second edge router, a second firewall, a second core switch. The moment you start thinking about what happens when any single device dies, the whole topology changes. That thinking shaped every decision in this network from the first diagram.
03
EVE-NG's limitations made the design better
The proper production design for access layer redundancy is MLAG — each end device has dual uplinks, one to each access switch in the pair, and MLAG makes those two switches appear as a single logical device to the downstream host. No STP blocking, no wasted links, full active/active redundancy. The same applies going up the stack — distribution switches MLAG'd to the core, access switches MLAG'd to distribution. EVE-NG can't replicate the physical link-down behavior that makes MLAG failover work, so the lab uses active-backup bonding as the documented alternative. Working around that constraint forced a clearer understanding of what MLAG is actually solving — and why it's the right answer when you're building for real.
04
Two firewalls is not always better than one
The design went through a phase where it had a separate internal segmentation firewall and a separate perimeter firewall. After building it out, it was overengineered for pfSense — the two-pair approach added complexity without adding proportionate value at this scale. Collapsed back to one CARP pair for the main hospital network. The OT pair is justified because it's a genuinely separate security domain, not just a second enforcement point on the same traffic.
05
Script your secondary configs
Manually configuring fw3 as a mirror of fw2 across 14 VLANs, 14 CARP VIPs, pfsync, and XMLRPC sync settings is not just tedious — it's a source of subtle errors that are painful to debug. Scripting the generation makes it repeatable, auditable, and guaranteed to be consistent. Worth the upfront investment on any HA deployment with more than 4-5 interfaces.
06
Document the gap between simulation and production
EVE-NG virtual links don't go down when a node is powered off — the carrier stays up and LACP doesn't detect the failure. Rather than working around this with a hack, it's documented honestly with a reference to production validation on physical hardware. That's more useful to someone reading the portfolio than a workaround that makes the simulation look cleaner than it is.
About

Built by Elijah Ali — age 20

I'm a network engineer based in Lancaster, PA. My day-to-day involves BGP, OSPF, VRRP, MLAG, pfSense HA firewall clusters, and MikroTik hardware — the same stack that runs Valleybrook. I didn't design this network in a vacuum. I designed it against the same problems I solve at work, with the same tools I use every day.

I founded Ali-AS Network LLC as a solo network consulting venture targeting municipalities, medical offices, and SMBs. The positioning is audit-first, I go into a network, document what exists, identify what's broken or risky, and build a remediation plan. Valleybrook is what that engagement looks like when the client needs the full buildout, not just the audit.

The things in this project that I'm most proud of aren't the technologies, it's understanding and the decisions. Deciding that two internal firewalls was overcomplicated and the right answer was one well-configured pair. Deciding that the OT handoff needed its own dedicated L2 switch rather than going through the core stack. These are the decisions that come from understanding what you're building and why, not from following a template.

I built this at 20 years old and 1 year of real world experience. The gap between where I am and where I want to be which is running my own firm designing complex infrastructure, is smaller than it looks. This journey has been extremley fun and exciting. This is the work.
Elijah Ali · Ali-AS Network LLC · [email protected]

Production experience

BGP/OSPF on enterprise fiber infrastructure · pfSense HA firewall clusters · MikroTik RouterOS · VRRP · iPerf3 throughput testing · production fiber infrastructure engineering

Ali-AS Network LLC

Solo network consulting · audit first positioning · Lancaster County PA · municipalities · medical offices · SMBs · PA LLC filed · aliasnetwork.net

If you want a network engineer who thinks about the why, not just the how: [email protected]