P01-T06 - Base Firewall
Objective
Apply the first validated CHR firewall policy so the router is administratively protected, LAN networks can reach the internet, and guest or DMZ traffic is isolated from internal LAN services until explicit service rules are added later.
Inputs
| Key | Value |
|---|---|
| Router | HQ-CHR01 |
| Mgmt list | MGMT |
| Hypervisor list | HYPERVISORS |
| WAN list | WAN |
| LAN list | LAN |
| Backup list | BACKUP |
| Guest list | GUEST |
| DMZ list | DMZ |
| Servers list | SERVERS |
Target State
| Property | Value |
|---|---|
| Input policy | Established, ICMP, management, hypervisors, then WAN/default drop |
| Forward policy | Established, LAN to WAN, backup to servers, guest isolation, DMZ isolation, default drop |
Validated lab status
Validated against the live lab on Friday, July 17, 2026:
- the base input and forward policy was deployed successfully
- management from
VLAN100was validated HQ-CHR01retained internet access after firewall applicationHQ-DC01retained internet access through the router after firewall application- later DHCP relay validation proved that DHCP-specific
inputrules must be inserted beforeINPUT - Default Drop, not appended after it
Prechecks
- Complete
P01-T05. - Confirm interface lists are populated correctly.
- Print current filter rules first:
If the router is clean and has no conflicting default rules, continue. If it already has active rules in production, review before applying anything.
Execution
Deploy the input chain rules as a managed block and enforce order by comment:
:if ([:len [/ip firewall filter find where comment="INPUT - Established"]] = 0) do={
/ip firewall filter add chain=input action=accept connection-state=established,related comment="INPUT - Established"
}
:if ([:len [/ip firewall filter find where comment="INPUT - Invalid"]] = 0) do={
/ip firewall filter add chain=input action=drop connection-state=invalid comment="INPUT - Invalid"
}
:if ([:len [/ip firewall filter find where comment="INPUT - ICMP"]] = 0) do={
/ip firewall filter add chain=input action=accept protocol=icmp comment="INPUT - ICMP"
}
:if ([:len [/ip firewall filter find where comment="INPUT - Management"]] = 0) do={
/ip firewall filter add chain=input action=accept in-interface-list=MGMT comment="INPUT - Management"
}
:if ([:len [/ip firewall filter find where comment="INPUT - Hypervisors"]] = 0) do={
/ip firewall filter add chain=input action=accept in-interface-list=HYPERVISORS comment="INPUT - Hypervisors"
}
:if ([:len [/ip firewall filter find where comment="INPUT - Drop WAN"]] = 0) do={
/ip firewall filter add chain=input action=drop in-interface-list=WAN comment="INPUT - Drop WAN"
}
:if ([:len [/ip firewall filter find where comment="INPUT - Default Drop"]] = 0) do={
/ip firewall filter add chain=input action=drop comment="INPUT - Default Drop"
}
:local InputEstablished [/ip firewall filter find where comment="INPUT - Established"]
:local InputInvalid [/ip firewall filter find where comment="INPUT - Invalid"]
:local InputIcmp [/ip firewall filter find where comment="INPUT - ICMP"]
:local InputMgmt [/ip firewall filter find where comment="INPUT - Management"]
:local InputHypervisors [/ip firewall filter find where comment="INPUT - Hypervisors"]
:local InputDropWan [/ip firewall filter find where comment="INPUT - Drop WAN"]
:local InputDefaultDrop [/ip firewall filter find where comment="INPUT - Default Drop"]
:foreach RuleId in=$InputDefaultDrop do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$InputDropWan do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$InputHypervisors do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$InputMgmt do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$InputIcmp do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$InputInvalid do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$InputEstablished do={ /ip firewall filter move $RuleId 0 }
Deploy the forward chain rules as a managed block and enforce order by comment:
:if ([:len [/ip firewall filter find where comment="FWD - Established"]] = 0) do={
/ip firewall filter add chain=forward action=accept connection-state=established,related comment="FWD - Established"
}
:if ([:len [/ip firewall filter find where comment="FWD - Invalid"]] = 0) do={
/ip firewall filter add chain=forward action=drop connection-state=invalid comment="FWD - Invalid"
}
:if ([:len [/ip firewall filter find where comment="FWD - LAN to Internet"]] = 0) do={
/ip firewall filter add chain=forward action=accept in-interface-list=LAN out-interface-list=WAN comment="FWD - LAN to Internet"
}
:if ([:len [/ip firewall filter find where comment="FWD - Backup"]] = 0) do={
/ip firewall filter add chain=forward action=accept in-interface-list=BACKUP out-interface-list=SERVERS comment="FWD - Backup"
}
:if ([:len [/ip firewall filter find where comment="FWD - Guest Isolation"]] = 0) do={
/ip firewall filter add chain=forward action=drop in-interface-list=GUEST out-interface-list=LAN comment="FWD - Guest Isolation"
}
:if ([:len [/ip firewall filter find where comment="FWD - DMZ Isolation"]] = 0) do={
/ip firewall filter add chain=forward action=drop in-interface-list=DMZ out-interface-list=LAN comment="FWD - DMZ Isolation"
}
:if ([:len [/ip firewall filter find where comment="FWD - Default Drop"]] = 0) do={
/ip firewall filter add chain=forward action=drop comment="FWD - Default Drop"
}
:local FwdEstablished [/ip firewall filter find where comment="FWD - Established"]
:local FwdInvalid [/ip firewall filter find where comment="FWD - Invalid"]
:local FwdLanInternet [/ip firewall filter find where comment="FWD - LAN to Internet"]
:local FwdBackup [/ip firewall filter find where comment="FWD - Backup"]
:local FwdGuestIsolation [/ip firewall filter find where comment="FWD - Guest Isolation"]
:local FwdDmzIsolation [/ip firewall filter find where comment="FWD - DMZ Isolation"]
:local FwdDefaultDrop [/ip firewall filter find where comment="FWD - Default Drop"]
:foreach RuleId in=$FwdDefaultDrop do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$FwdDmzIsolation do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$FwdGuestIsolation do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$FwdBackup do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$FwdLanInternet do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$FwdInvalid do={ /ip firewall filter move $RuleId 0 }
:foreach RuleId in=$FwdEstablished do={ /ip firewall filter move $RuleId 0 }
If a comment matches zero rules, the :foreach does nothing. If it matches multiple rules because of duplicates, each one is still moved safely.
Do not permit inter-VLAN business traffic yet. Service-specific flows for AD, DNS, DHCP, and SMB should be added later as explicit rules when Windows services are deployed.
Important: when Windows DHCP is hosted on a server in another VLAN, the later service runbooks must add both:
- a
DHCP relayentry onCHR - explicit
inputrules for relay client requests and server replies beforeINPUT - Default Drop
Without those input rules, the relay can be configured correctly and still fail at runtime. This failure mode was reproduced in the live lab until the DHCP relay rules were moved above INPUT - Default Drop.
Validation
Run:
From H1:
Pass criteria:
- Filter counters increase on active rules.
H1still reaches172.20.100.1.- CHR has outbound connectivity.
- Guest and DMZ networks are blocked from generic LAN access.
- No broad admin access exists from WAN.
- Input chain order is:
INPUT - EstablishedINPUT - InvalidINPUT - ICMPINPUT - ManagementINPUT - HypervisorsINPUT - Drop WANINPUT - Default Drop- Forward chain order is:
FWD - EstablishedFWD - InvalidFWD - LAN to InternetFWD - BackupFWD - Guest IsolationFWD - DMZ IsolationFWD - Default Drop
Evidence
- Output of
/ip firewall filter print stats - Output of
ping 172.20.100.1fromH1 - Output of
/ping 1.1.1.1 - Output of
/ping google.com
Rollback
- Remove only the newly added filter rules if access breaks in a known way.
- If rule order is corrupted, restore from the last known backup before firewall application.