Forty seats, a patio, two tablets running the till, two card terminals and a queue out of the door at 08:30. The network has to stay out of the way. We build it on a single MikroTik router plus one PoE switch in 11 tested steps: card terminals walled off to shrink PCI scope, a click-through guest portal with per-device limits, a 4G backup that only the tills may use, mDNS so the staff tablet finds the music system, and remote management that dials out so it works even behind 4G CGNAT.
Full network · all steps built
highlighted = lines added in the selected step · earlier steps shown plain · later steps hidden
This is part 3 of the Build series, and the smallest network in it. That makes it the most common one: almost every café, bakery and small restaurant has these same devices on one flat network, usually the ISP's router with the guest Wi-Fi password on the counter and the card terminal plugged in next to the music box.
The design challenge is proportion. The business can't justify enterprise gear or an IT person, but it handles card payments, hosts strangers on its Wi-Fi and loses money every minute the till is offline. One router and one switch, configured carefully, cover all of it.
01
A fictional but typical specialty coffee shop: busy mornings, laptop workers all afternoon, an owner who's never on site at closing.
The café seats 40 inside and 16 on the patio. Orders go through two tablets running a cloud POS, a kitchen display tablet at the espresso bar, and a networked receipt printer. Payments go through two standalone card terminals, paired with the acquirer over the internet. There's a music streamer controlled from the tablets, a menu screen, an espresso machine that reports telemetry to its maker, three cameras recording to a cloud NVR, and an office PC for the owner's accounts. Guests want Wi-Fi, and the laptop crowd wants it all afternoon.
| Requirement | Where it comes from, and what it forces |
|---|---|
| R1 Payments | Card terminals handle cardholder data. Isolating them so nothing else can reach them, and they reach only their acquirer, keeps the rest of the network out of PCI DSS scope (subject to the segmentation being tested). |
| R2 Guest Wi-Fi | Guests accept terms of use before going online, and sessions expire. One guest can't use more than their share. |
| R3 Tills first | A patio full of video calls must never slow down an order or a payment. Guests get at most 60% of the line. |
| R4 Outages | The fibre goes down a few times a year. Tills and card terminals continue on 4G; guests, camera uploads and IoT don't, because they would eat the data plan in an hour. |
| R5 Music & menu | Staff control the music and the menu screen from the POS tablets, even though those devices are on different VLANs. |
| R6 Staff turnover | Baristas change every season. The POS Wi-Fi password never goes on a personal phone, and the guest network can't reach anything that matters anyway. |
| R7 Remote care | Managed remotely by an IT contractor, including during a 4G outage behind carrier NAT. No inbound ports open on the router. |
| R8 Budget | Network hardware under €1,000. Cabling is quoted separately. |
02
Small doesn't mean simple. Each of these takes something away to make the result easier to run.
A hAP ax³ routes, firewalls, runs the hotspot and CAPsMAN, and its own Wi-Fi 6 radio covers the inside. A single outdoor wAP ax covers the patio. There's no controller box and no second indoor AP, so the whole network is two configs plus a switch. The trade-off is that the router sits in the back office where the radio isn't ideal; a 40-seat room is small enough that this is fine. A bigger venue would move the radio out to ceiling APs.
Card terminals that integrate with the till over the LAN (the "ECR" protocol) need a rule from the POS tablets into the payment network. That rule pulls the tablets into PCI scope. Terminals paired with the acquirer through the cloud need nothing from the LAN, so their VLAN can be completely sealed: out to the acquirer, nothing in. The cashier types the amount twice (or the POS pushes it via the cloud), and the network stays simple.
The usual dual-WAN design throttles everything on the backup. This one refuses whole zones on it: guests, cameras and IoT are rejected on the 4G interface, so the tills keep the full 4G bandwidth and a 20 GB plan lasts days, not hours. Guests see "no internet" during an outage. That's honest, and it keeps the business running.
A remote-management VPN that listens on the router fails exactly when it's needed: on 4G, the router sits behind carrier-grade NAT and can't receive connections. So R1 is a WireGuard client of the contractor's hub, with a keepalive. It works on fibre, on 4G and behind any NAT, and there's no open port on the router's WAN.
03
Seven small VLANs on one router. Each exists because a different set of rules applies to it.
| VLAN · subnet | Who lives here · notes |
|---|---|
| 10 OFFICE · 10.40.10.0/24 | Owner's PC .10 (wired), owner's laptop on CAFE-Staff. |
| 20 POS · 10.40.20.0/24 | POS tablets .21–.22, kitchen display .23, receipt printer .30. Hidden SSID CAFE-POS. |
| 25 PAYMENT · 10.40.25.0/24 | Card terminals .11–.12. Wired only. Out to the acquirer, nothing in. |
| 30 IOT · 10.40.30.0/24 | Music streamer .20, menu screen .21, espresso machine .22. |
| 40 CCTV · 10.40.40.0/24 | Three cameras .21–.23, uploading to a cloud NVR. |
| 50 GUEST · 10.40.50.0/24 | Hotspot. Open SSID CAFE-Guest, portal with terms, 2-hour sessions. |
| 99 MGMT · 10.40.99.0/24 | R1 .1, switch .11, patio wAP .21. Plus WireGuard 10.250.0.14 towards the IT hub. |
| WAN · fibre + 4G | ether1: fibre ONT (PPPoE, as most Greek FTTH lines are). ether5: 4G in passthrough mode (DHCP, carrier NAT). |
04
Rows start, columns receive. Default deny. In a network this small every cell is one or two firewall lines.
Notice the Payment row and column: the card terminals reach exactly one destination and nothing reaches them. That empty column is the PCI argument. The "no 4G" cells are new compared with the other Build posts: they don't stop a zone from using the internet, only from using the expensive backup line.
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 Payments | step 2 · step 4 | static-only DHCP on V25; ACQUIRER host-name list; V25 out-only and in-drop rules | "Payment seal" drill, section 16 |
| R2 Guest Wi-Fi | step 3 · step 6 | open SSID with client isolation; hotspot trial login, 2 h sessions | "Guest portal" drill |
| R3 Tills first | step 7 | 5 Mb/s per device from the hotspot; 180/30 total cap in a queue tree | "Busy patio" drill |
| R4 Outages | step 8 | recursive failover to 4G; NO4G list rejected on ether5 | "Fibre cut" drill |
| R5 Music & menu | step 9 | mDNS repeat v20↔v30; speaker callback port only | "Music" drill |
| R6 Staff turnover | step 3 | WPA3-only hidden CAFE-POS, key set by the manager | "Ex-employee" drill |
| R7 Remote care | step 10 | WireGuard dial-out with keepalive; no WAN ports open | "Remote care" drill |
| R8 Budget | section 19 | hAP ax³ + CRS112 + wAP ax + LtAP | Bill of materials total |
The build
Counter devices first, internet last. Each step ends with a checkpoint.
Eleven steps: the counter switch, the router, Wi-Fi, payment isolation, the rest of the firewall, the guest portal, guest limits, internet with 4G backup, mDNS, remote management and hardening. Use Safe Mode (Ctrl+X) for every bridge change on a remote device.
05 · Step 1 of 11
Everything with a cable plugs into one 8-port PoE switch under the counter. Each port goes straight into its VLAN.
▲ Show step 1 in the interactive topology · see what this step adds, and click any device for its config
/system identity set name=SW-COUNTER
/interface bridge add name=bridge vlan-filtering=no
/interface bridge port
add bridge=bridge interface=sfp1 frame-types=admit-only-vlan-tagged comment="R1 via S-RJ01 copper module"
add bridge=bridge interface=ether1 pvid=25 comment="card terminal 1"
add bridge=bridge interface=ether2 pvid=25 comment="card terminal 2"
add bridge=bridge interface=ether3 pvid=20 comment="receipt printer"
add bridge=bridge interface=ether4 pvid=30 comment="music streamer"
add bridge=bridge interface=ether5 pvid=30 comment="menu screen"
add bridge=bridge interface=ether6 pvid=40 comment="camera 1 (PoE)"
add bridge=bridge interface=ether7 pvid=40 comment="camera 2 (PoE)"
add bridge=bridge interface=ether8 pvid=40 comment="camera 3 (PoE)"
/interface bridge vlan
add bridge=bridge vlan-ids=20,25,30,40 tagged=sfp1
add bridge=bridge vlan-ids=99 tagged=bridge,sfp1
/interface vlan add name=v99-mgmt interface=bridge vlan-id=99
/ip address add address=10.40.99.11/24 interface=v99-mgmt
/ip route add gateway=10.40.99.1
/interface ethernet poe set ether1,ether2,ether3,ether4,ether5 poe-out=off # only the cameras take power
/interface ethernet disable sfp2,sfp3,sfp4
/interface bridge set bridge vlan-filtering=yesThe eight copper ports are all in use, so the uplink to the router uses an SFP port with a 1G copper module (S-RJ01). PoE output is switched off on every port that doesn't power a camera. Passive PoE into a card terminal's Ethernet port is a classic way to kill one.
/interface bridge vlan print: 25 on ether1–2, 20 on ether3, 30 on ether4–5, 40 on ether6–8, all tagged on sfp1./interface ethernet poe print shows power only on ether6–8.06 · Step 2 of 11
The hAP ax³ becomes the gateway for seven small networks. No internet yet.
▲ Show step 2 in the interactive topology · see what this step adds, and click any device for its config
/system identity set name=R1 /interface bridge add name=bridge vlan-filtering=no /interface bridge port add bridge=bridge interface=ether2 frame-types=admit-only-vlan-tagged comment="SW-COUNTER trunk" add bridge=bridge interface=ether3 pvid=99 comment="patio wAP trunk (mgmt untagged)" add bridge=bridge interface=ether4 pvid=10 comment="office PC" /interface bridge vlan add bridge=bridge vlan-ids=10 tagged=bridge,ether3 add bridge=bridge vlan-ids=20 tagged=bridge,ether2,ether3 add bridge=bridge vlan-ids=25,30,40 tagged=bridge,ether2 add bridge=bridge vlan-ids=50 tagged=bridge,ether3 add bridge=bridge vlan-ids=99 tagged=bridge,ether2 /interface vlan add name=v10-office interface=bridge vlan-id=10 add name=v20-pos interface=bridge vlan-id=20 add name=v25-pay interface=bridge vlan-id=25 add name=v30-iot interface=bridge vlan-id=30 add name=v40-cctv interface=bridge vlan-id=40 add name=v50-guest interface=bridge vlan-id=50 add name=v99-mgmt interface=bridge vlan-id=99 /ip address add address=10.40.10.1/24 interface=v10-office add address=10.40.20.1/24 interface=v20-pos add address=10.40.25.1/24 interface=v25-pay add address=10.40.30.1/24 interface=v30-iot add address=10.40.40.1/24 interface=v40-cctv add address=10.40.50.1/24 interface=v50-guest add address=10.40.99.1/24 interface=v99-mgmt
/ip pool add name=p-pos ranges=10.40.20.50-10.40.20.99 add name=p-guest ranges=10.40.50.20-10.40.50.250 # … p-office, p-iot, p-cctv the same way /ip dhcp-server add name=d-pos interface=v20-pos address-pool=p-pos lease-time=1d add name=d-pay interface=v25-pay address-pool=static-only lease-time=1d # reservations only add name=d-guest interface=v50-guest address-pool=p-guest lease-time=30m /ip dhcp-server network add address=10.40.20.0/24 gateway=10.40.20.1 dns-server=10.40.20.1 add address=10.40.25.0/24 gateway=10.40.25.1 dns-server=10.40.25.1 add address=10.40.50.0/24 gateway=10.40.50.1 dns-server=10.40.50.1 /ip dhcp-server lease add server=d-pay mac-address=00:0B:4F:00:00:11 address=10.40.25.11 comment="card terminal 1" add server=d-pay mac-address=00:0B:4F:00:00:12 address=10.40.25.12 comment="card terminal 2" /ip dns set allow-remote-requests=yes servers=9.9.9.9,149.112.112.112 /interface bridge set bridge vlan-filtering=yes
The payment VLAN has no pool at all (static-only): only the two known terminals get an address, so an unknown device on a payment port gets nothing. The guest lease is 30 minutes: phones come and go all day, and a long lease would exhaust the pool by lunchtime. Every device that the firewall treats individually (card terminals, music, menu screen, printer) gets a reservation, so its address never changes under a rule.
ping 10.40.99.11 reaches the switch.07 · Step 3 of 11
Three SSIDs on two radios. One is open for guests, one is hidden for the tills, one is for the owner.
▲ Show step 3 in the interactive topology · see what this step adds, and click any device for its config
/interface wifi security add name=sec-pos authentication-types=wpa3-psk passphrase="********" add name=sec-staff authentication-types=wpa2-psk,wpa3-psk passphrase="********" /interface wifi datapath add name=dp-guest bridge=bridge vlan-id=50 client-isolation=yes add name=dp-pos bridge=bridge vlan-id=20 add name=dp-staff bridge=bridge vlan-id=10 /interface wifi configuration add name=cfg-guest ssid=CAFE-Guest datapath=dp-guest country=Greece add name=cfg-pos ssid=CAFE-POS security=sec-pos datapath=dp-pos country=Greece hide-ssid=yes add name=cfg-staff ssid=CAFE-Staff security=sec-staff datapath=dp-staff country=Greece # the router's own radios: guest on the master, POS and staff as virtual APs /interface wifi set [find default-name=wifi1] configuration=cfg-guest disabled=no /interface wifi add name=wifi1-pos master-interface=wifi1 configuration=cfg-pos disabled=no /interface wifi add name=wifi1-staff master-interface=wifi1 configuration=cfg-staff disabled=no # … the same three on wifi2 (2.4 GHz) # the patio wAP is provisioned over its untagged management VLAN /interface wifi capsman set enabled=yes interfaces=v99-mgmt /interface wifi provisioning add action=create-dynamic-enabled \ master-configuration=cfg-guest slave-configurations=cfg-pos,cfg-staff
CAFE-POS uses WPA3 only: the iPads support it, and a staff member who learns the password can't easily join it from an old phone. Hiding the SSID isn't security; it only stops it from appearing in guests' lists. The real control is that the password is set on the tablets by the manager and never told to staff. Rotate it whenever someone with a manager role leaves. The guest SSID is open. The portal in step 6 adds terms of use, not encryption. Modern guest traffic is HTTPS anyway, and client isolation stops guests from reaching each other.
/interface wifi registration-table print: the POS tablets on wifi1-pos, a test phone on wifi1 (guest).08 · Step 4 of 11
The most important ten lines in the network: the terminals reach their acquirer, and nothing reaches them.
! R1 — C1121X: IOS ACLs can't match host names, so the acquirer's ! published address ranges go into an object-group object-group network ACQUIRER 198.51.100.0 255.255.255.0 ip access-list extended V25-IN permit udp 10.40.25.0 0.0.0.255 host 10.40.25.1 eq domain permit tcp 10.40.25.0 0.0.0.255 object-group ACQUIRER eq 443 deny ip any any log ip access-list extended V25-OUT permit tcp any 10.40.25.0 0.0.0.255 established deny ip any any log ! nothing starts a connection into payments interface Vlan25 ip access-group V25-IN in ip access-group V25-OUT out
/ip firewall address-list
add list=ACQUIRER address=pay.acquirer.example comment="from the acquirer's integration guide"
add list=ACQUIRER address=tms.acquirer.example comment="terminal management + updates"
/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=v25-pay dst-address-list=ACQUIRER protocol=tcp dst-port=443 \
comment="terminals -> acquirer only"
add chain=forward action=drop in-interface=v25-pay log=yes log-prefix=PAY-OUT comment="terminals -> anything else"
add chain=forward action=drop out-interface=v25-pay log=yes log-prefix=PAY-IN comment="nothing starts a connection into payments"RouterOS resolves a host name in an address list and keeps the dynamic IP entries up to date, re-resolving as the DNS TTL expires. That's exactly right for acquirers that publish host names rather than IP ranges. But it means the firewall depends on R1's own DNS: if a terminal works at opening and fails at noon, look at /ip firewall address-list print where list=ACQUIRER. A CDN-fronted acquirer may have rotated to an address R1 hasn't resolved yet. Ask the acquirer for their published IP ranges if they have them.
Segmentation can take systems out of PCI DSS scope, but only if it actually works, and that has to be tested (the drills in section 16 are a start, and the acquirer's questionnaire will ask). If your terminals integrate with the POS over the LAN, add exactly that one port from the tablets' reserved addresses and accept that the tablets are now in scope. None of this replaces the terminal vendor's own security; it limits what a compromised guest phone or espresso machine could ever reach.
ping 10.40.25.11 fails, and /log print where message~"PAY-IN" shows it.09 · Step 5 of 11
Protect the router, then the matrix, then a logged drop.
/interface list add name=WAN add name=LAN add name=MGMT /interface list member add list=MGMT interface=v99-mgmt add list=LAN interface=v10-office # … v20-pos, v25-pay, v30-iot, v40-cctv, v50-guest, v99-mgmt into LAN as well /ip firewall filter add chain=input action=accept connection-state=established,related,untracked add chain=input action=drop connection-state=invalid add chain=input action=accept protocol=icmp add chain=input action=accept in-interface-list=MGMT add chain=input action=accept in-interface-list=LAN protocol=udp dst-port=53,67 add chain=input action=accept in-interface-list=LAN protocol=tcp dst-port=53 add chain=input action=drop log=yes log-prefix=IN-DROP # forward, after the payment rules from step 4 add chain=forward action=accept in-interface=v20-pos out-interface-list=WAN add chain=forward action=accept in-interface=v10-office out-interface-list=WAN add chain=forward action=accept in-interface=v30-iot out-interface-list=WAN add chain=forward action=accept in-interface=v40-cctv out-interface-list=WAN add chain=forward action=accept in-interface=v50-guest out-interface-list=WAN add chain=forward action=accept in-interface=v10-office out-interface=v40-cctv protocol=tcp dst-port=443,554 \ comment="owner views cameras on site" add chain=forward action=accept in-interface-list=MGMT add chain=forward action=drop log=yes log-prefix=FWD-DROP
The WAN list stays empty until step 8, so nothing reaches the internet yet. There's deliberately no FastTrack rule: the hAP ax³ easily handles a 300 Mb/s line with queues, and FastTrack would bypass the guest limits in step 7.
10 · Step 6 of 11
Click to accept the terms, get two hours. No accounts, no passwords, no SMS.
! Embedded wireless controller (Catalyst 9800/EWC syntax): web consent instead of a router hotspot parameter-map type webauth CONSENT type consent wlan CAFE-Guest 3 CAFE-Guest no security wpa no security wpa wpa2 no security wpa akm dot1x security web-auth security web-auth parameter-map CONSENT no shutdown wireless profile policy GUEST vlan 50 session-timeout 7200 idle-timeout 900 no shutdown ! per-client 5 Mb/s: a QoS policy applied per client on the GUEST policy profile
/ip hotspot user profile
add name=guest rate-limit=5M/5M idle-timeout=15m shared-users=1
/ip hotspot profile
add name=hs-cafe hotspot-address=10.40.50.1 dns-name=wifi.cafe.local html-directory=hotspot-cafe \
login-by=trial trial-uptime-limit=2h trial-uptime-reset=1d trial-user-profile=guest
/ip hotspot add name=hs-guest interface=v50-guest address-pool=p-guest profile=hs-cafe disabled=no
/ip hotspot walled-garden add dst-host=menu.cafe.example comment="our own menu site works before login"hotspot-cafe/login.html is a copy of the default login page with the terms of use and a checkbox; its "Connect" button points at the trial-login link ($(link-login-only)?dst=$(link-orig-esc)&username=T-$(mac-esc)). The hotspot adds its own dynamic rules to the top of the filter and NAT tables (shown with a D flag). Leave them alone; they're what intercepts unauthenticated traffic. For more, see the hotspot post.
Phones use a random MAC address per network, which is stable for a given SSID. Trial limits still work per device, unless the guest taps "forget network", which gives them a new MAC and a fresh two hours. Accept that; it's a coffee shop, not a bank. And if a guest opens an HTTPS site before logging in, the browser shows a certificate warning, because the hotspot can't impersonate that site. The OS's own captive-portal check uses plain HTTP and opens the login page automatically, so in practice guests rarely see the warning.
/ip hotspot active print shows it with the guest profile; /queue simple print dynamic shows its 5M/5M queue.11 · Step 7 of 11
Each guest device gets 5 Mb/s from the hotspot. All guests together get at most 60% of the line. Nothing else is shaped at all.
/ip firewall mangle add chain=forward action=mark-packet in-interface=v50-guest new-packet-mark=guest-up passthrough=no add chain=forward action=mark-packet out-interface=v50-guest new-packet-mark=guest-down passthrough=no /queue tree add name=guest-down parent=global packet-mark=guest-down max-limit=180M queue=pcq-download-default add name=guest-up parent=global packet-mark=guest-up max-limit=30M queue=pcq-upload-default
Why a queue tree for the total and not one more simple queue? The hotspot creates a dynamic simple queue per device, and a packet only goes through the first simple queue that matches it. A "total" simple queue would either catch everything (bypassing the per-device limits) or nothing, depending on where it lands in the list. A queue tree is processed independently of simple queues, so each guest packet passes through both: its own 5 Mb/s queue and the shared 180/30 cap.
/queue tree print stats shows guest-down dropping.12 · Step 8 of 11
Fibre is primary and probed. The 4G line takes over automatically, but only for the tills, the terminals and the office.
▲ Show step 8 in the interactive topology · see what this step adds, and click any device for its config
! R1 — PPPoE dialer, built-in LTE, IP SLA instead of recursive routes interface GigabitEthernet0/0/0 pppoe-client dial-pool-number 1 interface Dialer1 ip address negotiated encapsulation ppp dialer pool 1 ppp chap hostname cafe@isp ppp chap password 0 ******** ip mtu 1492 ip tcp adjust-mss 1452 ip nat outside ip sla 1 icmp-echo 1.1.1.1 source-interface Dialer1 frequency 5 ip sla schedule 1 life forever start-time now track 1 ip sla 1 reachability ip route 1.1.1.1 255.255.255.255 Dialer1 ip route 0.0.0.0 0.0.0.0 Dialer1 track 1 ip route 0.0.0.0 0.0.0.0 Cellular0/1/0 250
/interface pppoe-client add name=pppoe-fibre interface=ether1 user=cafe@isp password=******** \
add-default-route=no use-peer-dns=no disabled=no
/ip dhcp-client add interface=ether5 default-route-distance=2 use-peer-dns=no comment="4G (LtAP passthrough)"
/interface list member
add list=WAN interface=pppoe-fibre
add list=WAN interface=ether5
/ip route
add dst-address=1.1.1.1/32 gateway=pppoe-fibre scope=10 comment="probe via fibre"
add dst-address=0.0.0.0/0 gateway=1.1.1.1 target-scope=11 check-gateway=ping distance=1 comment="main: fibre"
/ip firewall nat add chain=srcnat action=masquerade out-interface-list=WAN! R1 — the LTE interface gets its own zone; only the tills and payments get a pair to it zone security LTE interface Cellular0/1/0 zone-member security LTE zone-pair security ZP-POS-LTE source POS destination LTE service-policy type inspect PM-OUT zone-pair security ZP-PAY-LTE source PAY destination LTE service-policy type inspect PM-OUT zone-pair security ZP-OFFICE-LTE source OFFICE destination LTE service-policy type inspect PM-OUT ! no GUEST, IOT or CCTV → LTE pairs: those zones have no path to 4G at all
/interface list add name=NO4G
/interface list member
add list=NO4G interface=v30-iot
add list=NO4G interface=v40-cctv
add list=NO4G interface=v50-guest
/ip firewall filter add chain=forward action=reject reject-with=icmp-network-unreachable \
in-interface-list=NO4G out-interface=ether5 place-before=0 comment="guests, cameras, IoT never use 4G"The LtAP runs in passthrough mode: it hands its carrier address straight to R1 by DHCP, so R1 sees the 4G link as a plain Ethernet WAN with a DHCP default route at distance 2. The reject rule sits at the very top of the forward chain, above the established/related accept. That way even a connection that was established on fibre is cut the moment its packets start leaving via 4G, so a camera's long-running cloud upload can't keep going over 4G.
With drop, a guest's phone waits for timeouts and keeps retrying, and some apps retry very aggressively. With reject and "network unreachable", the phone learns immediately that there's no internet and shows it. Also note that 1.1.1.1 is now pinned to the fibre as the probe target, which is why R1's own DNS uses Quad9 (step 2) and not Cloudflare.
/ip firewall filter print stats).13 · Step 9 of 11
The music app finds speakers by multicast, and multicast doesn't cross a router. RouterOS can repeat it, and the firewall still decides who gets to connect.
! R1 — IOS-XE Service Discovery Gateway: learn the speaker on V30, announce it on V20 mdns-sd gateway interface Vlan30 mdns-sd gateway interface Vlan20 mdns-sd gateway ! filter by service type for your music system (service-list / service-policy); ! the syntax differs between releases, check the SDG guide for yours
/ip dns set mdns-repeat-ifaces=v20-pos,v30-iot,v10-office
/ip firewall address-list
add list=MUSIC address=10.40.30.20
add list=MENU address=10.40.30.21
/ip firewall filter
add chain=forward action=accept in-interface=v20-pos dst-address-list=MUSIC \
place-before=[find log-prefix=FWD-DROP] comment="tablets control the music"
add chain=forward action=accept in-interface=v10-office dst-address-list=MUSIC \
place-before=[find log-prefix=FWD-DROP] comment="owner's laptop controls the music"
add chain=forward action=accept in-interface=v20-pos dst-address-list=MENU protocol=tcp dst-port=443 \
place-before=[find log-prefix=FWD-DROP] comment="tablets update the menu screen"
add chain=forward action=accept src-address-list=MUSIC out-interface=v20-pos protocol=tcp dst-port=3400-3401 \
place-before=[find log-prefix=FWD-DROP] comment="speaker -> app events (vendor-specific)"Discovery is only half of it. Several music systems also open connections from the speaker back to the app to push "now playing" updates. Without that rule, the app finds the speaker and plays, but its controls freeze after a minute. Port 3400 is one vendor's choice. Check your system's documented ports and allow only those, only from the speaker's reserved address. Never allow the whole IoT VLAN into the POS VLAN.
14 · Step 10 of 11
R1 calls home. The IT contractor's hub never needs to reach the café; the café keeps the tunnel open from its side.
▲ Show step 10 in the interactive topology · see what this step adds, and click any device for its config
! R1 — FlexVPN client: the router dials out to the contractor's hub, NAT-T through any CGNAT crypto ikev2 profile TO-HUB match identity remote fqdn hub.example.net identity local fqdn cafe-r1.example.net authentication local rsa-sig authentication remote rsa-sig pki trustpoint IT-CA dpd 10 3 periodic crypto ipsec profile TO-HUB-IPSEC set ikev2-profile TO-HUB crypto ikev2 client flexvpn HUB peer 1 fqdn hub.example.net dynamic client connect Tunnel1 interface Tunnel1 ip address negotiated tunnel source Dialer1 tunnel destination dynamic tunnel protection ipsec profile TO-HUB-IPSEC
/interface wireguard add name=wg-it listen-port=13231
/interface wireguard peers add interface=wg-it comment="IT hub" public-key="<hub public key>" \
endpoint-address=hub.example.net endpoint-port=51820 allowed-address=10.250.0.0/24 persistent-keepalive=25s
/ip address add address=10.250.0.14/24 interface=wg-it
/interface list member add list=MGMT interface=wg-itThere's no input rule for UDP 13231: R1 starts the tunnel, so the hub's replies arrive as an established connection. The keepalive every 25 seconds holds the NAT mapping open, whether that NAT belongs to the fibre ISP's router or to the mobile carrier. Because wg-it is in the MGMT list, the contractor reaches the router, the switch and the patio wAP. The owner doesn't need a VPN at all: the cameras' cloud NVR app and the cloud POS dashboards already work from anywhere. For the hub side and key handling, see the WireGuard post.
/interface wireguard peers print: a recent "last handshake" on both fibre and (with the fibre unplugged) 4G.ssh netadmin@10.250.0.14 works on both.15 · Step 11 of 11
Management only from the MGMT list, no default accounts, and a config copy that lives somewhere else.
/ip service disable telnet,ftp,www,api,api-ssl
/ip service set ssh address=10.40.99.0/24,10.250.0.0/24
/ip service set winbox address=10.40.99.0/24,10.250.0.0/24
/tool mac-server set allowed-interface-list=MGMT
/tool mac-server mac-winbox set allowed-interface-list=MGMT
/ip neighbor discovery-settings set discover-interface-list=MGMT
/user add name=netadmin group=full password=********
/user disable admin
/system ntp client set enabled=yes servers=time.cloudflare.com
/system scheduler add name=nightly interval=1d start-time=03:30:00 on-event={
/export show-sensitive file=nightly
:delay 5s
/tool fetch upload=yes url="sftp://10.250.0.1/backups/cafe-r1.rsc" src-path=nightly.rsc \
user=backup password=********
}
# on SW-COUNTER: only the uplink may answer DHCP
/interface bridge set bridge dhcp-snooping=yes
/interface bridge port set [find interface=sfp1] trusted=yesThe nightly export goes through the WireGuard tunnel to the contractor's hub, so a dead router is replaced by a spare hAP and one import, not by an afternoon of reconfiguring. show-sensitive includes the Wi-Fi and PPPoE passwords, so the hub stores those files encrypted (see backups and hardening).
cafe-r1.rsc is on the hub with today's date.16
Run these on a quiet afternoon. The results go into the PCI questionnaire, so write them down.
| Drill (requirement) | What must happen |
|---|---|
| Payment seal (R1) | From every other VLAN, including guest Wi-Fi: nmap -Pn 10.40.25.0/24 finds nothing. From the terminals' VLAN (a laptop on ether1, temporarily): only the acquirer's hosts on 443 answer. |
| Guest portal (R2) | A new phone gets the portal automatically; it can't reach 10.40.0.0/16 before or after login. |
| Busy patio (R3) | Saturate the guest network; a card payment and a POS order complete in normal time. |
| Fibre cut (R4) | Tills and terminals continue on 4G within ~15–20 s. Guests, cameras and the espresso machine are refused. Watch the 4G data counter for 30 minutes: only tens of MB. |
| Music (R5) | The POS tablet controls the music; the speaker can't reach anything except its callback port on the tablets. |
| Ex-employee (R6) | A phone with the old staff password: can't join CAFE-POS (different password, WPA3 only). |
| Remote care (R7) | On 4G only, the contractor still reaches R1 through WireGuard. No port is open on the WAN. |
17
Who would attack a café? Mostly opportunists: someone at a table with a laptop, or someone who walks in to swap a card terminal.
18
Everything except the radios runs on a free CHR, including the hotspot.
| This post | In the lab |
|---|---|
| R1 hAP ax³ | A CHR with ether1 (PPPoE to an "ISP" CHR acting as PPPoE server), ether2 trunk, ether5 (DHCP from a second "4G" CHR). Hotspot, queues, failover, mDNS repeat and WireGuard all work. |
| SW-COUNTER | A CHR bridge with VLAN filtering. No PoE, otherwise the same. |
| Wi-Fi | Replace each SSID with a VM NIC on its VLAN; a browser VM on VLAN 50 tests the hotspot portal. |
| IT hub | Any Linux VM with WireGuard, reachable from both "ISPs". |
19
Indicative EU street prices, late 2026, excluding VAT.
| Item | Indicative (EUR, ex VAT) |
|---|---|
| R1 · hAP ax³ | 140 – 170 |
| SW-COUNTER · CRS112-8P-4S + S-RJ01 | 230 – 290 |
| Patio · wAP ax | 130 – 160 |
| 4G backup · LtAP-class LTE router | 120 – 200, plus a 20 GB business SIM (~15–25/month) |
| Small UPS (router, switch, LtAP) | 120 – 180 |
| Network hardware total | ≈ 740 – 1,000, plus ~10 cable runs |
Appendix
Same brief, same VLANs, on Cisco's small-branch line. The Cisco tabs on the config blocks above show the key steps side by side; this appendix covers what changes underneath.
| Role | This post → Cisco |
|---|---|
| R1 + 4G + indoor Wi-Fi | hAP ax³ + LtAP → one C1121X-8PLTEPWE (router, LTE and Wi-Fi in one box) |
| SW-COUNTER (PoE) | CRS112-8P-4S → Catalyst 1000-8P-2G-L |
| Patio AP | wAP ax → an outdoor Catalyst AP joined to the embedded controller |
| Indicative total | ≈ 740 – 1,000 → ≈ 3,000 – 4,500 EUR ex VAT |
| Feature | This post → Cisco |
|---|---|
| Payment allowlist | address list with host names → object-group network with the acquirer's IP ranges |
| Guest portal | RouterOS hotspot on the router → web-consent WLAN on the wireless controller |
| Per-guest limit | hotspot user profile → per-client QoS on the policy profile |
| Fibre | pppoe-client → PPPoE Dialer interface |
| Failover | recursive routes → IP SLA + track |
| Backup for tills only | reject on ether5 → LTE in its own zone with pairs only from POS/PAY/OFFICE |
| mDNS across VLANs | mdns-repeat-ifaces → Service Discovery Gateway |
| Remote management | WireGuard client → FlexVPN client with tunnel destination dynamic |
Host names become address ranges. The payment allowlist is the one place where Cisco is less convenient: IOS ACLs match addresses, so you need the acquirer's published ranges and must update them when the acquirer changes provider. The portal moves to the Wi-Fi controller, which is actually the more natural place for it. One box replaces three, at about four times the price, with a support contract behind it.
Takeaways
This is part 3 of the Build series. Earlier: the law firm, the gaming center. Next: the supermarket.
Most small hospitality networks are one flat network with the card terminal next to the guest Wi-Fi. I set up networks like this one in a day, with the payment isolation tested and documented for your acquirer.
Book a Discovery Call →