network-infra-utility 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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +21 -0
  3. data/CHANGELOG.md +31 -4
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +70 -0
  6. data/Rakefile +1 -1
  7. data/bin/dns-query +834 -0
  8. data/bin/geo-doc +135 -0
  9. data/bin/geo-get +1 -1
  10. data/document/ASNum/346/250/241/345/235/227/345/212/237/350/203/275/350/257/264/346/230/216.md +242 -0
  11. data/document/DNSQuery/345/267/245/345/205/267/344/275/277/347/224/250/346/226/271/346/263/225.md +248 -0
  12. data/document/Geo/345/221/275/344/273/244/345/267/245/345/205/267/344/275/277/347/224/250/346/226/271/346/263/225.md +441 -0
  13. data/document/IP/346/250/241/345/235/227/345/212/237/350/203/275/350/257/264/346/230/216.md +297 -0
  14. data/document/MAC/346/250/241/345/235/227/345/212/237/350/203/275/350/257/264/346/230/216.md +296 -0
  15. data/document/SSH/350/277/236/346/216/245/345/256/242/346/210/267/347/253/257/344/275/277/347/224/250/346/226/271/346/263/225.md +764 -0
  16. data/network-infra-utility.gemspec +4 -2
  17. data/network.rb +3 -1
  18. data/service/geodb/GeoAPI.md +1 -0
  19. data/service/geodb/geodb.rb +278 -1
  20. data/service/ssh/README.md +942 -0
  21. data/service/ssh/bin/ssh-client +198 -0
  22. data/service/ssh/design/SSH/350/277/236/346/216/245/345/256/242/346/210/267/347/253/257/345/212/237/350/203/275/351/234/200/346/261/202/346/226/207/346/241/243.md +292 -0
  23. data/service/ssh/design/SSH/350/277/236/346/216/245/345/256/242/346/210/267/347/253/257/350/257/246/347/273/206/350/256/276/350/256/241/346/226/207/346/241/243.md +1521 -0
  24. data/service/ssh/design/SSH/350/277/236/346/216/245/345/256/242/346/210/267/347/253/257/350/275/257/344/273/266/350/256/276/350/256/241/346/226/207/346/241/243.md +2493 -0
  25. data/service/ssh/ext/ssh_core/bin/ssh_core.cmd +28 -0
  26. data/service/ssh/ext/ssh_core/config/sys.config +0 -0
  27. data/service/ssh/ext/ssh_core/config/vm.args +0 -0
  28. data/service/ssh/ext/ssh_core/local_deps/jsx/CHECKSUM +1 -0
  29. data/service/ssh/ext/ssh_core/local_deps/jsx/LICENSE +21 -0
  30. data/service/ssh/ext/ssh_core/local_deps/jsx/README.md +696 -0
  31. data/service/ssh/ext/ssh_core/local_deps/jsx/VERSION +1 -0
  32. data/service/ssh/ext/ssh_core/local_deps/jsx/contents.tar.gz +0 -0
  33. data/service/ssh/ext/ssh_core/local_deps/jsx/metadata.config +15 -0
  34. data/service/ssh/ext/ssh_core/local_deps/jsx/rebar.config +17 -0
  35. data/service/ssh/ext/ssh_core/local_deps/jsx/rebar.lock +1 -0
  36. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx.app.src +10 -0
  37. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx.erl +506 -0
  38. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_config.erl +393 -0
  39. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_config.hrl +18 -0
  40. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_consult.erl +81 -0
  41. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_decoder.erl +1909 -0
  42. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_encoder.erl +116 -0
  43. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_parser.erl +1214 -0
  44. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_to_json.erl +408 -0
  45. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_to_term.erl +389 -0
  46. data/service/ssh/ext/ssh_core/local_deps/jsx/src/jsx_verify.erl +121 -0
  47. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx.erl +506 -0
  48. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_config.erl +393 -0
  49. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_config.hrl +18 -0
  50. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_consult.erl +81 -0
  51. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_decoder.erl +1909 -0
  52. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_encoder.erl +116 -0
  53. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_parser.erl +1214 -0
  54. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_to_json.erl +408 -0
  55. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_to_term.erl +389 -0
  56. data/service/ssh/ext/ssh_core/local_deps/jsx/src/src/jsx_verify.erl +121 -0
  57. data/service/ssh/ext/ssh_core/rebar.config +24 -0
  58. data/service/ssh/ext/ssh_core/rebar.lock +1 -0
  59. data/service/ssh/ext/ssh_core/src/ssh_auth_engine.erl +156 -0
  60. data/service/ssh/ext/ssh_core/src/ssh_channel_stm.erl +232 -0
  61. data/service/ssh/ext/ssh_core/src/ssh_codec.erl +83 -0
  62. data/service/ssh/ext/ssh_core/src/ssh_conn_sup.erl +48 -0
  63. data/service/ssh/ext/ssh_core/src/ssh_conn_worker.erl +535 -0
  64. data/service/ssh/ext/ssh_core/src/ssh_core.app.src +36 -0
  65. data/service/ssh/ext/ssh_core/src/ssh_core_app.erl +11 -0
  66. data/service/ssh/ext/ssh_core/src/ssh_core_sup.erl +46 -0
  67. data/service/ssh/ext/ssh_core/src/ssh_infra_sup.erl +104 -0
  68. data/service/ssh/ext/ssh_core/src/ssh_ipc.hrl +80 -0
  69. data/service/ssh/ext/ssh_core/src/ssh_ipc_coalesce.erl +94 -0
  70. data/service/ssh/ext/ssh_core/src/ssh_ipc_gateway.erl +467 -0
  71. data/service/ssh/ext/ssh_core/src/ssh_ipc_proto.erl +95 -0
  72. data/service/ssh/ext/ssh_core/src/ssh_jump_chain.erl +101 -0
  73. data/service/ssh/ext/ssh_core/src/ssh_keepalive_mgr.erl +222 -0
  74. data/service/ssh/ext/ssh_core/src/ssh_known_hosts_proxy.erl +67 -0
  75. data/service/ssh/ext/ssh_core/src/ssh_port_fwd.erl +225 -0
  76. data/service/ssh/ext/ssh_core/src/ssh_sftp_session.erl +250 -0
  77. data/service/ssh/ext/ssh_core/src/ssh_sftp_sup.erl +62 -0
  78. data/service/ssh/ext/ssh_core_rs/Cargo.lock +2345 -0
  79. data/service/ssh/ext/ssh_core_rs/Cargo.toml +30 -0
  80. data/service/ssh/ext/ssh_core_rs/bin/ssh_core_rs +34 -0
  81. data/service/ssh/ext/ssh_core_rs/bin/ssh_core_rs.cmd +40 -0
  82. data/service/ssh/ext/ssh_core_rs/src/channel.rs +296 -0
  83. data/service/ssh/ext/ssh_core_rs/src/coalesce.rs +143 -0
  84. data/service/ssh/ext/ssh_core_rs/src/codec.rs +71 -0
  85. data/service/ssh/ext/ssh_core_rs/src/conn.rs +628 -0
  86. data/service/ssh/ext/ssh_core_rs/src/gateway.rs +389 -0
  87. data/service/ssh/ext/ssh_core_rs/src/handler.rs +293 -0
  88. data/service/ssh/ext/ssh_core_rs/src/keepalive.rs +194 -0
  89. data/service/ssh/ext/ssh_core_rs/src/main.rs +351 -0
  90. data/service/ssh/ext/ssh_core_rs/src/portfwd.rs +378 -0
  91. data/service/ssh/ext/ssh_core_rs/src/proto.rs +198 -0
  92. data/service/ssh/ext/ssh_core_rs/src/sftp.rs +294 -0
  93. data/service/ssh/lib/network_infra_utility/ssh/automation/macro_engine.rb +213 -0
  94. data/service/ssh/lib/network_infra_utility/ssh/client.rb +257 -0
  95. data/service/ssh/lib/network_infra_utility/ssh/config/schema.rb +90 -0
  96. data/service/ssh/lib/network_infra_utility/ssh/config/settings.rb +103 -0
  97. data/service/ssh/lib/network_infra_utility/ssh/config/store.rb +90 -0
  98. data/service/ssh/lib/network_infra_utility/ssh/ipc/coalesce.rb +83 -0
  99. data/service/ssh/lib/network_infra_utility/ssh/ipc/errors.rb +36 -0
  100. data/service/ssh/lib/network_infra_utility/ssh/ipc/router.rb +212 -0
  101. data/service/ssh/lib/network_infra_utility/ssh/ipc/transport.rb +81 -0
  102. data/service/ssh/lib/network_infra_utility/ssh/security/host_key.rb +211 -0
  103. data/service/ssh/lib/network_infra_utility/ssh/security/vault.rb +211 -0
  104. data/service/ssh/lib/network_infra_utility/ssh/session/history.rb +56 -0
  105. data/service/ssh/lib/network_infra_utility/ssh/session/manager.rb +92 -0
  106. data/service/ssh/lib/network_infra_utility/ssh/session/session.rb +109 -0
  107. data/service/ssh/lib/network_infra_utility/ssh/session/tree.rb +95 -0
  108. data/service/ssh/lib/network_infra_utility/ssh/terminal/ansi_parser.rb +435 -0
  109. data/service/ssh/lib/network_infra_utility/ssh/terminal/buffer.rb +78 -0
  110. data/service/ssh/lib/network_infra_utility/ssh/terminal/emulator.rb +159 -0
  111. data/service/ssh/lib/network_infra_utility/ssh/terminal/logger.rb +195 -0
  112. data/service/ssh/lib/network_infra_utility/ssh/terminal/screen.rb +212 -0
  113. data/service/ssh/lib/network_infra_utility/ssh/terminal/theme.rb +127 -0
  114. data/service/ssh/lib/network_infra_utility/ssh/version.rb +7 -0
  115. data/service/ssh/lib/network_infra_utility/ssh.rb +44 -0
  116. data/support/basic/as_num.rb +221 -0
  117. data/support/basic/mac_address.rb +281 -0
  118. data/version.rb +1 -1
  119. metadata +138 -1
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "thor"
5
+ require_relative "../lib/network_infra_utility/ssh/client"
6
+
7
+ module NetworkInfraUtility
8
+ module SSH
9
+ # CLI 入口,Thor 命令行框架。
10
+ # V1.0:简单读-发-收交互模式
11
+ # V2.0:升级为 curses 多面板 TUI
12
+ class CLI < Thor
13
+ desc "connect HOST", "连接到 SSH 服务器"
14
+ option :user, aliases: "-u", required: true, desc: "用户名"
15
+ option :port, aliases: "-p", type: :numeric, default: 22, desc: "端口"
16
+ option :key, aliases: "-i", desc: "私钥文件路径"
17
+ option :jump, aliases: "-J", desc: "跳板机 (user@host:port)"
18
+ option :name, desc: "会话名称"
19
+ option :password, type: :boolean, desc: "使用密码认证(交互输入)"
20
+ option :theme, desc: "终端配色主题"
21
+ option :connect_timeout, type: :numeric, desc: "连接超时(秒),默认60"
22
+ option :keepalive_interval, type: :numeric, desc: "保活心跳间隔(秒),默认30,设0禁用"
23
+ option :algorithms, type: :string, desc: "自定义算法,格式: kex=algo1,algo2;cipher=aes256-ctr"
24
+
25
+ def connect(host)
26
+ client = Client.new
27
+ client.start_engine
28
+
29
+ spec = {
30
+ host: host,
31
+ port: options[:port],
32
+ user: options[:user],
33
+ name: options[:name]
34
+ }
35
+ spec[:key_path] = options[:key] if options[:key]
36
+ spec[:jumps] = parse_jumps(options[:jump]) if options[:jump]
37
+
38
+ if options[:password]
39
+ spec[:auth] = { type: "password", password: ask_password }
40
+ end
41
+
42
+ spec[:terminal] = { theme: options[:theme] } if options[:theme]
43
+
44
+ # 场景2: 可配置连接超时
45
+ spec[:connect_timeout_ms] = options[:connect_timeout] * 1000 if options[:connect_timeout]
46
+
47
+ # 场景3: 可配置保活间隔
48
+ if options[:keepalive_interval]
49
+ if options[:keepalive_interval] > 0
50
+ client.ipc.call("keepalive.set_interval", { interval_ms: options[:keepalive_interval] * 1000 })
51
+ end
52
+ end
53
+
54
+ # 场景1: 自定义算法
55
+ spec[:algorithms] = parse_algorithms(options[:algorithms]) if options[:algorithms]
56
+
57
+ session = client.connect(spec)
58
+ terminal = session.open_terminal(theme: options[:theme])
59
+
60
+ say "Connected to #{options[:user]}@#{host}:#{options[:port]}", :green
61
+ say "Type 'exit' to disconnect.", :cyan
62
+ say ""
63
+
64
+ start_interactive(session, terminal)
65
+ rescue => e
66
+ warn "Error: #{e.message}"
67
+ exit 1
68
+ ensure
69
+ client&.stop
70
+ end
71
+
72
+ desc "batch FILE", "批量在多个会话上执行命令"
73
+ option :command, aliases: "-c", required: true, desc: "要执行的命令"
74
+ option :serial, type: :boolean, default: false, desc: "串行执行(默认并行)"
75
+
76
+ def batch(file)
77
+ sessions_spec = load_sessions_from_file(file)
78
+
79
+ client = Client.new
80
+ client.start_engine
81
+
82
+ sessions = sessions_spec.map do |spec|
83
+ session = client.connect(spec)
84
+ session.open_terminal
85
+ session
86
+ end
87
+
88
+ say "Executing '#{options[:command]}' on #{sessions.size} sessions...", :cyan
89
+
90
+ if options[:serial]
91
+ sessions.each do |session|
92
+ say "[#{session.name}] ", :yellow
93
+ session.terminal.send("#{options[:command]}\r")
94
+ sleep 2
95
+ end
96
+ else
97
+ threads = sessions.map do |session|
98
+ Thread.new do
99
+ session.terminal.send("#{options[:command]}\r")
100
+ end
101
+ end
102
+ threads.each(&:join)
103
+ sleep 2
104
+ end
105
+
106
+ say "Done.", :green
107
+ rescue => e
108
+ warn "Error: #{e.message}"
109
+ exit 1
110
+ ensure
111
+ client&.stop
112
+ end
113
+
114
+ desc "version", "显示版本信息"
115
+ def version
116
+ puts NetworkInfraUtility::SSH::VERSION
117
+ end
118
+
119
+ desc "themes", "列出自带配色主题"
120
+ def themes
121
+ Terminal::Theme.builtin_names.each { |name| puts " #{name}" }
122
+ end
123
+
124
+ private
125
+
126
+ # V1.0:简单的读-发-收循环
127
+ # V2.0:升级为 curses 多面板 TUI
128
+ def start_interactive(session, terminal)
129
+ loop do
130
+ line = $stdin.gets
131
+ break if line.nil? || line.chomp == "exit"
132
+
133
+ if line.chomp == "quit"
134
+ break
135
+ end
136
+
137
+ terminal.puts(line.chomp)
138
+ end
139
+ rescue Interrupt
140
+ # Ctrl+C 退出
141
+ nil
142
+ end
143
+
144
+ # 解析跳板机参数
145
+ # @param jump_str [String] "user@host:port,user2@host2:port2"
146
+ # @return [Array<Hash>] [{user:, host:, port:}, ...]
147
+ def parse_jumps(jump_str)
148
+ jump_str.split(",").map do |j|
149
+ if j =~ /\A([^@]+)@([^:]+):(\d+)\z/
150
+ { user: Regexp.last_match(1), host: Regexp.last_match(2), port: Regexp.last_match(3).to_i }
151
+ else
152
+ raise "Invalid jump format: #{j} (expected user@host:port)"
153
+ end
154
+ end
155
+ end
156
+
157
+ # 交互式密码输入(不回显)
158
+ def ask_password
159
+ print "Password: "
160
+ system("stty -echo") if $stdin.tty?
161
+ password = $stdin.gets&.chomp
162
+ ensure
163
+ system("stty echo") if $stdin.tty?
164
+ puts
165
+ end
166
+
167
+ # 从文件加载会话列表
168
+ # @param file [String] YAML 文件路径
169
+ # @return [Array<Hash>]
170
+ def load_sessions_from_file(file)
171
+ require "yaml"
172
+
173
+ data = YAML.safe_load(File.read(file), symbolize_names: true)
174
+ raise "Invalid session file format" unless data.is_a?(Array) || data.is_a?(Hash)
175
+
176
+ data.is_a?(Hash) ? [data] : data
177
+ end
178
+
179
+ # 解析算法自定义参数
180
+ # 格式: kex=curve25519-sha256,diffie-hellman-group14-sha256;cipher=aes256-ctr
181
+ # @param str [String]
182
+ # @return [Hash] { kex: [...], cipher: [...], ... }
183
+ def parse_algorithms(str)
184
+ str.split(";").each_with_object({}) do |pair, result|
185
+ key, vals = pair.split("=", 2)
186
+ raise "Invalid algorithms format: #{pair}" unless vals
187
+
188
+ result[key.strip.to_sym] = vals.split(",").map(&:strip)
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ require_relative "../lib/network_infra_utility/ssh/version"
196
+ require_relative "../lib/network_infra_utility/ssh/terminal/theme"
197
+
198
+ NetworkInfraUtility::SSH::CLI.start(ARGV)
@@ -0,0 +1,292 @@
1
+
2
+ # SSH 连接客户端功能需求文档
3
+
4
+ > **文档版本**:v1.0
5
+ > **编写日期**:2026-08-02
6
+ > **文档状态**:初稿
7
+
8
+ ---
9
+
10
+ ## 1 文档概述
11
+
12
+ ### 1.1 编写目的
13
+
14
+ 本文档定义 SSH 连接客户端产品的完整功能需求与非功能需求,为产品设计、开发、测试验收提供统一依据。所有功能需求均具有唯一编号与可量化的验收指标,确保可测试、可验收。
15
+
16
+ ### 1.2 产品范围
17
+
18
+ 本产品定位为面向网络工程师、运维人员、开发者的跨平台 SSH 终端管理工具,覆盖远程连接、会话管理、文件传输、端口转发、终端交互、自动化操作等核心场景。
19
+
20
+ ### 1.3 术语定义
21
+
22
+ | 术语 | 定义 |
23
+ |------|------|
24
+ | SSH | Secure Shell,加密远程登录协议 |
25
+ | SFTP | SSH File Transfer Protocol,基于 SSH 的文件传输协议 |
26
+ | OTP | 一次性密码(One-Time Password),本文中指 2FA 场景 |
27
+ | MOSH | Mobile Shell,支持漫游和丢包恢复的远程连接协议 |
28
+ | X11 | X Window System 协议,用于远程图形应用转发 |
29
+ | RTT | Round-Trip Time,连接往返延迟 |
30
+ | FUR | First Useful Response,首次有效响应时间 |
31
+
32
+ ### 1.4 需求编号规则
33
+
34
+ - 格式:`FR-<模块代号>-<三位序号>`
35
+ - 模块代号:CONN(连接)、SESS(会话)、FILE(文件传输)、SEC(安全)、NET(网络)、TERM(终端)、AUTO(自动化)、COLLAB(协作)
36
+ - 优先级:P0(必须)、P1(重要)、P2(增强)
37
+
38
+ ---
39
+
40
+ ## 2 总体要求
41
+
42
+ ### 2.1 用户角色
43
+
44
+ | 角色 | 典型场景 |
45
+ |------|----------|
46
+ | 网络工程师 | 管理大量网络设备(交换机/路由器/防火墙),需要在数十台设备上批量执行命令 |
47
+ | 运维工程师 | 日常服务器运维,文件传输,端口转发排查 |
48
+ | 开发者 | 远程开发,端口转发到本地,多环境切换 |
49
+
50
+ ### 2.2 目标平台
51
+
52
+ | 平台 | 版本要求 |
53
+ |------|----------|
54
+ | Windows | 10 及以上(x64) |
55
+ | macOS | 12 Monterey 及以上 |
56
+ | Linux | Ubuntu 20.04+ / CentOS 8+ / 通用 x64 |
57
+
58
+ ---
59
+
60
+ ## 3 功能需求
61
+
62
+ ### 3.1 连接管理(CONN)
63
+
64
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
65
+ |------|----------|--------|----------|--------------|
66
+ | FR-CONN-001 | SSH2 协议支持 | P0 | 支持 SSH-2 协议,覆盖主流密钥交换与认证算法 | ① 支持密钥交换算法 ≥ 6 种(curve25519-sha256、diffie-hellman-group14-sha256、diffie-hellman-group16-sha512、ecdh-sha2-nistp256/384/521 等)② 支持公钥算法 ≥ 5 种(rsa-sha2-256/512、ssh-ed25519、ecdsa-sha2-nistp256/384/521)③ 支持对称加密算法 ≥ 6 种(aes256-gcm、aes128-gcm、chacha20-poly1305 等)④ 支持消息认证算法 ≥ 4 种(hmac-sha2-256、hmac-sha2-512 等)⑤ 协议握手完成时间 ≤ 2s(局域网 RTT < 5ms 环境)|
67
+ | FR-CONN-002 | 多认证方式 | P0 | 支持密码、公钥、键盘交互三种认证方式,单次连接支持多认证方式回退 | ① 支持认证方式 ≥ 3 种 ② 认证方式可配置优先级链(如公钥失败 → 密码)③ 密钥格式支持 ≥ 4 种(OpenSSH 格式、PuTTY .ppk、PKCS#8、SEC1)④ 密钥对生成支持 ≥ 3 种类型(RSA 2048/4096、ECDSA、Ed25519)|
68
+ | FR-CONN-003 | 跳板机跳转 | P0 | 支持通过 ProxyJump 配置多级跳板登录目标主机 | ① 支持跳板级数 ≥ 3 级 ② 跳板链可视化配置界面 ③ 每级跳板可独立配置认证方式 ④ 跳板链连接建立总耗时 ≤ 3 × 单跳握手时间 + 1s |
69
+ | FR-CONN-004 | 连接保活 | P0 | 支持 KeepAlive 心跳机制,防止 NAT 超时断连 | ① KeepAlive 间隔可配置,范围 5–300 秒 ② 连续丢失心跳 ≥ 3 次后判定断连并通知用户 ③ 空闲连接在无 KeepAlive 时存活时间 ≥ NAT 超时阈值(默认 30 分钟不主动断开)|
70
+ | FR-CONN-005 | 自动重连 | P1 | 断线后自动重新建立连接,恢复会话上下文 | ① 重连尝试次数可配置,范围 1–10 次 ② 重连间隔可配置,范围 1–60 秒,支持指数退避 ③ 重连成功后终端回滚缓冲内容保留 ④ 网络恢复后自动重连触发延迟 ≤ 5s ⑤ 重连成功率 ≥ 95%(短暂网络中断 < 30s 场景)|
71
+ | FR-CONN-006 | 多协议支持 | P1 | 除 SSH 外,支持 Telnet、Serial(串口)、RDP、VNC 协议连接 | ① 支持协议总数 ≥ 5 种 ② Telnet 协议支持协商终端类型与窗口大小 ③ Serial 支持波特率范围 300–921600,覆盖 ≥ 12 档标准值 ④ 每种协议可独立配置连接参数 |
72
+ | FR-CONN-007 | MOSH 支持 | P2 | 支持 MOSH 协议,提供移动网络环境下的弹性连接 | ① 支持 IP 漫游,切换网络后恢复时间 ≤ 3s ② 丢包率 20% 环境下仍可保持交互 ③ 需要远程端安装 mosh-server |
73
+
74
+ ### 3.2 会话管理(SESS)
75
+
76
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
77
+ |------|----------|--------|----------|--------------|
78
+ | FR-SESS-001 | 标签页与窗口拆分 | P0 | 支持多标签页管理,支持窗口水平/垂直拆分 | ① 单窗口标签页上限 ≥ 50 ② 支持水平拆分、垂直拆分、嵌套拆分 ≥ 3 层 ③ 拖拽可调整拆分面板大小 ④ 拆分面板可独立关闭/最大化 |
79
+ | FR-SESS-002 | 会话分组与树形管理 | P0 | 支持按项目/环境/机房对会话进行文件夹分组 | ① 支持分组嵌套层级 ≥ 5 层 ② 支持拖拽移动会话到不同分组 ③ 支持分组折叠/展开 ④ 单分组下会话数上限 ≥ 500 ⑤ 支持分组级别批量操作(如全部连接)|
80
+ | FR-SESS-003 | 会话导入导出 | P1 | 支持 JSON/CSV 格式会话配置导入导出 | ① 支持导出格式 ≥ 2 种(JSON、CSV)② 导出数据包含完整连接参数,不包含明文密码 ③ 支持选择性导出(按分组/按会话)④ 导入时自动校验格式,冲突项给出明确提示 ⑤ 支持从 SecureCRT/XTerminal/MobaXterm 导入会话(兼容格式 ≥ 3 种第三方工具)|
81
+ | FR-SESS-004 | 会话搜索 | P1 | 在会话列表中按名称/主机/IP/标签快速搜索 | ① 搜索字段覆盖 ≥ 4 个 ② 搜索响应时间 ≤ 200ms(1000 条会话)③ 支持模糊搜索与精确匹配切换 ④ 支持按标签筛选 |
82
+ | FR-SESS-005 | 最近连接列表 | P1 | 快速访问最近使用的会话 | ① 最近列表保留条数 ≥ 20 ② 按使用时间倒序排列 ③ 支持置顶常用会话 |
83
+ | FR-SESS-006 | 会话锁屏 | P2 | 临时离开时锁定全部会话 | ① 锁定后所有终端输入被屏蔽 ② 解锁需输入主密码 ③ 可配置自动锁屏超时时间,范围 1–60 分钟 |
84
+
85
+ ### 3.3 文件传输(FILE)
86
+
87
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
88
+ |------|----------|--------|----------|--------------|
89
+ | FR-FILE-001 | SFTP 可视化浏览器 | P0 | 内置 SFTP 文件浏览器,支持拖拽上传/下载 | ① 支持目录浏览层级无限制 ② 支持拖拽上传/下载 ③ 支持文件列表排序(名称/大小/修改时间/权限)④ 支持 ≥ 3 种视图模式(列表/详细/图标)⑤ 传输速度 ≥ 50 MB/s(千兆局域网,单文件 > 100MB)|
90
+ | FR-FILE-002 | SCP 命令传输 | P0 | 支持命令行方式文件传输 | ① 支持 `scp` 命令完整语法 ② 支持递归传输目录(-r)③ 支持断点续传 ④ 传输完成后校验文件大小与哈希 |
91
+ | FR-FILE-003 | 双面板同步浏览 | P1 | 终端与 SFTP 浏览器联动,当前目录自动同步 | ① 终端 `cd` 切换目录后,SFTP 面板 ≤ 1s 内自动跟随 ② SFTP 面板可手动锁定/解锁同步 ③ 同步延迟 ≤ 500ms |
92
+ | FR-FILE-004 | ZMODEM(rz/sz) | P1 | 支持 rz/sz 命令在终端中直接上传/下载文件 | ① 自动检测 rz/sz 命令触发文件传输窗口 ② 支持批量文件传输 ③ 传输进度实时显示 ④ 传输中断后可重新发起 |
93
+ | FR-FILE-005 | 批量文件传输 | P1 | 支持多选文件批量上传/下载,带进度条 | ① 批量传输文件数上限 ≥ 500 ② 支持并发传输通道数可配置,范围 1–10 ③ 每个文件独立进度条 + 总体进度条 ④ 传输失败自动重试次数可配,默认 3 次 |
94
+ | FR-FILE-006 | 远程文件编辑 | P2 | 远程文件右键调用本地编辑器编辑,保存后自动上传 | ① 支持配置 ≥ 1 种外部编辑器 ② 自动监听文件修改并上传 ③ 上传前可预览 diff ④ 编辑超时阈值可配置,默认 30 分钟 |
95
+
96
+ ### 3.4 安全与凭据管理(SEC)
97
+
98
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
99
+ |------|----------|--------|----------|--------------|
100
+ | FR-SEC-001 | 凭据加密存储 | P0 | 会话密码与密钥使用强加密算法存储在本地 | ① 加密算法为 AES-256-GCM 或同等强度 ② 主密码不可逆存储(PBKDF2/Argon2,迭代 ≥ 100000 次)③ 配置文件中不存在明文凭据 ④ 密钥文件权限自动设为 600(Unix)/ ACL 限制(Windows)|
101
+ | FR-SEC-002 | 主机密钥验证 | P0 | 首次连接记录主机指纹,后续连接校验一致性 | ① 首次连接弹出指纹确认对话框 ② 主机密钥变更时阻断连接并高亮告警 ③ 指纹算法覆盖 SHA-256/SHA-512 ④ 已知主机列表可查看/编辑/清空 ⑤ 支持按主机/IP 管理已知密钥 |
102
+ | FR-SEC-003 | SSH Agent 集成 | P1 | 支持 ssh-agent 密钥管理与 Agent 转发 | ① 自动检测系统 ssh-agent ② 支持 Agent 转发配置(ForwardAgent)③ 支持密钥密码缓存时长可配置 ④ 密钥缓存超时范围 5 分钟–永不超时 |
103
+ | FR-SEC-004 | 密钥对生成 | P1 | 内置密钥对生成功能 | ① 支持密钥类型 ≥ 3 种(RSA、ECDSA、Ed25519)② RSA 密钥长度可选 2048/3072/4096 ③ 生成时可配置密钥注释 ④ 支持设置密钥密码 ⑤ 可导出公钥格式 ≥ 2 种(OpenSSH、PEM)|
104
+ | FR-SEC-005 | 凭据同步加密 | P2 | 跨设备同步凭据时端到端加密 | ① 同步数据客户端加密,服务端零知识 ② 加密密钥派生自主密码 + 设备盐 ③ 同步冲突时提供三方合并界面 |
105
+ | FR-SEC-006 | 2FA/MFA 支持 | P2 | 支持双因素认证登录远程主机 | ① 支持 TOTP(RFC 6238)② 支持 keyboard-interactive 响应链 ③ OTP 种子可加密存储 ④ 支持 OTP 生成周期 30s/60s 可配置 |
106
+
107
+ ### 3.5 网络与代理(NET)
108
+
109
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
110
+ |------|----------|--------|----------|--------------|
111
+ | FR-NET-001 | 端口转发 | P0 | 支持本地/远程/动态端口转发 | ① 支持转发类型 3 种(Local、Remote、Dynamic)② 单会话可配置转发规则数 ≥ 20 条 ③ 可视化规则列表,支持启用/禁用单条规则 ④ 转发规则支持通配符端口 ⑤ 转发延迟开销 ≤ 2ms |
112
+ | FR-NET-002 | SOCKS5/HTTP 代理 | P1 | SSH 连接可通过 HTTP/SOCKS5 代理发起 | ① 支持代理类型 ≥ 2 种(HTTP CONNECT、SOCKS5)② 代理认证支持用户名/密码 ③ 可按会话配置不同代理 ④ 代理连接超时可配置,默认 10s |
113
+ | FR-NET-003 | X11 转发 | P2 | 支持远程图形应用的 X11 转发 | ① 内置 X Server 或可对接外部 X Server ② 支持单个应用窗口转发 ③ X11 转发延迟 ≤ 50ms(局域网)|
114
+ | FR-NET-004 | 连接诊断 | P1 | 内置网络诊断工具 | ① 集成工具 ≥ 4 种(ping、traceroute、TCP 端口检测、DNS 解析)② ping 支持包数/包大小可配置 ③ 端口检测支持超时配置,精度 ≤ 100ms ④ 诊断结果一键复制 |
115
+ | FR-NET-005 | 流量统计 | P2 | 显示每个会话的上下行流量统计 | ① 实时刷新间隔可配置,最小 1s ② 显示上行/下行/总量 ③ 支持按会话/按日/按月汇总 ④ 统计数据可导出 CSV |
116
+
117
+ ### 3.6 终端体验(TERM)
118
+
119
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
120
+ |------|----------|--------|----------|--------------|
121
+ | FR-TERM-001 | 终端仿真 | P0 | 支持多种终端仿真类型 | ① 支持终端类型 ≥ 3 种(xterm-256color、vt100、vt220)② 支持 256 色 + TrueColor(24 位)③ 支持 URL/文件路径/IP 自动识别可点击 ④ 正确处理 ANSI 转义序列覆盖率 ≥ 95% |
122
+ | FR-TERM-002 | 主题与配色 | P0 | 支持自定义配色方案 | ① 内置配色方案 ≥ 10 套 ② 支持导入 iTerm2/VSCode 配色文件 ③ 可自定义 16 色调色板 + 前景/背景色 ④ 主题切换实时生效 |
123
+ | FR-TERM-003 | 字体配置 | P0 | 支持自定义终端字体 | ① 支持任意等宽字体 ② 字号范围 8–32 ③ 支持行距调整 0.8–2.0 ④ 支持 Nerd Font / Powerline 字体正确渲染 ⑤ 中英文混排不错位 |
124
+ | FR-TERM-004 | 快捷键定制 | P1 | 所有快捷键可自定义映射 | ① 可定制快捷键覆盖 ≥ 30 个操作 ② 支持快捷键方案预设 ≥ 3 套(默认/Vim/Emacs)③ 支持 Chord 组合键(如 Ctrl+X Ctrl+C)④ 冲突检测与提示 |
125
+ | FR-TERM-005 | 搜索与高亮 | P1 | 终端内容搜索与关键词高亮 | ① 支持正则表达式搜索 ② 搜索范围可限定(当前屏幕/全缓冲区)③ 输入文本与输出文本视觉区分(颜色/背景)④ 关键词高亮数量无上限 ⑤ 搜索定位高亮,支持上一个/下一个导航 |
126
+ | FR-TERM-006 | 日志记录 | P0 | 会话日志自动保存 | ① 支持自动/手动开启日志 ② 日志带时间戳(可配置格式)③ 单文件日志大小上限可配置,默认 100MB,超出后自动轮转 ④ 轮转文件保留数量可配置,默认 10 个 ⑤ 日志可按会话分文件存储 ⑥ 支持日志格式纯文本/HTML(带颜色还原)|
127
+ | FR-TERM-007 | 回滚缓冲区 | P0 | 大容量回滚缓冲 | ① 默认缓冲行数 ≥ 10000 行 ② 可配置范围 1000–100000 行 ③ 回滚搜索响应 ≤ 200ms(10000 行缓冲)④ 缓冲内容可导出为文本文件 |
128
+ | FR-TERM-008 | 输入同步/广播 | P1 | 同一输入同时发送到多个终端 | ① 支持选择 ≥ 2 个会话进行广播输入 ② 广播时可指定只输入不回车 ③ 支持组广播(按分组)④ 广播状态有明确视觉标识 ⑤ 紧急停止快捷键一键取消广播 |
129
+ | FR-TERM-009 | 代码片段管理 | P1 | 常用命令片段保存和快速插入 | ① 片段支持变量占位符(如 `${ip}`、`${port}`)② 片段可分组管理 ③ 支持快捷搜索插入 ④ 单组片段数上限 ≥ 200 ⑤ 支持导入/导出片段库 |
130
+ | FR-TERM-010 | 智能选中 | P1 | URL/路径/IP 自动识别并高亮 | ① 自动识别类型 ≥ 3 种(URL、文件路径、IP 地址)② 双击选中单词,三击选中整行 ③ Ctrl+点击 URL 在浏览器打开 ④ Ctrl+点击路径在 SFTP 面板定位 |
131
+ | FR-TERM-011 | 窗口透明度 | P2 | 背景透明度调节 | ① 透明度范围 10%–100% ② 可配置是否在失焦时自动降低透明度 ③ 支持背景图片设置 |
132
+ | FR-TERM-012 | 光标样式 | P2 | 光标样式可配置 | ① 光标形状 ≥ 3 种(块状/竖线/下划线)② 闪烁频率可配置 / 可关闭 ③ 光标颜色可自定义 |
133
+
134
+ ### 3.7 自动化(AUTO)
135
+
136
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
137
+ |------|----------|--------|----------|--------------|
138
+ | FR-AUTO-001 | 登录宏/脚本 | P0 | 连接后自动执行预设命令序列 | ① 单会话宏步骤数上限 ≥ 50 步 ② 每步支持配置等待匹配文本/正则后继续 ③ 步骤间延迟可配置 0–30s ④ 支持条件分支(匹配成功 A 路径/失败 B 路径)⑤ 宏执行失败可配置继续/中止/询问 |
139
+ | FR-AUTO-002 | 会话录放 | P2 | 录制和回放终端操作 | ① 录制文件格式为标准 asciicast(asciinema 兼容)② 回放支持倍速 0.5x–4x ③ 回放支持暂停/跳转 ④ 录制时自动标注时间戳 |
140
+ | FR-AUTO-003 | 命令批量执行 | P1 | 选择多个会话,同一命令同时下发 | ① 批量执行目标会话数上限 ≥ 100 ② 执行结果分面板显示 ③ 支持结果聚合对比(关键词高亮差异)④ 执行超时可配置,默认 30s ⑤ 支持串行/并行两种执行模式 |
141
+ | FR-AUTO-004 | 本地 Shell 集成 | P1 | 内置本地终端入口 | ① 支持 Shell 类型 ≥ 3 种(Windows: PowerShell/CMD/WSL;macOS: zsh/bash;Linux: bash/zsh/fish)② 本地与远程会话在同一个标签管理下 ③ 支持 WSL 的自动检测与集成 |
142
+ | FR-AUTO-005 | 脚本引擎扩展 | P2 | 支持 Lua/Python 脚本扩展 | ① 支持脚本语言 ≥ 1 种 ② 提供 API 接口 ≥ 20 个(会话管理、终端读写、文件操作等)③ 支持 Hook 机制(连接前/断开后/数据接收时)④ 脚本可注册自定义命令到菜单 |
143
+
144
+ ### 3.8 团队协作与跨平台(COLLAB)
145
+
146
+ | 编号 | 功能名称 | 优先级 | 功能描述 | 量化验收指标 |
147
+ |------|----------|--------|----------|--------------|
148
+ | FR-COLLAB-001 | 跨平台支持 | P1 | Windows/macOS/Linux 三端覆盖 | ① 三端功能一致度 ≥ 95% ② 配置文件格式跨平台兼容 ③ 同一配置可在三端直接使用 ④ 安装包体积 ≤ 150MB(单平台)|
149
+ | FR-COLLAB-002 | 配置云同步 | P2 | 会话/设置跨设备云端同步 | ① 同步内容覆盖会话配置、密钥、代码片段、主题 ② 端到端加密,服务端不可解密 ③ 同步延迟 ≤ 5s ④ 支持多设备同时在线 ⑤ 冲突检测与手动解决 |
150
+ | FR-COLLAB-003 | 团队共享 | P2 | 团队共享会话配置,凭据不入库 | ① 共享内容分离:连接参数可共享、凭据不上传 ② 支持 RBAC 角色 ≥ 3 种(管理员/编辑者/只读)③ 共享空间支持分组 ④ 操作审计日志保留 ≥ 90 天 |
151
+ | FR-COLLAB-004 | 便携版 | P2 | 免安装绿色版 | ① 全部配置存储在程序目录下 ② 无需管理员权限运行 ③ 可从 U 盘/云盘直接运行 ④ 便携版与安装版配置可互相迁移 ⑤ 便携版体积 ≤ 80MB |
152
+
153
+ ---
154
+
155
+ ## 4 非功能需求
156
+
157
+ ### 4.1 性能指标
158
+
159
+ | 编号 | 指标名称 | 量化标准 |
160
+ |------|----------|----------|
161
+ | NFR-PERF-001 | 连接建立时间 | 局域网环境(RTT < 5ms)下 SSH 握手 + 认证完成 ≤ 2s |
162
+ | NFR-PERF-002 | 终端渲染帧率 | 持续输出场景(如 `yes` 命令)下渲染帧率 ≥ 30fps |
163
+ | NFR-PERF-003 | 终端输入延迟 | 按键到屏幕回显延迟 ≤ 50ms(局域网)|
164
+ | NFR-PERF-004 | SFTP 传输速度 | 千兆局域网下单线程传输 ≥ 50 MB/s |
165
+ | NFR-PERF-005 | 内存占用 | 10 个活跃会话同时运行,内存占用 ≤ 500MB |
166
+ | NFR-PERF-006 | 并发会话数 | 单实例可稳定维持 ≥ 50 个活跃 SSH 会话 |
167
+ | NFR-PERF-007 | 大缓冲渲染 | 50000 行回滚缓冲区内搜索,响应时间 ≤ 500ms |
168
+ | NFR-PERF-008 | 启动时间 | 冷启动到主界面可交互 ≤ 3s |
169
+
170
+ ### 4.2 可靠性
171
+
172
+ | 编号 | 指标名称 | 量化标准 |
173
+ |------|----------|----------|
174
+ | NFR-REL-001 | 连接稳定性 | 连续运行 72h 无崩溃,无内存泄漏(内存增长 ≤ 5%)|
175
+ | NFR-REL-002 | 异常恢复 | 网络中断后程序不崩溃,恢复网络后自动重连成功率 ≥ 95% |
176
+ | NFR-REL-003 | 数据完整性 | 文件传输后 MD5/SHA-256 校验通过率 100% |
177
+
178
+ ### 4.3 安全性
179
+
180
+ | 编号 | 指标名称 | 量化标准 |
181
+ |------|----------|----------|
182
+ | NFR-SEC-001 | 凭据存储 | 本地配置文件、日志文件、内存 dump 中均无明文凭据 |
183
+ | NFR-SEC-002 | 加密强度 | 密钥派生函数迭代次数 ≥ 100000 次(PBKDF2)或 Argon2id |
184
+ | NFR-SEC-003 | 依赖安全 | 第三方库无已知 CVE 高危漏洞(发布前扫描)|
185
+
186
+ ### 4.4 可用性
187
+
188
+ | 编号 | 指标名称 | 量化标准 |
189
+ |------|----------|----------|
190
+ | NFR-USE-001 | 学习成本 | 新手从安装到首次成功连接 SSH ≤ 5 分钟 |
191
+ | NFR-USE-002 | 操作效率 | 常用操作(新建会话/连接/断开/传输文件)快捷键覆盖率 100% |
192
+ | NFR-USE-003 | 国际化 | 支持中英文双语界面,语言可切换 |
193
+
194
+ ### 4.5 兼容性
195
+
196
+ | 编号 | 指标名称 | 量化标准 |
197
+ |------|----------|----------|
198
+ | NFR-COMP-001 | 操作系统兼容 | Windows 10+, macOS 12+, Ubuntu 20.04+, CentOS 8+ |
199
+ | NFR-COMP-002 | SSH 服务端兼容 | 兼容 OpenSSH 7.0+、Dropbear 2019+、Cisco IOS/IOS-XE、华为 VRP |
200
+ | NFR-COMP-003 | 显示器适配 | 支持 HiDPI/4K 显示,1080p/2K/4K 下字体不模糊 |
201
+
202
+ ---
203
+
204
+ ## 5 版本规划
205
+
206
+ ### 5.1 V1.0 — MVP 核心(P0 需求)
207
+
208
+ > 目标:可用的单用户 SSH 终端
209
+
210
+ | 需求编号 | 功能名称 |
211
+ |----------|----------|
212
+ | FR-CONN-001 | SSH2 协议支持 |
213
+ | FR-CONN-002 | 多认证方式 |
214
+ | FR-CONN-003 | 跳板机跳转 |
215
+ | FR-CONN-004 | 连接保活 |
216
+ | FR-SESS-001 | 标签页与窗口拆分 |
217
+ | FR-SESS-002 | 会话分组与树形管理 |
218
+ | FR-FILE-001 | SFTP 可视化浏览器 |
219
+ | FR-FILE-002 | SCP 命令传输 |
220
+ | FR-SEC-001 | 凭据加密存储 |
221
+ | FR-SEC-002 | 主机密钥验证 |
222
+ | FR-NET-001 | 端口转发 |
223
+ | FR-TERM-001 | 终端仿真 |
224
+ | FR-TERM-002 | 主题与配色 |
225
+ | FR-TERM-003 | 字体配置 |
226
+ | FR-TERM-006 | 日志记录 |
227
+ | FR-TERM-007 | 回滚缓冲区 |
228
+ | FR-AUTO-001 | 登录宏/脚本 |
229
+
230
+ ### 5.2 V2.0 — 效率增强(P1 需求)
231
+
232
+ > 目标:多会话批量管理、文件传输增强、网络诊断
233
+
234
+ | 需求编号 | 功能名称 |
235
+ |----------|----------|
236
+ | FR-CONN-005 | 自动重连 |
237
+ | FR-CONN-006 | 多协议支持 |
238
+ | FR-SESS-003 | 会话导入导出 |
239
+ | FR-SESS-004 | 会话搜索 |
240
+ | FR-SESS-005 | 最近连接列表 |
241
+ | FR-FILE-003 | 双面板同步浏览 |
242
+ | FR-FILE-004 | ZMODEM(rz/sz)|
243
+ | FR-FILE-005 | 批量文件传输 |
244
+ | FR-SEC-003 | SSH Agent 集成 |
245
+ | FR-SEC-004 | 密钥对生成 |
246
+ | FR-NET-002 | SOCKS5/HTTP 代理 |
247
+ | FR-NET-004 | 连接诊断 |
248
+ | FR-TERM-004 | 快捷键定制 |
249
+ | FR-TERM-005 | 搜索与高亮 |
250
+ | FR-TERM-008 | 输入同步/广播 |
251
+ | FR-TERM-009 | 代码片段管理 |
252
+ | FR-TERM-010 | 智能选中 |
253
+ | FR-AUTO-003 | 命令批量执行 |
254
+ | FR-AUTO-004 | 本地 Shell 集成 |
255
+ | FR-COLLAB-001 | 跨平台支持 |
256
+
257
+ ### 5.3 V3.0 — 差异化竞争力(P2 需求)
258
+
259
+ > 目标:协作、跨平台同步、高级扩展
260
+
261
+ | 需求编号 | 功能名称 |
262
+ |----------|----------|
263
+ | FR-CONN-007 | MOSH 支持 |
264
+ | FR-SESS-006 | 会话锁屏 |
265
+ | FR-FILE-006 | 远程文件编辑 |
266
+ | FR-SEC-005 | 凭据同步加密 |
267
+ | FR-SEC-006 | 2FA/MFA 支持 |
268
+ | FR-NET-003 | X11 转发 |
269
+ | FR-NET-005 | 流量统计 |
270
+ | FR-TERM-011 | 窗口透明度 |
271
+ | FR-TERM-012 | 光标样式 |
272
+ | FR-AUTO-002 | 会话录放 |
273
+ | FR-AUTO-005 | 脚本引擎扩展 |
274
+ | FR-COLLAB-002 | 配置云同步 |
275
+ | FR-COLLAB-003 | 团队共享 |
276
+ | FR-COLLAB-004 | 便携版 |
277
+
278
+ ---
279
+
280
+ ## 附录 A:需求统计总览
281
+
282
+ | 维度 | P0 | P1 | P2 | 合计 |
283
+ |------|----|----|----|----|
284
+ | 连接管理(CONN)| 4 | 2 | 1 | 7 |
285
+ | 会话管理(SESS)| 2 | 3 | 1 | 6 |
286
+ | 文件传输(FILE)| 2 | 3 | 1 | 6 |
287
+ | 安全与凭据(SEC)| 2 | 2 | 2 | 6 |
288
+ | 网络与代理(NET)| 1 | 2 | 2 | 5 |
289
+ | 终端体验(TERM)| 5 | 4 | 3 | 12 |
290
+ | 自动化(AUTO)| 1 | 2 | 2 | 5 |
291
+ | 协作与平台(COLLAB)| 0 | 1 | 3 | 4 |
292
+ | **合计** | **17** | **19** | **15** | **51** |