Design a HIPAA-Compliant Hospital Firewall
Build a segmented hospital network firewall lab with pfSense and Snort IDS.
Introduction
30 Second Summary
When a hospital network gets breached, attackers rarely stop at one system. They move sideways from a compromised device to the database holding every patient's records. The firewall rules that stop this lateral movement are the single most critical security control in healthcare IT.
In this project, you will build a fully functional hospital network firewall lab using pfSense in VirtualBox. You will segment it into three isolated hospital zones, write default-deny firewall rules that block unauthorized cross-zone traffic, prove your segmentation works with live tests, and package the whole thing as a professional GitHub portfolio piece.
What You'll Build
When you are done, you can open your pfSense dashboard, show a hiring manager three isolated hospital zones, run a ping from the Medical IoT zone toward the Clinical zone, and watch it get blocked and logged in real time. Then you can hand them a compliance document explaining exactly which proposed HIPAA Security Rule requirement each firewall rule satisfies.
By the end of this project, you'll have:
- A multi-zone hospital firewall with three isolated network segments (Clinical, Medical IoT, Administrative) where you can test real traffic boundaries and see blocked packets logged in the firewall console.
- A default-deny rule set with compliance documentation that maps each allowlist entry to the proposed HIPAA Security Rule requirement it satisfies, ready to present to an auditor or interviewer.
- A GitHub portfolio repository containing your network architecture diagram, exported firewall rules, compliance mapping, and screenshot evidence proving that lateral movement between zones is blocked.
- Secret Mission: Configure Snort IDS monitoring to detect a port scan targeting your Clinical zone and observe the alert signatures in real time.
Are there any prerequisites?
You need basic networking knowledge (IP addresses, subnets, ports) and Oracle VirtualBox already installed on Windows. If you do not have VirtualBox yet, install it from virtualbox.org before starting.
Before We Start
Before building anything, take a moment to lock in what you're about to create and why it matters for your career in healthcare IT security. This reflection sets the context for every hands-on step that follows.
Set Up pfSense in VirtualBox
A hospital network needs clear boundaries between different types of systems. Clinical workstations storing patient records must be isolated from medical devices and from administrative computers. To enforce these boundaries, you need a firewall appliance sitting between each zone.
pfSense CE is an open-source firewall used in healthcare labs and real hospital environments. In this step, you will create a pfSense virtual machine with four network interfaces, install the firewall software, and verify it recognizes all interfaces.
In this step, get ready to:
- Create a VirtualBox VM with four network adapters mapped to hospital zones.
- Install pfSense CE 2.8.1 using the Netgate Installer.
- Assign interfaces and verify pfSense recognizes all four.
Create the pfSense-Hospital VM
Each network adapter in VirtualBox represents a physical network port on your virtual firewall. You need four: one for internet access (WAN) and three for isolated hospital zones.
- Press the Windows key to open your search bar.
- Type VirtualBox and press Enter to open it.
- Click New in the toolbar to create a new virtual machine.
- Set Name to pfSense-Hospital.
- Set Type to BSD and Version to FreeBSD (64-bit).
- Set memory to 2048 MB.
- Create a virtual hard disk with 16 GB dynamically allocated.
- Click Finish to create the VM.
You should see pfSense-Hospital in the VirtualBox machine list on the left side.
Now configure the four network adapters. Each adapter maps to a hospital network zone.
- Right-click pfSense-Hospital in the machine list and select Settings.
- Click Network in the left panel.
- On the Adapter 1 tab, confirm it is enabled and set Attached to to NAT. Expand Advanced and set Adapter Type to Intel PRO/1000 MT Desktop (82540EM).
- Click the Adapter 2 tab. Check Enable Network Adapter. Set Attached to to Internal Network. In the Name field, type CLINICAL. Set Adapter Type to Intel PRO/1000 MT Desktop (82540EM).
- Click the Adapter 3 tab. Check Enable Network Adapter. Set Attached to to Internal Network. In the Name field, type MEDIOT. Set Adapter Type to Intel PRO/1000 MT Desktop (82540EM).
- Click the Adapter 4 tab. Check Enable Network Adapter. Set Attached to to Internal Network. In the Name field, type ADMIN. Set Adapter Type to Intel PRO/1000 MT Desktop (82540EM).
- Click OK to save all settings.
What do these adapters represent?
Adapter 1 (NAT) gives pfSense internet access through your host PC. This becomes the WAN interface (em0).
Adapters 2-4 are Internal Networks. Each Internal Network name creates an isolated Layer 2 segment. VMs assigned to the same name can talk to each other, but cannot reach VMs on different names. This is how you simulate physically separate hospital network zones without needing real hardware.
Don't see the Adapter 3 or 4 tabs?
VirtualBox shows all four adapter tabs by default. If you only see two, make sure you are in the VM Settings window (not the global preferences). Right-click the VM name and select Settings again.
help me find the network adapter tabs in VirtualBox settings
Install pfSense CE and assign interfaces
The pfSense installer is an online installer. It downloads pfSense CE from Netgate servers during the install process. Your VM's NAT adapter provides the internet connectivity it needs.
- With pfSense-Hospital selected in VirtualBox, click Settings again.
- Click Storage in the left panel.
- Under Controller: IDE, click the empty disc icon.
- On the right side, click the small disc icon next to Optical Drive and select Choose a disk file.
- Navigate to your downloaded pfSense-CE-2.8.1-RELEASE-amd64.iso file and select it.
- Click OK to save, then click Start to boot the VM.
What happens when you boot?
The Netgate Installer will launch automatically. It needs internet access to download pfSense packages from Netgate servers. Since Adapter 1 is set to NAT, VirtualBox provides a DHCP address and routes internet traffic through your host PC.
Follow the installer prompts to install pfSense CE.
- Accept the license terms when prompted.
- At the Welcome Menu, select Install to start the installation process.
- For the network setup, select em0 as the WAN interface (this is your NAT adapter). Leave the WAN configuration as DHCP.
- When prompted about device eligibility, select Install CE to install pfSense CE Software.
- At the version selection screen, choose the current stable version (2.8.1).
- Let the installer download and install pfSense to the target disk. This takes a few minutes depending on your internet speed.
- When installation completes, select Reboot.
Remove the ISO before reboot
VirtualBox may boot from the ISO again instead of the installed disk. If you see the installer again after reboot, power off the VM, go to Settings > Storage, right-click the ISO under the IDE controller, and select Remove Attachment. Then start the VM again.
After reboot, pfSense boots from disk and reaches the interface assignment screen.
- When asked if you want to configure VLANs, type n and press Enter.
- For the WAN interface, type em0 and press Enter.
- For the LAN interface, type em1 and press Enter.
- For the Optional 1 (OPT1) interface, type em2 and press Enter.
- For the Optional 2 (OPT2) interface, type em3 and press Enter.
- When asked to proceed, type y to confirm the assignments.
What is each interface for?
em0 (WAN) connects to the internet through VirtualBox NAT. This gives pfSense and its zones access to external resources.
em1 (LAN) maps to the CLINICAL Internal Network. This will hold systems that store and access ePHI.
em2 (OPT1) maps to the MEDIOT Internal Network. This isolates medical IoT devices like infusion pumps and monitors.
em3 (OPT2) maps to the ADMIN Internal Network. This separates general business systems from clinical data.
Verify your pfSense console
Before you run anything else, what do you expect to see on the pfSense console now that all four interfaces are assigned?
After interface assignment completes, pfSense displays its main console menu. Look at the top of the screen.
- Confirm you see all four interfaces listed at the top of the console.
- WAN (em0) should show an IP address assigned via DHCP from VirtualBox NAT. This is typically 10.0.2.15.
- LAN (em1), OPT1 (em2), and OPT2 (em3) should show no IP address yet.
You should also see a numbered menu with options like "1) Assign Interfaces" and "2) Set interface(s) IP address". This menu is the pfSense console where you will manage your firewall.
WAN shows no IP or a different address?
If WAN shows no IP, the NAT adapter may not be configured correctly. Power off the VM, go to Settings > Network > Adapter 1, and confirm it is set to NAT (not "NAT Network" or "Internal Network"). Restart the VM.
If you see a different IP like 10.0.2.16, that is normal. VirtualBox NAT assigns addresses from its own DHCP pool. Any 10.0.2.x address means WAN is working correctly.
help me troubleshoot why pfSense WAN has no IP address in VirtualBox
Your firewall appliance is running. Next up, you will configure IP addresses on each hospital zone and access the pfSense web dashboard.
Configure Hospital Network Zones
Your pfSense firewall has four interfaces recognized, but they are just raw network ports with no identity or addressing. A hospital network needs clearly defined zones, each with its own IP subnet and DHCP service so devices receive addresses automatically when they connect.
In this step, you will assign IP addresses and DHCP ranges to each interface, build a test VM to confirm connectivity, and then access the pfSense web dashboard for the first time. This is your first visible result: a management dashboard showing your three hospital zones live and addressable.
In this step, get ready to:
- Assign static IP addresses and DHCP ranges to the Clinical, Medical IoT, and Admin interfaces.
- Create an Ubuntu test VM on the Clinical zone and verify it receives a DHCP address from pfSense.
- Access the pfSense web GUI and rename interfaces to match hospital zone names.
Assign IP addresses to hospital zone interfaces
Each hospital zone needs its own subnet so devices within it are logically separated at the network layer. You will use the pfSense console menu to configure each interface one at a time.
What is the IP scheme?
Each zone gets a /24 subnet (254 usable host addresses) with a DHCP pool carved out of the upper range. The gateway address (.1) belongs to pfSense itself.
- CLINICAL (em1/LAN): 10.10.10.0/24 with gateway 10.10.10.1.
- MEDIOT (em2/OPT1): 10.20.20.0/24 with gateway 10.20.20.1.
- ADMIN (em3/OPT2): 10.30.30.0/24 with gateway 10.30.30.1.
The pfSense console option 2 is interactive. It will prompt you for the interface number, IP address, subnet mask, whether to enable DHCP, and the DHCP range.
- In the pfSense console, type 2 and press Enter to select "Set interface(s) IP address".
- When prompted to select the interface number, type 2 to select LAN (em1).
- Enter the new LAN IPv4 address: 10.10.10.1.
- Enter the subnet bit count: 24.
- Press Enter to skip the upstream gateway (none needed for LAN).
- When asked to enable the DHCP server, type y.
- Enter the DHCP range start address: 10.10.10.100.
- Enter the DHCP range end address: 10.10.10.199.
When pfSense asks whether to revert to HTTP, type n to keep HTTPS for the web GUI. The console will confirm the new LAN address and return to the main menu.
- Repeat the process for OPT1 (em2) by selecting option 2 again, then choosing interface number 3 for OPT1.
- Enter IPv4 address 10.20.20.1, subnet 24, enable DHCP with range 10.20.20.100 to 10.20.20.199.
- Repeat once more for OPT2 (em3) by choosing interface number 4.
- Enter IPv4 address 10.30.30.1, subnet 24, enable DHCP with range 10.30.30.100 to 10.30.30.199.
After all three are configured, the pfSense console menu should show each interface with its new IP address listed next to it.
Interface showing the wrong IP or no IP?
- Double-check you selected the correct interface number (2 for LAN, 3 for OPT1, 4 for OPT2) at the first prompt.
- Make sure the subnet bit count is 24, not 255.255.255.0 (pfSense asks for CIDR notation here).
- If you entered the wrong values, simply run option 2 again for that interface and re-enter the correct information. Help me fix my pfSense interface IP configuration
Create the test VM on the Clinical zone
You need a machine inside one of your hospital zones to test connectivity and access the pfSense web GUI. An Ubuntu Server VM on the Clinical network acts as your test endpoint for the rest of the project.
- In VirtualBox, click New to create a new VM.
- Set the name to Ubuntu-Test.
- Set Type to Linux and Version to Ubuntu (64-bit).
- Allocate 1024 MB of RAM.
- Create a virtual hard disk with 10 GB (dynamically allocated).
- Open Settings for the new VM and navigate to the Network section.
- Set Adapter 1 to Internal Network with the name CLINICAL.
- Mount the Ubuntu Server 24.04 LTS ISO in the Storage settings as a virtual optical disk.
- Start the VM and follow the Ubuntu Server installer.
- Accept all default settings (minimal install).
- When the installer asks about network configuration, it should automatically detect an IP from the 10.10.10.100-199 range via DHCP.
- Complete the installation and reboot when prompted.
Once Ubuntu boots to a login prompt, log in and verify your network address by running:
ip addr show
You should see an IP address in the 10.10.10.100-199 range assigned to your network interface. This confirms pfSense's DHCP server on the Clinical zone is working.
Not seeing a 10.10.10.x address?
- Confirm the VM's network adapter is set to Internal Network with the name CLINICAL (case-sensitive, must match the pfSense-Hospital VM exactly).
- Make sure the pfSense VM is still running. The DHCP server only responds when pfSense is active.
- Try requesting a fresh DHCP lease by running sudo dhclient in the Ubuntu terminal.
- Help me get a DHCP address from pfSense on my test VM
Access the pfSense web GUI and rename interfaces
The pfSense web GUI is where you will manage all firewall rules going forward. Accessing it from your test VM proves end-to-end connectivity between the Clinical zone and the firewall.
- From the Ubuntu test VM terminal, test connectivity to the pfSense gateway by running:
curl -k https://10.10.10.1
You should see HTML output from the pfSense login page. The -k flag tells curl to accept the self-signed SSL certificate.
Why the certificate warning?
pfSense serves its web GUI over HTTPS by default using a self-signed certificate. Since no Certificate Authority has vouched for it, tools like curl and browsers will warn you. In a lab environment this is expected and safe to bypass.
- If your Ubuntu install includes a desktop environment, open a browser and navigate to https://10.10.10.1. Accept the certificate warning.
- Log in with the default credentials: username admin and password pfsense.
What if I only have a terminal?
If you installed Ubuntu Server without a desktop, you can still verify web GUI access using the curl command above. For the interface renaming steps that follow, you can use a text-based browser like w3m or lynx, or install a minimal desktop with sudo apt install firefox xorg and then start it with startx.
Now you will rename the OPT interfaces so they display meaningful hospital zone names throughout the GUI.
- In the pfSense web GUI, click Interfaces in the top menu, then select OPT1.
- In the Description field, change the value to MEDIOT.
- Make sure the Enable interface checkbox is checked.
- Click Save at the bottom of the page, then click Apply Changes.
- Repeat for OPT2: click Interfaces in the top menu, then select OPT2.
- Change the Description to ADMIN, ensure it is enabled, click Save, then Apply Changes.
Why rename interfaces?
The Description field in pfSense becomes the interface name displayed on firewall rule tabs, DHCP settings, and the dashboard. Naming them CLINICAL, MEDIOT, and ADMIN makes every rule you write in the next steps immediately clear in terms of which hospital zone it protects.
Before you check the dashboard, predict what you expect to see. How many zones should appear, and what IPs should each one display?
- Click Dashboard in the top menu (or click the pfSense logo) to return to the main overview.
You should see all three hospital zones listed with their assigned IPs: LAN (CLINICAL) at 10.10.10.1, MEDIOT at 10.20.20.1, and ADMIN at 10.30.30.1. The WAN interface shows 10.0.2.15 from VirtualBox NAT.
Dashboard not showing all interfaces?
- If MEDIOT or ADMIN does not appear, navigate back to Interfaces and confirm the Enable interface checkbox is checked for each one.
- Click Save and Apply Changes after enabling. The dashboard refreshes to show newly enabled interfaces.
- Help me get all three interfaces showing on my pfSense dashboard
Your hospital network architecture is live. Three zones are addressable, DHCP is serving IPs, and you have management access through the web GUI. Next up, you will test whether this "segmented" network actually prevents traffic from crossing between zones.
Expose the Segmentation Gap
Your hospital zones have separate IP ranges, but separate addressing does not mean isolated traffic.
Before writing any firewall rules, you need to prove whether pfSense actually blocks cross-zone traffic by default. This is the critical test that HIPAA auditors ask about: can a compromised device on one zone reach another?
In this step, get ready to:
- Test cross-zone connectivity from the CLINICAL zone to MEDIOT and ADMIN gateways.
- Identify the default pfSense rule that allows unrestricted traffic.
- Document the segmentation gap that the proposed HIPAA Security Rule requires you to close.
Test cross-zone connectivity from CLINICAL
If your network segmentation is working correctly, a device on the CLINICAL zone should NOT be able to reach gateways on other zones. Let's find out what actually happens.
Before you run this test, think: do you expect the ping from your CLINICAL test VM to the MEDIOT gateway (10.20.20.1) to succeed or fail?
- In your Ubuntu test VM terminal on the CLINICAL zone, ping the MEDIOT gateway by running this command:
ping -c 3 10.20.20.1
The ping succeeds. You get replies from 10.20.20.1. Your CLINICAL zone can freely talk to the MEDIOT gateway.
- Now ping the ADMIN gateway by running:
ping -c 3 10.30.30.1
This also succeeds. Your hospital zones can talk to each other freely. A device on the CLINICAL network can reach both MEDIOT and ADMIN with no restrictions.
This is the gap
Your "segmented" network is NOT actually segmented. In a real hospital, this means a compromised infusion pump on the CLINICAL zone could pivot to the EHR database, medical devices, or administrative systems.
Identify the default rule causing the gap
Something in pfSense is explicitly allowing this traffic. Let's find it.
- Switch back to the pfSense web GUI at https://10.10.10.1.
- Click Firewall in the top menu.
- Click Rules.
- Select the LAN tab (this is your CLINICAL interface).
You should see a single rule listed: the "Default allow LAN to any rule" with action Pass, source LAN net, and destination set to any.
Why does pfSense allow all LAN traffic by default?
pfSense ships with a default rule that trusts all traffic originating from the LAN interface. This is convenient for home users who want internet access immediately after setup.
In a hospital environment, this default is dangerous. It means any device on the CLINICAL zone (mapped to LAN) can reach any other zone with zero restrictions. This single rule is the root cause of your segmentation gap.
Confirm MEDIOT and ADMIN interface rules
The gap is asymmetric. Let's check what the other zones look like.
- Click the MEDIOT tab in the firewall rules view.
There are no rules listed. OPT interfaces in pfSense do not get a default allow rule.
- Click the ADMIN tab.
Also empty. No rules means no traffic passes. The implicit deny blocks everything originating from those zones.
What does this mean for your hospital network?
Traffic originating FROM MEDIOT and ADMIN zones is already blocked outbound (no rules = implicit deny). But traffic TO those zones from CLINICAL passes freely through the default LAN rule.
This is the gap that the proposed HIPAA Security Rule requires you to close. Proposed 45 CFR 164.312(a)(2)(vi) requires regulated entities to "implement technical controls to segment their electronic information systems in a reasonable and appropriate manner."
You have now identified and documented the segmentation gap: the default allow LAN to any rule lets CLINICAL traffic flow freely to MEDIOT and ADMIN zones.
You have proven that your hospital network has a critical segmentation gap. Next up, you will close this gap by implementing a default-deny firewall policy with explicit clinical allowlists that map to proposed HIPAA requirements.
Implement HIPAA Default-Deny Firewall Rules
In the previous step, you proved that your hospital zones are not actually isolated. A single default rule on the CLINICAL interface lets traffic flow freely to the MEDIOT and ADMIN gateways. That is exactly the gap the proposed HIPAA Security Rule NPRM targets.
Now you will close that gap by implementing a default-deny posture with explicit allowlists on every zone. This is the core skill hiring managers test for in healthcare IT security roles. Can you write least-privilege rules that protect ePHI while keeping legitimate clinical traffic flowing?
In this step, get ready to:
- Delete the default allow-all rule on the CLINICAL interface and replace it with explicit allowlists.
- Create matching default-deny rules for the MEDIOT and ADMIN zones.
- Prove that cross-zone lateral movement is now blocked while essential services still work.
Delete the default rule and create CLINICAL zone allowlists
The CLINICAL interface currently has one rule: pass everything from the LAN network to any destination. You will delete it and replace it with five explicit rules that allow only DNS, NTP, and HTTPS outbound while blocking all paths to the other zones.
- In the pfSense web GUI, navigate to Firewall in the top menu.
- Select Rules from the dropdown.
- Click the LAN tab (this is your CLINICAL interface).
- Select the checkbox next to the Default allow LAN to any rule.
- Click the Delete button to remove it.
- Confirm the deletion when prompted.
Now create the five CLINICAL zone rules. Each rule is added by clicking the Add button (down arrow to add to the end of the list).
- Create Rule 1: Action Pass, IPv4, Protocol TCP/UDP, Source CLINICAL net, Destination CLINICAL address, Destination Port 53 (DNS). Description: Allow Clinical zone DNS via pfSense.
- Create Rule 2: Action Pass, IPv4, Protocol UDP, Source CLINICAL net, Destination CLINICAL address, Destination Port 123 (NTP). Description: Allow Clinical zone NTP.
- Create Rule 3: Action Pass, IPv4, Protocol TCP, Source CLINICAL net, Destination any, Destination Port 443 (HTTPS). Description: Allow Clinical zone HTTPS outbound for EHR cloud access.
- Create Rule 4: Action Block, IPv4, any protocol, Source CLINICAL net, Destination MEDIOT net. Description: Block Clinical to Medical IoT - prevent lateral movement.
- Create Rule 5: Action Block, IPv4, any protocol, Source CLINICAL net, Destination ADMIN net. Description: Block Clinical to Admin - zone isolation.
- Click Apply Changes to activate all five rules.
Your CLINICAL interface now shows five explicit rules with no default pass rule remaining.
Why these specific ports?
Port 53 (DNS) allows clinical workstations to resolve domain names. Port 123 (NTP) ensures accurate timestamps, which the HIPAA audit controls requirement specifically calls for.
Port 443 (HTTPS) outbound allows encrypted connections to cloud-hosted EHR systems. Everything else is denied by default.
- Switch to your Ubuntu test VM on the CLINICAL zone.
- Test that the CLINICAL rules are working by running this command:
ping -c 3 10.20.20.1
The ping should now time out with no response. Your block rule to the MEDIOT gateway is active.
Ping still succeeds?
Make sure you clicked Apply Changes after creating all rules. Rules are not active until applied.
Also confirm you deleted the original Default allow LAN to any rule. If it still appears in the rule list, that pass-all rule takes precedence over your block rules.
Need more help? Help me troubleshoot why my pfSense block rules aren't taking effect on the CLINICAL interface.
Create MEDIOT and ADMIN zone rules
The MEDIOT and ADMIN interfaces have no rules at all, which means pfSense already blocks traffic originating from them (implicit deny on OPT interfaces). However, you still need explicit rules to allow essential services and to document your security posture for auditors.
- In the pfSense web GUI, navigate to Firewall > Rules.
- Click the MEDIOT tab.
- Create Rule 1: Action Pass, IPv4, Protocol TCP/UDP, Source MEDIOT net, Destination MEDIOT address, Destination Port 53. Description: Allow MedIoT DNS.
- Create Rule 2: Action Pass, IPv4, Protocol UDP, Source MEDIOT net, Destination MEDIOT address, Destination Port 123. Description: Allow MedIoT NTP for device sync.
- Create Rule 3: Action Block, IPv4, any protocol, Source MEDIOT net, Destination CLINICAL net. Description: Block MedIoT to Clinical - protect ePHI.
- Create Rule 4: Action Block, IPv4, any protocol, Source MEDIOT net, Destination ADMIN net. Description: Block MedIoT to Admin.
- Click Apply Changes.
Now configure the ADMIN zone with the same pattern.
- Click the ADMIN tab.
- Create Rule 1: Action Pass, IPv4, Protocol TCP/UDP, Source ADMIN net, Destination ADMIN address, Destination Port 53. Description: Allow Admin DNS.
- Create Rule 2: Action Pass, IPv4, Protocol UDP, Source ADMIN net, Destination ADMIN address, Destination Port 123. Description: Allow Admin NTP.
- Create Rule 3: Action Pass, IPv4, Protocol TCP, Source ADMIN net, Destination any, Destination Port 443. Description: Allow Admin HTTPS outbound.
- Create Rule 4: Action Block, IPv4, any protocol, Source ADMIN net, Destination CLINICAL net. Description: Block Admin to Clinical - protect ePHI.
- Create Rule 5: Action Block, IPv4, any protocol, Source ADMIN net, Destination MEDIOT net. Description: Block Admin to MedIoT.
- Click Apply Changes.
Why explicit block rules when OPT interfaces already deny by default?
The implicit deny on OPT interfaces is invisible. It does not appear in the rule list and does not generate log entries.
Explicit block rules are visible to auditors, show up in firewall logs, and document your intent. HIPAA compliance requires documented evidence of your security controls.
Verify segmentation blocks lateral movement
All three zones now have explicit rules enforcing a default-deny posture. Time to prove it works.
- Switch to your Ubuntu test VM on the CLINICAL zone.
Before you run the next commands, predict: will the pings to the MEDIOT and ADMIN gateways succeed or fail? Will DNS resolution still work?
- Test connectivity to the MEDIOT gateway by running:
ping -c 3 10.20.20.1
You should see the request time out with no response. Your block rule is preventing CLINICAL from reaching the MEDIOT zone.
- Test connectivity to the ADMIN gateway by running:
ping -c 3 10.30.30.1
This also times out. The CLINICAL zone is now completely isolated from both other zones.
- Verify that essential services still work by running:
nslookup google.com
DNS resolves successfully. Your allowlist on port 53 permits the CLINICAL zone to reach pfSense for name resolution while blocking everything else.
What does this prove?
Your rules block lateral movement while preserving essential services. A compromised infusion pump on the MEDIOT zone cannot reach the EHR database on the CLINICAL zone.
This is the exact scenario the proposed HIPAA Security Rule requires you to prevent under proposed 45 CFR 164.312(a)(2)(vi).
- Return to the pfSense web GUI.
- Navigate to Status > System Logs > Firewall.
You should see entries showing blocked packets with the source IP (your test VM), destination (MEDIOT or ADMIN gateway), and the rule that matched. This log data is your audit evidence for HIPAA compliance.
Not seeing blocked entries in the log?
Explicit block rules in pfSense log traffic by default. If you do not see entries, make sure you ran the ping commands after applying your rules.
Also check that you are on the Firewall tab within System Logs, not the General tab.
Still stuck? Help me find my blocked traffic entries in pfSense firewall logs.
Your hospital firewall now enforces true network segmentation. Next up, you will document everything and package it as a GitHub portfolio piece that proves your work to hiring managers.
Document and Package for GitHub
Your firewall rules work. Cross-zone traffic is blocked, DNS resolves, and the logs prove it. But none of that matters to a hiring manager who cannot see your work.
In this step, you will export your pfSense configuration, capture evidence screenshots, and package everything into a GitHub repository with professional compliance documentation. This is how you turn a lab exercise into a portfolio piece that demonstrates real HIPAA Security Rule readiness.
In this step, get ready to:
- Export your pfSense firewall configuration and capture evidence screenshots.
- Create a repository with a README, compliance mapping, and organized evidence.
- Push to GitHub and verify the rendered documentation.
Export firewall configuration and capture evidence
HIPAA auditors need two things: your firewall rules and proof they work. You will export the pfSense configuration as XML (the auditable rule set) and take screenshots of the dashboard, rules, and logs (the visual evidence).
- In the pfSense web GUI, navigate to Diagnostics in the top menu.
- Click Backup & Restore.
- Leave the Backup Area dropdown at its default (All). This captures your entire configuration including all firewall rules.
- Click Download Configuration as XML.
- Save the downloaded file to your Windows Desktop. Rename it to pfsense-rules.xml.
What does this XML file contain?
The pfSense configuration XML includes every firewall rule, interface assignment, DHCP setting, and zone definition you configured. It is a complete, machine-readable record of your hospital network architecture. An auditor can inspect it to verify your segmentation without needing access to the live firewall.
Now capture the visual evidence that proves your configuration works.
- Navigate to Status > Dashboard. Take a screenshot showing all three zones (CLINICAL, MEDIOT, ADMIN) with their assigned IPs and status. Save it as dashboard.png.
- Navigate to Firewall > Rules > LAN (CLINICAL). Take a screenshot of your rules. Repeat for the MEDIOT and ADMIN tabs. Save them as rules-clinical.png, rules-mediot.png, and rules-admin.png.
- Navigate to Status > System Logs > Firewall. Take a screenshot showing blocked cross-zone packets. Save it as firewall-logs.png.
- Switch to your Ubuntu test VM. Run ping -c 3 10.20.20.1 and take a screenshot showing the timeout. Save as ping-blocked.png.
- Run nslookup google.com and take a screenshot showing successful resolution. Save as dns-works.png.
You should now have six screenshot files and one XML configuration file saved to your Desktop.
Screenshots not capturing the full window?
Use Alt+PrintScreen (Windows) to capture only the active window. If the pfSense tables are too wide, zoom out in your browser with Ctrl+- before capturing.
Help me organize my evidence screenshots for the portfolio.
Create the repository structure and documentation
With your evidence captured, you need a professional repository structure that a hiring manager can read in under two minutes. The README provides the architecture overview, and the compliance mapping ties every rule to a specific HIPAA requirement.
- Open a terminal on your Windows machine (PowerShell or Git Bash).
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and directory structure by running these commands:
mkdir hospital-firewall-lab
cd hospital-firewall-lab
mkdir configs evidence
- Confirm the directory structure exists by running:
ls
You should see configs and evidence listed in the output.
- Move your pfsense-rules.xml file into the configs directory. Move all your .png screenshot files into the evidence directory.
- Create the README.md file. Open a text editor and paste the following content as the first section:
# Hospital Network Firewall - HIPAA Security Rule Compliance Lab
## Overview
A fully functional hospital network segmentation lab implementing the network isolation requirements proposed in the HIPAA Security Rule NPRM (90 FR 898, January 6, 2025). This project demonstrates proactive compliance readiness for the mandatory segmentation specification under proposed 45 CFR 164.312(a)(2)(vi), ahead of the anticipated July 2027 finalization.
## Regulatory Context
| Milestone | Date/Status |
|-----------|-------------|
| NPRM published (Federal Register 90 FR 898) | January 6, 2025 |
| Comment period closed (~4,745 comments) | March 7, 2025 |
| Final rule projected | July 2027 |
| Compliance deadline (estimated) | ~March 2028 (240 days post-publication) |
The proposed rule eliminates the "addressable" vs "required" distinction and makes network segmentation a required implementation specification. This lab implements that requirement now.
Why include regulatory context?
This table shows hiring managers you understand the compliance timeline, not just the technical implementation. It demonstrates you are tracking real regulatory developments and building skills proactively.
- Continue adding the network architecture diagram section below the regulatory context:
## Network Architecture
```
[Internet]
|
[NAT - WAN]
|
+-------------------+
| pfSense CE 2.8.1 |
| Hospital Firewall |
+---+-------+---+---+
| | |
em1/LAN em2/OPT1 em3/OPT2
| | |
+---------+--+ +--+------+ +--+--------+
| CLINICAL | | MEDIOT | | ADMIN |
| 10.10.10.0 | | 10.20.20.0| | 10.30.30.0|
| /24 | | /24 | | /24 |
+------------+ +----------+ +-----------+
EHR, Billing, Infusion Email, HR,
Clinical WS Pumps, Office Apps
Monitors
```
- Add the zone design table, firewall policy summary, and key results section:
## Zone Design
| Zone | Interface | Subnet | Purpose | HIPAA Alignment |
|------|-----------|--------|---------|------------------|
| CLINICAL | em1 (LAN) | 10.10.10.0/24 | Systems storing/accessing ePHI | Protects electronic Protected Health Information |
| MEDIOT | em2 (OPT1) | 10.20.20.0/24 | Medical IoT devices | Isolates devices that cannot run endpoint agents |
| ADMIN | em3 (OPT2) | 10.30.30.0/24 | General business IT | Separates non-clinical systems from ePHI |
## Firewall Policy
Default-deny posture on all interfaces. Only explicitly documented traffic is permitted.
See [COMPLIANCE_MAPPING.md](COMPLIANCE_MAPPING.md) for full rule-to-requirement mapping.
## Key Results
- Cross-zone lateral movement blocked (verified via ping tests and firewall logs)
- DNS and NTP services maintained for operational continuity
- HTTPS outbound permitted for cloud EHR access
- All blocked traffic logged for audit evidence
- Snort IDS configured to detect network reconnaissance
- Add the final section with repository structure, tools used, and references:
## Repository Structure
```
/configs - pfSense firewall rule exports (XML)
/evidence - Screenshots of test results and IDS alerts
COMPLIANCE_MAPPING.md - Rule-to-HIPAA requirement mapping
README.md - This file
```
## Tools Used
- pfSense CE 2.8.1 (firewall/router)
- Oracle VirtualBox (virtualization)
- Snort IDS with Emerging Threats Open rules (threat detection)
- Ubuntu Server 24.04 LTS (test endpoint)
## References
- [HIPAA Security Rule NPRM (90 FR 898)](https://www.federalregister.gov/documents/2025/01/06/2024-30983/hipaa-security-rule-to-strengthen-the-cybersecurity-of-electronic-protected-health-information)
- [HHS 405(d) Health Industry Cybersecurity Practices](https://405d.hhs.gov/)
- [pfSense Documentation](https://docs.netgate.com/pfsense/en/latest/)
- Save README.md in the root of your hospital-firewall-lab folder.
- Verify the file was saved correctly by running:
cat README.md | head -5
You should see the first five lines of your README, starting with # Hospital Network Firewall.
Seeing garbled characters or empty output?
Make sure you saved the file with UTF-8 encoding. If using Notepad on Windows, select UTF-8 from the encoding dropdown when saving. If the file is empty, confirm you saved it inside the hospital-firewall-lab directory, not your Desktop root.
Help me fix my README.md file encoding or location issue.
Now create the compliance mapping document. This is the file that connects every firewall rule to a specific HIPAA requirement.
- Create a new file called COMPLIANCE_MAPPING.md. Paste the header and CLINICAL zone mapping:
# HIPAA Compliance Mapping - Hospital Firewall Rules
## Proposed Requirement: Network Segmentation
**Citation:** Proposed 45 CFR 164.312(a)(2)(vi) - "implement technical controls to segment their electronic information systems in a reasonable and appropriate manner"
## Rule-to-Requirement Mapping
### CLINICAL Zone (em1/LAN) - ePHI Systems
| Rule # | Action | Source | Destination | Port | HIPAA Requirement | Rationale |
|--------|--------|--------|-------------|------|-------------------|-----------|
| 1 | Pass | CLINICAL net | CLINICAL address | 53 (DNS) | Access Control - 164.312(a)(1) | Clinical systems require name resolution for EHR connectivity |
| 2 | Pass | CLINICAL net | CLINICAL address | 123 (NTP) | Audit Controls - 164.312(b) | Accurate timestamps required for audit log integrity |
| 3 | Pass | CLINICAL net | Any | 443 (HTTPS) | Transmission Security - 164.312(e)(1) | Encrypted outbound access for cloud-hosted EHR systems |
| 4 | Block | CLINICAL net | MEDIOT net | Any | Access Control - 164.312(a)(2)(vi) | Prevent lateral movement to medical device zone |
| 5 | Block | CLINICAL net | ADMIN net | Any | Access Control - 164.312(a)(2)(vi) | Isolate ePHI systems from administrative network |
What does this mapping prove?
Each row ties a specific firewall rule to a HIPAA Security Rule section. The DNS allow rule maps to Access Control because clinical systems need name resolution to reach the EHR. The NTP allow maps to Audit Controls because accurate timestamps are required for log integrity. The block rules map directly to the proposed segmentation requirement.
This is exactly the format compliance officers use when documenting technical safeguards during audits.
- Add the MEDIOT and ADMIN zone mappings below the CLINICAL table:
### MEDIOT Zone (em2/OPT1) - Medical IoT Devices
| Rule # | Action | Source | Destination | Port | HIPAA Requirement | Rationale |
|--------|--------|--------|-------------|------|-------------------|-----------|
| 1 | Pass | MEDIOT net | MEDIOT address | 53 (DNS) | Access Control - 164.312(a)(1) | Device management requires name resolution |
| 2 | Pass | MEDIOT net | MEDIOT address | 123 (NTP) | Audit Controls - 164.312(b) | Medical devices require time synchronization for data accuracy |
| 3 | Block | MEDIOT net | CLINICAL net | Any | Access Control - 164.312(a)(2)(vi) | Prevent compromised IoT devices from reaching ePHI |
| 4 | Block | MEDIOT net | ADMIN net | Any | Access Control - 164.312(a)(2)(vi) | Contain medical device zone from administrative systems |
### ADMIN Zone (em3/OPT2) - Administrative Systems
| Rule # | Action | Source | Destination | Port | HIPAA Requirement | Rationale |
|--------|--------|--------|-------------|------|-------------------|-----------|
| 1 | Pass | ADMIN net | ADMIN address | 53 (DNS) | Access Control - 164.312(a)(1) | Administrative systems require name resolution |
| 2 | Pass | ADMIN net | ADMIN address | 123 (NTP) | Audit Controls - 164.312(b) | Timestamp accuracy for administrative audit logs |
| 3 | Pass | ADMIN net | Any | 443 (HTTPS) | Workforce Security - 164.308(a)(3) | Encrypted internet access for business operations |
| 4 | Block | ADMIN net | CLINICAL net | Any | Access Control - 164.312(a)(2)(vi) | Administrative users access ePHI only through defined authenticated pathways |
| 5 | Block | ADMIN net | MEDIOT net | Any | Access Control - 164.312(a)(2)(vi) | Prevent administrative systems from reaching medical devices |
- Add the compliance evidence table and regulatory notes as the final section:
## Compliance Evidence
| Evidence Type | Location | Purpose |
|---------------|----------|---------|
| Blocked traffic logs | /evidence/firewall-logs.png | Proves segmentation is enforced |
| Cross-zone ping test (fail) | /evidence/ping-blocked.png | Demonstrates lateral movement prevention |
| DNS resolution test (pass) | /evidence/dns-works.png | Proves essential services maintained |
| Snort IDS alerts | /evidence/snort-alerts.png | Demonstrates threat detection capability |
| pfSense rule export | /configs/pfsense-rules.xml | Auditable firewall configuration |
## Regulatory Notes
- This implementation addresses the **proposed** HIPAA Security Rule (NPRM, 90 FR 898, Jan 6, 2025), not a finalized requirement
- The final rule is projected for July 2027 with compliance ~240 days after publication
- HHS 405(d) Health Industry Cybersecurity Practices already recommend network segmentation as an enhanced voluntary practice
- The current HIPAA Security Rule (in effect since 2013) requires reasonable and appropriate technical safeguards; segmentation is a recognized method to satisfy this under existing law
- Save COMPLIANCE_MAPPING.md in the root of your hospital-firewall-lab folder.
- Verify your full repository structure by running:
ls -R
You should see README.md, COMPLIANCE_MAPPING.md, a configs directory containing pfsense-rules.xml, and an evidence directory containing your screenshot files.
✔️ I see all files listed
Your repository structure is complete. Every file is in the right place.
ⓧ Some files are missing
Check that you moved your screenshots into the evidence directory and the XML export into configs. On Windows, you can use File Explorer to drag files into the correct folders, then re-run ls -R to confirm.
Push to GitHub and verify
Your documentation and evidence are organized locally. The final step is pushing everything to GitHub where a hiring manager can browse it.
- Initialize a git repository and make your first commit by running these commands:
git init
git add .
git commit -m "Add HIPAA hospital firewall lab with compliance documentation"
What do these commands do?
The git init command creates a new git repository in your current folder. The git add . stages every file for commit. The git commit saves a snapshot of all your work with a descriptive message.
- Go to github.com in your browser and create a new repository named hospital-firewall-lab. Leave it public. Do not initialize it with a README (you already have one).
- Copy the remote URL GitHub provides. Push your local repository by running these commands (replace the URL with your own):
git remote add origin [[REPO_URL="https://github.com/YOUR-USERNAME/hospital-firewall-lab.git"]]
git branch -M main
git push -u origin main
- Wait for the push to complete. You should see output confirming the branch was pushed to origin/main.
Before you check the result, what do you expect to see when you open the repository on GitHub? Think about which file GitHub renders automatically on the landing page.
- Open your repository URL in the browser. GitHub automatically renders README.md on the landing page.
- Verify your ASCII network architecture diagram displays correctly.
- Click COMPLIANCE_MAPPING.md and confirm the tables render with proper column alignment.
- Open the evidence folder and confirm your screenshots are visible.
- Open the configs folder and confirm pfsense-rules.xml is present.
Your rendered README should display the network architecture diagram, link to your compliance mapping, and show your test evidence proving segmentation works. Your portfolio piece is live.
Tables look broken on GitHub?
Markdown tables need a blank line above the header row and no extra spaces inside pipe characters. If columns are misaligned, check that every row has the same number of | characters. Edit the file on GitHub directly and preview the changes using the Preview tab.
Help me fix my markdown table formatting on GitHub.
Secret mission
Add Snort IDS Monitoring
Firewall rules block known-bad traffic, but they cannot detect suspicious patterns like port scans or reconnaissance probes. In this secret mission, you will install Snort IDS on your pfSense firewall, configure it to monitor the Clinical zone, and prove it detects a simulated network scan. This is the skill that separates a network engineer from a SOC analyst.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally in VirtualBox, so there are no ongoing cloud costs.
Resources you used:
- pfSense-Hospital VM in VirtualBox (pfSense CE 2.8.1 with Snort IDS).
- Ubuntu-Test VM in VirtualBox (Ubuntu Server 24.04 LTS).
- pfSense CE 2.8.1 ISO file and Ubuntu Server 24.04 LTS ISO file on your local disk.
- GitHub repository with README, compliance mapping, configs, and evidence.
- Local git repository on your machine.
Keep everything running
No action needed. Choose this if you're still actively building on your hospital firewall lab or plan to extend it further.
- Your VMs remain in VirtualBox, ready to start at any time.
- Your GitHub repository stays live as a portfolio piece.
- ISO files remain on disk in case you want to rebuild or add more VMs later.
Pause - I'll come back to this later
Shut down the VMs to free up RAM and CPU. Your configurations are saved inside the virtual disks, so everything will be there when you return.
- In VirtualBox Manager, right-click the pfSense-Hospital VM and select Close > Power Off.
- Right-click the Ubuntu-Test VM and select Close > Power Off.
- Your GitHub repository stays live. No action needed there.
- Optionally delete the ISO files to reclaim disk space. You can re-download them later if needed.
Delete - I don't want to use this again
Remove all project VMs, local files, and optionally the GitHub repository to start completely fresh.
- In VirtualBox Manager, right-click the pfSense-Hospital VM, select Remove, then choose Delete all files. This removes the VM and its virtual disk.
- Right-click the Ubuntu-Test VM, select Remove, then choose Delete all files.
- Delete the pfSense CE ISO file and Ubuntu Server ISO file from your Downloads folder (or wherever you saved them).
- Delete your local project folder containing README.md, COMPLIANCE_MAPPING.md, /configs, and /evidence.
- To delete the GitHub repository: open your repository on GitHub, click Settings, scroll to the bottom to the Danger Zone section, and click Delete this repository. Follow the confirmation prompts.
Nice Work!
Nice Work!
Nice work! You just built a production-grade hospital network firewall lab in pfSense, implementing the network segmentation architecture proposed in the 2025 HIPAA Security Rule NPRM.
You've learned how to:
- Design and implement multi-zone network segmentation in pfSense, identifying and closing a critical default-allow gap that would have permitted unrestricted lateral movement between hospital zones.
- Write default-deny firewall rules with documented compliance rationale, mapping each allowlist entry to the specific HIPAA Security Rule requirement it satisfies.
- Validate segmentation with logged evidence of blocked cross-zone traffic and package the complete project as a GitHub-ready portfolio repository with architecture diagrams, rule exports, and compliance documentation.
- Secret Mission: Configured Snort IDS to detect and alert on network reconnaissance targeting the Clinical zone, demonstrating SOC-ready threat detection and automated blocking skills.
Ready to quiz yourself?