# Exchanging data between 2 PLCs on different IP ranges — the OT-compliant approach

> Real-world case with 2 S7-1500F CPUs, SCALANCE SC, PN/PN Coupler and an industrial DMZ. How to link 2 sensitive infrastructures while respecting Purdue, IEC 62443 and NIS2.

- Source : https://industryhub.site/en/articles/echange-data-2-automates-ot
- Published : 2026-01-15
- Author : IndustryHub
- Language : English
- Keywords : siemens, s7-1500, scalance, profinet, opc-ua, segmentation, purdue, iec-62443

## The context

A large refinery operates two sensitive units:

- **Unit A — Atmospheric distillation**: driven by a **Siemens S7-1517F-3 PN/DP CPU** on subnet `10.20.10.0/24`. ATEX zone 1 atmosphere, SIL 2 on the process safety functions.
- **Unit B — Hydrocracker**: driven by a **Siemens S7-1518F-4 PN/DP CPU** on subnet `10.20.20.0/24`. ATEX zone 1 atmosphere, SIL 3 on some ESD loops.

The business requirement is simple: **Unit B must continuously read 12 process variables from Unit A** (cut temperatures, flow rates, column level) to optimize its own control. Acceptable latency: 200 ms. No round-trip command — flow **A → B only**.

The cybersecurity requirement is not: the two PLCs cannot sit on the same IP range. A compromise of A must **not** allow an attacker to pivot to B. Triton/Trisis (2017) demonstrated that, once inside the SIS of Unit A, an attacker could have disabled the explosion protections.

This is the typical situation faced by **tens of thousands of industrial sites** worldwide.

## What you must NOT do

Three classic anti-patterns that solve the business problem but break the OT posture.

| Anti-pattern | Why it "works" | Why it's dangerous |
|---|---|---|
| **Put both CPUs on the same VLAN** | "Simple, they talk directly over S7" | A VLAN is not real segmentation. A compromised PLC sees the other. And `Put/Get S7` requires enabling dangerous functions (force outputs, stop CPU). |
| **Route the traffic through the head-office IT firewall** | "The central firewall sees everything" | The IT firewall is not qualified for industrial protocols. It lets S7 through without inspection, and it becomes a single point of failure. Worse: a WAN outage cuts the control loop. |
| **Site-to-site IPsec VPN between the two units** | "Encrypted tunnel, logical isolation" | Once the tunnel is up, both networks see each other. Ransomware that encrypts A spreads to B in 30 seconds (cf. NotPetya / Maersk 2017). |

## The 3 OT-compliant options

```
┌────────────────────────────────────────────────────────────────────────────────┐
│  Option 1 — PN/PN COUPLER             ▶ Physical wiring, no IP routing         │
│                                                                                │
│    CPU A ── PROFINET ── ┤PN/PN├ ── PROFINET ── CPU B                          │
│                                                                                │
│    + Maximum security (galvanic, absolute isolation)                           │
│    + No IP/firewall configuration — Plug & Play                                │
│    + Certified for SIL if you pick the safety variant                          │
│    − Limited throughput (1,408 bytes / direction)                              │
│    − Direct physical cable → suited to adjacent units only                     │
│    − No native audit trail or logs                                             │
└────────────────────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────────────────────┐
│  Option 2 — OPC UA via SCALANCE SC + INDUSTRIAL DMZ       ◀ RECOMMENDED ▶     │
│                                                                                │
│  Unit A            ┌───────────── DMZ ───────────┐          Unit B             │
│  10.20.10.0/24     │  10.20.99.0/24              │          10.20.20.0/24     │
│                    │                              │                            │
│  CPU A ───SC1──┤ FW1 │── OPC UA proxy ───┤ FW2 │── SC2 ─── CPU B              │
│   (OPC UA          │                              │            (OPC UA         │
│   server)          │                              │             client)        │
│                                                                                │
│    + End-to-end OPC UA Sign + Encrypt encryption                               │
│    + Mutual authentication via X.509 certificates                              │
│    + Fine-grained firewall rules (one port, one IP, one certificate)           │
│    + Full audit (who, when, which variables)                                   │
│    + Scalable: a 3rd unit can be added without touching A or B                 │
│    − Longer configuration (certificates, rules)                                │
└────────────────────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────────────────────┐
│  Option 3 — UNIDIRECTIONAL DATA DIODE                                          │
│                                                                                │
│    CPU A ──TX── ▶▶▶ DIODE ▶▶▶ ──RX── CPU B   (optical hardware)               │
│                                                                                │
│    + Ultimate security: feedback physically impossible                         │
│    + Ideal for nuclear, defense, SIL 4 functional safety                       │
│    − High cost (€10–50k per diode)                                            │
│    − No handshake — needs a loss-tolerant protocol                             │
│    − No acknowledgment → hard to debug                                          │
└────────────────────────────────────────────────────────────────────────────────┘
```

For our case (continuous A → B flow, 12 variables, 200 ms latency, no nuclear), **option 2 is the right trade-off**: robust, auditable, scalable. That's what we deploy.

## Selected architecture — OPC UA + industrial DMZ

```
═════════════════════════════════════════════════════════════════════════════════
  UNIT A                     INDUSTRIAL DMZ                         UNIT B
  10.20.10.0/24 (VLAN 10)    10.20.99.0/24 (VLAN 99)                10.20.20.0/24 (VLAN 20)
═════════════════════════════════════════════════════════════════════════════════

  CPU S7-1517F-3 PN/DP       IPC547G — OPC UA proxy                 CPU S7-1518F-4 PN/DP
  10.20.10.10                10.20.99.10                            10.20.20.10
  OPC UA Server,             SIMATIC OPC UA                         OPC UA Client
  port 4840                  Aggregating Server                     → 10.20.99.10
       │                            │                                      │
       │ PROFINET                   │ Ethernet                             │ PROFINET
       │                            │                                      │
  SCALANCE XC208             SCALANCE XC208                         SCALANCE XC208
  10.20.10.20                10.20.99.20                            10.20.20.20
       │                            │                                      │
       │ Ethernet uplink            │                                      │ Ethernet uplink
       │ (fiber)                    │ (internal DMZ)                       │ (fiber)
       │                            │                                      │
  ┌────┴───────────┐                │                              ┌───────┴─────────┐
  │ SCALANCE       │                │                              │ SCALANCE        │
  │   SC632-2C     │                │                              │   SC632-2C      │
  │      FW1       │ ─.99.1 ────────┼─────────────── .99.2─        │      FW2        │
  │ eth0 : .10.1   │                │                              │ eth0 : .99.2    │
  │ eth1 : .99.1   │                                               │ eth1 : .20.1    │
  └────────────────┘                                               └─────────────────┘

═════════════════════════════════════════════════════════════════════════════════
  Allow FW1 : Proxy 10.20.99.10 ──► CPU A 10.20.10.10   tcp/4840  (OPC UA Sign+Encrypt)
  Allow FW2 : CPU B 10.20.20.10 ──► Proxy 10.20.99.10   tcp/4840  (OPC UA Sign+Encrypt)
  All other traffic → DENY + SIEM log
═════════════════════════════════════════════════════════════════════════════════
```

**Hardware components used:**

| Reference | Role | Quantity |
|---|---|---|
| `6ES7517-3FP00-0AB0` — S7-1517F-3 PN/DP | Unit A CPU (SIL 2) | 1 |
| `6ES7518-4FP00-0AB0` — S7-1518F-4 PN/DP | Unit B CPU (SIL 3) | 1 |
| `6GK5208-0BA00-2AC2` — SCALANCE XC208 | Managed industrial switch (1× per zone: A, DMZ, B) | 3 |
| `6GK5632-2GS00-2AC2` — SCALANCE SC632-2C | Industrial L3 firewall / OPC UA DPI (FW1 between A↔DMZ, FW2 between DMZ↔B) | 2 |
| `6AG4112-2HH40-1AS2` — IPC547G | Industrial PC for the OPC UA proxy in the DMZ | 1 |

**Architectural principles to keep in mind:**

1. **The industrial DMZ (10.20.99.0/24) is a separate subnet**, neither A nor B. It is what hosts the OPC UA proxy — not A, not B.
2. **No direct A ↔ B flow**. All communication goes through the proxy, and each firewall allows only **one** unidirectional flow.
3. **The proxy aggregates**: it reads the 12 variables from A and exposes them to B. If B makes an abnormal request, the proxy refuses — it does not "tunnel" through to A.
4. **Two separate firewalls in series** — FW1 between Unit A and the DMZ, FW2 between the DMZ and Unit B. This is **network defense in depth**: compromising one firewall is not enough to reach the other unit.
5. **PROFINET stays inside each unit** (PLC ↔ switch). PROFINET RT (layer 2) NEVER crosses an L3 firewall — it is OPC UA encapsulated over TCP/IP that bridges the zones.

## Addressing plan and VLANs

| Subnet | VLAN | Use | Allowed hosts |
|---|---|---|---|
| `10.20.10.0/24` | 10 | OT Unit A (PROFINET, S7) | CPU A, HMI A, distributed sensors A |
| `10.20.20.0/24` | 20 | OT Unit B (PROFINET, S7) | CPU B, HMI B, distributed sensors B |
| `10.20.99.0/24` | 99 | Industrial DMZ | OPC UA proxy, jump server, NDR |
| `10.20.100.0/24` | 100 | Switch/firewall management | Admin console only |

The VLANs are configured on the SCALANCE XC208 switches with a **trunk** towards the SCALANCE SC632-2C. No inter-VLAN routing at the switch level — the firewall decides.

## Step-by-step configuration

### Step 1 — Enable the OPC UA Server on CPU A (TIA Portal V19+)

In the properties of the S7-1517F CPU:

1. **Protection & Security → Connection mechanisms**: uncheck `Permit access with PUT/GET communication`. (We disable legacy S7 — we will go ONLY through OPC UA.)
2. **OPC UA → Server → General**: enable `Activate OPC UA server`. Port `4840` (standard).
3. **OPC UA → Server → Security**:
   - `Security policy`: **`Basic256Sha256 — Sign and Encrypt`** only. Uncheck all the `None` and `Sign only` policies.
   - `User authentication`: uncheck `Allow guest access`. Check `Allow authentication via user name and password` + enable the user list.
   - Create a dedicated user, e.g. `opcua-proxy-readonly` with a strong password stored in a vault (Vault, CyberArk).
4. **OPC UA → Server → Server interfaces**: create an interface that exposes ONLY the 12 required variables (and nothing else). Create a custom object type containing those 12 variables.

The **Allow-list** principle: publish only what is explicitly necessary. If you publish the entire CPU memory, the proxy gets far too much visibility.

### Step 2 — Install the proxy's X.509 certificate on CPU A

```text
# Generate the CSR on CPU A (TIA Portal)
TIA Portal → CPU A → Certificate Manager →
  Generate certificate signing request (CSR) →
  Subject: CN=cpu-A-opcua, O=Raffinerie, C=FR

# The CSR is signed by the internal PKI (Microsoft AD CS, HashiCorp Vault,
# or Siemens SIMATIC Logon Service Center).

# Import the signed certificate onto CPU A and the proxy's certificate
# into the CPU's "Trusted certificates" store.
```

**Always mutual certificates.** The proxy authenticates the CPU, the CPU authenticates the proxy. Annual renewal automated via the PKI.

### Step 3 — Configure the OPC UA proxy (Siemens SIMATIC OPC UA aggregating server)

On the IPC547G in the DMZ, install the **SIMATIC OPC UA Aggregating Server** (equivalent alternatives: Kepware KEPServerEX, Matrikon UA Tunneller).

```yaml
# Aggregator configuration (simplified excerpt)
endpoints:
  # Endpoint exposed on the B side (interface 10.20.99.10)
  - name: server-for-unit-b
    url: opc.tcp://10.20.99.10:4840
    security: Basic256Sha256
    auth: certificate-only
    allowed_clients:
      - cn=cpu-B-opcua,o=Raffinerie  # ONLY B's certificate is accepted

  # Client towards CPU A (egress 10.20.99.10 → 10.20.10.10)
upstream:
  - name: cpu-a
    url: opc.tcp://10.20.10.10:4840
    security: Basic256Sha256
    user: opcua-proxy-readonly
    password_vault: vault://kv/opc-ua/cpu-a

  # Mapping: what is read on the A side is exposed on the B side
  variables:
    - source: "ns=3;s=UnitA.T_Coupe1"
      target: "Variables/TCoupe1"
      access: read-only
    - source: "ns=3;s=UnitA.T_Coupe2"
      target: "Variables/TCoupe2"
      access: read-only
    # ... 10 more
```

Three key points:
- **`read-only`** on every exposed variable. Even if B is compromised, it cannot write into A.
- **certificate-only authentication**: no password to steal on the B side.
- **Logging enabled**: every session, every read, is logged to the SIEM (via syslog to Splunk / Wazuh).

### Step 4 — Configure the two SCALANCE SC632-2C

The SCALANCE SC is an industrial L3 firewall that speaks OPC UA natively (stateful protocol inspection). We deploy **two separate firewalls in series** — a single round-trip per flow, a single allow rule per firewall.

```text
# ═══════════════════════════════════════════════════════════════
# FW1 — between Unit A (eth0 = 10.20.10.1) and DMZ (eth1 = 10.20.99.1)
# ═══════════════════════════════════════════════════════════════
# Only allowed flow: DMZ proxy ──► CPU A (OPC UA read)
allow  src 10.20.99.10  dst 10.20.10.10  tcp/4840  proto OPC-UA-secure
allow  src 10.20.10.10  dst 10.20.99.10  established              # responses
deny   src any          dst any          log

# ═══════════════════════════════════════════════════════════════
# FW2 — between DMZ (eth0 = 10.20.99.2) and Unit B (eth1 = 10.20.20.1)
# ═══════════════════════════════════════════════════════════════
# Only allowed flow: CPU B ──► DMZ proxy (OPC UA client session)
allow  src 10.20.20.10  dst 10.20.99.10  tcp/4840  proto OPC-UA-secure
allow  src 10.20.99.10  dst 10.20.20.10  established              # responses
deny   src any          dst any          log
```

**Two effective allow rules** (one per firewall), everything else is denied and logged to the SIEM. This is the principle of **network least privilege**.

**Immediate validation tests:**
- From any workstation in Unit A, `ping 10.20.20.10` (CPU B) → **timeout**: FW1 blocks any egress not explicitly authorized. ✓
- From any workstation in Unit B, `ping 10.20.10.10` (CPU A) → **timeout**: double block by FW2 then FW1. ✓
- From the DMZ proxy, `ping 10.20.10.10` → **OK**: the FW1 rule allows it.
- From the DMZ proxy, `ping 10.20.20.10` → **timeout**: the proxy NEVER needs to initiate towards B (it is B that calls the proxy). FW2 blocks.

If any of these 4 tests does not give the expected result, there is a hole in the deny rule — to be fixed BEFORE going to production.

### Step 5 — Enable OPC UA Deep Packet Inspection

The SCALANCE SC offers a DPI option that inspects the OPC UA content on top of the TCP header. Benefits:

- Rejects `Write` requests even when the port and IP are authorized
- Rejects requests to unauthorized nodes (NodeID allow-list)
- Detects massive browsing attempts (attacker enumeration)

```text
# OPC UA DPI policy applied on the SC632
methods_allowed: [Read, Browse, TranslateBrowsePath]
methods_denied:  [Write, Call, AddNodes, DeleteNodes]
namespace_allow: ["ns=3;s=UnitA.*"]   # only our allow-list
rate_limit:      "100 req / s"        # brute-force browsing detection
```

### Step 6 — Enable the NDR / OT-IDS probe

A Dragos, Nozomi or Claroty CTD is connected on a mirror port of the SCALANCE XC208 on the DMZ side. It:

- Builds the automatic inventory (CPU A, CPU B, proxy)
- Learns the OPC UA traffic baseline over 7 days
- Alerts on any deviation: new client, new variable read, new temporal pattern

The OT IDS is what detects a Triton in time. Indispensable under NIS2 (article 21 § 2 b).

### Step 7 — Test and validate

| Test | Method | Expected result |
|---|---|---|
| Read a variable from B | OPC UA Client block in CPU B → reads `UnitA.T_Coupe1` | Correct value, latency < 200 ms |
| Direct ping CPU B → CPU A | `ping 10.20.10.10` from an IPC in VLAN 20 | **Timeout** (denied by firewall) |
| Write attempt from B | OPC UA Write call to a variable in A | **BadUserAccessDenied** |
| Massive browsing attempt | Script that browses 10,000 nodes in 1 s | DPI block beyond 100 req/s, SIEM alert |
| Fake client certificate | Connection with a non-imported self-signed cert | **BadCertificateUntrusted** |

## Cyber checks to perform afterwards

- [ ] **IDS inventory**: CPU A, CPU B and the proxy appear correctly. No unexpected device.
- [ ] **Centralized OPC UA logs**: 100% of sessions are seen on the SIEM side, with timestamp and identity.
- [ ] **Proxy outage test**: if the proxy goes down, B keeps running on its last known value (fallback logic in the CPU B program).
- [ ] **Certificate rotation**: a PKI cron renews the certificates 30 days before expiry.
- [ ] **Backup**: the IPC547G proxy image is backed up air-gapped quarterly.
- [ ] **Written incident plan**: if A is compromised, who isolates the proxy? Procedure ≤ 15 min.
- [ ] **Vendor audit**: Siemens maintenance goes through a PAM jump server (Wallix), not direct access to the proxy.

## Classic pitfalls

1. **"Just for this test"** — you add an `allow any any` firewall rule for 5 minutes to debug. You forget it. It stays for 3 years. Always open a ticket and remove the rule after debugging.
2. **Self-signed certificate** on the proxy in production. It works, but the warning is ignored by operators who end up clicking on anything. Always a PKI-signed certificate.
3. **Shared `opcua-proxy-readonly` account** across all proxies. If one proxy is compromised, the password allows reading the other CPUs. One account per `(proxy, CPU)` pair.
4. **No fallback logic on the B side**: if the proxy goes down, B's control loop receives `Bad` values and trips to safety — an unplanned shutdown. Always implement `if quality != Good then use_last_known_value`.
5. **DMZ "for now"** on the same VLAN as IT. The industrial DMZ is a DEDICATED zone — neither IT nor OT. If you share it with IT, NotPetya can jump into it.
6. **Routed PROFINET**: NEVER route PROFINET RT between VLANs. L2 multicast does not survive. PROFINET stays internal to each unit, OPC UA does the bridging.

## Going further

- The [OT Cybersecurity](/en/technologies/cybersecurity-ot) hub covers the Purdue model and the multi-site interconnection section in detail.
- The [PLC](/en/technologies/plc) hub details the Siemens S7-1500F CPUs and their OPC UA capabilities.
- The [Industrial networks](/en/technologies/fieldbuses) hub compares PROFINET, OPC UA and the other protocols.
- The [IEC 62443](/en/standards/iec-62443) page gives the full normative framework for this architecture.

**One last thing:** what we just did looks like over-engineering the first time you see it. Four firewall interfaces, a proxy, certificates, DPI… Compare it to the cost of a Triton on your hydrocracker. The conversation is quick.
