Configuring Secure OPC UA Communication: SIMATIC IOT2040 to S7-1500
Engineers integrating a SIMATIC IOT2040 (or the successor IOT2050) as an OPC UA client against a SIMATIC S7-1500 OPC UA server frequently encounter connection failures when transitioning from None to Basic128Rsa15 security. The failure almost always traces back to certificate trust, endpoint URL binding, or a deprecated security policy that the S7-1500 firmware 2.0 server still offers. This reference walks through the complete commissioning path, from TIA Portal server activation through Linux certificate installation on the IOT device and final Node-RED flow validation.
1. Problem Description
A typical reported failure pattern looks like this:
- The SIMATIC IOT2040 runs the
node-red-contrib-opcuapackage against a S7-1500 (firmware V2.0) configured as an OPC UA server. - With No Security enabled on the server endpoint, the client successfully opens a session and subscribes to monitored items.
- When the user enables Basic128Rsa15 - Sign or Basic128Rsa15 - SignAndEncrypt in TIA Portal, supplies a username/password identity, and mirrors the same policy plus credentials in the Node-RED OPC-UA client node, the subscribe operation fails with a service-fault error and the connection drops.
- Exporting the PLC server certificate and copying it onto the IOT2040 does not by itself resolve the issue because the destination directory and the trust-chain handling on the Linux image are not obvious.
The same client that connects fine with No Security will not establish a secure channel even when the policy and credentials match. Root cause analysis (Section 3) shows that three independent conditions must all be true before the secure subscribe succeeds: certificate trust chain, endpoint URL hostname match, and client/server security-policy negotiation.
2. OPC UA Security Architecture Overview
OPC UA security rests on three orthogonal layers, all of which must be correctly configured or the connection fails with Bad_SecurityChecksFailed, Bad_CertificateUntrusted, or Bad_CommunicationError:
- Transport layer — UA TCP binary protocol over a single TCP connection (default port 4840).
-
SecureChannel layer — ASymmetric/RSA key exchange signs or signs-and-encrypts every message using a SecurityPolicy. The legacy
Basic128Rsa15uses RSA-1536 + SHA-1 and is deprecated in OPC UA 1.04 but still the most common policy on S7-1500 firmware 2.0.x. NewerBasic256Sha256andAes128Sha256RsaOaepare required on firmware V2.6 and later. - Application layer — ActivateSession exchanges user identity tokens (anonymous, username/password, certificate, issued token) and applies the user authorization configured on the server.
Per the OPC Foundation guidance on secure connectivity, every secure endpoint requires a PKI where the client trusts the server certificate and the server trusts the client certificate. A unidirectional trust is not sufficient; OPC UA performs mutual X.509 authentication during OpenSecureChannel.
OpenSecureChannel request with Bad_CertificateUntrusted even when the policy, credentials, and endpoint URL are otherwise perfect.
3. Root Cause Analysis
Four root causes account for >90% of the secure-connection failures reported between Node-RED OPC UA clients and S7-1500 servers:
3.1 Untrusted Server Certificate on the Client
The Node-RED OPC UA client uses the bundled node-opcua library. That library stores trusted peer certificates in the directory designated by the NODEOPCUA_CA_PATH environment variable or the user-specific PKI folder (typically ~/.node-opcua/pki/rejected on first contact). If the S7-1500 server certificate is in rejected/ rather than trusted/, the client refuses to consume the Hello response and aborts.
3.2 Untrusted Client Certificate on the Server
TIA Portal places every incoming client certificate into the Rejected certificates tab of the OPC UA server configuration. Until the engineer manually moves that certificate to Trusted certificates, the S7-1500 closes the channel. On firmware V2.0, this move must be performed within TIA Portal; later firmware versions offer a runtime web interface.
3.3 Endpoint URL Hostname Mismatch
The S7-1500 server certificate is generated for the PLC's configured OPC UA server name. If the Node-RED client connects to opc.tcp://192.168.1.10:4840 but the certificate was issued for PLC-S71500, the URL match check fails with Bad_CertificateHostNameInvalid. The hostname inside the certificate must equal the hostname portion of the endpoint URL the client uses.
3.4 Disabled Server Endpoint With No Security Allowed
If No Security remains enabled alongside Basic128Rsa15, the client may negotiate the weakest policy available. The connection can then succeed in plaintext regardless of the policy chosen in Node-RED, masking the certificate fault. This explains the symptom that disabling No Security appears to change nothing — the certificate handling was always broken.
4. Prerequisites
| Component | Requirement |
|---|---|
| SIMATIC IOT2040 | Example Image V2.4 or later; Node.js 10.x; Node-RED preinstalled |
| Node-RED OPC UA package |
node-red-contrib-opcua v0.2.16 or newer |
| SIMATIC S7-1500 CPU | Firmware V2.0 or later with OPC UA server activated |
| TIA Portal | V15.1 or later, matching the CPU firmware generation |
| Network | TCP/4840 reachable from IOT2040 to PLC; no L4 firewall blocking the binary protocol |
| User identity | Username/password defined on the PLC OPC UA server with at least read authorization for the target tags |
| OpenSSL on IOT2040 | Pre-installed in the example image; verify with openssl version
|
5. Step-by-Step Configuration
Step 1 — Activate the OPC UA Server on the S7-1500 in TIA Portal
- In the device view, open Properties → OPC UA → Server.
- Check Activate OPC UA server.
- Set Server name to a fully qualified identifier such as
urn:siemens:simatic:s71500:plc1or a DNS name. This string becomes the certificate subject and the endpoint URL. - Under Security policies, disable No Security entirely. Enable only Basic128Rsa15 - Sign and Basic128Rsa15 - SignAndEncrypt for the initial pilot.
- Under User authentication, enable Username and password. Add a user (e.g.
opcuser) and assign read/write rights on the data blocks that will be exposed. - Compile and download to the PLC.
Step 2 — Export the Server Certificate
- In TIA Portal, go to OPC UA → Certificates → Server certificates.
- Right-click the active server certificate and choose Export certificate.
- Save it in DER (binary) format as
plc_server.der. Convert to PEM with OpenSSL if the IOT image requires PEM:
openssl x509 -inform DER -in plc_server.der -out plc_server.pem
Step 3 — Place the Certificate in the IOT2040 Trust Store
The Node-RED OPC UA client uses node-opcua's PKI. The default directory on the example image is:
/home/root/.node-opcua/pki/trusted/certs/
Create the directory tree if it does not exist and copy the PEM file:
mkdir -p /home/root/.node-opcua/pki/trusted/certs
cp plc_server.pem /home/root/.node-opcua/pki/trusted/certs/
chmod 644 /home/root/.node-opcua/pki/trusted/certs/plc_server.pem
If you operate Node-RED as a different user, place the file under that user's home directory. Some example images run Node-RED under node-red — verify with ps aux | grep node-red.
Step 4 — Generate or Locate the Client ApplicationInstanceCertificate
node-opcua creates a self-signed certificate at first start in:
/home/root/.node-opcua/pki/own/certs/client_selfsigned_cert.pem
If the directory is empty, run any OPC UA client configuration once with security disabled to force generation, then export client_selfsigned_cert.der for upload to TIA Portal.
Step 5 — Trust the Client Certificate on the S7-1500
- Convert the client PEM to DER:
openssl x509 -in client_selfsigned_cert.pem -outform der -out client.der
- In TIA Portal, go to OPC UA → Certificates → Trusted client certificates.
- Import
client.der. Assign the Read and (if needed) Write rights. - Re-download the project to the PLC.
Step 6 — Configure the Node-RED OPC UA Client Node
Open the OPC-UA Client node properties:
| Field | Value |
|---|---|
| Endpoint |
opc.tcp://<PLC-IP>:4840 — must match the server-name subject |
| Security Policy | Basic128Rsa15 |
| Security Mode | SignAndEncrypt |
| User Identity | UserName |
| Username | opcuser |
| Password | matches TIA Portal |
| Certificate (own) | leave default (auto-generated PEM in ~/.node-opcua/pki/own) |
Step 7 — Deploy and Verify
- Deploy the flow in Node-RED.
- Watch the debug pane for the connected status event.
- Trigger a
subscribeaction. A successful subscribe logssubscriptionIdand monitored-item IDs.
6. Verification Procedure
Use the following checklist after the secure flow is deployed. Each item has a positive and a negative signal so a field engineer can quickly isolate regressions.
| Check | Command / Observation | Pass criterion |
|---|---|---|
| TCP reachability | nc -zv <PLC-IP> 4840 |
succeeded! |
| Certificate trusted on IOT2040 | ls ~/.node-opcua/pki/trusted/certs/ |
plc_server.pem present |
| Certificate trusted on S7-1500 | TIA Portal Trusted client certificates | client certificate listed |
| Node-RED log | tail node-red.log
|
no Bad_CertificateUntrusted lines |
| Read sample tag | inject read payload from inject node |
returns current value |
| Subscribe sample tag |
opcua-item node with interval 1000 ms |
payload arrives every second |
7. Troubleshooting Matrix
| Service result | Hex | Likely cause | Corrective action |
|---|---|---|---|
Bad_SecurityChecksFailed |
0x80130000 | Certificate signature invalid or expired | Regenerate certificate, ensure system clock within ±5 min |
Bad_CertificateUntrusted |
0x801A0000 | Peer cert not in trust list | Copy to ~/.node-opcua/pki/trusted/certs or TIA Portal trusted list |
Bad_CertificateHostNameInvalid |
0x80160000 | URL hostname does not match cert subject | Use the exact hostname from the cert in the endpoint URL |
Bad_CertificateTimeInvalid |
0x80150000 | PLC or IOT clock outside validity window | Enable NTP on both devices |
Bad_UserAccessDenied |
0x801F0000 | User lacks authorization for the tag | Adjust TIA Portal OPC UA user rights |
Bad_IdentityTokenRejected |
0x80200000 | Username/password mismatch | Recreate the user in TIA Portal |
Bad_SecurityPolicyRejected |
0x80240000 | Policy not enabled on server | Enable Basic128Rsa15 on the endpoint |
Bad_CommunicationError |
0x80050000 | TCP drop, firewall, or wrong port | Verify port 4840 and route |
8. node-red-contrib-opcua v0.2.16 Instability
The v0.2.16 package line is known to:
- Crash the Node-RED editor when flows are published with secure endpoints.
- Require a manual
node-red-restartafter a secure channel is dropped, since the OpenSecureChannel state is not recovered automatically. - Leak handles when many short-lived subscriptions are created.
Mitigation:
- Upgrade to v0.2.20 or later where these regressions are addressed.
- Configure systemd to auto-restart Node-RED after a crash: edit
/etc/systemd/system/node-red.serviceand addRestart=on-failure. - Limit the number of simultaneous monitored items per subscription to 100 or fewer.
- Wrap the opcua-client node in a status-driven
catchflow that re-injects a reconnect trigger on everyconnectionStatusevent of type disconnected.
9. Migrating from IOT2040 to IOT2050
If the pilot moves to the SIMATIC IOT2050 (successor to IOT2040), the PKI paths and default user change. The home directory becomes /home/iot2050 by default, and Node-RED runs as the iot2050 user. Adjust the certificate copy command accordingly:
mkdir -p /home/iot2050/.node-opcua/pki/trusted/certs
cp plc_server.pem /home/iot2050/.node-opcua/pki/trusted/certs/
The firmware V2.6 S7-1500 server additionally offers Basic256Sha256. Selecting it from the Node-RED side requires the same trust chain but uses SHA-256 instead of SHA-1, eliminating the deprecated Basic128Rsa15 exposure flagged by modern vulnerability scanners.
10. Architectural Diagram
11. Performance and Sizing Notes
For typical S7-1500 deployments, the OPC UA server can sustain the following on a firmware V2.0 CPU without session-throttling:
- Up to 40 concurrent client sessions.
- Up to 2,000 monitored items per session, 100,000 total per CPU.
- Minimum publishing interval of 100 ms; 250 ms is the practical floor for sign-and-encrypt on an IOT2040.
Sign-and-encrypt roughly doubles CPU load on the S7-1500 compared with sign-only because every message body is encrypted in addition to being signed. For pure telemetry uploads with no write-back, prefer Sign to keep CPU headroom available for the PLC scan.
12. FAQ
Where exactly must the S7-1500 server certificate be copied on the IOT2040?
Place the PEM-encoded server certificate in /home/root/.node-opcua/pki/trusted/certs/ (or /home/iot2050/.node-opcua/pki/trusted/certs/ on the IOT2050). The node-opcua library reads from this directory when the client builds the secure channel. Files in rejected/ are treated as untrusted and cause Bad_CertificateUntrusted.
Why does the connection fail even after I disable "No Security" on the PLC?
Disabling No Security removes the plaintext fallback, but the failure is almost always certificate-trust related, not policy related. Export the client certificate from ~/.node-opcua/pki/own/certs/, convert it to DER, and import it under Trusted client certificates in TIA Portal. Re-download the project so the PLC runtime reloads the trust list.
Which client certificate does Node-RED actually use?
node-opcua generates a self-signed ApplicationInstanceCertificate at first start, stored as client_selfsigned_cert.pem in ~/.node-opcua/pki/own/certs/. This is the file the S7-1500 must trust. If you have rotated it, export the most recent one; do not upload an older file from a backup.
Can I use Basic256Sha256 instead of Basic128Rsa15?
Yes, on S7-1500 firmware V2.6 and later, Basic256Sha256 is available and recommended because it removes the deprecated SHA-1 dependency. The trust-chain procedure is identical; only the policy selection in both TIA Portal and the Node-RED OPC UA client changes.
The Node-RED editor crashes when I publish a secure flow — is this a bug?
node-red-contrib-opcua v0.2.16 has a known regression that crashes the editor when flows containing secure endpoints are deployed. Upgrade to v0.2.20 or later, and enable systemd auto-restart with Restart=on-failure so a crashed runtime recovers without manual intervention.
How do I confirm the secure channel is actually encrypted and not downgraded?
Run Wireshark on a mirrored port between the IOT2040 and the PLC, decode as OPC UA, and inspect the OpenSecureChannelRequest. The SecurityPolicyUri must read http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15 and the SecurityMode must equal SignAndEncrypt (value 3). Anything else indicates a downgrade.
Does No Security left enabled break Basic128Rsa15?
It does not break the channel, but it allows the client to silently negotiate plaintext. The symptom is that Node-RED appears to honor the configured policy yet the Wireshark capture shows unencrypted payloads. Always disable No Security on the S7-1500 endpoint when commissioning secure communication to remove this ambiguity.