ssh-channels-hub 0.2.0

A CLI tool for managing SSH port forwarding tunnels with auto-reconnect
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# 使用教程

本文档提供 SSH Channels Hub 的常见使用场景和详细教程。

## 目录

1. [端口转发(SSH 隧道)]#端口转发ssh-隧道
2. [远程端口转发(ssh -R 风格)]#远程端口转发ssh--r-风格
3. [监控远程日志]#监控远程日志
4. [执行远程命令]#执行远程命令
5. [多 channels 管理]#多-channels-管理

---

## 端口转发(SSH 隧道)

### 场景说明

当你需要在本地访问远程服务器上的服务时,可以使用 SSH 端口转发功能。例如:

- 远程服务器上有一个监听在 `8080` 端口的 Web 服务
- 你希望通过本地 `18080` 端口访问这个服务
- 流量将通过 SSH 隧道安全地转发

### 配置步骤

#### 1. 定义 hosts

首先在配置文件中定义一个 host:

```toml
[[hosts]]
name = "remote-server"
host = "your-remote-server.com"  # 远程服务器地址
port = 22                         # SSH 端口(可选,默认为 22)
username = "your-username"        # SSH 用户名

[hosts.auth]
type = "key"                      # 认证方式:key 或 password
key_path = "~/.ssh/id_rsa"        # SSH 私钥路径
# 如果密钥有密码保护,可以添加:
# passphrase = "your-key-passphrase"
```

**使用密码认证的示例**:

```toml
[[hosts]]
name = "remote-server"
host = "your-remote-server.com"
port = 22                         # SSH 端口(可选,默认为 22)
username = "your-username"

[hosts.auth]
type = "password"
password = "your-password"
```

#### 2. 定义 channels

然后定义一个 channel 来实现端口转发:

```toml
[[channels]]
name = "web-service-tunnel"       # channel 名称(唯一标识)
hostname = "remote-server"         # 引用上面定义的 host name
ports = "18080:8080"               # 格式 "本地端口:远程端口"
# dest_host = "127.0.0.1"         # 可选,默认为 "127.0.0.1"
```

### 完整配置示例

```toml
# 重连配置(全局)
[reconnection]
max_retries = 0
initial_delay_secs = 1
max_delay_secs = 30
use_exponential_backoff = true

# hosts 定义
[[hosts]]
name = "remote-server"
host = "example.com"
port = 22                         # SSH 端口(可选,默认为 22)
username = "user"

[hosts.auth]
type = "key"
key_path = "~/.ssh/id_rsa"

# channels 定义
[[channels]]
name = "web-service-tunnel"
hostname = "remote-server"
ports = "18080:8080"
# dest_host = "127.0.0.1"  # 可选,默认为 "127.0.0.1"
```

### 使用方法

1. **保存配置文件**

   将上述配置保存到默认配置文件位置(按顺序查找,使用匹配的第一个):
   - **当前目录**: `./configs.toml`
   - **Linux/macOS**: `~/.config/ssh-channels-hub/config.toml`
   - **Windows**: `%APPDATA%\ssh-channels-hub\config.toml`

   或使用自定义路径,通过 `--config` 参数指定。

2. **验证配置**

   ```bash
   ssh-channels-hub validate
   ```

   或验证指定配置文件:

   ```bash
   ssh-channels-hub validate --config /path/to/config.toml
   ```

3. **启动服务**

   前台运行(默认,按 Ctrl+C 停止):

   ```bash
   ssh-channels-hub start
   ```

   后台运行(daemon 模式):

   ```bash
   ssh-channels-hub start -D
   #
   ssh-channels-hub start --daemon
   ```

   启用调试日志:

   ```bash
   ssh-channels-hub start --debug
   ```

4. **访问服务**

   启动成功后,在浏览器或客户端中访问:

   ```text
   http://localhost:18080
   ```

   流量将通过 SSH 隧道转发到远程服务器的 `127.0.0.1:8080`
---

## 远程端口转发(ssh -R 风格)

### 场景说明

当你想把**本机**上的服务暴露到**远程 SSH 服务器**的端口时,使用远程端口转发(等价于 `ssh -R`)。例如:

- 本机有一个监听在 `80` 端口的 Web 服务
- 你希望远程服务器上的 `8022` 端口接受连接后,经 SSH 隧道转发到本机 `127.0.0.1:80`
- 这样从外网访问「服务器:8022」即可访问你本机的 Web 服务

### 配置步骤

在 channel 中设置 `channel_type = "forwarded-tcpip"`,`ports` 格式为 **"远程端口:本地端口"**:

```toml
[[channels]]
name = "expose-local-web"
channel_type = "forwarded-tcpip"
hostname = "remote-server"   # 引用上面定义的 host
ports = "8022:80"             # 远程服务器绑定 8022,转发到本机 127.0.0.1:80
# dest_host = "127.0.0.1"     # 可选,本机要连接到的地址,默认为 127.0.0.1
```

### 使用方法

1. 启动服务后,SSH 会向服务器发送 `tcpip-forward` 请求,在服务器上绑定指定端口(如 8022)。
2. 当有人连接「服务器:8022」时,服务器通过 SSH 打开 `forwarded-tcpip` 通道,本程序连接本机 `dest_host:local_port` 并双向转发数据。
3. 在服务器上可用 `curl http://127.0.0.1:8022` 或从外网访问「服务器公网 IP:8022」来访问本机服务(需服务器防火墙放行)。

**注意**:`ssh test` 命令只测试本地监听端口,不会测试远程转发 channel;远程转发需在服务器侧用实际连接验证。

---

(上文「端口转发」一节中的后续步骤:)

1. **检查状态**

   ```bash
   ssh-channels-hub status
   ```

2. **停止服务**

   通过 IPC 向运行中的服务发送停止信号,服务会主动退出并清理;然后删除 run 文件(`.pid``.port`)。若使用非默认配置,需加 `--config`
   ```bash
   ssh-channels-hub stop
   ssh-channels-hub stop --config /path/to/config.toml
   ```

### 工作原理

端口转发的工作原理:

```text
本地应用 → localhost:18080 → SSH 隧道 → 远程服务器:127.0.0.1:8080
```

- **ports** (`"本地端口:远程端口"`): 本地监听端口与远程目标端口,均为必填,例如 `"18080:8080"`
- **目标地址** (`dest_host`): 远程服务器上的目标地址,默认为 `127.0.0.1`(可选)

### 注意事项

1. **服务监听地址**

   确保远程服务器上的服务监听在正确的地址:
   - 如果服务监听在 `127.0.0.1:8080``dest_host` 使用 `"127.0.0.1"`
   - 如果服务监听在 `0.0.0.0:8080``dest_host` 仍使用 `"127.0.0.1"` 即可

2. **端口占用**

   **自动检查**: 服务启动前会自动检查所有配置的本地端口是否被占用。如果检测到端口已被占用,服务将不会启动,并显示明确的错误信息,例如:

   ```text
   Error: Port(s) already in use: 18080, 3306. Please stop the application using these ports or change the configuration.
   ```

   如果遇到端口占用错误,可以:
   - 更换为其他端口(如 `18081``18082` 等)
   - 或停止占用该端口的程序
   - 手动检查端口占用情况:

   ```bash
   # Linux/macOS
   lsof -i :18080
   #
   netstat -an | grep 18080

   # Windows
   netstat -ano | findstr :18080
   ```

3. **SSH 权限**

   确保 SSH 用户有权限访问远程服务器,并且能够建立 SSH 连接。

4. **防火墙**

   确保本地防火墙允许监听配置中的本地端口(`ports` 中的本地端口)。

### 常见使用场景

#### 场景 1: 访问远程数据库

```toml
[[hosts]]
name = "db-server"
host = "db.example.com"
username = "admin"

[hosts.auth]
type = "key"
key_path = "~/.ssh/id_rsa"

[[channels]]
name = "mysql-tunnel"
hostname = "db-server"
ports = "3306:3306"
dest_host = "127.0.0.1"
```

然后可以使用 MySQL 客户端连接 `localhost:3306`。

#### 场景 2: 访问远程 Web 服务

```toml
[[hosts]]
name = "web-server"
host = "web.example.com"
username = "deploy"

[hosts.auth]
type = "key"
key_path = "~/.ssh/deploy_key"

[[channels]]
name = "web-tunnel"
hostname = "web-server"
ports = "8080:80"
dest_host = "127.0.0.1"
```

访问 `http://localhost:8080` 即可访问远程服务器的 Web 服务。

#### 场景 3: 访问远程 Redis

```toml
[[hosts]]
name = "redis-server"
host = "redis.example.com"
username = "redis-user"

[hosts.auth]
type = "password"
password = "your-password"

[[channels]]
name = "redis-tunnel"
hostname = "redis-server"
ports = "6379:6379"
dest_host = "127.0.0.1"
```

---

## 监控远程日志

### 日志监控场景

需要实时监控远程服务器上的日志文件,例如应用日志、系统日志等。

### 日志监控配置

```toml
[[hosts]]
name = "app-server"
host = "app.example.com"
username = "admin"

[hosts.auth]
type = "key"
key_path = "~/.ssh/id_rsa"

[[channels]]
name = "app-logs"
hostname = "app-server"
ports = "9999:22"   # 占位示例;当前仅支持端口转发
dest_host = "127.0.0.1"
```

**注意**: 对于日志监控,实际上应该使用 `session` 类型的 channel,而不是 `direct-tcpip`。当前配置系统主要支持端口转发场景。日志监控功能可能需要使用其他工具或等待后续功能支持。

---

## 执行远程命令

### 命令执行场景

需要在远程服务器上执行命令并查看输出。

**注意**: 当前版本的配置系统主要支持端口转发场景。执行远程命令的功能可能需要使用其他工具或等待后续功能支持。

---

## 多 channels 管理

### 多 channels 场景

同时管理多个 SSH 连接和端口转发。

### 多 channels 配置

```toml
[reconnection]
max_retries = 0
initial_delay_secs = 1
max_delay_secs = 30
use_exponential_backoff = true

# 定义多个 hosts
[[hosts]]
name = "server1"
host = "server1.example.com"
username = "user1"

[hosts.auth]
type = "key"
key_path = "~/.ssh/id_rsa"

[[hosts]]
name = "server2"
host = "server2.example.com"
username = "user2"

[hosts.auth]
type = "password"
password = "password2"

# 定义多个 channels
[[channels]]
name = "db-tunnel"
hostname = "server1"
ports = "3306:3306"
dest_host = "127.0.0.1"

[[channels]]
name = "web-tunnel"
hostname = "server2"
ports = "8080:80"
dest_host = "127.0.0.1"

[[channels]]
name = "redis-tunnel"
hostname = "server1"
ports = "6379:6379"
dest_host = "127.0.0.1"
```

### 使用说明

1. 所有 channels 会在服务启动时同时建立
2. 每个 channel 独立管理,互不影响
3. 如果某个 channel 断开,会自动重连(根据重连配置)
4. 使用 `status` 命令可以查看所有 channels 的状态

---

## 故障排查

### 连接失败

1. **检查 SSH 连接**

   ```bash
   ssh username@hostname -p port
   ```

   确保能够手动建立 SSH 连接。

2. **检查认证信息**

   - 密钥路径是否正确
   - 密钥权限是否正确(应该是 600)
   - 密码是否正确

3. **检查网络连接**

   确保能够访问远程服务器的 SSH 端口。

### 端口转发不工作

1. **检查本地端口**

   服务启动时会自动检查端口占用。如果启动失败并提示端口被占用,请检查:

   ```bash
   # Linux/macOS
   lsof -i :18080

   # Windows
   netstat -ano | findstr :18080
   ```

   如果端口被占用,请停止占用该端口的程序或更换配置中的端口号。

2. **检查远程服务**

   在远程服务器上检查服务是否正常运行:

   ```bash
   # 在远程服务器上执行
   curl http://127.0.0.1:8080
   ```

3. **检查日志**

   使用 `--debug` 参数启动服务,查看详细日志:

   ```bash
   ssh-channels-hub start --debug
   ```

### 配置错误

使用 `validate` 命令检查配置:

```bash
ssh-channels-hub validate
```

常见错误:

- `hostname` 字段引用了不存在的 `hosts.name`
- 缺少必需的字段(如 `name``hostname``ports` 等)
- TOML 格式错误(括号不匹配、引号不匹配等)

---

## 相关文档

- [配置文档]./configuration.md - 详细的配置说明
- [架构设计]./architecture.md - 系统架构说明
- [工作流程]./workflow.md - 应用程序工作流程

---

## 反馈和建议

如果遇到问题或有改进建议,请:

1. 查看 [故障排查]#故障排查 部分
2. 检查 [配置文档]./configuration.md 中的详细说明
3. 提交 Issue 或 PR