@hyzyn/dsh-tty 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,74 @@
1
+ export function parseSshConfig(text) {
2
+ const entries = [];
3
+ /** 当前 Host 块:模式列表 + 选项表(键已小写)。 */
4
+ let block = null;
5
+ const flush = () => {
6
+ if (block === null)
7
+ return;
8
+ const concrete = block.patterns.length > 0 && block.patterns.every((p) => p !== '' && !/[*?!]/.test(p));
9
+ if (concrete) {
10
+ const name = block.patterns[0];
11
+ const host = block.options.get('hostname') ?? name;
12
+ const user = block.options.get('user');
13
+ const portRaw = Number(block.options.get('port'));
14
+ const port = Number.isInteger(portRaw) && portRaw >= 1 && portRaw <= 65535 ? portRaw : 22;
15
+ const identityFile = block.options.get('identityfile');
16
+ if (typeof user === 'string' && user.trim() !== '' && entries.length < 100) {
17
+ entries.push({
18
+ name,
19
+ host,
20
+ port,
21
+ username: user.trim(),
22
+ auth: identityFile !== undefined && identityFile.trim() !== '' ? 'key' : 'agent',
23
+ keyPath: identityFile !== undefined ? identityFile.trim() : '',
24
+ passphrase: '',
25
+ password: '',
26
+ agentForward: false,
27
+ });
28
+ }
29
+ }
30
+ block = null;
31
+ };
32
+ for (const rawLine of text.split(/\r?\n/)) {
33
+ let line = rawLine.trim();
34
+ if (line === '' || line.startsWith('#'))
35
+ continue;
36
+ // 行内注释(非引号内的第一个 ' #'):宽容处理为直接截断
37
+ const hash = line.indexOf(' #');
38
+ if (hash !== -1)
39
+ line = line.slice(0, hash).trim();
40
+ if (line === '')
41
+ continue;
42
+ let key;
43
+ let rest;
44
+ const eq = line.indexOf('=');
45
+ if (eq > 0 && !/\s/.test(line.slice(0, eq))) {
46
+ key = line.slice(0, eq).trim();
47
+ rest = line.slice(eq + 1).trim();
48
+ }
49
+ else {
50
+ const match = line.match(/^(\S+)\s+(.*)$/);
51
+ if (match === null)
52
+ continue;
53
+ key = match[1];
54
+ rest = match[2].replace(/^=\s*/, ''); // 宽容「key = value」的空格等号写法
55
+ }
56
+ const keyLower = key.toLowerCase();
57
+ if (keyLower === 'host') {
58
+ flush();
59
+ // 「Host = name」的孤立等号当作分隔符宽容丢弃
60
+ block = { patterns: rest.split(/\s+/).filter((p) => p !== '' && p !== '='), options: new Map() };
61
+ continue;
62
+ }
63
+ if (block === null)
64
+ continue;
65
+ if (keyLower === 'include')
66
+ continue; // 不展开,避免读入用户无法预期的文件
67
+ if (block.options.has(keyLower))
68
+ continue; // 首个生效(OpenSSH 语义)
69
+ block.options.set(keyLower, rest.replace(/^"+|"+$/g, ''));
70
+ }
71
+ flush();
72
+ return entries;
73
+ }
74
+ //# sourceMappingURL=ssh-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh-config.js","sourceRoot":"","sources":["../src/ssh-config.ts"],"names":[],"mappings":"AAeA,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,OAAO,GAAmB,EAAE,CAAA;IAClC,kCAAkC;IAClC,IAAI,KAAK,GAAgE,IAAI,CAAA;IAE7E,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,KAAK,KAAK,IAAI;YAAE,OAAM;QAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACvG,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;YAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAA;YAClD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACtC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;YACjD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;YACzF,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACtD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC3E,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI;oBACJ,IAAI;oBACJ,IAAI;oBACJ,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE;oBACrB,IAAI,EAAE,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;oBAChF,OAAO,EAAE,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;oBAC9D,UAAU,EAAE,EAAE;oBACd,QAAQ,EAAE,EAAE;oBACZ,YAAY,EAAE,KAAK;iBACpB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,KAAK,GAAG,IAAI,CAAA;IACd,CAAC,CAAA;IAED,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QACzB,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QACjD,gCAAgC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC/B,IAAI,IAAI,KAAK,CAAC,CAAC;YAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;QAClD,IAAI,IAAI,KAAK,EAAE;YAAE,SAAQ;QACzB,IAAI,GAAW,CAAA;QACf,IAAI,IAAY,CAAA;QAChB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;YAC9B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;YAC1C,IAAI,KAAK,KAAK,IAAI;gBAAE,SAAQ;YAC5B,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YACd,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA,CAAC,yBAAyB;QAChE,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;QAClC,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,KAAK,EAAE,CAAA;YACP,8BAA8B;YAC9B,KAAK,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,CAAA;YAChG,SAAQ;QACV,CAAC;QACD,IAAI,KAAK,KAAK,IAAI;YAAE,SAAQ;QAC5B,IAAI,QAAQ,KAAK,SAAS;YAAE,SAAQ,CAAC,oBAAoB;QACzD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAQ,CAAC,mBAAmB;QAC7D,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3D,CAAC;IACD,KAAK,EAAE,CAAA;IACP,OAAO,OAAO,CAAA;AAChB,CAAC"}
package/lib/ssh.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ConnectConfig } from 'ssh2';
1
2
  import { PassThrough } from 'node:stream';
2
3
  export interface TermExit {
3
4
  exitCode: number | null;
@@ -17,6 +18,13 @@ export interface TermHandle {
17
18
  /** terminate 失败后的最后手段(本地 PTY:对顶层 shell 直接 SIGKILL)。 */
18
19
  forceKill?(): void;
19
20
  }
21
+ /** TOFU 主机指纹记录。 */
22
+ export interface HostKeyRecord {
23
+ host: string;
24
+ port: number;
25
+ /** hostVerifier 收到的原样 sha256 十六进制指纹。 */
26
+ fingerprint: string;
27
+ }
20
28
  /** 内联 SSH 连接规格(ws 帧或连接簿条目共用)。 */
21
29
  export interface SshSpec {
22
30
  host: string;
@@ -26,6 +34,8 @@ export interface SshSpec {
26
34
  keyPath?: string;
27
35
  passphrase?: string;
28
36
  password?: string;
37
+ /** OpenSSH agent forwarding:远程可用本地 ssh-agent 的钥匙(git clone 等)。 */
38
+ agentForward?: boolean;
29
39
  }
30
40
  /** 连接簿条目(带名字,存 settings)。 */
31
41
  export interface SshHostEntry extends SshSpec {
@@ -39,9 +49,39 @@ export interface SshSpawnOptions {
39
49
  info(msg: string): void;
40
50
  warn(msg: string): void;
41
51
  };
52
+ /**
53
+ * known_hosts TOFU 钉扎存储:首次连接 record() 记录指纹,之后 get() 校验。
54
+ * 缺省时退化为 accept-and-log(仅记录指纹,无条件放行)。
55
+ */
56
+ hostKeyStore?: HostKeyStore;
42
57
  }
58
+ /** 主机指纹钉扎存储(宿主半体实现为 LiveConfig + settings 持久化)。 */
59
+ export interface HostKeyStore {
60
+ /** 已记录的指纹(hostVerifier 收到的原样十六进制串);未记录返回 undefined。 */
61
+ get(host: string, port: number): string | undefined;
62
+ /** 首次连接握手时记录指纹。 */
63
+ record(host: string, port: number, fingerprint: string): void;
64
+ }
65
+ declare function expandHome(path: string): string;
66
+ /** 供 ~/.ssh/config 导入路由使用(~ 与 ~/ 前缀展开 home)。 */
67
+ export { expandHome };
43
68
  /** 展示用目标串:user@host(非默认端口时带 :port)。 */
44
69
  export declare function sshTarget(spec: SshSpec): string;
70
+ /** 构造连接配置(认证三态 + keepalive + hostHash);隧道管理器与 spawnSsh 共用。 */
71
+ export declare function buildConnectConfig(spec: SshSpec): ConnectConfig;
72
+ /** TOFU 主机指纹策略(hostVerifier 接线);返回的 mismatchMessage() 供连接错误路径取人类可读拒绝原因。 */
73
+ export declare function applyHostKeyPolicy(options: {
74
+ connectConfig: ConnectConfig;
75
+ spec: SshSpec;
76
+ store?: HostKeyStore;
77
+ logger?: {
78
+ info(msg: string): void;
79
+ warn(msg: string): void;
80
+ };
81
+ target: string;
82
+ }): {
83
+ mismatchMessage(): string | null;
84
+ };
45
85
  /**
46
86
  * 建立 SSH 连接并打开交互 shell channel,返回 TermHandle。
47
87
  * 失败(连接超时/认证被拒/host 不可达)时 reject 带人类可读信息。
package/lib/ssh.js CHANGED
@@ -12,12 +12,11 @@
12
12
  * password / passphrase 支持 `env:VAR` 前缀从进程环境变量取值(配合
13
13
  * dsh-env-manager 插件托管密钥,避免明文写入 settings 文件)。
14
14
  *
15
- * 主机密钥策略:当前版本为 accept-and-log——hostVerifier 记录 sha256 指纹
16
- * 后无条件放行,每次连接都接受并记录,等同于
17
- * `ssh -o StrictHostKeyChecking=no`(而非 accept-new):不做 known_hosts
18
- * 钉扎,首次连接不询问,同一主机指纹变更也不会告警,因此存在被中间人
19
- * (MITM)冒充的风险。loopback 围栏保证只有本机 Web GUI 能发起连接,
20
- * 仅作为缓解;known_hosts 钉扎留作后续项。
15
+ * 主机密钥策略:known_hosts TOFU(trust-on-first-use)钉扎——hostVerifier 里
16
+ * 首次连接记录 sha256 指纹(经 HostKeyStore 持久化),之后每次连接校验:
17
+ * 指纹一致放行;指纹变更拒绝连接(防中间人冒充),用户确认安全后可在
18
+ * 设置卡片删除该主机记录重连。未提供 hostKeyStore 时退化为 accept-and-log
19
+ * (旧行为,测试路径用)。
21
20
  */
22
21
  import { Client } from 'ssh2';
23
22
  import { readFileSync } from 'node:fs';
@@ -43,6 +42,8 @@ function expandHome(path) {
43
42
  return join(homedir(), path.slice(2));
44
43
  return path;
45
44
  }
45
+ /** 供 ~/.ssh/config 导入路由使用(~ 与 ~/ 前缀展开 home)。 */
46
+ export { expandHome };
46
47
  /** 展示用目标串:user@host(非默认端口时带 :port)。 */
47
48
  export function sshTarget(spec) {
48
49
  const port = spec.port ?? 22;
@@ -51,7 +52,8 @@ export function sshTarget(spec) {
51
52
  /* ------------------------------------------------------------------ *
52
53
  * 连接与 channel 包装
53
54
  * ------------------------------------------------------------------ */
54
- function buildConnectConfig(spec) {
55
+ /** 构造连接配置(认证三态 + keepalive + hostHash);隧道管理器与 spawnSsh 共用。 */
56
+ export function buildConnectConfig(spec) {
55
57
  const auth = spec.auth ?? 'agent';
56
58
  const base = {
57
59
  host: spec.host,
@@ -60,7 +62,8 @@ function buildConnectConfig(spec) {
60
62
  readyTimeout: 20000,
61
63
  keepaliveInterval: 10000,
62
64
  keepaliveCountMax: 3,
63
- // accept-and-log:记录指纹后放行(见文件头策略说明)
65
+ // hostVerifier 依赖 hostHash 计算指纹;放行与否由 spawnSsh 里的
66
+ // TOFU 策略(HostKeyStore)决定,见文件头策略说明
64
67
  hostHash: 'sha256',
65
68
  };
66
69
  if (auth === 'agent') {
@@ -83,8 +86,38 @@ function buildConnectConfig(spec) {
83
86
  // 大量服务端(如部分路由器/堡垒机)只开 keyboard-interactive
84
87
  base.tryKeyboard = true;
85
88
  }
89
+ // agent forwarding 需要 agent 通道:key/password 认证时也把 SSH_AUTH_SOCK
90
+ // 挂上(只用于转发,不参与认证)。@types/ssh2 的 ConnectConfig.agentForward
91
+ // 在缺 agent 时会直接 throw,故这里仅在 SOCK 存在时设置
92
+ if (spec.agentForward === true && process.env.SSH_AUTH_SOCK !== undefined && process.env.SSH_AUTH_SOCK !== '') {
93
+ base.agent = base.agent ?? process.env.SSH_AUTH_SOCK;
94
+ }
86
95
  return base;
87
96
  }
97
+ /** TOFU 主机指纹策略(hostVerifier 接线);返回的 mismatchMessage() 供连接错误路径取人类可读拒绝原因。 */
98
+ export function applyHostKeyPolicy(options) {
99
+ const { connectConfig, spec, store, logger, target } = options;
100
+ const port = spec.port ?? 22;
101
+ let hostKeyMismatch = null;
102
+ connectConfig.hostVerifier = (hash) => {
103
+ const known = store?.get(spec.host, port);
104
+ if (known === undefined) {
105
+ store?.record(spec.host, port, hash);
106
+ logger?.info(`[dsh-tty] ssh ${target} 首次连接,已记录 host key 指纹 sha256:${hash}(TOFU)`);
107
+ return true;
108
+ }
109
+ if (known === hash) {
110
+ logger?.info(`[dsh-tty] ssh ${target} host key 指纹匹配(sha256:${hash})`);
111
+ return true;
112
+ }
113
+ hostKeyMismatch =
114
+ `SSH 主机密钥指纹变更:${target} 已记录 sha256:${known},本次为 sha256:${hash}。` +
115
+ '可能是主机重装或换钥匙,也可能是中间人(MITM)冒充;确认安全后,到 设置 → 插件 → 终端面板 → SSH 主机密钥记录 删除该主机再重连。';
116
+ logger?.warn(`[dsh-tty] ${hostKeyMismatch}`);
117
+ return false;
118
+ };
119
+ return { mismatchMessage: () => hostKeyMismatch };
120
+ }
88
121
  /**
89
122
  * 建立 SSH 连接并打开交互 shell channel,返回 TermHandle。
90
123
  * 失败(连接超时/认证被拒/host 不可达)时 reject 带人类可读信息。
@@ -92,6 +125,10 @@ function buildConnectConfig(spec) {
92
125
  export async function spawnSsh(spec, options) {
93
126
  const target = sshTarget(spec);
94
127
  const logger = options.logger;
128
+ // agent forwarding 预检:缺 SSH_AUTH_SOCK 时 ssh2 只会静默不转发,这里显式报错
129
+ if (spec.agentForward === true && (process.env.SSH_AUTH_SOCK === undefined || process.env.SSH_AUTH_SOCK === '')) {
130
+ throw new Error('agent forwarding 需要 SSH_AUTH_SOCK(本机未运行 ssh-agent 或变量未设置)');
131
+ }
95
132
  const conn = new Client();
96
133
  const output = new PassThrough();
97
134
  let exitCode = null;
@@ -121,14 +158,13 @@ export async function spawnSsh(spec, options) {
121
158
  };
122
159
  // 认证配置可能抛错(keyPath 读不到 / env 变量缺失)——先构造再连
123
160
  const connectConfig = buildConnectConfig(spec);
124
- connectConfig.hostVerifier = (hash) => {
125
- logger?.info(`[dsh-tty] ssh ${target} host key sha256:${hash}(accept-and-log 放行)`);
126
- return true;
127
- };
161
+ const policy = applyHostKeyPolicy({ connectConfig, spec, store: options.hostKeyStore, logger, target });
128
162
  const channel = await new Promise((resolve, reject) => {
129
163
  let settled = false;
130
164
  conn.on('ready', () => {
131
- conn.shell({ term: options.term, cols: options.cols, rows: options.rows }, (error, ch) => {
165
+ // agentForward 走 per-channel 请求(@types/ssh2 的 ShellOptions 未声明,
166
+ // 运行时支持;仅在本机 agent 存在时生效,见 buildConnectConfig)
167
+ conn.shell({ term: options.term, cols: options.cols, rows: options.rows, agentForward: spec.agentForward === true }, (error, ch) => {
132
168
  settled = true;
133
169
  if (error !== undefined && error !== null) {
134
170
  conn.end();
@@ -141,7 +177,11 @@ export async function spawnSsh(spec, options) {
141
177
  conn.on('error', (error) => {
142
178
  if (!settled) {
143
179
  settled = true;
144
- reject(new Error(`SSH 连接失败(${target}): ${error.message}`));
180
+ const mismatch = policy.mismatchMessage();
181
+ if (mismatch !== null)
182
+ reject(new Error(mismatch));
183
+ else
184
+ reject(new Error(`SSH 连接失败(${target}): ${error.message}`));
145
185
  }
146
186
  else {
147
187
  logger?.warn(`[dsh-tty] ssh ${target} 连接错误: ${error.message}`);
package/lib/ssh.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ssh.js","sourceRoot":"","sources":["../src/ssh.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssh.js","sourceRoot":"","sources":["../src/ssh.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { HostKeyStore, SshHostEntry } from './ssh.js';
2
+ /** 隧道规格(settings 存储;bookName 引用连接簿条目提供主机与认证)。 */
3
+ export interface TunnelSpec {
4
+ name: string;
5
+ bookName: string;
6
+ /** local = -L(本地监听 → 服务端侧拨号);remote = -R(服务端监听 → 本地拨号) */
7
+ direction: 'local' | 'remote';
8
+ /** local:本地监听端口 */
9
+ localPort?: number;
10
+ /** local:服务端侧拨号目标主机;remote:服务端监听地址(缺省 127.0.0.1) */
11
+ remoteHost?: string;
12
+ /** local:服务端侧目标端口;remote:服务端监听端口 */
13
+ remotePort?: number;
14
+ /** remote:本地拨号目标主机(缺省 127.0.0.1) */
15
+ localTargetHost?: string;
16
+ /** remote:本地拨号目标端口 */
17
+ localTargetPort?: number;
18
+ enabled: boolean;
19
+ }
20
+ export type TunnelState = 'connecting' | 'active' | 'error' | 'stopped';
21
+ export interface TunnelStatus {
22
+ name: string;
23
+ bookName: string;
24
+ direction: 'local' | 'remote';
25
+ enabled: boolean;
26
+ state: TunnelState;
27
+ error: string | null;
28
+ /** 规则的人类可读形式:`本机:5432 → db:5432` / `远程:8080 → 本机:3000` */
29
+ rule: string;
30
+ /** 当前活跃连接数 */
31
+ connections: number;
32
+ totalConnections: number;
33
+ /** 最近一次 forwardOut/转发失败原因(隧道本身 active 但目标拨号失败时可见) */
34
+ lastForwardError: string | null;
35
+ }
36
+ export interface TunnelLogger {
37
+ info(msg: string): void;
38
+ warn(msg: string): void;
39
+ }
40
+ export declare class TunnelManager {
41
+ private readonly logger;
42
+ private readonly store;
43
+ /** 按名字解析连接簿条目(实时读取,重连自动用最新凭证) */
44
+ private readonly resolveBook;
45
+ private readonly tunnels;
46
+ constructor(logger: TunnelLogger, store: HostKeyStore,
47
+ /** 按名字解析连接簿条目(实时读取,重连自动用最新凭证) */
48
+ resolveBook: (bookName: string) => SshHostEntry | undefined);
49
+ /** 按配置对齐运行态:新增/删除/规格变更重建,启停切换资源。幂等。 */
50
+ reconcile(specs: TunnelSpec[]): void;
51
+ list(): TunnelStatus[];
52
+ disposeAll(): void;
53
+ /** ------------------------------------------------------------------ */
54
+ private startTunnel;
55
+ private stopTunnel;
56
+ private connectTunnel;
57
+ /** remote 方向:让服务端监听端口(重连后必须重新调用,断线即失效)。 */
58
+ private bindRemoteListen;
59
+ private onRemoteConnection;
60
+ private onLocalConnection;
61
+ /** 失败且不再自动重试(需要人工介入:如远程端口被占、本地监听端口非法/无权限)。 */
62
+ private failTunnel;
63
+ /** 失败后按指数退避重连(1s→15s 封顶);重连期间保持 error 态供 UI 展示原因。 */
64
+ private scheduleRetry;
65
+ }