Edge Network Security
The Consystence edge runs at the boundary between a corporate IT network and an operational technology (OT) network of controllers and field devices. That boundary is the highest-value target on the site: anything that can reach the controller can, in principle, influence physical plant. The edge’s reference network policy therefore follows a SCADA threat model, not an OWASP-web one: segment the two networks, default-deny all traffic, and allow-list only the ports the edge needs (and, on the OT side, the exact controller addresses).
This page sets out that reference policy for the edge host. The edge expresses it
as a dual-NIC nftables ruleset, which
it generates from its Firewall configuration. For the target VL3 installation
see VL3 Edge Setup, for the workshop’s Orin host see
Nvidia Orin Edge, and for the broader runtime see the
Edge overview.
Dual-NIC segmentation
Section titled “Dual-NIC segmentation”The reference edge host has two physical network interfaces, which are never bridged. The interface names below are the defaults; set them to the host’s own:
| Interface | Role | Faces | Setting |
|---|---|---|---|
eth0 | IT uplink | The site server (upstream) | ItInterface |
eth1 | OT field | Controllers and field devices (downstream) | OtInterface |
eth0 carries the edge’s connection home to the site server: telemetry,
heartbeats and the store-and-forward flush. eth1 carries only industrial
protocol traffic to the controllers. The policy drops all forwarding between the
two interfaces (BlockForwarding, default true), so the edge host does not
route traffic between the IT and OT networks.
flowchart LR
SS["Site server<br/>(edge listener)"]
subgraph EDGE["Edge host (dual-NIC, reference policy)"]
direction TB
IT["eth0 — IT uplink<br/>outbound edge port / 53 / 123"]
OT["eth1 — OT field<br/>44818 to configured controllers"]
FW["forward chain:<br/>default-deny (no IT<->OT routing)"]
end
CTRL["PLCnext / controller"]
FIELD["Field IO"]
SS <-->|"TLS"| IT
OT <-->|"EtherNet/IP CIP"| CTRL
CTRL --> FIELD
IT -.-x FW
OT -.-x FW
Default-deny posture
Section titled “Default-deny posture”Every chain in the generated ruleset defaults to drop. The policy permits only what a rule explicitly allows, and that applies to inbound, outbound and forwarded traffic alike: the input, output and forward chains all start from a drop policy.
Default-deny on the output chain is deliberate: even outbound connections the edge initiates must match an allow rule. IT-side rules match by interface and port; to keep the edge to the hosts it needs, restrict the IT-side egress destinations (DNS, NTP and the site server) in the site network wherever the deployment allows it. OT rules also pin the configured controller addresses.
Established and related flows are accepted, invalid inbound packets are dropped, and loopback is allowed in both directions. Everything that falls through is logged and dropped; see OT traffic monitoring.
Allowed ports
Section titled “Allowed ports”The reference policy opens only these flows.
| Port | Protocol | Interface | Direction | Purpose |
|---|---|---|---|---|
| 22 | tcp | eth0 (IT) | inbound | SSH administration |
| Site server edge port (site-specific; the examples use 5001) | tcp | eth0 (IT) | outbound | gRPC upstream to the site server’s edge listener (TLS). Use the port in Upstream:ServerUrl |
| 53 | tcp + udp | eth0 (IT) | outbound | DNS |
| 123 | udp | eth0 (IT) | outbound | NTP (time sync) |
| 44818 | tcp + udp | eth1 (OT) | inbound + outbound | EtherNet/IP CIP to the controller |
PLCnext gRPC port (PlcNext:GrpcPort, default 41100) | tcp | eth1 (OT) | outbound | gRPC to a remote PLCnext, where the edge uses one |
A few points worth calling out:
- The OT side opens only EtherNet/IP CIP (44818), plus the PLCnext gRPC port where the PLCnext is remote (see the note below). EtherNet/IP CIP is the protocol the edge (or, in the border-gateway topology, the co-located PLCnext) uses to reach a ControlLogix controller or IO rack. See PLC communication.
- IT outbound is scoped to the ports the edge needs. The IT side may use only the site server’s edge port (upstream), 53 (DNS) and 123 (NTP); restrict those egress destinations in the site network wherever the deployment allows, so the edge reaches only the hosts it needs. The OT side is tighter still: it may only reach the configured controller(s) on 44818, plus the PLCnext gRPC port where the PLCnext is remote.
- SSH (22) is the only inbound IT rule in the reference policy. Administrative access is deliberately the single inbound exception, and it can be removed for fully headless deployments by editing the policy.
OT traffic monitoring
Section titled “OT traffic monitoring”In the reference policy the OT side is allow-listed by source and destination address, not just by port:
- Inbound OT rules pin the allowed source addresses, so the edge accepts EtherNet/IP CIP only from the controller(s) configured for the site, not from anything else that appears on the OT segment.
- Outbound OT rules pin the destination addresses, so the edge talks only to those controllers.
This address pinning is the enforcement half of OT traffic monitoring. The observation half is the passive network monitor described below.
Every packet that falls through the allow rules is logged before it is
dropped, with a distinct prefix per chain ([CSY-DROP-IN], [CSY-DROP-OUT],
[CSY-DROP-FWD]) so drops are easy to separate in the kernel log. Under normal
operation the forward chain should log nothing, because nothing legitimately
routes across the IT/OT boundary, so any forward-chain drops are a strong signal
worth investigating. Output-chain drops surface processes attempting egress on
unpermitted ports.
Passive monitoring: the OT network monitor
Section titled “Passive monitoring: the OT network monitor”Enforcement is only half the picture. The edge also includes a passive OT
network monitor that observes rather than blocks. Each time the local
diagnostics API’s GET /api/network is called, it reads per-interface counters
from /proc/net/dev and lists established connections via ss
(connection-level metadata only, no deep packet inspection), and it flags three
classes of network anomaly. Collection runs on request; scheduled background
collection is planned.
| Anomaly | Trigger |
|---|---|
| Unexpected source | An established connection from an IP not in AllowedOtSources |
| Traffic spike | Combined rx+tx rate on the monitored interface exceeds TrafficSpikeThreshold (bytes/sec) |
| Unexpected port | An established connection where neither endpoint port is in ExpectedOtPorts |
It is configured under the NetworkMonitor section (values shown are the
defaults, with a per-site controller address):
{ "NetworkMonitor": { "MonitorInterface": "eth1", "CollectInterfaces": ["eth0", "eth1"], "AllowedOtSources": ["192.0.2.10"], "ExpectedOtPorts": [44818], "TrafficSpikeThreshold": 10000000 }}The monitor and the firewall status are both surfaced through the edge’s local
diagnostics API: GET /api/network returns interface metrics, active
connections and detected anomalies, and GET /api/firewall returns the firewall
status. By default the API listens on 127.0.0.1:8080, on the device only. To
reach it from a management network, set LocalApi:Address together with
LocalApi:TokenFile, and allow its port inbound on that interface; requests
from another host then need that token. Keep that address on a trusted
management network and off the OT side.
Configuration
Section titled “Configuration”The policy is declarative and binds from the edge configuration under the
Firewall section, from which the edge generates the nftables ruleset. Allow
rules are deployment-specific, so define ItRules and OtRules explicitly for
the ports, interfaces and controller addresses the site needs, as below. A
site’s controller addresses go in AllowedSources on the OT rules. Setting
Enabled to false turns the policy off.
{ "Firewall": { "Enabled": true, "ItInterface": "eth0", "OtInterface": "eth1", "BlockForwarding": true, "ItRules": { "InboundAllow": [ { "Port": 22, "Protocol": "tcp", "Description": "SSH" } ], "OutboundAllow": [ { "Port": 5001, "Protocol": "tcp", "Description": "gRPC upstream (site server edge port)" }, { "Port": 53, "Protocol": "tcp+udp", "Description": "DNS" }, { "Port": 123, "Protocol": "udp", "Description": "NTP" } ] }, "OtRules": { "InboundAllow": [ { "Port": 44818, "Protocol": "tcp+udp", "Description": "EtherNet/IP CIP", "AllowedSources": ["192.0.2.10"] } ], "OutboundAllow": [ { "Port": 44818, "Protocol": "tcp+udp", "Description": "EtherNet/IP CIP", "AllowedSources": ["192.0.2.10"] } ] } }}Each rule carries a Port, a Protocol (tcp, udp, or tcp+udp), a
Description (written as a comment line above the rule in the generated
ruleset), and optional AllowedSources. On OT rules, AllowedSources pins the
source address (inbound) or the destination address (outbound); IT rules match
by interface and port. An empty AllowedSources means any source or
destination, so on OT rules always pin the controller addresses. Where the
PLCnext is remote, add an OT OutboundAllow rule for its gRPC port, pinned to
its address.
Why segmentation matters here
Section titled “Why segmentation matters here”Network segmentation is a control-safety boundary, not just a confidentiality one. The edge sits beside controllers that drive physical equipment, so limiting who can talk to the edge, and what the edge can talk to, keeps the OT network’s exposure as small as possible.
Related
Section titled “Related”- VL3 Edge Setup — the target installation on a VL3
- Nvidia Orin Edge — the edge runtime on the workshop’s Orin host
- PLCnext Border Gateway — an accepted target topology, demonstrated in our workshop
- PLC Communication — EtherNet/IP CIP and gRPC drivers
- Edge overview — the edge runtime in context