/** * @module node-opcua-server */ import { EventEmitter } from "node:events"; import type { OPCUACertificateManager } from "node-opcua-certificate-manager"; import { type ICertificateChainProvider } from "node-opcua-common"; import { type Certificate, type PrivateKey } from "node-opcua-crypto/web"; import { MessageSecurityMode, SecurityPolicy, ServerSecureChannelLayer, type ServerSecureChannelParent } from "node-opcua-secure-channel"; import { ApplicationDescription, EndpointDescription, UserTokenType } from "node-opcua-service-endpoints"; import type { StatusCode } from "node-opcua-status-code"; import type { IHelloAckLimits } from "node-opcua-transport"; import type { IChannelData } from "./i_channel_data"; import type { ISocketData } from "./i_socket_data"; export interface OPCUAServerEndPointOptions { /** * the tcp port */ port: number; /** * the tcp host */ host?: string; /** * the DER certificate chain */ certificateChain: Certificate[]; /** * privateKey */ privateKey: PrivateKey; certificateManager: OPCUACertificateManager; /** * the default secureToken lifetime @default=60000 */ defaultSecureTokenLifetime?: number; /** * the maximum number of connection allowed on the TCP server socket * @default 20 */ maxConnections?: number; /** * the timeout for the TCP HEL/ACK transaction (in ms) * @default 30000 */ timeout?: number; serverInfo: ApplicationDescription; objectFactory?: unknown; transportSettings?: IServerTransportSettings; } export interface IServerTransportSettings { adjustTransportLimits: (hello: IHelloAckLimits) => IHelloAckLimits; } export interface EndpointDescriptionParams { restricted?: boolean; allowUnsecurePassword?: boolean; resourcePath?: string; alternateHostname?: string[]; hostname: string; /** * Override the port used in the endpoint URL. * When set, the endpoint URL uses this port instead of the * server's listen port. The server does NOT listen on this port. * Useful for Docker port-mapping, reverse proxies, and NAT. */ advertisedPort?: number; securityPolicies: SecurityPolicy[]; userTokenTypes: UserTokenType[]; } /** * Per-URL security overrides for advertised endpoints. * * When `advertisedEndpoints` contains a config object, the endpoint * descriptions generated for that URL use the overridden security * settings instead of inheriting from the main endpoint. * * Any field that is omitted falls back to the main endpoint's value. * * @example * ```ts * advertisedEndpoints: [ * // Public: SignAndEncrypt only, no anonymous * { * url: "opc.tcp://public.example.com:4840", * securityModes: [MessageSecurityMode.SignAndEncrypt], * allowAnonymous: false * }, * // Internal: inherits everything from main endpoint * "opc.tcp://internal:48480" * ] * ``` */ export interface AdvertisedEndpointConfig { /** The full endpoint URL, e.g. `"opc.tcp://public.example.com:4840"` */ url: string; /** Override security modes (default: inherit from main endpoint) */ securityModes?: MessageSecurityMode[]; /** Override security policies (default: inherit from main endpoint) */ securityPolicies?: SecurityPolicy[]; /** Override anonymous access (default: inherit from main endpoint) */ allowAnonymous?: boolean; /** Override user token types (default: inherit from main endpoint) */ userTokenTypes?: UserTokenType[]; } /** * An advertised endpoint entry — either a plain URL string (inherits * all settings from the main endpoint) or a config object with * per-URL security overrides. */ export type AdvertisedEndpoint = string | AdvertisedEndpointConfig; /** * Normalize any `advertisedEndpoints` input into a uniform * `AdvertisedEndpointConfig[]`. * * This coercion is done early so that all downstream code * (endpoint generation, IP/hostname extraction) only deals * with one type. */ export declare function normalizeAdvertisedEndpoints(raw?: AdvertisedEndpoint | AdvertisedEndpoint[]): AdvertisedEndpointConfig[]; export interface AddStandardEndpointDescriptionsParam { allowAnonymous?: boolean; disableDiscovery?: boolean; securityModes?: MessageSecurityMode[]; restricted?: boolean; allowUnsecurePassword?: boolean; resourcePath?: string; alternateHostname?: string[]; hostname?: string; securityPolicies?: SecurityPolicy[]; userTokenTypes?: UserTokenType[]; /** * Additional endpoint URL(s) to advertise. * * Use when the server is behind Docker port-mapping, * a reverse proxy, or a NAT gateway. * * Each entry can be a plain URL string (inherits all security * settings from the main endpoint) or an * `AdvertisedEndpointConfig` object with per-URL overrides. * * The server still listens on `port` — these are purely * advertised aliases. * * @example Simple string (inherits main settings) * ```ts * advertisedEndpoints: "opc.tcp://localhost:48481" * ``` * * @example Mixed array with per-URL security overrides * ```ts * advertisedEndpoints: [ * "opc.tcp://internal:48480", * { * url: "opc.tcp://public.example.com:4840", * securityModes: [MessageSecurityMode.SignAndEncrypt], * allowAnonymous: false * } * ] * ``` */ advertisedEndpoints?: AdvertisedEndpoint | AdvertisedEndpoint[]; } /** * Parse an `opc.tcp://hostname:port` URL and extract hostname and port. * @internal */ export declare function parseOpcTcpUrl(url: string): { hostname: string; port: number; }; /** * OPCUAServerEndPoint a Server EndPoint. * A sever end point is listening to one port * note: * see OPCUA Release 1.03 part 4 page 108 7.1 ApplicationDescription */ export declare class OPCUAServerEndPoint extends EventEmitter implements ServerSecureChannelParent { #private; /** * the tcp port */ port: number; host: string | undefined; certificateManager: OPCUACertificateManager; defaultSecureTokenLifetime: number; maxConnections: number; timeout: number; bytesWrittenInOldChannels: number; bytesReadInOldChannels: number; transactionsCountOldChannels: number; securityTokenCountOldChannels: number; serverInfo: ApplicationDescription; objectFactory: unknown; _on_new_channel?: (channel: ServerSecureChannelLayer) => void; _on_channel_secured?: (channel: ServerSecureChannelLayer) => void; _on_close_channel?: (channel: ServerSecureChannelLayer) => void; _on_connectionRefused?: (socketData: ISocketData) => void; _on_openSecureChannelFailure?: (socketData: ISocketData, channelData: IChannelData) => void; /** * Optional callback to adjust the certificate status code * during OpenSecureChannel. * * When set (typically by `installPushCertificateManagementOnServer`), * this callback is invoked whenever the base certificate check * returns a non-Good status. It can choose to relax certain * errors (e.g. untrusted/missing-CRL) based on application * policy such as the server being in NoConfiguration state. */ onAdjustCertificateStatus?: (statusCode: StatusCode, certificate: Certificate) => StatusCode | Promise; /** * Implements `ServerSecureChannelParent.adjustCertificateStatus`. * Delegates to the `onAdjustCertificateStatus` callback if set. */ adjustCertificateStatus(statusCode: StatusCode, certificate: Certificate): StatusCode | Promise; private _channels; private _server?; private _endpoints; private _listen_callback?; private _started; private _counter; private _policy_deduplicator; private transportSettings?; constructor(options: OPCUAServerEndPointOptions); dispose(): void; toString(): string; toJSON(): Record; getChannels(): ServerSecureChannelLayer[]; /** * Returns the X509 DER form of the server certificate */ getCertificate(): Certificate; /** * Returns the X509 DER form of the server certificate */ getCertificateChain(): Certificate[]; /** * Replace the certificate chain provider for this endpoint. * * Used by push certificate management to switch from the * default static provider to a disk-based one that re-reads * certificates on demand. * * Invalidates the cached `combine_der` result so that * `EndpointDescription.serverCertificate` getters pick up * the new chain immediately. */ setCertificateProvider(provider: ICertificateChainProvider): void; /** * Return the current certificate chain provider. * Useful for calling `invalidate()` after certificate rotation. */ getCertificateProvider(): ICertificateChainProvider; /** * Invalidate the combined DER cache. * * Called after the underlying provider's chain changes * (e.g. after `provider.invalidate()` or `provider.update()`). * The next `EndpointDescription.serverCertificate` access * will recompute the combined DER from the provider. */ invalidateCombinedDerCache(): void; /** * Convenience method: invalidate both the provider's cache * (so it re-reads from disk) and the combined DER cache * (so endpoint descriptions recompute `serverCertificate`). * * Prefer this over calling `getCertificateProvider().invalidate()` * and `invalidateCombinedDerCache()` separately. */ invalidateCertificates(): void; /** * Get the combined DER certificate (all certs concatenated) * for use in EndpointDescription.serverCertificate. * Cached internally; invalidated by provider changes. * @internal */ getCombinedCertificate(): Certificate | undefined; /** * the private key */ getPrivateKey(): PrivateKey; /** * The number of active channel on this end point. */ get currentChannelCount(): number; /** */ getEndpointDescription(securityMode: MessageSecurityMode, securityPolicy: SecurityPolicy, endpointUrl: string | null): EndpointDescription | null; addEndpointDescription(securityMode: MessageSecurityMode, securityPolicy: SecurityPolicy, options: EndpointDescriptionParams): void; addRestrictedEndpointDescription(options: EndpointDescriptionParams): void; addStandardEndpointDescriptions(options?: AddStandardEndpointDescriptionsParam): void; /** * returns the list of end point descriptions. */ endpointDescriptions(): EndpointDescription[]; /** */ listen(callback: (err?: Error) => void): void; killClientSockets(callback: (err?: Error) => void): void; suspendConnection(callback: (err?: Error) => void): void; restoreConnection(callback: (err?: Error) => void): void; abruptlyInterruptChannels(): void; /** */ shutdown(callback: (err?: Error) => void): void; /** */ start(callback: (err?: Error) => void): void; get bytesWritten(): number; get bytesRead(): number; get transactionsCount(): number; get securityTokenCount(): number; get activeChannelCount(): number; private _dump_statistics; private _setup_server; private _on_client_connection; private _preregisterChannel; private _un_pre_registerChannel; /** * @private */ private _registerChannel; /** */ private _unregisterChannel; private _end_listen; /** * shutdown_channel * @param channel * @param inner_callback */ private shutdown_channel; /** * @private */ private _prevent_DDOS_Attack; } export interface EndpointDescriptionEx extends EndpointDescription { _parent: OPCUAServerEndPoint; restricted: boolean; }