PLC4X (Proxy)

The plc4x protocol is PLC4X’s own proxy protocol: one PLC4X instance (typically the PLC4X Server) accepts connections from a plc4x client and relays reads and writes on to a real PLC using any other PLC4X driver (s7, modbus, ads, opcua, simulated, …​). It is useful when a PLC is only reachable from the machine running the server - for example behind a firewall or on an isolated OT network - while clients live elsewhere. Authentication is mandatory and the default transport is TLS.

Supported Operations

Operation What it does here

read

Reads a tag from the remote PLC via the proxy.

write

Writes a tag on the remote PLC via the proxy.

Subscribing and browsing are not supported: the driver only overrides read and write.

Connection String

The plc4x protocol connection has the following format:

plc4x:{transport}://{host}:{port}?remote-connection-string={url-encoded-connection-string}&username={user}&password={pass}

{transport} is tls (the default, and used when no transport is given) or tcp (plaintext, an explicit opt-in for trusted networks or testing). remote-connection-string is the URL-encoded connection string the proxy should open against the actual PLC. username and password are mandatory.

Example connection strings, TLS (default) and plaintext TCP:

plc4x:tls://host:59837?remote-connection-string=s7&username=op&password=hunter2&tls.verify=false
plc4x://host?remote-connection-string=s7%3A%2F%2Foperator%3Ahunter2%40plc%3A102

Connection String Options

Name

Type

Default Value

Required

Description

Name

PLC4X (Proxy-Protocol)

Code

plc4x

Maven Dependency

<dependency>
  <groupId>org.apache.plc4x</groupId>
  <artifactId>plc4j-driver-plc4x</artifactId>
  <version>1.1.0</version>
</dependency>

Default Transport

tls

Supported Transports

  • tls

  • tcp

Config options:

remote-connection-string

STRING

URL-Encoded connection string to use on the proxy side to reach the given PLC.

request-timeout-ms

INT

5000

Default timeout for all types of requests.

username

STRING

Username for authenticating against the PLC4X proxy server. Authentication is mandatory.

password

STRING

Password for authenticating against the PLC4X proxy server. Authentication is mandatory.

Transport config options:

tls

tls.verify

BOOLEAN

true

tls.ignore-common-name

BOOLEAN

false

Accept a server certificate issued for a different host than the one connected to

tls.trust-store

STRING

Key store of certificates to trust, instead of the JVM’s public authorities

tls.trust-store-password

STRING

Password of the trust store named by tls.trust-store

tls.trust-store-type

STRING

PKCS12

Type of the trust store named by tls.trust-store

tls.version

STRING

TLS protocol version (e.g., 'TLSv1.2', 'TLSv1.3'). If not set, uses TLS 1.3 with fallback to TLS 1.2.

tls.keystore

STRING

Path to keystore (PKCS12/JKS) containing the client certificate and private key for mutual TLS.

tls.keystore-password

STRING

Password for the client keystore.

tls.keystore-type

STRING

Keystore type (e.g., 'PKCS12', 'JKS'). Defaults to PKCS12.

tls.log-session-keys

BOOLEAN

false

Log TLS session keys to the audit log in SSLKEYLOGFILE format for Wireshark decryption.

tls.connect-timeout-ms

INT

5000

Connection timeout in milliseconds.

tls.read-timeout-ms

INT

0

Socket read timeout in milliseconds. 0 means no timeout.

tls.write-timeout-ms

INT

0

Socket write timeout in milliseconds. 0 means no timeout.

tls.no-delay

BOOLEAN

true

Enable TCP_NODELAY (disable Nagle’s algorithm).

tls.keep-alive

BOOLEAN

false

Enable SO_KEEPALIVE.

tls.send-buffer-size

INT

81920

Send buffer size in bytes. 0 uses system default.

tls.receive-buffer-size

INT

81920

Receive buffer size in bytes. 0 uses system default.

tls.local-address

STRING

Local address to bind to (optional). If not set, uses default.

tls.local-port

INT

0

Local port to bind to (optional). 0 uses ephemeral port.

tcp

tcp.connect-timeout-ms

INT

5000

Connection timeout in milliseconds.

tcp.read-timeout-ms

INT

0

Socket read timeout in milliseconds. 0 means no timeout.

tcp.write-timeout-ms

INT

0

Socket write timeout in milliseconds. 0 means no timeout.

tcp.no-delay

BOOLEAN

true

Enable TCP_NODELAY (disable Nagle’s algorithm).

tcp.keep-alive

BOOLEAN

false

Enable SO_KEEPALIVE.

tcp.send-buffer-size

INT

81920

Send buffer size in bytes. 0 uses system default.

tcp.receive-buffer-size

INT

81920

Receive buffer size in bytes. 0 uses system default.

tcp.local-address

STRING

Local address to bind to (optional). If not set, uses default.

tcp.local-port

INT

0

Local port to bind to (optional). 0 uses ephemeral port.

Tag Addresses

Addressing is implemented in C and Java. See the protocol support matrix for what each implementation does.

General Format

A plc4x tag address names a tag on the remote connection that the proxy opened - not a tag on the proxy connection itself. The driver does not parse or validate the address; it splits off the trailing :{type} suffix and passes the remainder straight through to the remote connection, so the address must follow the tag syntax of whichever driver the remote-connection-string points at:

{remote-tag-address}:{data-type}

For example, with a remote connection to a simulated PLC, a tag address is a simulated-driver address followed by the PLC4X value type:

RANDOM/foo:BOOL
STDOUT/foo:INT

Data Types

The trailing :{data-type} suffix is one of the standard PLC4X value types, for example BOOL, BYTE, WORD, DWORD, USINT, UINT, UDINT, ULINT, SINT, INT, DINT, LINT, REAL, LREAL, CHAR or WCHAR.

Examples

Reading from and writing to a remote simulated connection:

RANDOM/foo:BOOL
RANDOM/foo:DWORD
RANDOM/foo:LREAL
STDOUT/foo:BOOL
STDOUT/foo:UDINT
STDOUT/foo:WCHAR