Every industrial site will tell you the OT network is segmented. Most of them believe it. A fair number are wrong, and the interesting thing is that they are rarely wrong about the firewall – the firewall is usually configured exactly as designed. They are wrong because a path exists that the design never contemplated.
A vendor installed a remote-access appliance in 2019 and nobody decommissioned it. An engineering laptop has two network interfaces and sits on both sides at once. A historian was given a second address to solve a data collection problem during commissioning. A firewall rule was written for a two-week integration project and is still there four years later, with no owner and a comment field reading “temp – remove after cutover”.
Segmentation is the primary control protecting industrial systems, for the reasons the previous article laid out: Modbus and its contemporaries have no authentication, so reachability is authorisation. A control that important deserves to be tested rather than assumed. This article covers how to do that without becoming the incident.
It builds on the environment from How to Build a Safe OT Cybersecurity Lab and assumes the asset inventory from Passive OT Asset Discovery with Wireshark, because you cannot test paths between devices you have not yet identified.
Safety classification: Amber. Unlike the previous articles, this one transmits packets. In the lab that is unremarkable. On a production network it requires written authorisation, an agreed window, a named operations contact and abort criteria before anything is sent. The techniques below are ordered specifically so that the safest ones come first and the riskiest are needed least often.
What you are actually testing
The question “is the network segmented” is too vague to answer. Break it into three that can be answered with evidence.
First, is there a path? Can a host in one zone establish a connection to a host in another, on any port at all? This is a binary question about reachability and it is the one that matters most.
Second, is the path the intended one? A path that exists by design, documented and justified, is a different finding from one nobody knew about. Both need recording, but only one is a vulnerability.
Third, is the control observable? When a connection is denied, does that denial appear in a log somewhere a human or a SIEM will see it? A control that works silently is a control you cannot evidence, and one whose failure you will not notice.
Most assessments answer only the first question. The second is what makes the report useful to the site, and the third is what turns segmentation from a static configuration into something monitored.
Start with the paths you can find without sending anything
Before generating a single packet, extract everything the existing evidence will give you. This is free, it is safe, and it frequently finds the answer before active testing begins.
The firewall ruleset is the obvious starting point, and it should be read adversarially rather than descriptively. Look for any-any rules, rules with source or destination groups that have grown over time, rules with no description, rules referencing hosts that no longer exist, and rules whose stated purpose ended years ago. In pfSense and OPNsense the configuration exports as XML, so it can be diffed against a previous version to see what has changed and when.
Routing tables tell you what the network believes is reachable. A route from the OT segment toward a corporate subnet is a design statement, whether or not anyone intended it. Check the firewall’s routing table, and check each host’s:
ip route show
The passive capture from the discovery work is the third source, and often the most revealing. If you already have traffic from the OT segment, look for anything crossing a zone boundary that should not:
tshark -r ot-discovery.pcap -Y "ip.src==192.168.30.0/24 && !(ip.dst==192.168.30.0/24)" \
-T fields -e ip.src -e ip.dst -e tcp.dstport | sort -u
That single command lists every destination outside the control segment that a control-segment host has actually spoken to. Observed traffic is stronger evidence than any configuration file, because it demonstrates a path that works rather than one that should.
Look specifically for hosts appearing in more than one segment’s traffic. A device with interfaces in two zones bypasses the firewall entirely, and no ruleset review will reveal it, because from the firewall’s perspective nothing is wrong.
Progressive active testing
When you do start transmitting, escalate deliberately. Each step below is more informative and more intrusive than the last, and most assessments never need to reach the end.
The governing principle is that the target of a segmentation test is the network, not the device. You are asking whether a packet can traverse a boundary. Where possible, aim the test at something that is not a controller.
Step one: test toward the firewall, not the PLC
If a jump host and a PLC sit on the same segment, and you can reach the jump host from where you should not, the segmentation has already failed. You have your answer without any packet reaching a controller.
Where a segment has no such device, a test against the segment’s gateway address establishes whether routing works before you go anywhere near industrial equipment.
Step two: single-port connection attempts
Start with one connection, to one port, on one host, and observe what happens. Netcat with a short timeout is the right instrument, because it does exactly one thing:
nc -vz -w 3 192.168.30.20 502
Three outcomes, each meaning something different. A connection that succeeds proves a path exists. A connection refused means the packet reached the host and the host actively rejected it – the path exists even though the service does not. A timeout usually means a firewall silently dropped it, which is the correct behaviour for a default-deny rule.
That middle case is the one people misread. “Connection refused” is not a passing test. It means your traffic crossed the boundary.
Step three: careful scanning, if scanning is warranted
Scanning industrial devices carries the risks covered in the discovery article – small connection tables, real-time constraints, embedded stacks that were never fuzzed. Where a scan is genuinely necessary, constrain it hard.
Use full TCP connect scans rather than half-open. A SYN scan leaves connections half-established, and embedded devices are precisely the class of hardware that handles that badly; a completed handshake, closed cleanly, is gentler on a device with a four-entry connection table.
Slow the timing down, scan one host at a time, and limit the ports to the ones you have a reason to test:
nmap -sT -T2 --max-parallelism 1 --host-timeout 5m \
-p 502,102,44818,20000 -Pn 192.168.30.20
Nothing here is aggressive by IT standards, and that is the point. Never run service or version detection against a controller during a segmentation test – -sV sends protocol-specific probes designed to elicit responses, which is a different activity with a different risk profile, and it is not what you are trying to establish.
If the site has spare or cold-standby equipment identical to what is in production, ask whether you can scan that instead. Many will say yes, and it converts the whole question into a lab exercise.
Step four: protocol-level verification
Occasionally you need to prove not just that a port is reachable but that the protocol works across the boundary – typically because a site disputes the finding, or because a firewall claims to be doing application-layer inspection.
Keep it to a single read. Never write:
mbpoll -a 1 -t 4 -r 1 -c 1 -1 192.168.30.20
The -1 flag polls once and exits rather than looping. A single read of one register is the smallest possible demonstration, and it is enough. Anyone who tells you a write is needed to prove the point is proposing to change a live process to win an argument.
Test in both directions, and from every zone
Segmentation is not symmetric, and testing it in one direction is the most common methodological gap in this work.
An OT host that can initiate outbound connections to the internet is a serious finding even if nothing can reach it inbound, because that is the path malware uses to establish command and control and to exfiltrate. Test outbound reachability explicitly from inside the control segment:
nc -vz -w 3 8.8.8.8 53
nc -vz -w 3 1.1.1.1 443
Both should time out. Check DNS resolution separately, since a control segment that can resolve external names usually has a path you have not found yet.
Then build the full matrix. For each pair of zones, in each direction, test the ports that matter. In the lab that means the test workstation toward the DMZ and control segments, the jump host toward control, control toward the internet, and control back toward IT. Record the expected result and the observed result for each, and treat every mismatch as a finding regardless of which direction it favours.
The pairs people forget are the ones that produce the findings: OT back toward IT, and any zone toward the management network the switches and firewalls live on.
Verify the denials are visible
This is the step that separates a segmentation test from a segmentation audit, and it takes ten minutes.
For each connection you expect to be blocked, check that the block was logged. In pfSense and OPNsense, the firewall log filtered to the source address should show the denied attempt with source, destination, port and rule. If it does not appear, either logging is off on that rule or the traffic never reached the firewall – and the second possibility means there is another path you have not found.
Then check whether the log reaches anywhere useful. A denial recorded on the firewall and never forwarded to a SIEM is evidence available only to whoever thinks to look, which in practice is nobody. Note the gap.
Cross-referencing your own test traffic against the logs also validates the monitoring itself. If you generated forty denied connections and the log shows twelve, that discrepancy is worth more than any individual reachability finding.
What you will actually find
The same handful of issues recur at site after site, and knowing them shapes where to look first.
Dual-homed hosts are the most common and the most serious. An engineering workstation, a historian or a domain controller with interfaces in two zones bypasses the firewall completely. They are invisible in a ruleset review, and they are usually there for a reason somebody found compelling at the time. Look for hosts appearing in traffic from both segments, and check the interface list on any Windows host you have access to.
Vendor remote-access appliances are the second. Cellular routers, jump servers and support tunnels installed by an equipment supplier frequently sit inside the OT network with an outbound path the site does not monitor and sometimes does not know about. They rarely appear on the network diagram.
Overly broad allow rules come third. A rule permitting the entire DMZ subnet to reach the entire control subnet on any port is technically segmentation, and practically not. The test is whether the rule expresses a specific flow between specific hosts or merely a boundary between address ranges.
Then there is management-plane access. Switches, firewalls and virtualisation hosts often have management interfaces reachable from IT while carrying OT traffic. That is a path around the segmentation rather than through it, and it is routinely out of scope in assessments that should have included it.
Finally, asymmetric rules: outbound permitted where inbound is blocked. Nearly always this is an oversight rather than a decision.
Recording it so somebody can act
A reachability matrix with expected and observed results is the core of the deliverable, but on its own it does not tell a site what to do.
For each unintended path, record the evidence – the command run, the output, the timestamp, and the corresponding firewall log entry or its absence. Then record what the path allows in process terms rather than network terms. “The IT subnet can reach TCP/502 on the tank controller” is a technical fact. “A host on the corporate network can issue commands that start the transfer pump” is the same fact in language that gets the finding fixed, and it is accurate, because with Modbus reachability and authorisation are the same thing.
Distinguish paths that are unintended from those that are intended but undocumented. The remediation differs: one is closed, the other is written down, justified and given an owner and a review date.
And record what you did not test. A segmentation assessment bounded to the zones you had access to, during the window you were given, is a legitimate result – provided the boundary is stated rather than implied.
What comes next
Segmentation tells you which paths exist. It does not tell you what happens on the paths that are meant to be there, which is why the next two articles build an OT traffic baseline and then use it to detect unauthorised commands.
Those are complementary controls rather than alternatives. Segmentation is preventive and static; it fails silently when someone adds a rule. Detection is continuous and notices the change. Sites that rely on one alone tend to discover the gap at an inconvenient moment.
When was your segmentation last verified rather than assumed?
Firewall rulesets describe intent. Reachability testing describes reality, and the gap between them accumulates quietly – a vendor appliance, a dual-homed workstation, a rule that outlived its project.
CyberLabs OT security assessments examine network segmentation, remote-access pathways, industrial device exposure and monitoring controls, while accounting for operational availability and recovery requirements.