SSHv2 client library for MoonBit with password and publickey authentication, SFTP v3, and local/remote/SOCKS5 port forwarding. / 使用 MoonBit 实现的 SSHv2 客户端库,支持密码/公钥认证、SFTP v3 文件传输及本地/远程/SOCKS5 端口转发
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号
MoonSSH — MoonBit SSH 客户端库
使用 MoonBit 实现的 SSHv2 客户端库
libcrypto,不重复造轮子1. 项目状态
src/socket/socket.mbt+socket.c(自带 socket FFI,支持 POSIX 与 Winsock2)Client::connect()src/packet.mbt:length / padding / payload / MAC(EtM 流加密模式)src/kex.mbt:ecdh-sha2-nistp256/diffie-hellman-group14-sha256/diffie-hellman-group14-sha1derive_keys()),HMAC-SHA-1/256 扩展ssh-rsa/rsa-sha2-256/rsa-sha2-512/ssh-dss/ecdsa-sha2-nistp256/384/521/ssh-ed25519Client::auth_password()完整流程Client::auth_publickey()(two-step 查询 + 签名);私钥支持 RSA / Ed25519 / DSA / ECDSA;公钥文件必须是 OpenSSH 单行格式Client::auth_keyboard_interactive()Client::auth_auto():none → publickey → keyboard-interactive → passwordexec命令执行Client::exec()返回(stdout, stderr)shell通道Client::shell()(不管理交互式 I/O,仅打开 shell 通道)known_hosts解析|1|…)待支持src/sftp.mbt)Client::forward_remote_port()—tcpip-forward全局请求 +forwarded-tcpip通道Client::forward_local_port()—direct-tcpip通道(双向relay_data中继)Client::forward_socks5()— SOCKS5 代理2. 架构
2.1 协议状态机
3. 项目结构
4. 快速开始
4.1 前置依赖
libcryptossh -i验证 sshdWindows 额外依赖 MinGW:
Linux
macOS:
4.2 启动测试 sshd
scripts/ssh-server/下提供本地 docker sshd 启动脚本(每个脚本独立监听端口):password.shlscr.io/linuxserver/openssh-server(密码模式)1022key-ed25519.sh2022key-rsa.sh3022key-ecdsa.sh4022forwarding.sh5022例如启动密码模式 sshd:
4.3 构建与运行
仓库根没有统一
run.sh,每个cmd/*子包自带run-*.sh脚本(除output/仅作演示外),它们做:source .env注入MSSH_HOST/MSSH_PORT/MSSH_USERNAME/MSSH_PASSWORD等变量export MOONBIT_CLI_ARGS="..."(CLI 参数通过环境变量传入 main,避免对 argv 解析的兼容问题)moon clean && moon run . --target native(一次完成编译 + 运行)CLI 参数在 main 里通过
@utils.get_argv()从MOONBIT_CLI_ARGS读取并 tokenize,因此所有命令行参数都集中在一个环境变量里。4.3.1 密码认证
等价的手动调用:
4.3.2 公钥认证(Ed25519 / RSA / ECDSA)
cmd/key/提供三个独立脚本,对应三种密钥类型:cmd/key/.env注入workspace(docker 容器内的工作目录)。如果 sshd 直接跑在本地,请把${workspace}/scripts/ssh-server/id_*改成宿主机路径。4.3.3 SFTP 文件传输
cmd/sftp/run.sh是一个端到端冒烟脚本:依次执行 ls / → mkdir → ls → put → ls → get → stat → rm → rmdir → ls。脚本先moon build一次,再多次切换MOONBIT_CLI_ARGS调用同一个二进制:支持的子命令:
ls <path>/get <remote>/put <local> <remote>/rm <path>/mkdir <path>/rmdir <path>/stat <path>。4.3.4 端口转发
端口转发通过
cmd/forwarding/入口;每种模式对应一个独立run-*.sh脚本:5. 核心模块
5.1
ConnectOptions安全默认值:
ConnectOptions::new(...)默认策略是Strict(entries=[], on_unknown=reject)——未显式配置则拒绝所有未知主机。 请按下列四种模式之一显式启用校验:.with_strict_host_key_check(content)HostKeyMismatch(MITM 警告)。.with_trust_on_first_use(content, prompt)prompt(host, alg, key) -> Bool决定是否接受并持久化到 entries;之后按 Strict 校验。.with_host_key_verifier(f)(alg, key) -> Bool回调完全接管校验;适用于自定义指纹格式、HSM / 外部 Trust Store 集成。.with_insecure_host_key()content由调用方读取 known_hosts 文件得到(本库不直接依赖文件系统,保持协议层纯净)。构造示例:
KEX 阶段在收到服务端公钥时根据策略产出
HostKeyDecision:Accept→ 继续;RejectMismatch/RejectUnknown/RejectByUser→ 抛出HostKeyMismatch,原因见HostKeyDecision::reason(host, alg)。5.2
Client顶层 APIClient::connect(opts) -> Client raise SshErrorClient::kex() -> Unit raise SshErrorClient::auth_password(pwd) -> Unit raise SshErrorClient::auth_publickey(key_path) -> Unit raise SshErrorssh-rsa/rsa-sha2-256/rsa-sha2-512/ssh-ed25519/ecdsa-sha2-nistp256/384/521/ssh-dssClient::auth_keyboard_interactive(answer_fn) -> Unit raise SshErrorClient::auth_auto(pwd, key_path?) -> Unit raise SshErrorClient::open_session() -> ChannelClient::exec(ch, cmd) -> (String, String) raise SshError(stdout, stderr)Client::shell(ch) -> Unit raise SshErrorClient::forward_local_port(local_port, remote_host, remote_port) -> Unit raise SshErrorClient::forward_remote_port(remote_port, local_host, local_port) -> Unit raise SshErrorClient::forward_socks5(local_port) -> Unit raise SshErrorClient::cancel_remote_forward(address, port) -> Unit raise SshErrorClient::close() -> Unit5.3
Channel通道底层消息:OPEN / OPEN_CONFIRMATION / OPEN_FAILURE / WINDOW_ADJUST / DATA / EXTENDED_DATA / EOF / CLOSE / REQUEST(含
exit-status/exit-signal/exec/shell/pty-req)。通道类型:
Session— exec / shell / subsystemDirectTcpip(host, port)— 本地转发(-L),客户端发起ForwardedTcpip(host, port)— 远程转发(-R),服务端发起5.4
SftpClientSFTP v3 文件传输协议客户端:
5.5
known_hostssrc/known_hosts.mbt提供 OpenSSHknown_hosts文件的解析与匹配:支持通配符(
*/?);host:port形式自动展开为[host]:port(当 port ≠ 22)。 尚未支持 HMAC-SHA1 哈希形式(|1|…)——遇到会直接返回不匹配。6. 开发流程
6.1 修改后必跑
6.2 覆盖率
6.3 派生代码
src/socket/(socket.mbt/socket.c)派生于moonbitlang/async/tls(Apache 2.0)。任何修改请保留:moonbitlang/async/socket→src/socket)7. 路线图
x11-req+x11通道,RFC 4254 §6.3.2)进展:
Client::exec_pty()高层封装(build_channel_request_pty已就绪)x11-req全局请求 +x11通道类型 +X11FakeCookie/MIT-MAGIC-COOKIE-1协议)|1|…)8. 跨平台注意
9. 引用
10. License
Apache-2.0。详见 LICENSE。