One store in a regional chain: eight staffed lanes, four self-checkouts, a warehouse full of handheld scanners, shelf labels and deli scales that change price overnight, cold rooms that must never warm up, and 24 cameras. The tills talk to head office and nowhere else. We build it on Cisco from the lanes up in 12 tested steps, ending with an IKEv2 tunnel to HQ, an LTE backup reserved for what keeps the store trading, and a refrigeration vendor who can only get in on Tuesday mornings.
Full network · all steps built
highlighted = lines added in the selected step · earlier steps shown plain · later steps hidden
This is part 4 of the Build series, and the first one that's part of something bigger: the store is a branch of a chain. The POS backend, ERP, price management and security operations all live at head office. The store's network has to do two things well: keep its own zones apart, and give each zone exactly the path to HQ it needs.
Retail is also where payment-card rules bite hardest. With dozens of payment devices in one building, every zone that can reach a till is in PCI DSS scope. The design aim is that almost nothing can.
01
A fictional but typical 1,500 m² neighbourhood supermarket, store number 142 in a chain of 60.
The store has 8 staffed lanes, each with a POS terminal and an IP PIN pad, plus 4 self-checkouts. The sales floor uses electronic shelf labels driven by 6 radio base stations, the deli, bakery and butcher have networked scales, and screens at the entrance show offers. The warehouse uses Wi-Fi handheld scanners for receiving and stock counts. The cold rooms and display fridges are monitored by a refrigeration controller that the refrigeration contractor services remotely. There are 24 cameras, a PA and music system, a small office, and customer Wi-Fi. Head office runs the POS backend, payment gateway, ERP, warehouse management and price systems in its data center, reached over the internet.
| Requirement | Where it comes from, and what it forces |
|---|---|
| R1 Payment scope | PCI DSS: the lanes and self-checkouts form the cardholder data environment (CDE). They reach HQ's POS and payment systems and nothing else; nothing in the store reaches them. |
| R2 Keep trading | A store that can't take cards loses thousands an hour. Lanes and handhelds must survive a fibre cut (LTE backup), and the LTE line carries nothing else. |
| R3 HQ is the only way out for the CDE | The tills never browse; payments go through HQ's gateway. Store-to-HQ traffic is encrypted end to end. |
| R4 Prices change overnight | HQ pushes the next day's prices to scales and shelf labels between 02:00 and 05:00. That path has to exist, in that direction only. |
| R5 Food safety | Refrigeration alarms reach HQ's monitoring 24/7. The contractor gets in only in agreed windows, from one known host, and every session is logged. |
| R6 Warehouse roaming | Handhelds move between 4 APs while scanning a pallet; roams must be fast enough that the scanning app doesn't time out. |
| R7 CCTV | 24 cameras at up to 4 Mb/s each stay off every other switch, and off the WAN except for HQ security viewing. |
| R8 Chain-wide sameness | Sixty stores, one design. Addresses, VLAN numbers and configs are templates where only the store number changes. |
02
Most of these come from the store being one of sixty.
The lanes don't need "internet with a filter"; they need HQ. So the CDE's ACL on the core permits only HQ's address space, and the zone firewall on the edge has no INSIDE→OUTSIDE class for the CDE subnet. A compromised till can't phone home to anyone but head office. Proving that, which a PCI assessor will ask for, is a two-line check rather than a review of an internet filter.
Twenty-four cameras would fill an access switch's ports, PoE budget and uplink. A dedicated C9200L-48P with an uplink that carries only VLAN 60 keeps camera traffic and any compromised camera physically away from the lanes, and lets the camera installer work on that switch without touching anything else.
A static virtual tunnel interface (IKEv2 + IPsec, tunnel mode) makes HQ look like a routed next hop: ip route 172.16.0.0 255.255.0.0 Tunnel0. That is easier to template across 60 stores than crypto maps, plays well with QoS, and allows a second tunnel over LTE with a floating route. The tunnel is also its own firewall zone, so "what may HQ reach in the store" is a zone-pair policy.
During a fibre outage, the store doesn't need the internet. It needs HQ. The LTE interface is in its own zone that allows nothing but the backup tunnel's IKE and ESP. The office, guests and signage simply wait, so the LTE data plan stays small and there's nothing to filter.
03
10.50.x.0/24 is store 142's block (a chain would use 10.<store>.x or a /16 per region). VLAN IDs are identical in every store.
| VLAN · subnet | Who lives here · gateway · DHCP |
|---|---|
| 10 CDE · 10.50.10.0/24 | Lane POS .11–.18, PIN pads .21–.28, SCOs .31–.34. Static, from HQ's build. GW .1 on CORE. |
| 20 OFFICE · 10.50.20.0/24 | Office PCs, manager laptops. DHCP on CORE. |
| 30 HANDHELD · 10.50.30.0/24 | Warehouse and shop-floor scanners on Wi-Fi. DHCP on CORE. |
| 40 STORE-IOT · 10.50.40.0/24 | Scales .41–.44, ESL base stations .51–.56, signage .61, PA .71. DHCP reservations. |
| 45 REFRIG · 10.50.45.0/24 | Refrigeration controller .10. Static. |
| 50 GUEST · 10.50.50.0/24 | Shoppers' Wi-Fi. L2 only on the core, GW and DHCP on R1. |
| 60 CCTV · 10.50.60.0/24 | NVR .10, cameras .101–.124. Static. |
| 99 MGMT · 10.50.99.0/24 | Switches, APs (EWC), UPS. CORE .1, ACC-FRONT .11, ACC-BACK .12, SW-CCTV .13. |
| 900 TRANSIT · 10.50.255.0/29 | R1 .1 ↔ CORE .2. |
| HQ · 172.16.0.0/16 | POS backend 172.16.10.20, WMS 172.16.30.15, ESL/scale managers 172.16.40.0/24, BMS 172.16.45.20, syslog 172.16.50.5, vendor jump host 172.16.5.10. |
04
Rows start, columns receive. Default deny. Two columns are new compared with a standalone business: HQ via the tunnel, and HQ as a source.
Two rows deserve a second look. The CDE row has exactly one allowed cell, and it's "HQ". The HQ row is not "trusted, allow all": head office reaches the lanes only for POS management, the IoT only to push prices, and the refrigeration only through the vendor window in step 11. A compromise at head office shouldn't automatically become a compromise of every store.
04b
Every requirement from the brief, the steps that implement it, the config that does it, and the test that proves it.
| Requirement | Implemented in | Key config | Proven by |
|---|---|---|---|
| R1 Payment scope | step 1 · step 6 · step 8 | sticky MAC + no errdisable recovery; V10-IN permits only 172.16.0.0/16; no CDE class in INSIDE-TO-INET | "CDE seal" and "Device swap" drills, section 17 |
| R2 Keep trading | step 10 | IP SLA on the fibre; Tunnel1 over LTE always up; floating route to HQ; LTE zone with self-zone only | "Fibre cut" drill |
| R3 HQ is the only way out | step 6 · step 8 · step 9 | V10-IN, NAT-SRC without the CDE, STORE-TO-HQ class | "CDE egress" drill |
| R4 Prices change overnight | step 9 | HQ-TO-STORE permits 172.16.40.0/24 → 10.50.40.0/24 | "Overnight prices" drill |
| R5 Food safety | step 11 | time-range VENDOR-REFRIG + audit-trail; alarms path independent of the window | "Vendor window" drill |
| R6 Warehouse roaming | step 5 | MKT-SCAN with 802.11r/k/v, 5 GHz, raised minimum rate | "Warehouse walk" drill |
| R7 CCTV | step 3 · step 4 | own switch; Po3 carries VLANs 60 and 99 only; V60-IN replies only | "CCTV" drill |
| R8 Chain-wide sameness | step 9 | per-store values limited to store number, tunnel /30 and WAN address; certificates from the chain CA | Template diff between two stores |
The build
Lanes first, head office last. Every step ends with a checkpoint.
Twelve steps: front-of-store access, back-of-store access, the CCTV switch, the core, Wi-Fi, the PCI ACLs, the edge router, the fibre and zone firewall, the HQ tunnel, LTE backup, vendor access, and finally QoS with logging. Each step that adds equipment opens with the topology: built parts solid, the step's additions in orange, later steps faded.
05 · Step 1 of 12
Sixteen lane ports, four self-checkouts, one signage screen. Each payment port remembers the one device allowed on it.
▲ Show step 1 in the interactive topology · see what this step adds, and click any device for its config
hostname ACC-FRONT vtp mode transparent spanning-tree mode rapid-pvst vlan 10 name CDE vlan 20 name OFFICE vlan 30 name HANDHELD vlan 40 name STORE-IOT vlan 45 name REFRIG vlan 50 name GUEST vlan 60 name CCTV vlan 99 name MGMT vlan 666 name PARKING ! ! lanes: one POS and one PIN pad per lane, each pinned to its own MAC interface range GigabitEthernet1/0/1 - 16 description LANE POS / PIN PAD switchport mode access switchport access vlan 10 switchport port-security maximum 1 switchport port-security mac-address sticky switchport port-security violation shutdown switchport port-security spanning-tree portfast spanning-tree bpduguard enable interface range GigabitEthernet1/0/17 - 20 description SELF-CHECKOUT switchport mode access switchport access vlan 10 switchport port-security maximum 1 switchport port-security mac-address sticky switchport port-security spanning-tree portfast spanning-tree bpduguard enable interface GigabitEthernet1/0/21 description SIGNAGE switchport mode access switchport access vlan 40 spanning-tree portfast interface range GigabitEthernet1/0/22 , GigabitEthernet1/0/23 - 24 switchport access vlan 666 shutdown ! Gi1/0/23-24 become AP trunks in step 5 ! no errdisable recovery cause psecure-violation ! a swapped PIN pad stays down until a person looks
# ACC-FRONT — CRS328-24P-4S+: one known MAC per lane port, learning off
/interface bridge add name=bridge vlan-filtering=no
:for i from=1 to=16 do={
/interface bridge port add bridge=bridge interface=("ether" . $i) pvid=10 learn=no \
frame-types=admit-only-untagged-and-priority-tagged comment="lane POS / PIN pad"
}
/interface bridge host add bridge=bridge interface=ether5 mac-address=00:13:C4:00:03:21 # lane 3 PIN pad
# … one static host per lane device and per self-checkout (ether17-20)
/interface bridge port add bridge=bridge interface=ether21 pvid=40 comment="signage"
/interface bridge vlan add bridge=bridge vlan-ids=10,40,50,99 tagged=sfp-sfpplus1
/interface ethernet disable ether22,ether23,ether24
/interface bridge set bridge vlan-filtering=yes
# a swapped PIN pad just gets no traffic forwarded: silent, not err-disabled (see the appendix)PCI DSS expects stores to detect swapped or tampered payment devices. With maximum 1 and a sticky MAC, a different device on a lane port shuts the port immediately, and with errdisable recovery off it stays shut. That's noisy on purpose: the lane stops taking cards, a supervisor gets called, and someone physically inspects the PIN pad before IT re-enables the port. The sticky MACs are saved into the startup config with write memory after the store's devices are installed, and a PIN pad replacement is a ticket, not a shrug.
show port-security: one sticky MAC per lane port after all lanes are powered.err-disabled and a syslog message appears; it stays down until shutdown/no shutdown after the sticky entry is cleared.06 · Step 2 of 12
A second access switch for everything behind the shop floor. Each device type lands in the VLAN whose rules fit it.
▲ Show step 2 in the interactive topology · see what this step adds, and click any device for its config
hostname ACC-BACK
! (same VLAN database as ACC-FRONT)
interface range GigabitEthernet1/0/1 - 4
description OFFICE
switchport mode access
switchport access vlan 20
spanning-tree portfast
spanning-tree bpduguard enable
interface range GigabitEthernet1/0/5 - 8
description DELI / BAKERY / BUTCHER SCALES
switchport mode access
switchport access vlan 40
spanning-tree portfast
interface range GigabitEthernet1/0/9 - 14
description ESL BASE STATIONS (PoE)
switchport mode access
switchport access vlan 40
spanning-tree portfast
interface GigabitEthernet1/0/15
description REFRIGERATION CONTROLLER
switchport mode access
switchport access vlan 45
switchport port-security mac-address sticky
switchport port-security
spanning-tree portfast
interface GigabitEthernet1/0/16
description PA / MUSIC
switchport mode access
switchport access vlan 40
spanning-tree portfastThe scales, shelf-label base stations, signage and PA share VLAN 40 because they share a rule: talk to their manager servers at HQ and nothing in the store. The refrigeration controller gets VLAN 45 to itself, because it's the one device an outside contractor reaches into, and because a food-safety system deserves its own small, boring network.
show vlan brief: ports in 20, 40 and 45 as planned.show power inline: the ESL base stations draw power on Gi1/0/9–14.07 · Step 3 of 12
24 cameras and the NVR on their own hardware, with an uplink that carries one VLAN.
▲ Show step 3 in the interactive topology · see what this step adds, and click any device for its config
hostname SW-CCTV vlan 60 name CCTV vlan 99 name MGMT interface range GigabitEthernet1/0/1 - 24 description CAMERA switchport mode access switchport access vlan 60 switchport port-security mac-address sticky switchport port-security spanning-tree portfast spanning-tree bpduguard enable interface GigabitEthernet1/0/48 description NVR switchport mode access switchport access vlan 60 spanning-tree portfast interface range GigabitEthernet1/0/25 - 47 shutdown
Recording traffic (24 cameras into the NVR, ~100 Mb/s in total) stays inside this switch. Only viewing, a few streams at a time, ever crosses the uplink. That uplink, configured in step 4, allows VLANs 60 and 99 and nothing else, so even a misconfigured camera port can't land in another VLAN.
show interfaces Gi1/0/48 | include rate shows the recording load.show power inline | include Available: enough budget left for the outdoor cameras with heaters.08 · Step 4 of 12
Three port-channels, one gateway per routed VLAN, and DHCP served locally so the store doesn't depend on HQ to boot a scanner.
▲ Show step 4 in the interactive topology · see what this step adds, and click any device for its config
hostname CORE vtp mode transparent spanning-tree mode rapid-pvst spanning-tree vlan 1-4094 priority 4096 ip routing ! (same VLAN database, plus vlan 900 TRANSIT) interface range GigabitEthernet1/1/1 - 2 channel-group 1 mode active interface range GigabitEthernet1/1/3 - 4 channel-group 2 mode active interface range GigabitEthernet1/0/23 - 24 channel-group 3 mode active interface range Port-channel1 - 2 switchport mode trunk switchport trunk native vlan 666 switchport trunk allowed vlan 10,20,30,40,45,50,99 switchport nonegotiate interface Port-channel3 description SW-CCTV: cameras and management only switchport mode trunk switchport trunk native vlan 666 switchport trunk allowed vlan 60,99 switchport nonegotiate ! interface Vlan10 description CDE ip address 10.50.10.1 255.255.255.0 no ip redirects no ip proxy-arp ! Vlan20, 30, 40, 45, 60, 99: same shape, own subnet ! no "interface Vlan50": guests are routed by R1 only (step 7) ! ip dhcp excluded-address 10.50.20.1 10.50.20.49 ip dhcp pool OFFICE network 10.50.20.0 255.255.255.0 default-router 10.50.20.1 dns-server 172.16.0.53 ip dhcp pool HANDHELD network 10.50.30.0 255.255.255.0 default-router 10.50.30.1 dns-server 172.16.0.53 lease 0 12 ! STORE-IOT: reservations per MAC (client-identifier), same pattern
DNS points at HQ's resolver (172.16.0.53), which is reachable once the tunnel is up in step 9. Until then the checkpoint tests use addresses. The ACC switches get matching channel-group uplinks and a VLAN 99 management SVI, as in the law-firm build.
show etherchannel summary: Po1–Po3 all (SU).show interfaces trunk: Po3 allows only 60 and 99.09 · Step 5 of 12
Six APs, one embedded controller, two SSIDs. The handheld SSID is tuned for fast roaming; the guest SSID only has to be isolated.
▲ Show step 5 in the interactive topology · see what this step adds, and click any device for its config
| SSID | Security · VLAN · tuning |
|---|---|
| MKT-SCAN | WPA2/WPA3-Personal (the scanner fleet's lowest common denominator) · VLAN 30 · 802.11r (Fast Transition) + 802.11k/v so scanners roam between the 4 warehouse APs in milliseconds · 5 GHz only · minimum data rate raised to 12 Mb/s so clients don't cling to a distant AP |
| MARKET-Guest | Open, client isolation on · VLAN 50, terminated on R1 · 2.4 + 5 GHz |
interface range GigabitEthernet1/0/21 - 24 ! ACC-BACK; on ACC-FRONT the range is Gi1/0/23 - 24
description AP (FlexConnect local switching)
switchport mode trunk
switchport trunk native vlan 99
switchport trunk allowed vlan 30,50,99
switchport nonegotiate
spanning-tree portfast trunk
no shutdownSome older handheld scanners fail to associate at all with an SSID that advertises 802.11r. Test the actual scanner model before the store opens. If it's a problem, use "FT adaptive" mode (FT for clients that ask for it, plain WPA2 for the rest) or a separate SSID for the old devices until they're replaced. A personal (PSK) key on a scanner fleet is a known trade-off: rotate it when a scanner is lost, and the HANDHELD VLAN's ACL in step 6 limits what a stolen key can reach.
10 · Step 6 of 12
The CDE gets an ACL with one permit line. Everything else gets "what this zone may start", with the CDE always excluded.
ip access-list extended V10-IN
remark CDE: lanes and SCOs reach HQ and nothing else
10 permit icmp 10.50.10.0 0.0.0.255 host 10.50.10.1
20 permit ip 10.50.10.0 0.0.0.255 172.16.0.0 0.0.255.255
30 deny ip any any log
!
ip access-list extended V20-IN
remark OFFICE: HQ, store-IoT admin, NVR viewing, internet. Never the CDE.
10 permit udp any any eq bootps
15 permit icmp any host 10.50.20.1
20 deny ip any 10.50.10.0 0.0.0.255 log
30 permit ip 10.50.20.0 0.0.0.255 172.16.0.0 0.0.255.255
40 permit tcp 10.50.20.0 0.0.0.255 10.50.40.0 0.0.0.255 eq 443
50 permit tcp 10.50.20.0 0.0.0.255 host 10.50.60.10 eq 443
60 deny ip any 10.0.0.0 0.255.255.255 log
70 deny ip any 172.16.0.0 0.15.255.255
80 deny ip any 192.168.0.0 0.0.255.255
90 permit ip 10.50.20.0 0.0.0.255 any
!
ip access-list extended V30-IN
remark HANDHELD: the warehouse system at HQ, nothing else
10 permit udp any any eq bootps
20 permit udp 10.50.30.0 0.0.0.255 host 172.16.0.53 eq domain
30 permit tcp 10.50.30.0 0.0.0.255 host 172.16.30.15 eq 443
40 deny ip any any log
!
ip access-list extended V40-IN
remark STORE-IOT: their managers at HQ, replies to the office, vendor clouds
10 permit udp any any eq bootps
20 permit ip 10.50.40.0 0.0.0.255 172.16.40.0 0.0.0.255
30 permit tcp 10.50.40.0 0.0.0.255 10.50.20.0 0.0.0.255 established
40 deny ip any 10.0.0.0 0.255.255.255 log
50 deny ip any 172.16.0.0 0.15.255.255
60 deny ip any 192.168.0.0 0.0.255.255
70 permit tcp 10.50.40.0 0.0.0.255 any eq 443
!
ip access-list extended V45-IN
remark REFRIG: alarms to HQ BMS, replies to the vendor jump host
10 permit tcp host 10.50.45.10 host 172.16.45.20 eq 443
20 permit tcp host 10.50.45.10 host 172.16.5.10 established
30 deny ip any any log
!
ip access-list extended V60-IN
remark CCTV: the NVR answers viewers, nothing else
10 permit tcp host 10.50.60.10 eq 443 10.50.20.0 0.0.0.255 established
20 permit tcp host 10.50.60.10 eq 443 172.16.0.0 0.0.255.255 established
30 deny ip any any log
!
interface Vlan10
ip access-group V10-IN in
! … V20-IN to V60-IN on their SVIs the same way# R1 (CCR2004) — routing moves off the core; the same policy as a stateful forward chain /ip firewall filter add chain=forward action=accept connection-state=established,related,untracked add chain=forward action=drop connection-state=invalid add chain=forward action=accept in-interface=v10-cde out-interface-list=HQ comment="CDE: HQ and nothing else" add chain=forward action=drop in-interface=v10-cde log=yes log-prefix=CDE-OUT add chain=forward action=drop out-interface=v10-cde log=yes log-prefix=CDE-IN comment="nothing in the store reaches a till" add chain=forward action=accept in-interface=v20-office out-interface-list=HQ add chain=forward action=accept in-interface=v20-office out-interface=v40-iot protocol=tcp dst-port=443 add chain=forward action=accept in-interface=v20-office dst-address=10.50.60.10 protocol=tcp dst-port=443 add chain=forward action=accept in-interface=v30-handheld dst-address=172.16.30.15 protocol=tcp dst-port=443 add chain=forward action=accept in-interface=v40-iot dst-address=172.16.40.0/24 add chain=forward action=accept in-interface=v45-refrig src-address=10.50.45.10 dst-address=172.16.45.20 protocol=tcp dst-port=443 add chain=forward action=drop log=yes log-prefix=FWD-DROP
In V20-IN, line 20 (deny to the CDE) sits above the HQ permit and the internet permit, even though the later private-address denies would also catch it. That's deliberate: an auditor reads the ACL top-down, and "the office can never reach the CDE" should be visible as an explicit, logged line, not something they have to infer from the order of later rules. Every non-CDE ACL could start the same way; here the IoT, refrigeration and CCTV ACLs already can't reach 10.50.10.0/24 at all.
show access-lists V20-IN shows line 20 counting.11 · Step 7 of 12
R1 arrives on the inside first: a transit link to the core, the guest network terminated on its own subinterface, and a guest DHCP pool.
▲ Show step 7 in the interactive topology · see what this step adds, and click any device for its config
hostname R1-EDGE interface GigabitEthernet0/0/2 description CORE Gi1/0/1 (trunk: 50, 900) no ip address interface GigabitEthernet0/0/2.900 encapsulation dot1Q 900 ip address 10.50.255.1 255.255.255.248 interface GigabitEthernet0/0/2.50 encapsulation dot1Q 50 ip address 10.50.50.1 255.255.255.0 ! ip dhcp excluded-address 10.50.50.1 10.50.50.9 ip dhcp pool GUEST network 10.50.50.0 255.255.255.0 default-router 10.50.50.1 dns-server 9.9.9.9 149.112.112.112 lease 0 2 policy-map GUEST-LIMIT class class-default police cir 20000000 interface GigabitEthernet0/0/2.50 service-policy input GUEST-LIMIT service-policy output GUEST-LIMIT ! ip route 10.50.0.0 255.255.0.0 10.50.255.2
interface GigabitEthernet1/0/1 description R1-EDGE Gi0/0/2 switchport mode trunk switchport trunk native vlan 666 switchport trunk allowed vlan 50,900 switchport nonegotiate ip access-list extended V900-IN 10 deny ip 10.50.50.0 0.0.0.255 any log 20 permit ip any any interface Vlan900 ip address 10.50.255.2 255.255.255.248 ip access-group V900-IN in ip route 0.0.0.0 0.0.0.0 10.50.255.1
This is the same guest pattern as the law-firm build: the core never routes guest traffic, every guest packet goes through R1, and the core's transit ACL drops anything sourced from the guest subnet as a second, independent control.
ping 10.50.10.11 fails, and show access-lists V900-IN counts the attempt.ping 10.50.255.1; from R1, ping 10.50.20.1.12 · Step 8 of 12
The fibre goes in. Only the office, the store IoT's HTTPS and the guests may use it directly, and the CDE is not on that list in any form.
▲ Show step 8 in the interactive topology · see what this step adds, and click any device for its config
interface GigabitEthernet0/0/0 description FIBRE (static 203.0.113.42/29) ip address 203.0.113.42 255.255.255.248 ip nat outside no cdp enable ip route 0.0.0.0 0.0.0.0 203.0.113.41 ! ip access-list standard NAT-SRC permit 10.50.20.0 0.0.0.255 permit 10.50.40.0 0.0.0.255 permit 10.50.50.0 0.0.0.255 ip nat inside source list NAT-SRC interface GigabitEthernet0/0/0 overload interface GigabitEthernet0/0/2.900 ip nat inside interface GigabitEthernet0/0/2.50 ip nat inside ! zone security INSIDE zone security GUEST zone security OUTSIDE zone security HQ ip access-list extended INSIDE-TO-INET remark Office and store-IoT HTTPS only. The CDE, handhelds, refrigeration and CCTV are absent on purpose. permit ip 10.50.20.0 0.0.0.255 any permit tcp 10.50.40.0 0.0.0.255 any eq 443 class-map type inspect match-all CM-INET match access-group name INSIDE-TO-INET class-map type inspect match-any CM-ANY match protocol tcp match protocol udp match protocol icmp policy-map type inspect PM-IN-OUT class type inspect CM-INET inspect class class-default drop log policy-map type inspect PM-GST-OUT class type inspect CM-ANY inspect class class-default drop zone-pair security ZP-IN-OUT source INSIDE destination OUTSIDE service-policy type inspect PM-IN-OUT zone-pair security ZP-GST-OUT source GUEST destination OUTSIDE service-policy type inspect PM-GST-OUT interface GigabitEthernet0/0/2.900 zone-member security INSIDE interface GigabitEthernet0/0/2.50 zone-member security GUEST interface GigabitEthernet0/0/0 zone-member security OUTSIDE
The CDE is kept off the internet three times over: the core's V10-IN only permits HQ addresses, the NAT list doesn't include 10.50.10.0/24, and the zone firewall's INSIDE→OUTSIDE class doesn't match it. Each of those alone would be enough. Together they mean a single mistake never creates an internet path for a till.
show policy-map type inspect zone-pair ZP-IN-OUT sessions lists only office and IoT sources.13 · Step 9 of 12
One IKEv2 tunnel interface, a route to 172.16.0.0/16 through it, and a zone that says what HQ may reach in the store.
▲ Show step 9 in the interactive topology · see what this step adds, and click any device for its config
crypto ikev2 proposal P-HQ
encryption aes-gcm-256
prf sha384
group 19
crypto ikev2 policy POL-HQ
proposal P-HQ
crypto ikev2 profile PR-HQ
match identity remote address 198.51.100.20 255.255.255.255
identity local fqdn store-142.market.example
authentication local rsa-sig
authentication remote rsa-sig
pki trustpoint CHAIN-CA
dpd 10 3 periodic
crypto ipsec transform-set TS-GCM esp-gcm 256
mode tunnel
crypto ipsec profile IP-HQ
set transform-set TS-GCM
set ikev2-profile PR-HQ
!
interface Tunnel0
description HQ primary (over fibre)
ip address 10.255.142.2 255.255.255.252
ip mtu 1400
ip tcp adjust-mss 1360
tunnel source GigabitEthernet0/0/0
tunnel mode ipsec ipv4
tunnel destination 198.51.100.20
tunnel protection ipsec profile IP-HQ
zone-member security HQ
ip route 172.16.0.0 255.255.0.0 Tunnel0
ip route 198.51.100.20 255.255.255.255 203.0.113.41 ! HQ head-end 1 only via fibre
ip route 198.51.100.20 255.255.255.255 Null0 250# R1 — RouterOS has no static VTI: chains running MikroTik usually use WireGuard to HQ
/interface wireguard add name=wg-hq1 listen-port=13231
/interface wireguard peers add interface=wg-hq1 comment="HQ head-end 1" public-key="<head-end 1 key>" \
endpoint-address=198.51.100.20 endpoint-port=51820 allowed-address=172.16.0.0/16,10.255.142.0/30 \
persistent-keepalive=25s
/ip address add address=10.255.142.2/30 interface=wg-hq1
/interface list member add list=HQ interface=wg-hq1
/ip route add dst-address=172.16.0.0/16 gateway=10.255.142.1 check-gateway=ping distance=1 comment="HQ via fibre tunnel"
# IKEv2 + GRE is the alternative if HQ's head-ends must stay IPsecip access-list extended STORE-TO-HQ permit ip 10.50.10.0 0.0.0.255 172.16.0.0 0.0.255.255 permit ip 10.50.20.0 0.0.0.255 172.16.0.0 0.0.255.255 permit ip 10.50.30.0 0.0.0.255 172.16.0.0 0.0.255.255 permit ip 10.50.40.0 0.0.0.255 172.16.40.0 0.0.0.255 permit tcp host 10.50.45.10 host 172.16.45.20 eq 443 ip access-list extended HQ-TO-STORE remark HQ is not trusted blindly permit tcp 172.16.10.0 0.0.0.255 10.50.10.0 0.0.0.255 eq 443 ! POS management permit tcp 172.16.10.0 0.0.0.255 10.50.10.0 0.0.0.255 eq 22 permit tcp 172.16.40.0 0.0.0.255 10.50.40.0 0.0.0.255 ! price push to scales/ESL permit tcp 172.16.20.0 0.0.0.255 10.50.20.0 0.0.0.255 eq 3389 ! IT support permit tcp 172.16.60.0 0.0.0.255 host 10.50.60.10 eq 443 ! security viewing class-map type inspect match-all CM-TO-HQ match access-group name STORE-TO-HQ class-map type inspect match-all CM-FROM-HQ match access-group name HQ-TO-STORE policy-map type inspect PM-IN-HQ class type inspect CM-TO-HQ inspect class class-default drop log policy-map type inspect PM-HQ-IN class type inspect CM-FROM-HQ inspect class class-default drop log zone-pair security ZP-IN-HQ source INSIDE destination HQ service-policy type inspect PM-IN-HQ zone-pair security ZP-HQ-IN source HQ destination INSIDE service-policy type inspect PM-HQ-IN ! ! the router itself: IKE + ESP in, and replies to its own probes (step 10) ip access-list extended TO-SELF permit udp any any eq isakmp permit udp any any eq non500-isakmp permit esp any any permit icmp any any echo-reply class-map type inspect match-any CM-SELF match access-group name TO-SELF policy-map type inspect PM-OUT-SELF class type inspect CM-SELF pass class class-default drop zone-pair security ZP-OUT-SELF source OUTSIDE destination self service-policy type inspect PM-OUT-SELF
The store side above is a template where only store-142, the tunnel /30 and the WAN address change, which is what R8 asks for. Certificates from the chain's own CA (CHAIN-CA) beat pre-shared keys at 60 stores: revoking one store's certificate doesn't touch the other 59. At HQ, a single dynamic VTI (a virtual template matched by the stores' FQDN identities) serves every store. And the ip mtu 1400 / adjust-mss 1360 pair isn't optional: card-terminal and POS traffic that hits a silent MTU black hole inside the tunnel fails in ways that look like application bugs. The echo-reply line in TO-SELF prepares for step 10's IP SLA probe (the self-zone trap from the law firm).
show crypto ikev2 sa: READY; show crypto ipsec sa | include pkts: counters rising in both directions.ZP-HQ-IN.14 · Step 10 of 12
A second tunnel to a second HQ head-end, permanently up over LTE, with a floating route. The LTE line carries nothing else.
▲ Show step 10 in the interactive topology · see what this step adds, and click any device for its config
ip sla 1
icmp-echo 1.1.1.1 source-interface GigabitEthernet0/0/0
frequency 5
ip sla schedule 1 life forever start-time now
track 1 ip sla 1 reachability
delay down 10 up 60
ip route 1.1.1.1 255.255.255.255 203.0.113.41
ip route 1.1.1.1 255.255.255.255 Null0 250
no ip route 0.0.0.0 0.0.0.0 203.0.113.41
ip route 0.0.0.0 0.0.0.0 203.0.113.41 track 1
!
interface Cellular0/2/0
description LTE backup (carrier profile configured on the module)
ip address negotiated
zone-member security LTE
zone security LTE
zone-pair security ZP-LTE-SELF source LTE destination self
service-policy type inspect PM-OUT-SELF
ip route 198.51.100.21 255.255.255.255 Cellular0/2/0 ! HQ head-end 2 only via LTE
!
interface Tunnel1
description HQ backup (over LTE)
ip address 10.255.142.6 255.255.255.252
ip mtu 1400
ip tcp adjust-mss 1360
tunnel source Cellular0/2/0
tunnel mode ipsec ipv4
tunnel destination 198.51.100.21
tunnel protection ipsec profile IP-HQ-LTE
zone-member security HQ
ip route 172.16.0.0 255.255.0.0 Tunnel1 250# R1 — second tunnel over LTE, pinned to its own head-end, standby by distance
/ip dhcp-client add interface=ether5 add-default-route=no use-peer-dns=no comment="LTE passthrough"
/ip route add dst-address=198.51.100.21/32 gateway=ether5 comment="head-end 2 only via LTE"
/interface wireguard add name=wg-hq2 listen-port=13232
/interface wireguard peers add interface=wg-hq2 comment="HQ head-end 2" public-key="<head-end 2 key>" \
endpoint-address=198.51.100.21 endpoint-port=51820 allowed-address=172.16.0.0/16,10.255.142.4/30 \
persistent-keepalive=25s
/ip address add address=10.255.142.6/30 interface=wg-hq2
/interface list member add list=HQ interface=wg-hq2
/ip route add dst-address=172.16.0.0/16 gateway=10.255.142.5 check-gateway=ping distance=2 comment="HQ via LTE tunnel"
# no default route via LTE at all: office and guests simply have no path to itIP-HQ-LTE is the same IPsec profile with an IKEv2 profile matching head-end 2. Both tunnels are up all the time, because each head-end address is pinned to one physical path. When the fibre fails, DPD takes Tunnel0 down within ~30 s, its route to 172.16.0.0/16 disappears, and the floating route via Tunnel1 is already there: no IKE negotiation has to happen during the outage. There's no default route via LTE at all, and no zone pair from INSIDE or GUEST to LTE, so the office and guests get nothing during an outage, by design.
show crypto ikev2 sa: two SAs, to .20 (fibre) and .21 (LTE).show ip route 172.16.0.0 now points at Tunnel1.15 · Step 11 of 12
One source, one destination, one port, Tuesday mornings only, every session logged.
time-range VENDOR-REFRIG periodic Tuesday 9:00 to 12:00 ip access-list extended HQ-VENDOR permit tcp host 172.16.5.10 host 10.50.45.10 eq 443 time-range VENDOR-REFRIG parameter-map type inspect PMAP-AUDIT audit-trail on class-map type inspect match-all CM-VENDOR match access-group name HQ-VENDOR policy-map type inspect PM-HQ-IN class type inspect CM-VENDOR inspect PMAP-AUDIT class type inspect CM-FROM-HQ inspect class class-default drop log
# R1 — the firewall's time matcher does the window
/ip firewall filter add chain=forward action=accept src-address=172.16.5.10 dst-address=10.50.45.10 \
protocol=tcp dst-port=443 time=9h-12h,tue log=yes log-prefix=VENDOR \
place-before=[find log-prefix=FWD-DROP] comment="refrigeration vendor window"
/system logging action add name=hq target=remote remote=172.16.50.5
/system logging add topics=firewall action=hqThe contractor never connects to the store directly. They log into HQ's jump host (with their own MFA account, recorded by HQ), and only that host's address is allowed through, only to the controller's HTTPS port, only during the window. For an unplanned call-out, HQ's on-call engineer widens the time range for that day and puts it back afterwards; the change itself shows up in the config archive (step 12). Outside the window, the alarms still flow from the controller to HQ's monitoring system, because that path doesn't depend on the vendor rule.
16 · Step 12 of 12
Card payments and scanners first on the WAN, the same clock everywhere, and every log line at head office.
interface Tunnel0 qos pre-classify interface Tunnel1 qos pre-classify ip access-list extended CRITICAL permit ip 10.50.10.0 0.0.0.255 172.16.0.0 0.0.255.255 permit ip 10.50.30.0 0.0.0.255 172.16.0.0 0.0.255.255 class-map match-any CRIT match access-group name CRITICAL policy-map WAN-CHILD class CRIT bandwidth percent 30 class class-default fair-queue policy-map WAN-OUT class class-default shape average 95000000 service-policy WAN-CHILD interface GigabitEthernet0/0/0 service-policy output WAN-OUT
# R1 — WireGuard re-encapsulates, so queue the tunnel interface itself
/ip firewall mangle add chain=forward action=mark-packet new-packet-mark=crit out-interface-list=HQ \
src-address-list=CRITICAL passthrough=no
/ip firewall address-list
add list=CRITICAL address=10.50.10.0/24
add list=CRITICAL address=10.50.30.0/24
/queue tree
add name=hq parent=wg-hq1 max-limit=60M
add name=hq-crit parent=hq packet-mark=crit priority=1 limit-at=20M max-limit=60M
add name=hq-rest parent=hq packet-mark=no-mark priority=8 max-limit=60Mqos pre-classify matters here: after encryption, every packet leaving Gi0/0/0 to HQ is ESP between two public addresses, and the ACL above would never match. With pre-classify, the egress policy classifies on the original inner headers.
service timestamps log datetime msec localtime show-timezone ntp server 172.16.0.123 logging host 172.16.50.5 logging trap informational login on-failure log login on-success log archive log config logging enable notify syslog contenttype plaintext hidekeys
Every device logs to HQ's collector through the tunnel, timestamps match because they share HQ's NTP source, and every configuration change is logged with the user who made it. Administrative logins use HQ's TACACS+ servers with a local fallback account (see AAA with TACACS+ and hardening).
show policy-map interface Gi0/0/0: CRIT matches lane and scanner traffic while a large office upload runs.show ntp associations: synchronised on every device.17
These drills double as the evidence for the store's PCI segmentation test. Record each result with date and time.
| Drill (requirement) | What must happen |
|---|---|
| CDE seal (R1) | From every non-CDE VLAN, including guest Wi-Fi and a laptop on a scale port: a full scan of 10.50.10.0/24 finds nothing. From a laptop on a lane port (with that port's sticky MAC cleared for the test): only 172.16.0.0/16 answers. |
| Device swap (R1) | Swap a PIN pad: the port err-disables and stays down; the event is at HQ's log collector. |
| Fibre cut (R2) | Payments resume over LTE within ~40 s; office and guests are offline; LTE carries tunnel traffic only. |
| CDE egress (R3) | From a lane POS, any internet address is unreachable on fibre and on LTE. |
| Overnight prices (R4) | HQ's 02:00 push reaches scales and labels; a scale can't open a connection to HQ's POS servers. |
| Vendor window (R5) | Access works only on Tuesday 09:00–12:00 and only from the jump host; alarms reach HQ at all times. |
| Warehouse walk (R6) | A scanner app session survives a walk across all four warehouse APs. |
| CCTV (R7) | The cameras' recording traffic never appears on Po3 beyond viewing streams; HQ security can view; nothing else can. |
18
Where the residual risk sits once the segmentation is in place, and what covers it.
19
The store's inside runs well in Packet Tracer; the edge needs CML or EVE-NG for the full picture.
| This post | In Packet Tracer |
|---|---|
| Access + CCTV switches | 2960-24TT / 2960 Plus for PoE. VLANs, port-security with sticky MACs, port-channels: all work. |
| CORE | 3650-24PS with ip routing; SVIs, DHCP pools and every ACL in step 6 work. |
| R1-EDGE | ISR4331: subinterfaces, guest DHCP, NAT overload and static routes work. A second ISR4331 with a server behind it can stand in for HQ. |
| Partial / varies | ZBF, IKEv2 VTI with certificates, IP SLA, LTE, time-ranges in ZBF classes, QoS pre-classify. Build these on CML/EVE-NG with Cat8000v routers for R1 and the HQ head-ends. |
20
Indicative EU street prices, late 2026, excluding VAT. Chains buy in bulk and usually do better.
| Item | Indicative (EUR, ex VAT) |
|---|---|
| R1-EDGE · C8200L-1N-4T + LTE pluggable | 2,200 – 3,200 |
| CORE · C9200-24T-4G | 1,800 – 2,500 incl. DNA term |
| ACC-FRONT, ACC-BACK · 2× C9200L-24P-4G | 3,200 – 4,400 incl. DNA |
| SW-CCTV · C9200L-48P-4G | 2,600 – 3,400 incl. DNA |
| 6× C9115AXI (one runs EWC) | 3,600 – 4,800 |
| UPS for the comms room (core, R1, CCTV switch) | 900 – 1,400 |
| Network total | ≈ 14,300 – 19,700, plus structured cabling (~90 runs), the LTE plan, and the POS/ESL/CCTV systems themselves |
Appendix
Same store, same VLANs, same matrix, at roughly a quarter of the hardware cost. The MikroTik tabs on the config blocks above show the key steps side by side; this appendix covers what changes underneath.
| Role | This post → MikroTik |
|---|---|
| ACC-FRONT, ACC-BACK | 2× C9200L-24P-4G → 2× CRS328-24P-4S+ |
| SW-CCTV | C9200L-48P-4G → CRS354-48P-4S+2Q+ |
| CORE | C9200-24T (L3) → CRS326-24S+2Q+ (Layer 2 only) |
| R1 + LTE | C8200L-1N-4T + LTE module → CCR2004-16G-2S+ (all routing) + LtAP LTE in passthrough |
| Wi-Fi | 6× C9115AXI with EWC → 6× cAP ax with CAPsMAN |
| Indicative total | ≈ 14,300 – 19,700 → ≈ 3,500 – 4,500 EUR ex VAT |
| Feature | This post → MikroTik |
|---|---|
| Lane port lock | sticky MAC + err-disable → learn=no + static bridge hosts (silent drop) |
| Inter-VLAN policy | stateless SVI ACLs on the core → stateful forward chain on R1 |
| Tunnel to HQ | IKEv2 static VTI → WireGuard (or IKEv2 + GRE) |
| Tunnel failover | IP SLA + floating route → check-gateway on the tunnel peer + distance |
| Vendor window | time-range ACL in a ZBF class → firewall time= matcher |
| QoS for HQ traffic | qos pre-classify → queue tree on the tunnel interface |
| Logging | logging host + config archive → remote log action + nightly /export |
The tunnel technology changes, and with sixty stores that's a head-office decision, not a store one: HQ's head-ends must speak WireGuard (or IPsec with GRE). A swapped PIN pad is silent on MikroTik: the port just stops forwarding, with no err-disable state and no log line. For PCI evidence, add a monitoring check on the bridge host table or DHCP leases that alerts on a new MAC in VLAN 10. Routing moves to R1 and the firewall becomes stateful, as in the other MikroTik builds.
Fleet management is the other real difference: at sixty stores, Cisco shops use central tooling; MikroTik shops template RouterOS configs and push them with the API or Ansible.
Takeaways
qos pre-classify is what lets the WAN policy see a card payment inside the tunnel.This is part 4 of the Build series. Earlier: the law firm, the gaming center, the coffee shop. Next: the medical clinic.
I design store templates like this one and test the segmentation the way an assessor will, so the PCI evidence exists before anyone asks for it.
Book a Discovery Call →