connectbot/cbssh

GitHub: connectbot/cbssh

一个用 Kotlin 构建、采用协程和声明式协议解析的现代 SSH 客户端库,支持完整的 SSH 协议、SFTP 和端口转发。

Stars: 6 | Forks: 3

# ConnectBot SSH 客户端库 [![持续集成](https://img.shields.io/github/actions/workflow/status/connectbot/cbssh/ci.yml?branch=main&label=CI)](https://github.com/connectbot/cbssh/actions/workflows/ci.yml?query=branch%3Amain) [![Maven Central](https://img.shields.io/maven-central/v/org.connectbot.sshlib/sshlib?label=Maven%20Central&color=blue)](https://central.sonatype.com/artifact/org.connectbot.sshlib/sshlib) [![许可协议](https://img.shields.io/github/license/connectbot/cbssh?label=License&color=blue)](LICENSE) [![质量门禁状态](https://img.shields.io/sonar/quality_gate/connectbot_cbssh?server=https%3A%2F%2Fsonarcloud.io&label=Quality%20Gate)](https://sonarcloud.io/summary/overall?id=connectbot_cbssh) [![覆盖率](https://img.shields.io/sonar/coverage/connectbot_cbssh?server=https%3A%2F%2Fsonarcloud.io&label=Coverage)](https://sonarcloud.io/summary/overall?id=connectbot_cbssh) 这是使用 Kotlin 构建的 ConnectBot SSH 库。内部使用协程、协议定义文件和状态机来运行 SSH 协议。目前能够连接 SSH 服务器、进行身份验证,并提供交互式 shell 会话。 协议解析使用声明式的 Kaitai Struct 规范,从 `.ksy` 定义自动生成代码。内部状态机采用 KStateMachine 定义,实现协议状态与状态变更响应代码的清晰分离。 ## 功能 - **SSH 客户端**:连接、认证、打开 shell 会话、读写数据 - **协议解析**:完整的 SSH 线路协议覆盖(RFC 4250-4256、4419、5656、8308、8709、8731、9142) - **通道 I/O**:支持 PTY 的交互式 shell、stdout/stderr 流、流量控制 - **SFTP**:文件传输,支持完整的读/写/状态/目录操作([draft-ietf-secsh-filexfer](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer)) - **端口转发**:本地、远程和动态(SOCKS5)端口转发 - **代理转发**:转发 SSH 代理请求,支持会话绑定 - **传输层**:可插拔传输层(通过 Ktor 的 TCP,或自定义) ## 算法支持 该库支持多种现代 SSH 算法,包括: - **认证**:`publickey`(包括 FIDO2/SK)、`password`、`keyboard-interactive` - **主机密钥**:Ed25519、Ed448、ECDSA、RSA(SHA-2) - **密钥交换**:ML-KEM 混合、Curve25519、ECDH、DH group-exchange - **加密**:ChaCha20-Poly1305、AES-GCM、AES-CTR - **MAC**:HMAC-SHA2(包括 ETM 变体) 完整的支持算法列表及其对应的 RFC,请参见 [docs/ALGORITHMS.md](docs/ALGORITHMS.md)。 ## 快速开始 ### 构建 ``` ./gradlew build ``` ### 使用测试 CLI 客户端 项目包含一个“testapp”,允许您从测试客户端应用尝试该库。您可以通过运行以下命令来使用它: ``` ./gradlew :testapp:installDist ./testapp/build/install/testapp/bin/testapp user@host ./testapp/build/install/testapp/bin/testapp user@host -p 2222 # 启用更多 debug logging: ./testapp/build/install/testapp/bin/testapp -d user@host ``` ### 库 API ``` val client = SshClient("example.com", port = 22, hostKeyVerifier = myVerifier) client.connect() client.authenticatePassword("user", "pass") val session = client.openSession() session.requestPty() session.requestShell() // Read/write session.write("ls\n".toByteArray()) val output = session.read() // ByteArray? (null on EOF) // Or use coroutine channels directly session.stdout // ReceiveChannel session.stderr // ReceiveChannel // Clean up session.close() client.disconnect() ``` ### SFTP 文件传输 ``` val sftp = when (val result = client.openSftp()) { is SftpResult.Success -> result.value else -> error("Failed to open SFTP: $result") } try { // List a directory when (val result = sftp.listdir("/home/user")) { is SftpResult.Success -> result.value.forEach { println(it.filename) } is SftpResult.ServerError -> println("Server error: ${result.message}") else -> println("Error: $result") } // Read a file val handle = sftp.open("/home/user/file.txt", setOf(SftpOpenFlag.READ)).getOrThrow() val data = sftp.read(handle, 0L, 4096).getOrThrow() sftp.close(handle) } finally { sftp.close() } ``` ### FIDO2 / 安全密钥认证 该库支持使用 `sk-ssh-ed25519@openssh.com` 和 `sk-ecdsa-sha2-nistp256@openssh.com` 密钥进行认证。调用方需提供自己的 FIDO2 栈,并通过库提供的辅助函数公开生成的断言。 有关详细的实现细节和示例,请参见 [docs/SK_AUTH.md](docs/SK_AUTH.md)。 ### SSH 代理转发 启用 SSH 代理转发,允许远程服务器使用您的密钥: ``` // Implement an agent provider class MyAgentProvider : AgentProvider { override suspend fun getIdentities(): List { val keyBlob = loadPublicKeyBlob() return listOf(AgentIdentity(keyBlob, "my-key")) } override suspend fun signData(context: AgentSigningContext): ByteArray? { // Show approval UI to user with session context val approved = showSigningPrompt( "Remote server ${context.serverHostKey.toHex()} wants to use your key", "Session bound: ${context.isBound}" ) return if (approved) { signWithPrivateKey(context.publicKeyBlob, context.dataToSign) } else { null // Deny the request } } } // Enable agent forwarding val client = SshClient("bastion.example.com", hostKeyVerifier = myVerifier) client.connect() client.authenticatePassword("user", "pass") client.enableAgentForwarding(MyAgentProvider()) // Now remote servers can use your agent through forwarding val session = client.openSession() session.requestShell() // When you SSH from bastion to another server, it can request signatures ``` ## 兼容性测试 该库通过 Docker(使用 Testcontainers)针对多个 SSH 服务器实现进行了测试: - **OpenSSH** 9.9p2 — 完整集成测试,包括端口转发 - **AsyncSSH**(Python)— 密码、密钥交换、MAC 和公钥认证的兼容性测试 - **Dropbear** — 兼容性测试,包括 ML-KEM 后量子密钥交换 运行集成测试:`./gradlew :sshlib:test`(需要 Docker)。 ## 当前限制 - 仅客户端(无服务器实现) ## 许可协议 Apache License 2.0 — 请参阅 LICENSE 文件 ## 版权 Copyright 2019-2025, [Kenny Root](https://github.com/kruton/)
标签:Kaitai Struct, Kotlin, KStateMachine, Maven Central, SSH客户端, SSH库, 交互式Shell, 代理转发, 内存分配, 加密通信, 协程, 安全连接, 开源库, 搜索引擎爬虫, 文件传输, 端口转发, 网络通信, 远程访问