Apache SSHD 介绍与选型指南
Apache SSHD 2.20 的定位、组件模块构成、版本线与 JDK 兼容性、核心能力实测速览,以及与 JSch/sshj 等同类 Java SSH 库的选型对比
Apache SSHD 介绍与选型指南
目标:讲清 Apache SSHD(Apache MINA SSHD)是什么、能做什么、由哪些模块构成、版本线怎么选,以及在需要"在 Java 应用里提供/使用 SSH 能力"的场景下,与其他 Java SSH 库的选型对比。本文结论均已在 Ubuntu 22.04 + OpenJDK 17 环境使用 SSHD 2.20.0 完成实测验证(嵌入服务端、SFTP、客户端连接的完整操作步骤见《Apache SSHD 2.20 嵌入式集成使用指南》)。
一、环境信息
本文结论基于以下实测环境:
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Java:OpenJDK 17.0.20.1(javac 17.0.20.1 编译 + 运行,实测通过)
- 组件版本:Apache SSHD 2.20.0(2.x 最新稳定版)
- 对照组件:OpenSSH_8.9p1 Ubuntu-3ubuntu0.18(系统自带 SSH 服务端/客户端,用于交叉验证)
- 官方站点:https://mina.apache.org/sshd-project/
- 源码仓库:https://github.com/apache/mina-sshd
二、Apache SSHD 是什么
Apache SSHD 是 Apache MINA 顶级项目下的 纯 Java 实现的 SSH-2 协议库,它同时提供两个角色:
- SSH 服务端(SshServer):以嵌入式方式跑在 Java 应用进程内,让应用自己对外提供 SSH/SFTP/SCP 服务;
- SSH 客户端(SshClient):在 Java 代码里完成 SSH 连接、认证、远程命令执行、SFTP 文件传输。
它与 OpenSSH 的关系是"补位"而非"替代":
- OpenSSH 是独立安装的系统级 SSH 服务,由 root 管理用户体系;
- SSHD 是一个 jar 依赖,
SshServer.setUpDefaultServer()几十行代码就能让任意 Java 应用(运维控制台、文件网关、数据管道 Agent、CI 执行器)多出一个 SSH 接入点,认证逻辑完全由应用代码自定义(回调接口,可接数据库、LDAP、令牌等任意体系)。
项目名中的 MINA 指其底层默认使用 Apache MINA 的 NIO 框架(Nio2ServiceFactoryFactory,实测启动日志会打印 using Nio2ServiceFactoryFactory),同时官方也提供 MINA 1.x、Netty 两种 I/O 层实现模块可替换。
关键实测证据(本文所有能力均实测过):
- 启动嵌入式服务端,回显
Embedded SSHD listening on 0.0.0.0:2222, version=APACHE-SSHD-2.20.0; - 用系统
ssh命令登录该服务端执行whoami && uname -r,正常返回命令输出; - 用系统
sftp命令向该服务端上传/下载文件,往返内容一致; - 用 SSHD 客户端 API 连接 OpenSSH 8.9p1 服务端执行远程命令,认证与取回输出正常。
三、组件与模块构成
SSHD 按"核心 + 扩展"拆分成多个 Maven 制品,坐标统一为 org.apache.sshd。以下为 Maven Central 上 org/apache/sshd/ 路径下实测枚举到的全部模块(2026-10 查询):
| 模块 | 作用 | 是否必选 |
|---|---|---|
| sshd-core | SSH-2 协议核心,同时包含服务端与客户端 | 必选 |
| sshd-common | 通用工具/序列化/密钥解析,core 的底层依赖 | 必选(随 core 引入) |
| sshd-sftp | SFTP 子系统(服务端 SftpSubsystemFactory + 客户端 SftpClient) | SFTP 场景必选 |
| sshd-scp | SCP 客户端实现 | SCP 场景选装 |
| sshd-git | Git über SSH(为 JGit 提供 SSH 传输) | Git 场景选装 |
| sshd-cli | 命令行骨架(SimpleClient/Server 命令封装) | 选装 |
| sshd-ldap | LDAP 相关辅助 | 选装 |
| sshd-pam | PAM 认证对接(JPam 集成) | 选装 |
| sshd-putty | PuTTY 私钥格式解析 | 选装 |
| sshd-openpgp | OpenPGP 密钥解析 | 选装 |
| sshd-mina / sshd-netty | 替换默认 NIO2 的 I/O 层实现 | 选装 |
| sshd-osgi | OSGi 环境适配 | 选装 |
| sshd-contrib | 社区贡献的实验性扩展 | 选装 |
两个实测确认的关键事实:
- 没有独立的 sshd-client 制品。2.20.0 的客户端类(SshClient、ClientSession 等)全部在 sshd-core 内,实测访问
https://repo1.maven.org/maven2/org/apache/sshd/sshd-client/2.20.0/sshd-client-2.20.0.jar返回 404,而jar tf sshd-core-2.20.0.jar | grep -c "org/apache/sshd"统计到 575 个类。网上部分旧资料提到的 sshd-client 制品属于早期版本结构,2.x 不要找错依赖。 - 最小可运行依赖只有 4 个 jar(跑 SFTP 再加 1 个),全部来自 Maven Central,实测大小:
sshd-core-2.20.0.jar 970864 字节
sshd-common-2.20.0.jar 966659 字节
slf4j-api-1.7.36.jar 41125 字节
slf4j-simple-1.7.36.jar 15333 字节
sshd-sftp-2.20.0.jar 394207 字节 (SFTP 子系统时追加)
SSHD 自身只强依赖 slf4j-api(日志门面),用 slf4j-simple 即可直接跑,不需要引入 MINA/Netty 的完整发行包。
四、版本线与 JDK 兼容性
实测查询 Maven Central metadata:
<latest>3.0.0-M6</latest> # Maven Central latest 指向里程碑版本
<version>2.20.0</version> # 2.x 最新稳定版
3.0.0-M1 ~ 3.0.0-M6 # 3.0 里程碑序列
选型结论:
- 生产用 2.20.0(2.x 终线,问题修复充分,资料最多);
- 3.0.0-M6 是里程碑(milestone),包名有大幅重构(如
org.apache.sshd.server.SshServer迁移到org.apache.sshd.core等调整)、要求 JDK 11+,尝鲜可以,暂不建议生产; - JDK 要求:2.x 官方要求 Java 8+,实测在 OpenJDK 17.0.20.1 下编译与运行全部正常(本文全部示例即 JDK 17 编译);
- 2.x 与 3.x 的 API 不兼容,升级 3.x 需要改包名和部分工厂接口,评估成本时注意。
五、核心能力实测速览
以下能力均在 SSHD 2.20.0 + OpenJDK 17 实测通过,完整代码与逐步操作见《Apache SSHD 2.20 嵌入式集成使用指南》。
5.1 嵌入式 SSH 服务端
约 30 行代码内完成:监听端口、生成/加载主机密钥、自定义密码认证、挂载交互 shell 与 exec 命令工厂。实测启动回显:
Embedded SSHD listening on 0.0.0.0:2222, version=APACHE-SSHD-2.20.0
系统 ssh 客户端登录执行命令(服务端自定义认证 admin 账号):
$ sshpass -p q1w2e3r4 ssh -p 2222 admin@127.0.0.1 "whoami && uname -r && echo EMBEDDED_SSH_OK"
root
6.8.0-138-generic
EMBEDDED_SSH_OK
认证成功后服务端日志:
Session admin@/127.0.0.1:59504 authenticated
5.2 SFTP 文件传输
加入 sshd-sftp 依赖并注册 SftpSubsystemFactory 后,系统 sftp 命令可直接对嵌入式服务端上传下载,实测上传 /etc/hostname(13 字节)再取回,内容逐字节一致。
5.3 SSH 客户端
SshClient.setUpDefaultClient() 连接 OpenSSH 8.9p1 服务端,实测认证成功并取回远程命令输出:
Authed as admin, server version=SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.18
Linux <hostname> 6.8.0-138-generic ... x86_64 x86_64 x86_64 GNU/Linux
uid=1000(admin) gid=1000(admin) groups=1000(admin)
5.4 其他能力(协议层自带,未逐一实测)
- 端口转发(本地/远端/动态,SSH-2 direct-tcpip / forwarded-tcpip 通道);
- 公钥认证、键盘交互认证(KeyboardInteractiveAuthenticator);
- 代理跳板(ProxyJump 风格的跳板机连接);
- SCP 客户端(sshd-scp)、Git über SSH(sshd-git)。
六、选型对比:什么时候选 SSHD
Java 生态里能用的 SSH 库主要有四类,实测+资料评估对比如下:
| 维度 | Apache SSHD 2.20.0 | JSch(mwiede fork) | sshj | Trilead/Ganymed |
|---|---|---|---|---|
| SSH 客户端 | ✅ | ✅ | ✅ | ✅ |
| 嵌入式 SSH 服务端 | ✅ 独有成熟方案 | ❌ | ❌ | ❌ |
| SFTP 服务端 | ✅(sshd-sftp) | ❌ | ❌ | ❌ |
| SFTP 客户端 | ✅ | ✅ | ✅ | ✅ |
| 协议新特性(现代 KEX/密钥) | 跟进快(含 OpenSSH 扩展协商) | fork 后跟进 | 跟进 | 基本停滞 |
| 许可证 | Apache 2.0 | BSD 风格 | Apache 2.0 | BSD 风格 |
| 维护活跃度 | Apache MINA 项目持续维护 | 原版 2018 年停更,mwiede fork 活跃 | 活跃(com.hierynomus) | 低 |
选型建议:
- 需要在 Java 应用里提供 SSH/SFTP 服务端(给外部系统一个文件交换口、给运维一个诊断入口、构建内部跳板/审计网关):只有 SSHD 能做,无需纠结,直接选;
- 只做 SSH/SFTP 客户端(连别人的服务器执行命令、传文件):SSHD、sshj、JSch fork 都能胜任。偏好 API 现代化和文档丰富选 sshj;存量 JSch 代码建议迁到
com.github.mwiede:jschfork(坐标变了、包名不变,改动最小);SSHD 客户端的优势是与自家服务端同一套 API/密钥解析,且协议特性跟进最快; - 一次实现两端(如自研文件同步工具,一端起服务端、另一端做客户端):SSHD 一套依赖搞定两端,一致性最好;
- 需要 PAM/LDAP 认证对接:SSHD 官方带 sshd-pam、sshd-ldap 扩展模块。
七、限制与注意事项
以下限制均来自官方源码注释或实测确认:
- 没有权限分离(重要)。
ProcessShellFactory的类注释明确写着:SSHD 不提供 privilege separation,SSH 用户默认不与操作系统用户绑定,shell/命令以 SSHD 服务端进程自己的 OS 用户 运行。实测印证:嵌入服务端以 root 运行时,ssh 登录自定义账号 admin 执行whoami返回root。因此:- 嵌入服务端不要用 root 跑业务进程(最小权限原则);
- SFTP 上传的文件属主是服务进程用户(实测属主显示为服务端进程用户,协议层
ls -l显示 uid/gid 为 0/0 属正常现象); - 如需真实 OS 用户切换,要么为每个 SSH 会话自行 drop privilege,要么用系统 OpenSSH。
- SimpleGeneratorHostKeyProvider 的密钥文件是 Java 私有序列化格式(
.ser),OpenSSH 无法直接识别;实测生成hostkey.ser(1811 字节,权限 600)。跨工具共享主机密钥时用ClassLoadableResourceKeyPairProvider/PEM 格式加载。 - 默认服务端无任何认证:
setUpDefaultServer()后必须自己设置PasswordAuthenticator/PublickeyAuthenticator,否则拒绝所有登录(默认行为安全,但初学者容易以为没生效)。 - exec 与 shell 是两条通道:
ssh host cmd走 exec 通道(CommandFactory),ssh host走 shell 通道(ShellFactory),两者要分别设置,只设一个就会出现"能登录不能执行命令"或反之的现象(实测踩坑,排查过程见集成指南第 8 节)。 - 3.0 里程碑版本 API 不稳定,包名与 2.x 不同,复制网上示例代码时注意核对版本。
八、小结
- Apache SSHD 是 Java 生态里唯一成熟的开源嵌入式 SSH 服务端 + 客户端双端实现,Apache 2.0 许可,2.20.0 是当前生产首选版本;
- 最小依赖 4 个 jar(约 2 MB),SFTP 场景追加 sshd-sftp(约 0.4 MB),无重依赖;
- 选型一句话:要做服务端选 SSHD 没有第二选择;只做客户端可按团队偏好在 SSHD/sshj/JSch fork 中选;
- 两大使用红线:服务进程以非 root 运行(用户不与 OS 绑定)、shell/exec 两条通道分别配置。
- 下一篇:《Apache SSHD 2.20 嵌入式集成使用指南》—— 从 0 到 1 搭建嵌入式 SSH 服务端(含 shell/exec/SFTP 三通道实测与排查实录)