NET-110 · Lesson 12 of 12 · 33 min

Capstone: designing and addressing a small business network

▶ Video coming soon A video version of this lesson is on the way.

Rosa has signed a lease on a second cafe downtown, opening in the spring, and she wants both locations on a network that is secure, documented and easy for the next person to support. Sam and Jordan are asked to produce a complete design: the requirements, the VLANs and subnets for both sites, the IPv6 plan, DHCP scopes and reservations, the core services, the Wi-Fi plan, the firewall policy between networks, the link between the two cafes, and the documentation and tests that prove it all works. This capstone walks through that design from start to finish, drawing on every lesson in the course, and checks the plan with short Python scripts so that mistakes are caught on paper rather than on opening day.

Step 1: gather the requirements

A design starts with what the business needs, not with equipment. Sam interviews Rosa, Theo, Mei, Kai and Anita and lists the devices, the services they use and the rules that must apply. The payments industry's security standard, PCI DSS, sets one firm requirement: card terminals and the systems that handle card data must be separated from everything else and protected by firewall rules that allow only what they need. Guests must have internet access and nothing more. The roastery equipment talks to its manufacturer's cloud service and to the office for roast logs. Staff need the office file share, the printer and the internet. Network devices must be managed from a separate network that only Sam's and the contractor's laptops can reach.

Device counts and growth allowances
GroupMain site devicesDowntown cafe devicesAllow for growth to
Office and staff22: laptops, phones, printer, storage box6: manager laptop, staff phones, printer60 per site
Payments7: two tills, three card terminals, kitchen display, receipt printer5: two tills, two card terminals, receipt printer30 per site
Guest Wi-FiUp to 150 at busy timesUp to 80250 per site
Roastery and equipment8: roast controller, scales, sensors, grinder, cameras3: grinder, two cameras30 per site
Management6: firewall, switch, three access points4: firewall, switch, two access points14 per site

Growth allowances are generous on purpose. Private address space costs nothing, and readdressing a live network later costs a weekend. Sam also notes three non-network requirements that shape the design: the payment terminals' supplier must be able to support them remotely, the network must keep taking card payments if the link between the cafes fails, and everything must be documented well enough that an outside technician could take over.

Step 2: the addressing plan

Sam gives each site its own /16 from the 10.0.0.0/8 private range: 10.20.0.0/16 for the main site and 10.21.0.0/16 for downtown. Inside each site, every VLAN gets a /24 whose third octet matches the VLAN number. That uses far more space than the device counts need, but it means an address tells you its site and its network at a glance: 10.21.20.31 is downtown, payments, and the gateway of every network is always .1. Lesson 5's VLSM techniques would pack the same networks into a single /22, which is the right choice when address space is scarce, as it is with public addresses; here readability wins. Every /24 also comfortably exceeds the growth allowances.

The VLAN and address plan for both sites
VLANNameMain site IPv4Downtown IPv4IPv6 (main / downtown)Gateway
10Office and staff10.20.10.0/2410.21.10.0/242001:db8:5a00:10::/64 / 2001:db8:5a01:10::/64.1
20Payments10.20.20.0/2410.21.20.0/242001:db8:5a00:20::/64 / 2001:db8:5a01:20::/64.1
30Guest Wi-Fi10.20.30.0/2410.21.30.0/242001:db8:5a00:30::/64 / 2001:db8:5a01:30::/64.1
40Roastery and equipment10.20.40.0/2410.21.40.0/242001:db8:5a00:40::/64 / 2001:db8:5a01:40::/64.1
99Management10.20.99.0/2410.21.99.0/242001:db8:5a00:99::/64 / 2001:db8:5a01:99::/64.1

The IPv6 plan follows Lesson 6. The provider supplies a /48 for each site, 2001:db8:5a00::/48 for the main site and 2001:db8:5a01::/48 downtown, and each VLAN gets the /64 whose subnet ID matches its number. Within each /24, addresses are divided the same way everywhere: .1 is the gateway on the firewall, .2 to .49 are reserved for static devices and DHCP reservations, .50 to .249 are the DHCP pool, and .250 to .254 are spare for temporary use. Consistency is the point: anyone who has learned one network has learned all ten.

Generating the address plan for both sites and checking it for overlaps
import ipaddress

sites = {'main': 20, 'downtown': 21}
vlans = {10: 'office', 20: 'payments', 30: 'guest', 40: 'equipment', 99: 'management'}

plan = []
for site, second in sites.items():
    for vlan, name in vlans.items():
        net = ipaddress.ip_network('10.%d.%d.0/24' % (second, vlan))
        plan.append((site, vlan, name, net))

for site, vlan, name, net in plan[:6]:
    hosts = list(net.hosts())
    print(site.ljust(9), str(vlan).rjust(2), name.ljust(10), str(net).ljust(15), 'gateway', hosts[0])
print('...', len(plan), 'networks in total')

nets = [p[3] for p in plan]
clashes = [(a, b) for i, a in enumerate(nets) for b in nets[i + 1:] if a.overlaps(b)]
print('overlapping networks:', clashes or 'none')
print('all inside 10.0.0.0/8:', all(n.subnet_of(ipaddress.ip_network('10.0.0.0/8')) for n in nets))
Output
main      10 office     10.20.10.0/24   gateway 10.20.10.1
main      20 payments   10.20.20.0/24   gateway 10.20.20.1
main      30 guest      10.20.30.0/24   gateway 10.20.30.1
main      40 equipment  10.20.40.0/24   gateway 10.20.40.1
main      99 management 10.20.99.0/24   gateway 10.20.99.1
downtown  10 office     10.21.10.0/24   gateway 10.21.10.1
... 10 networks in total
overlapping networks: none
all inside 10.0.0.0/8: True

Try it yourself

Generate the address plan

Write address_plan(second_octet, vlans) that returns a dictionary mapping each VLAN number in the list vlans to a dictionary with the keys network (the /24 written as a string, 10.<second_octet>.<vlan>.0/24), gateway (the .1 address) and pool (a tuple of the first and last DHCP pool addresses, .50 and .249), all as strings.

For example, address_plan(21, [20])[20]['gateway'] is '10.21.20.1'.

def address_plan(second_octet, vlans):
    plan = {}
    for vlan in vlans:
        plan[vlan] = {'network': '10.%d.0.0/16' % second_octet}
    return plan

print(address_plan(21, [20]))

Step 3: switching, VLANs and Wi-Fi

At each site, the firewall-router connects to the switch over a trunk carrying all five VLANs, with a sub-interface on the firewall for each VLAN acting as its gateway. Wired devices connect to access ports in their own VLAN: tills and card terminals in VLAN 20, the roast controller and cameras in VLAN 40, office computers in VLAN 10. Every unused port is disabled and placed in an unused VLAN, so plugging a stranger's laptop into a spare socket gives it nothing. The links to the access points are trunks carrying VLANs 10, 20, 30 and 99, the last for managing the access points themselves.

The Wi-Fi plan follows Lesson 10. The main site gets three access points, adding the one over the back tables; downtown gets two. Each broadcasts three SSIDs: Ridgeline-Staff, WPA3 Personal, mapped to VLAN 10; Ridgeline-Guest, open with Enhanced Open encryption and client isolation, mapped to VLAN 30; and a hidden payments SSID with its own long passphrase, mapped to VLAN 20, for the wireless card terminals. 2.4 GHz radios use channels 1, 6 and 11; 5 GHz radios use non-overlapping 40 MHz channels; transmit power is moderate, and a site survey after installation confirms -67 dBm or better at every table and at the counter.

Step 4: DHCP, DNS and NTP

The firewall-router at each site runs DHCP for its five VLANs, so each site keeps working on its own if the link between them fails. Each scope uses the pool .50 to .249 with the gateway .1 and the site's firewall as DNS and NTP server. Lease times differ by network: two hours for guests, where devices come and go; one day for the office; one week for payments and equipment, which rarely change. Every till, card terminal, printer, camera and controller gets a DHCP reservation between .10 and .49, recorded in the inventory, so its address never changes and firewall rules can refer to it. Network devices in VLAN 99 get static addresses, because they must work before DHCP does.

Each firewall runs a caching DNS resolver that forwards to the provider's resolvers, with a filtering resolver for the guest VLAN that blocks known malicious domains. Internal names such as nas.main.ridgeline.internal and printer.downtown.ridgeline.internal let staff find devices without memorizing addresses. Each firewall synchronizes its clock with public NTP pool servers and serves time to its site, so every till, terminal and log in both cafes agrees to the second.

Try it yourself

Build the DHCP scopes

Write scopes(plan, leases) where plan is the output of address_plan from the earlier exercise (provided here as PLAN) and leases maps VLAN numbers to lease hours. Return a list of strings, one per VLAN in increasing VLAN order, formatted exactly like vlan 20 10.20.20.50-10.20.20.249 gw 10.20.20.1 dns 10.20.20.1 lease 168h. The DNS server is the gateway. If a VLAN has no entry in leases, use 24 hours.

def scopes(plan, leases):
    return ['vlan %d' % v for v in plan]

for line in scopes(PLAN, LEASES):
    print(line)

Step 5: the firewall policy

Traffic between VLANs, and between each site and the internet, passes through the firewall, which applies rules from the top down with the first match deciding. Sam writes the policy as a table first, with a reason for every rule, and only then configures it. The policy is the same at both sites apart from the site's addresses, and equivalent rules are applied to IPv6, so nothing slips past through the other protocol.

The inter-VLAN and internet firewall policy, checked from the top
OrderSourceDestinationServiceActionReason
1Payments VLAN 20Card processor addressesTCP 443AllowCard authorizations
2Payments VLAN 20Firewall .1UDP and TCP 53, UDP 123AllowDNS and time
3Payments VLAN 20AnyAnyDeny and logNothing else for card devices (PCI DSS)
4Guest VLAN 3010.0.0.0/8AnyDenyGuests never reach internal networks
5Guest VLAN 30InternetAnyAllowGuest internet access
6Office VLAN 10Storage box in VLAN 99TCP 445AllowFile share
7Office VLAN 10Equipment VLAN 40TCP 443AllowRoast controller dashboard
8Equipment VLAN 40Manufacturer cloudTCP 443AllowRoaster telemetry and updates
9Office VLAN 10InternetAnyAllowStaff internet access
10Admin laptopsManagement VLAN 99TCP 22, 443AllowDevice administration
11Main site and downtown internal networksThe other site's internal networksPer rules aboveAllowThrough the site-to-site tunnel
12AnyAnyAnyDeny and logDefault: everything not allowed above

Order matters. Rule 4, which stops guests reaching internal networks, must come before rule 5, which allows guests the internet; the other way round, rule 5 would match internal destinations first, because 10.0.0.0/8 is part of any address. Testing a policy on paper, by running sample connections through it, catches exactly this kind of mistake before it reaches the firewall.

Testing the firewall policy on paper: sample connections run through the rules in order
import ipaddress

RULES = [  # (source network, destination network, port or None for any, action)
    ('10.20.20.0/24', '198.51.100.0/24', 443, 'allow'),     # payments to the card processor
    ('10.20.20.0/24', '0.0.0.0/0', None, 'deny'),           # nothing else for payments
    ('10.20.30.0/24', '10.0.0.0/8', None, 'deny'),          # guests never reach inside
    ('10.20.30.0/24', '0.0.0.0/0', None, 'allow'),          # guests may use the internet
    ('10.20.10.0/24', '10.20.99.10/32', 445, 'allow'),      # office to the file share
    ('0.0.0.0/0', '0.0.0.0/0', None, 'deny'),               # default deny
]

def decide(src, dst, port):
    for number, (s, d, p, action) in enumerate(RULES, start=1):
        if (ipaddress.ip_address(src) in ipaddress.ip_network(s)
                and ipaddress.ip_address(dst) in ipaddress.ip_network(d)
                and (p is None or p == port)):
            return action + ' (rule ' + str(number) + ')'

tests = [('10.20.20.21', '198.51.100.25', 443), ('10.20.20.21', '10.20.10.37', 445),
         ('10.20.30.88', '10.20.20.21', 443), ('10.20.30.88', '203.0.113.200', 443),
         ('10.20.10.37', '10.20.99.10', 445), ('10.20.10.37', '10.20.99.10', 22)]
for src, dst, port in tests:
    print(src.ljust(12), '->', (dst + ':' + str(port)).ljust(20), decide(src, dst, port))
Output
10.20.20.21  -> 198.51.100.25:443    allow (rule 1)
10.20.20.21  -> 10.20.10.37:445      deny (rule 2)
10.20.30.88  -> 10.20.20.21:443      deny (rule 3)
10.20.30.88  -> 203.0.113.200:443    allow (rule 4)
10.20.10.37  -> 10.20.99.10:445      allow (rule 5)
10.20.10.37  -> 10.20.99.10:22       deny (rule 6)

The last test shows the default deny doing its job: SSH from an office laptop to the storage box is blocked, because only the admin laptops may manage devices, under a rule left out of this short version. Running a list of expected and forbidden connections through the policy after every change is a cheap habit that prevents expensive surprises.

Try it yourself

Evaluate firewall rules in order

RULES is a list of (source, destination, port, action) tuples, where source and destination are networks in CIDR notation, port is an integer or None for any port, and action is 'allow' or 'deny'. Write decide(rules, src, dst, port) that returns the action of the first rule that matches, or 'deny' if none does.

Then write audit(rules, cases) that takes a list of (src, dst, port, expected) tuples and returns the list of cases (as tuples, in order) whose decision differs from expected.

import ipaddress

def decide(rules, src, dst, port):
    return 'allow'

def audit(rules, cases):
    return []

print(audit(RULES, CASES))

Step 6: connecting the two sites

The cafes are joined by a site-to-site VPN: an encrypted IPsec tunnel between the two firewalls across the internet, with each firewall holding a static route to the other site's /16 through the tunnel, exactly as the routing table in Lesson 7 showed. Because each site has its own /16, one route covers everything at the other site, and the address plans never collide. The tunnel carries staff traffic, roast logs and the file share; card payments never use it, because each site's payment VLAN goes straight to the card processor over its own internet connection. If the tunnel or the downtown internet connection fails, downtown keeps selling: its tills and terminals need only their local firewall and the internet, and the shop's point-of-sale service stores sales locally until the connection returns.

A dedicated private circuit between the sites would be more predictable but costs far more; for two cafes, a VPN over business internet service is the usual choice. Sam documents the tunnel's settings, the pre-shared key's location in the password manager, and a test: from an office laptop at each site, ping the other site's firewall at 10.2x.99.1 and open the file share.

Step 7: documentation and testing

The design is only finished when it is written down and proven. Sam's documentation set covers: the requirements and the reasons for each design decision; the physical diagrams of both sites with rooms, cabinets, sockets and access points; the logical diagram with VLANs, subnets, gateways and the tunnel; the address plan and the reservations list; the device inventory with models, firmware and warranties; the firewall policy table with reasons; configuration backups of every network device; provider contacts and demarc locations; and a change log. All of it lives in the same repository as the shop's Python tools, so changes are reviewed and the inventory can be checked by script, as in Lesson 1.

Testing follows the layers and the policy. For each VLAN at each site: a device gets the right address, mask, gateway and DNS from DHCP; it can ping its gateway; names resolve; it can reach what the policy allows and cannot reach what it denies, checked from a laptop placed in each VLAN in turn. The guest network is tested from a phone: internet works, nothing internal answers, and other guests' devices are invisible. Card payments are tested with the processor's test transactions, then again with the site-to-site tunnel disabled. A Wi-Fi survey confirms coverage. Every result is recorded, so the next person can repeat the tests after any change.

Worked problem

Reviewing the design before it is built

Before ordering equipment, Rosa asks the contractor who will install it to review Sam's design. What would a careful reviewer check, and what might they find?

Show solution
  1. Requirements: every device group from the interviews has a VLAN, and every growth allowance fits its subnet: a /24 gives 254 hosts against 250 for guests at most.
  2. Addressing: the two /16s do not overlap each other or the provider's address ranges, and the script found no overlapping subnets.
  3. Policy: rules are ordered with specific denies before broad allows; payments may reach only the processor, DNS and NTP; IPv6 has matching rules.
  4. Resilience: each site keeps taking payments if the tunnel fails, but the main site's single firewall and switch remain single points of failure; the reviewer recommends a spare switch on the shelf and a cellular backup internet connection for the main site's payment VLAN.
  5. Operations: documentation and tests are complete; the reviewer asks for the management VLAN to be reachable only from named admin laptops, which rule 10 already does.

Answer: The design passes, with two improvements: a spare switch and cellular backup for the main site's payments, both added to the plan and the budget.

Common mistakes

  • MistakeDesigning around equipment instead of requirements.

    InsteadStart with devices, services, rules and growth, then choose the equipment.

  • MistakeUsing overlapping address ranges at two sites.

    InsteadGive each site its own block so routes and VPNs never collide.

  • MistakePutting a broad allow rule above a specific deny.

    InsteadOrder rules so specific denies come first, and test the policy with sample connections.

  • MistakeWriting firewall rules for IPv4 only.

    InsteadApply equivalent IPv6 rules on every dual-stack network.

  • MistakeLetting payments depend on the link between sites.

    InsteadKeep each site's payment path local so a tunnel failure does not stop sales.

  • MistakeCalling a design finished before testing and documenting it.

    InsteadTest every VLAN against the policy and record the results with the design.

Summary and key terms

  • A network design starts with requirements: devices, services, security rules such as PCI DSS, and growth.
  • Readable addressing, one /16 per site and one /24 per VLAN matching its number, makes operations easier.
  • Each VLAN also gets an IPv6 /64 from the site's /48, using the VLAN number as the subnet ID.
  • Trunks carry VLANs to the firewall and access points; SSIDs map to VLANs; unused ports are disabled.
  • Each site runs its own DHCP, DNS and NTP so it keeps working alone; reservations fix device addresses.
  • Firewall rules are ordered, specific before general, with reasons, default deny and matching IPv6 rules.
  • A site-to-site VPN joins the cafes, while payments stay local to each site.
  • Documentation and layered tests complete the design and make it supportable by others.
Requirements
What the network must do for the business, gathered before design begins.
Address plan
The allocation of networks, gateways, pools and reservations across a site.
PCI DSS
The payment card industry's data security standard, which requires card systems to be separated and protected.
Access port
A switch port carrying one VLAN, untagged, for an end device.
Site-to-site VPN
An encrypted tunnel that joins the networks of two sites across the internet.
Default deny
A final firewall rule that blocks everything not explicitly allowed.
Client isolation
A Wi-Fi feature that stops wireless clients on the same network reaching each other.
Single point of failure
A component whose failure stops the whole system.

Practice problems

Work each problem on paper first, then reveal the answer to check.

  1. Why does Sam give each site its own /16?

    Show answer

    So addresses never overlap between sites and one route covers the whole other site.

  2. What is the downtown payments network and its gateway?

    Show answer

    10.21.20.0/24, gateway 10.21.20.1.

  3. What IPv6 network does the main site's guest VLAN use?

    Show answer

    2001:db8:5a00:30::/64.

  4. Why must the guest deny rule come before the guest allow rule?

    Show answer

    Rules match in order; the broad allow would otherwise match internal destinations first.

  5. Why do card terminals get a week-long lease and a reservation?

    Show answer

    They rarely change, and firewall rules and records refer to their fixed addresses.

  6. What happens to card payments downtown if the site-to-site tunnel fails?

    Show answer

    Nothing: payments go directly to the processor over the local internet connection.

  7. Which three SSIDs does each access point broadcast?

    Show answer

    Ridgeline-Staff (VLAN 10), Ridgeline-Guest (VLAN 30) and a hidden payments SSID (VLAN 20).

  8. What should happen to unused switch ports?

    Show answer

    Disable them and place them in an unused VLAN.

  9. Name two single points of failure the reviewer found.

    Show answer

    The main site's firewall and switch.

  10. How are the firewall rules tested before configuration?

    Show answer

    By running sample allowed and forbidden connections through the ordered rules.

Lesson quiz · 5 questions

Score 60% or more to complete this lesson.

Take the quiz