Chapter 6 — Discrete structures
Lesson map
Lesson 06 published. Map, example, EX016.
flowchart TD
N0["Learning outcomes"]
N1["6.1 Zones and conduits as a graph"]
N2["6.2 Breadth-first search"]
N3["6.3 Cut edges"]
N4["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Worked example"]
EX --> Q["Exercise EX016"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["6.1 Zones and conduits as a graph"]
N2["6.2 Breadth-first search"]
N3["6.3 Cut edges"]
N4["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX016"]
[Learning outcomes]
|
v
[6.1 Zones and conduits as a graph]
|
v
[6.2 Breadth-first search]
|
v
[6.3 Cut edges]
|
v
[Synthesis]
|
v
[Worked example] --> [Exercise EX016]
Learning outcomes
You will (1) model zones and conduits as a directed graph; (2) compute reachability with breadth-first search; (3) reason about which single edge removal disconnects a critical node; and (4) use sets to express allow-lists.
6.1 Zones and conduits as a graph
IEC 62443-3-2 asks asset owners to partition a system into zones (groups of assets sharing security requirements) connected by conduits (the communication channels between zones). A directed graph captures this: nodes are zones, edges are conduits in the direction a session can be opened. A path from the enterprise zone to the safety zone is a question about graph reachability, which is mechanical once the graph is drawn honestly.
In the lab's graph, Maya records the conduits as ordered pairs, so MeterGW→SCADA and Control→SIS are visible edges rather than lines on a drawing.
6.2 Breadth-first search
BFS visits a start node, then all its neighbours, then theirs, marking each visited node once. It runs in time proportional to nodes plus edges, so even a large refinery's conduit list is checked instantly. The danger is not the algorithm but the input: a forgotten vendor modem or a dual-homed laptop is an edge the diagram omits.
"""Lab 06: reachability over a synthetic LDHP zone/conduit graph (BFS)."""
from collections import deque
CONDUITS = {"Enterprise": ["DMZ"], "DMZ": ["SCADA"], "SCADA": ["Control"],
"Control": ["SIS"], "MeterCloud": ["MeterGW"], "MeterGW": ["SCADA"], "SIS": []}
def reach(src):
seen, q = {src}, deque([src])
while q:
for n in CONDUITS.get(q.popleft(), []):
if n not in seen: seen.add(n); q.append(n)
return seen
for z in ["Enterprise", "MeterCloud", "SCADA"]:
r = sorted(reach(z) - {z}); print(f"{z:10} -> {r} SIS reachable: {'SIS' in r}")
CONDUITS["Control"] = [] # design change: SIS gets its own hardwired trip, no Control->SIS data conduit
print("after removing Control->SIS:", "SIS" in reach("Enterprise"))
Run with python3 lab_reach.py. Verified output:
Enterprise -> ['Control', 'DMZ', 'SCADA', 'SIS'] SIS reachable: True
MeterCloud -> ['Control', 'MeterGW', 'SCADA', 'SIS'] SIS reachable: True
SCADA -> ['Control', 'SIS'] SIS reachable: True
after removing Control->SIS: False
At LDHP, a vendor modem nobody recorded or EWS-1 connected to both office and control networks would add an edge the lab cannot know about; the BFS answer is only as true as the conduit list.
6.3 Cut edges
An edge whose removal disconnects the attacker-facing zones from the critical zone is a cut edge for that pair. In the lab, Control→SIS is such an edge: removing it makes SIS unreachable from Enterprise and from MeterCloud. Engineering often prefers removing a data conduit to a safety system entirely and relying on hardwired trips, which is exactly what the lab's design change represents.
Maya's note adds the second step: the MeterGW→SCADA edge exists only so billing can read flow totals, so replacing it with a one-way export from the historian removes the meter cloud's other path toward the control zone.
Worked example (synthetic LDHP)
The lab shows the meter cloud reaching SIS through MeterGW → SCADA → Control → SIS. Maya expresses the conduit list as a set of ordered pairs and notes that the MeterGW→SCADA edge exists only so billing can read flow totals. Replacing it with a one-way export from the historian removes a second path; removing Control→SIS removes the last one.
Synthetic case — Lakeside District Heating Plant. The zone names and conduits in the lab are invented to keep the graph small enough to check by hand.
Errors and limits
Reachability says a session may be opened, not that it will succeed or what it can do. Undirected drawings hide the difference between "SCADA polls the gateway" and "the gateway can connect to SCADA".
Exercises
- EX016 — Tracing a BFS by hand. List the order in which BFS from MeterCloud visits nodes in the original graph. Rubric: 3 = MeterCloud, MeterGW, SCADA, Control, SIS; 2 = right set, wrong order; 1 = missing a node; 0 = none.
- EX017 — An omitted vendor modem. A vendor modem gives the internet a direct conduit to Control. After the lab's design change, is SIS reachable from the internet? Rubric: 3 = no, Control has no outgoing edge to SIS after the change, but Control itself is now exposed; 2 = "no" only; 1 = "yes"; 0 = none.
- EX018 — Allow-list as a set. Express "HIST-1 may read from PLC-H; HMI-1 may read and write PLC-H" as a set of (source, destination, action) tuples. Rubric: 3 = three tuples, nothing extra; 2 = minor extra; 1 = uses ranges of hosts; 0 = none.
Synthesis
Drawing zones and conduits as a directed graph turns segmentation arguments into checks that anyone can rerun — provided the graph includes every real edge.
Continue studying — chapter 06 of 40
← Chapter 05 (draft) · Course chapter index · Chapter 07 (draft) →