feat: add gateway tls support
This commit is contained in:
@@ -250,6 +250,9 @@ actor GatewayEndpointStore {
|
|||||||
let bind = GatewayEndpointStore.resolveGatewayBindMode(
|
let bind = GatewayEndpointStore.resolveGatewayBindMode(
|
||||||
root: ClawdbotConfigFile.loadDict(),
|
root: ClawdbotConfigFile.loadDict(),
|
||||||
env: ProcessInfo.processInfo.environment)
|
env: ProcessInfo.processInfo.environment)
|
||||||
|
let scheme = GatewayEndpointStore.resolveGatewayScheme(
|
||||||
|
root: ClawdbotConfigFile.loadDict(),
|
||||||
|
env: ProcessInfo.processInfo.environment)
|
||||||
let host = GatewayEndpointStore.resolveLocalGatewayHost(bindMode: bind, tailscaleIP: nil)
|
let host = GatewayEndpointStore.resolveLocalGatewayHost(bindMode: bind, tailscaleIP: nil)
|
||||||
let token = deps.token()
|
let token = deps.token()
|
||||||
let password = deps.password()
|
let password = deps.password()
|
||||||
@@ -257,7 +260,7 @@ actor GatewayEndpointStore {
|
|||||||
case .local:
|
case .local:
|
||||||
self.state = .ready(
|
self.state = .ready(
|
||||||
mode: .local,
|
mode: .local,
|
||||||
url: URL(string: "ws://\(host):\(port)")!,
|
url: URL(string: "\(scheme)://\(host):\(port)")!,
|
||||||
token: token,
|
token: token,
|
||||||
password: password)
|
password: password)
|
||||||
case .remote:
|
case .remote:
|
||||||
@@ -294,9 +297,12 @@ actor GatewayEndpointStore {
|
|||||||
self.cancelRemoteEnsure()
|
self.cancelRemoteEnsure()
|
||||||
let port = self.deps.localPort()
|
let port = self.deps.localPort()
|
||||||
let host = await self.deps.localHost()
|
let host = await self.deps.localHost()
|
||||||
|
let scheme = GatewayEndpointStore.resolveGatewayScheme(
|
||||||
|
root: ClawdbotConfigFile.loadDict(),
|
||||||
|
env: ProcessInfo.processInfo.environment)
|
||||||
self.setState(.ready(
|
self.setState(.ready(
|
||||||
mode: .local,
|
mode: .local,
|
||||||
url: URL(string: "ws://\(host):\(port)")!,
|
url: URL(string: "\(scheme)://\(host):\(port)")!,
|
||||||
token: token,
|
token: token,
|
||||||
password: password))
|
password: password))
|
||||||
case .remote:
|
case .remote:
|
||||||
@@ -307,9 +313,12 @@ actor GatewayEndpointStore {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.cancelRemoteEnsure()
|
self.cancelRemoteEnsure()
|
||||||
|
let scheme = GatewayEndpointStore.resolveGatewayScheme(
|
||||||
|
root: ClawdbotConfigFile.loadDict(),
|
||||||
|
env: ProcessInfo.processInfo.environment)
|
||||||
self.setState(.ready(
|
self.setState(.ready(
|
||||||
mode: .remote,
|
mode: .remote,
|
||||||
url: URL(string: "ws://127.0.0.1:\(Int(port))")!,
|
url: URL(string: "\(scheme)://127.0.0.1:\(Int(port))")!,
|
||||||
token: token,
|
token: token,
|
||||||
password: password))
|
password: password))
|
||||||
case .unconfigured:
|
case .unconfigured:
|
||||||
@@ -478,6 +487,24 @@ actor GatewayEndpointStore {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func resolveGatewayScheme(
|
||||||
|
root: [String: Any],
|
||||||
|
env: [String: String]) -> String
|
||||||
|
{
|
||||||
|
if let envValue = env["CLAWDBOT_GATEWAY_TLS"]?.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||||
|
!envValue.isEmpty
|
||||||
|
{
|
||||||
|
return (envValue == "1" || envValue.lowercased() == "true") ? "wss" : "ws"
|
||||||
|
}
|
||||||
|
if let gateway = root["gateway"] as? [String: Any],
|
||||||
|
let tls = gateway["tls"] as? [String: Any],
|
||||||
|
let enabled = tls["enabled"] as? Bool
|
||||||
|
{
|
||||||
|
return enabled ? "wss" : "ws"
|
||||||
|
}
|
||||||
|
return "ws"
|
||||||
|
}
|
||||||
|
|
||||||
private static func resolveLocalGatewayHost(
|
private static func resolveLocalGatewayHost(
|
||||||
bindMode: String?,
|
bindMode: String?,
|
||||||
tailscaleIP: String?) -> String
|
tailscaleIP: String?) -> String
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ export type GatewayHttpConfig = {
|
|||||||
endpoints?: GatewayHttpEndpointsConfig;
|
endpoints?: GatewayHttpEndpointsConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type GatewayTlsConfig = BridgeTlsConfig;
|
||||||
|
|
||||||
export type GatewayConfig = {
|
export type GatewayConfig = {
|
||||||
/** Single multiplexed port for Gateway WS + HTTP (default: 18789). */
|
/** Single multiplexed port for Gateway WS + HTTP (default: 18789). */
|
||||||
port?: number;
|
port?: number;
|
||||||
@@ -151,5 +153,6 @@ export type GatewayConfig = {
|
|||||||
tailscale?: GatewayTailscaleConfig;
|
tailscale?: GatewayTailscaleConfig;
|
||||||
remote?: GatewayRemoteConfig;
|
remote?: GatewayRemoteConfig;
|
||||||
reload?: GatewayReloadConfig;
|
reload?: GatewayReloadConfig;
|
||||||
|
tls?: GatewayTlsConfig;
|
||||||
http?: GatewayHttpConfig;
|
http?: GatewayHttpConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -300,6 +300,15 @@ export const ClawdbotSchema = z
|
|||||||
})
|
})
|
||||||
.strict()
|
.strict()
|
||||||
.optional(),
|
.optional(),
|
||||||
|
tls: z
|
||||||
|
.object({
|
||||||
|
enabled: z.boolean().optional(),
|
||||||
|
autoGenerate: z.boolean().optional(),
|
||||||
|
certPath: z.string().optional(),
|
||||||
|
keyPath: z.string().optional(),
|
||||||
|
caPath: z.string().optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
http: z
|
http: z
|
||||||
.object({
|
.object({
|
||||||
endpoints: z
|
endpoints: z
|
||||||
|
|||||||
@@ -56,14 +56,16 @@ export function buildGatewayConnectionDetails(
|
|||||||
options.configPath ?? resolveConfigPath(process.env, resolveStateDir(process.env));
|
options.configPath ?? resolveConfigPath(process.env, resolveStateDir(process.env));
|
||||||
const isRemoteMode = config.gateway?.mode === "remote";
|
const isRemoteMode = config.gateway?.mode === "remote";
|
||||||
const remote = isRemoteMode ? config.gateway?.remote : undefined;
|
const remote = isRemoteMode ? config.gateway?.remote : undefined;
|
||||||
|
const tlsEnabled = config.gateway?.tls?.enabled === true;
|
||||||
const localPort = resolveGatewayPort(config);
|
const localPort = resolveGatewayPort(config);
|
||||||
const tailnetIPv4 = pickPrimaryTailnetIPv4();
|
const tailnetIPv4 = pickPrimaryTailnetIPv4();
|
||||||
const bindMode = config.gateway?.bind ?? "loopback";
|
const bindMode = config.gateway?.bind ?? "loopback";
|
||||||
const preferTailnet = bindMode === "auto" && !!tailnetIPv4;
|
const preferTailnet = bindMode === "auto" && !!tailnetIPv4;
|
||||||
|
const scheme = tlsEnabled ? "wss" : "ws";
|
||||||
const localUrl =
|
const localUrl =
|
||||||
preferTailnet && tailnetIPv4
|
preferTailnet && tailnetIPv4
|
||||||
? `ws://${tailnetIPv4}:${localPort}`
|
? `${scheme}://${tailnetIPv4}:${localPort}`
|
||||||
: `ws://127.0.0.1:${localPort}`;
|
: `${scheme}://127.0.0.1:${localPort}`;
|
||||||
const urlOverride =
|
const urlOverride =
|
||||||
typeof options.url === "string" && options.url.trim().length > 0
|
typeof options.url === "string" && options.url.trim().length > 0
|
||||||
? options.url.trim()
|
? options.url.trim()
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export type GatewayBridgeRuntime = {
|
|||||||
export async function startGatewayBridgeRuntime(params: {
|
export async function startGatewayBridgeRuntime(params: {
|
||||||
cfg: ClawdbotConfig;
|
cfg: ClawdbotConfig;
|
||||||
port: number;
|
port: number;
|
||||||
|
gatewayTls?: { enabled: boolean; fingerprintSha256?: string };
|
||||||
canvasHostEnabled: boolean;
|
canvasHostEnabled: boolean;
|
||||||
canvasHost: CanvasHostHandler | null;
|
canvasHost: CanvasHostHandler | null;
|
||||||
canvasRuntime: RuntimeEnv;
|
canvasRuntime: RuntimeEnv;
|
||||||
@@ -221,6 +222,7 @@ export async function startGatewayBridgeRuntime(params: {
|
|||||||
const discovery = await startGatewayDiscovery({
|
const discovery = await startGatewayDiscovery({
|
||||||
machineDisplayName: params.machineDisplayName,
|
machineDisplayName: params.machineDisplayName,
|
||||||
port: params.port,
|
port: params.port,
|
||||||
|
gatewayTls: params.gatewayTls,
|
||||||
bridgePort: bridge?.port,
|
bridgePort: bridge?.port,
|
||||||
bridgeTls: bridgeTls.enabled
|
bridgeTls: bridgeTls.enabled
|
||||||
? { enabled: true, fingerprintSha256: bridgeTls.fingerprintSha256 }
|
? { enabled: true, fingerprintSha256: bridgeTls.fingerprintSha256 }
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
export async function startGatewayDiscovery(params: {
|
export async function startGatewayDiscovery(params: {
|
||||||
machineDisplayName: string;
|
machineDisplayName: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
gatewayTls?: { enabled: boolean; fingerprintSha256?: string };
|
||||||
bridgePort?: number;
|
bridgePort?: number;
|
||||||
bridgeTls?: { enabled: boolean; fingerprintSha256?: string };
|
bridgeTls?: { enabled: boolean; fingerprintSha256?: string };
|
||||||
canvasPort?: number;
|
canvasPort?: number;
|
||||||
@@ -31,6 +32,8 @@ export async function startGatewayDiscovery(params: {
|
|||||||
const bonjour = await startGatewayBonjourAdvertiser({
|
const bonjour = await startGatewayBonjourAdvertiser({
|
||||||
instanceName: formatBonjourInstanceName(params.machineDisplayName),
|
instanceName: formatBonjourInstanceName(params.machineDisplayName),
|
||||||
gatewayPort: params.port,
|
gatewayPort: params.port,
|
||||||
|
gatewayTlsEnabled: params.gatewayTls?.enabled ?? false,
|
||||||
|
gatewayTlsFingerprintSha256: params.gatewayTls?.fingerprintSha256,
|
||||||
bridgePort: params.bridgePort,
|
bridgePort: params.bridgePort,
|
||||||
canvasPort: params.canvasPort,
|
canvasPort: params.canvasPort,
|
||||||
bridgeTlsEnabled: params.bridgeTls?.enabled ?? false,
|
bridgeTlsEnabled: params.bridgeTls?.enabled ?? false,
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import {
|
|||||||
type IncomingMessage,
|
type IncomingMessage,
|
||||||
type ServerResponse,
|
type ServerResponse,
|
||||||
} from "node:http";
|
} from "node:http";
|
||||||
|
import { createServer as createHttpsServer } from "node:https";
|
||||||
|
import type { TlsOptions } from "node:tls";
|
||||||
import type { WebSocketServer } from "ws";
|
import type { WebSocketServer } from "ws";
|
||||||
import { handleA2uiHttpRequest } from "../canvas-host/a2ui.js";
|
import { handleA2uiHttpRequest } from "../canvas-host/a2ui.js";
|
||||||
import type { CanvasHostHandler } from "../canvas-host/server.js";
|
import type { CanvasHostHandler } from "../canvas-host/server.js";
|
||||||
@@ -193,6 +195,7 @@ export function createGatewayHttpServer(opts: {
|
|||||||
handleHooksRequest: HooksRequestHandler;
|
handleHooksRequest: HooksRequestHandler;
|
||||||
handlePluginRequest?: HooksRequestHandler;
|
handlePluginRequest?: HooksRequestHandler;
|
||||||
resolvedAuth: import("./auth.js").ResolvedGatewayAuth;
|
resolvedAuth: import("./auth.js").ResolvedGatewayAuth;
|
||||||
|
tlsOptions?: TlsOptions;
|
||||||
}): HttpServer {
|
}): HttpServer {
|
||||||
const {
|
const {
|
||||||
canvasHost,
|
canvasHost,
|
||||||
@@ -203,11 +206,19 @@ export function createGatewayHttpServer(opts: {
|
|||||||
handlePluginRequest,
|
handlePluginRequest,
|
||||||
resolvedAuth,
|
resolvedAuth,
|
||||||
} = opts;
|
} = opts;
|
||||||
const httpServer: HttpServer = createHttpServer((req, res) => {
|
const httpServer: HttpServer = opts.tlsOptions
|
||||||
|
? createHttpsServer(opts.tlsOptions, (req, res) => {
|
||||||
|
void handleRequest(req, res);
|
||||||
|
})
|
||||||
|
: createHttpServer((req, res) => {
|
||||||
|
void handleRequest(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handleRequest(req: IncomingMessage, res: ServerResponse) {
|
||||||
// Don't interfere with WebSocket upgrades; ws handles the 'upgrade' event.
|
// Don't interfere with WebSocket upgrades; ws handles the 'upgrade' event.
|
||||||
if (String(req.headers.upgrade ?? "").toLowerCase() === "websocket") return;
|
if (String(req.headers.upgrade ?? "").toLowerCase() === "websocket") return;
|
||||||
|
|
||||||
void (async () => {
|
try {
|
||||||
if (await handleHooksRequest(req, res)) return;
|
if (await handleHooksRequest(req, res)) return;
|
||||||
if (await handleSlackHttpRequest(req, res)) return;
|
if (await handleSlackHttpRequest(req, res)) return;
|
||||||
if (handlePluginRequest && (await handlePluginRequest(req, res))) return;
|
if (handlePluginRequest && (await handlePluginRequest(req, res))) return;
|
||||||
@@ -230,12 +241,12 @@ export function createGatewayHttpServer(opts: {
|
|||||||
res.statusCode = 404;
|
res.statusCode = 404;
|
||||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||||
res.end("Not Found");
|
res.end("Not Found");
|
||||||
})().catch((err) => {
|
} catch (err) {
|
||||||
res.statusCode = 500;
|
res.statusCode = 500;
|
||||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||||
res.end(String(err));
|
res.end(String(err));
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
return httpServer;
|
return httpServer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { MAX_PAYLOAD_BYTES } from "./server-constants.js";
|
|||||||
import { attachGatewayUpgradeHandler, createGatewayHttpServer } from "./server-http.js";
|
import { attachGatewayUpgradeHandler, createGatewayHttpServer } from "./server-http.js";
|
||||||
import type { DedupeEntry } from "./server-shared.js";
|
import type { DedupeEntry } from "./server-shared.js";
|
||||||
import type { PluginRegistry } from "../plugins/registry.js";
|
import type { PluginRegistry } from "../plugins/registry.js";
|
||||||
|
import type { GatewayTlsRuntime } from "./server/tls.js";
|
||||||
|
|
||||||
export async function createGatewayRuntimeState(params: {
|
export async function createGatewayRuntimeState(params: {
|
||||||
cfg: import("../config/config.js").ClawdbotConfig;
|
cfg: import("../config/config.js").ClawdbotConfig;
|
||||||
@@ -27,6 +28,7 @@ export async function createGatewayRuntimeState(params: {
|
|||||||
controlUiBasePath: string;
|
controlUiBasePath: string;
|
||||||
openAiChatCompletionsEnabled: boolean;
|
openAiChatCompletionsEnabled: boolean;
|
||||||
resolvedAuth: ResolvedGatewayAuth;
|
resolvedAuth: ResolvedGatewayAuth;
|
||||||
|
gatewayTls?: GatewayTlsRuntime;
|
||||||
hooksConfig: () => HooksConfigResolved | null;
|
hooksConfig: () => HooksConfigResolved | null;
|
||||||
pluginRegistry: PluginRegistry;
|
pluginRegistry: PluginRegistry;
|
||||||
deps: CliDeps;
|
deps: CliDeps;
|
||||||
@@ -104,6 +106,7 @@ export async function createGatewayRuntimeState(params: {
|
|||||||
handleHooksRequest,
|
handleHooksRequest,
|
||||||
handlePluginRequest,
|
handlePluginRequest,
|
||||||
resolvedAuth: params.resolvedAuth,
|
resolvedAuth: params.resolvedAuth,
|
||||||
|
tlsOptions: params.gatewayTls?.enabled ? params.gatewayTls.tlsOptions : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
await listenGatewayHttpServer({
|
await listenGatewayHttpServer({
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export function logGatewayStartup(params: {
|
|||||||
cfg: ReturnType<typeof loadConfig>;
|
cfg: ReturnType<typeof loadConfig>;
|
||||||
bindHost: string;
|
bindHost: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
tlsEnabled?: boolean;
|
||||||
log: { info: (msg: string, meta?: Record<string, unknown>) => void };
|
log: { info: (msg: string, meta?: Record<string, unknown>) => void };
|
||||||
isNixMode: boolean;
|
isNixMode: boolean;
|
||||||
}) {
|
}) {
|
||||||
@@ -20,7 +21,8 @@ export function logGatewayStartup(params: {
|
|||||||
params.log.info(`agent model: ${modelRef}`, {
|
params.log.info(`agent model: ${modelRef}`, {
|
||||||
consoleMessage: `agent model: ${chalk.whiteBright(modelRef)}`,
|
consoleMessage: `agent model: ${chalk.whiteBright(modelRef)}`,
|
||||||
});
|
});
|
||||||
params.log.info(`listening on ws://${params.bindHost}:${params.port} (PID ${process.pid})`);
|
const scheme = params.tlsEnabled ? "wss" : "ws";
|
||||||
|
params.log.info(`listening on ${scheme}://${params.bindHost}:${params.port} (PID ${process.pid})`);
|
||||||
params.log.info(`log file: ${getResolvedLoggerSettings().file}`);
|
params.log.info(`log file: ${getResolvedLoggerSettings().file}`);
|
||||||
if (params.isNixMode) {
|
if (params.isNixMode) {
|
||||||
params.log.info("gateway: running in Nix mode (config managed externally)");
|
params.log.info("gateway: running in Nix mode (config managed externally)");
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import { resolveSessionKeyForRun } from "./server-session-key.js";
|
|||||||
import { startGatewaySidecars } from "./server-startup.js";
|
import { startGatewaySidecars } from "./server-startup.js";
|
||||||
import { logGatewayStartup } from "./server-startup-log.js";
|
import { logGatewayStartup } from "./server-startup-log.js";
|
||||||
import { startGatewayTailscaleExposure } from "./server-tailscale.js";
|
import { startGatewayTailscaleExposure } from "./server-tailscale.js";
|
||||||
|
import { loadGatewayTlsRuntime } from "./server/tls.js";
|
||||||
import { createWizardSessionTracker } from "./server-wizard-sessions.js";
|
import { createWizardSessionTracker } from "./server-wizard-sessions.js";
|
||||||
import { attachGatewayWsHandlers } from "./server-ws-runtime.js";
|
import { attachGatewayWsHandlers } from "./server-ws-runtime.js";
|
||||||
|
|
||||||
@@ -222,6 +223,10 @@ export async function startGatewayServer(
|
|||||||
|
|
||||||
const deps = createDefaultDeps();
|
const deps = createDefaultDeps();
|
||||||
let canvasHostServer: CanvasHostServer | null = null;
|
let canvasHostServer: CanvasHostServer | null = null;
|
||||||
|
const gatewayTls = await loadGatewayTlsRuntime(cfgAtStart.gateway?.tls, log.child("tls"));
|
||||||
|
if (cfgAtStart.gateway?.tls?.enabled && !gatewayTls.enabled) {
|
||||||
|
throw new Error(gatewayTls.error ?? "gateway tls: failed to enable");
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
canvasHost,
|
canvasHost,
|
||||||
httpServer,
|
httpServer,
|
||||||
@@ -244,6 +249,7 @@ export async function startGatewayServer(
|
|||||||
controlUiBasePath,
|
controlUiBasePath,
|
||||||
openAiChatCompletionsEnabled,
|
openAiChatCompletionsEnabled,
|
||||||
resolvedAuth,
|
resolvedAuth,
|
||||||
|
gatewayTls,
|
||||||
hooksConfig: () => hooksConfig,
|
hooksConfig: () => hooksConfig,
|
||||||
pluginRegistry,
|
pluginRegistry,
|
||||||
deps,
|
deps,
|
||||||
@@ -279,6 +285,9 @@ export async function startGatewayServer(
|
|||||||
const bridgeRuntime = await startGatewayBridgeRuntime({
|
const bridgeRuntime = await startGatewayBridgeRuntime({
|
||||||
cfg: cfgAtStart,
|
cfg: cfgAtStart,
|
||||||
port,
|
port,
|
||||||
|
gatewayTls: gatewayTls.enabled
|
||||||
|
? { enabled: true, fingerprintSha256: gatewayTls.fingerprintSha256 }
|
||||||
|
: undefined,
|
||||||
canvasHostEnabled,
|
canvasHostEnabled,
|
||||||
canvasHost,
|
canvasHost,
|
||||||
canvasRuntime,
|
canvasRuntime,
|
||||||
@@ -412,6 +421,7 @@ export async function startGatewayServer(
|
|||||||
cfg: cfgAtStart,
|
cfg: cfgAtStart,
|
||||||
bindHost,
|
bindHost,
|
||||||
port,
|
port,
|
||||||
|
tlsEnabled: gatewayTls.enabled,
|
||||||
log,
|
log,
|
||||||
isNixMode,
|
isNixMode,
|
||||||
});
|
});
|
||||||
|
|||||||
14
src/gateway/server/tls.ts
Normal file
14
src/gateway/server/tls.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import type { BridgeTlsConfig } from "../../config/types.gateway.js";
|
||||||
|
import {
|
||||||
|
type BridgeTlsRuntime,
|
||||||
|
loadBridgeTlsRuntime,
|
||||||
|
} from "../../infra/bridge/server/tls.js";
|
||||||
|
|
||||||
|
export type GatewayTlsRuntime = BridgeTlsRuntime;
|
||||||
|
|
||||||
|
export async function loadGatewayTlsRuntime(
|
||||||
|
cfg: BridgeTlsConfig | undefined,
|
||||||
|
log?: { info?: (msg: string) => void; warn?: (msg: string) => void },
|
||||||
|
): Promise<GatewayTlsRuntime> {
|
||||||
|
return await loadBridgeTlsRuntime(cfg, log);
|
||||||
|
}
|
||||||
@@ -15,6 +15,8 @@ export type GatewayBonjourAdvertiseOpts = {
|
|||||||
instanceName?: string;
|
instanceName?: string;
|
||||||
gatewayPort: number;
|
gatewayPort: number;
|
||||||
sshPort?: number;
|
sshPort?: number;
|
||||||
|
gatewayTlsEnabled?: boolean;
|
||||||
|
gatewayTlsFingerprintSha256?: string;
|
||||||
bridgePort?: number;
|
bridgePort?: number;
|
||||||
canvasPort?: number;
|
canvasPort?: number;
|
||||||
bridgeTlsEnabled?: boolean;
|
bridgeTlsEnabled?: boolean;
|
||||||
@@ -107,6 +109,12 @@ export async function startGatewayBonjourAdvertiser(
|
|||||||
if (typeof opts.bridgePort === "number" && opts.bridgePort > 0) {
|
if (typeof opts.bridgePort === "number" && opts.bridgePort > 0) {
|
||||||
txtBase.bridgePort = String(opts.bridgePort);
|
txtBase.bridgePort = String(opts.bridgePort);
|
||||||
}
|
}
|
||||||
|
if (opts.gatewayTlsEnabled) {
|
||||||
|
txtBase.gatewayTls = "1";
|
||||||
|
if (opts.gatewayTlsFingerprintSha256) {
|
||||||
|
txtBase.gatewayTlsSha256 = opts.gatewayTlsFingerprintSha256;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (typeof opts.canvasPort === "number" && opts.canvasPort > 0) {
|
if (typeof opts.canvasPort === "number" && opts.canvasPort > 0) {
|
||||||
txtBase.canvasPort = String(opts.canvasPort);
|
txtBase.canvasPort = String(opts.canvasPort);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user