the OPC UA server (`serverOptions`, `certificateStores`)
These keys shape the OPC UA server itself: the port and address it listens on, the endpoint URLs it advertises, its security, its limits and its certificates. They do not change how devices are read.
port: 4840 # the TCP port the server listens on
serverOptions:
buildInfo:
productName: Line 3 gateway
allowAnonymous: false
securityModes: [SignAndEncrypt]
advertisedEndpoints: opc.tcp://edge.plant.local:14840
certificateStores:
applicationPKI:
rootFolder: /pkis/ApplicationPKI
Every key is optional. The editor and the VS Code extension complete and
validate them as you type, and show the rules below that a schema cannot
express (the SRV-E codes).
Reaching the server from outside: advertised endpoints
A client first asks the server for its endpoints (GetEndpoints), then connects to the URL it gets back. By default that URL uses the machine's own host name and the port the server listens on. Behind Docker port mapping, NAT or a proxy, that is not the address clients can reach.
| Key | Use it when |
|---|---|
hostname | the machine's own name is wrong, but the port is right |
alternateHostname | clients use extra names or IP addresses, on the same port |
advertisedEndpoints | clients use a different host and/or port |
port: 4840
serverOptions:
advertisedEndpoints:
# inherits the security settings of the main endpoint
- opc.tcp://edge.plant.local:14840
# its own security settings; omitted fields inherit
- url: opc.tcp://gateway.example.com:4840
securityModes: [SignAndEncrypt]
securityPolicies: [Basic256Sha256]
allowAnonymous: false
The server still listens on port; advertised URLs are only what it tells
clients. Their host names are added to the server's self-signed certificate
when it is created. A certificate that already exists is not regenerated, so
strict clients may reject the new name until it is.
In the Docker stack, set OMNI_EDGE_ADVERTISED_ENDPOINTS in .env
instead of editing the configuration (comma-separated):
OMNI_EDGE_PORT_4840=14840
OMNI_EDGE_ADVERTISED_ENDPOINTS=opc.tcp://edge.plant.local:14840
Resource paths
An endpoint URL may end in a path: opc.tcp://host:4840/UA/Line3. Set it
for every endpoint with resourcePath:
serverOptions:
resourcePath: /UA/Line3
advertisedEndpoints: opc.tcp://gateway.example.com:4840/UA/Line3
An advertised URL always carries the server's resourcePath: node-opcua
cannot give one URL a path of its own. So an advertised URL whose path
differs from resourcePath is refused (SRV-E002) rather than advertised
without it.
Reverse Connect
With Reverse Connect (OPC 10000-6 §7.1.3) the server dials out to a client that is listening for it. The server then needs no open inbound port, which suits a gateway behind a firewall.
serverOptions:
reverseConnect:
connections:
- endpointUrl: opc.tcp://scada-host:8888 # the client's listener
reconnectDelay: 5000 # ms before re-dialing (default 5000)
maxReconnectDelay: 60000 # upper bound of the back-off (default 60000)
connectionTimeout: 120000 # ms the client has to open a channel (default 120000)
The client must be configured to accept reverse connections on that port.
In the Docker stack, OMNI_EDGE_REVERSE_CONNECT adds targets
(comma-separated opc.tcp:// URLs). Stopping the gateway stops the dialing
first.
Security
| Key | Default | |
|---|---|---|
allowAnonymous | true | false requires a user name/password or an X509 user certificate |
securityModes | all of None, Sign, SignAndEncrypt | the modes offered on every endpoint |
securityPolicies | node-opcua's set | None, Basic128Rsa15, Basic256, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss |
isAuditing | false | advertise auditing support |
Removing None from securityModes makes every client use a certificate
the server trusts: see the certificate stores below.
Limits
serverOptions:
maxAllowedSessionNumber: 50 # hard cap on concurrent sessions
maxConnectionsPerEndpoint: 20
timeout: 15000 # HEL/ACK timeout, ms: raise for slow links
serverCapabilities: # advertised to clients, and enforced
maxSessions: 50
maxSubscriptions: 100
maxMonitoredItemsPerSubscription: 1000
operationLimits:
maxNodesPerRead: 500 # a larger Read gets Bad_TooManyOperations
maxNodesPerBrowse: 500
serverCapabilities is what clients read under Server/ServerCapabilities
to size their requests; the server also enforces it.
maxAllowedSessionNumber is the hard cap on sessions.
Listening address and discovery
| Key | |
|---|---|
host | the address to listen on (default: all interfaces) |
registerServerMethod | HIDDEN (default), MDNS or LDS. NONE is accepted for older configurations and means HIDDEN |
discoveryServerEndpointUrl | the LDS to register with, for LDS |
disableDiscovery | disable GetEndpoints/FindServers on secure channels |
Certificate stores
The server keeps two PKI folders, each with its trusted, rejected and issuer certificates:
applicationPKI: the server's own certificate and key, and the client (application) certificates it trusts;userPKI: the X509 user certificates it accepts for login.
certificateStores:
applicationPKI:
rootFolder: /pkis/ApplicationPKI
userPKI:
rootFolder: /pkis/UserPKI
automaticallyAcceptUnknownCertificate: false
Default: $CERTIFICATE_STORE/ApplicationPKI and $CERTIFICATE_STORE/UserPKI
when CERTIFICATE_STORE is set (the Docker image sets /pkis), node-opcua's
per-user configuration folder otherwise. A refused client certificate lands
in rejected/; move it to trusted/certs/ to accept it.
automaticallyAcceptUnknownCertificate: true trusts every certificate
presented, for commissioning only.
:::warning Upgrading from 3.8.0 or earlier
Before this version both PKIs shared $CERTIFICATE_STORE/ApplicationPKI.
The server's own certificate stays there. If users log in with X509
certificates, copy their trusted certificates from ApplicationPKI/trusted/certs
to UserPKI/trusted/certs, or those users are rejected.
:::
Diagnostics
The gateway refuses to start on these, and the editor and the VS Code extension flag them on the offending line while you type:
| Code | Meaning |
|---|---|
| SRV-E001 | an advertised URL (or OMNI_EDGE_* value) is not an opc.tcp://host[:port][/path] URL |
| SRV-E002 | an advertised URL's resource path differs from resourcePath |
| SRV-E003 | resourcePath does not start with / |
Values given through OMNI_EDGE_ADVERTISED_ENDPOINTS and
OMNI_EDGE_REVERSE_CONNECT are checked only when the gateway starts: the
editor cannot see the gateway's environment.