1. 概述
SSHJ 是一个开源的 Java 库,通过 SSH 协议实现与远程服务器的安全通信。
本文将介绍 SSHJ 库的核心功能和使用方法,帮助开发者快速掌握这个强大的工具。
2. 依赖配置
使用 SSHJ 库前,需要在项目中添加以下 Maven 依赖:
<dependency>
<groupId>com.hierynomus</groupId>
<artifactId>sshj</artifactId>
<version>0.38.0</version>
</dependency>
最新版本可在 Maven 中央仓库 查询。
3. SSHJ 核心功能
SSHJ 库主要用于建立 SSH 安全连接,支持以下核心功能:
✅ 文件传输:通过 SCP 或 SFTP 协议上传/下载文件
✅ 端口转发:支持本地端口转发和远程端口转发
✅ 远程命令执行:在服务器上执行任意命令
✅ 连接管理:提供连接状态监控和保活机制
4. 建立 SSH 连接
SSHJ 支持两种认证方式:密码认证和公钥认证。
4.1. 密码认证
通过密码连接服务器需要指定主机、端口、用户名和密码:
String host = "192.168.1.100";
int port = 22;
String username = "admin";
String password = "securePassword123";
SSHClient client = new SSHClient();
client.addHostKeyVerifier(new PromiscuousVerifier());
client.connect(host, port);
client.authPassword(username, password);
⚠️ 注意:PromiscuousVerifier
会跳过主机密钥验证,生产环境应使用更安全的验证方式。
4.2. 公钥认证
使用公钥认证前,需确保:
- 客户端生成密钥对
- 公钥已添加到服务器的
authorized_keys
文件
String host = "192.168.1.100";
String username = "admin";
File privateKeyFile = new File("/home/user/.ssh/id_rsa");
int port = 22;
SSHClient client = new SSHClient();
KeyProvider privateKey = client.loadKeys(privateKeyFile.getPath());
client.addHostKeyVerifier(new PromiscuousVerifier());
client.connect(host, port);
client.authPublickey(username, privateKey);
5. 执行远程命令
通过 SSHJ 执行远程命令非常简单:
SSHClient sshClient = new SSHClient();
// ...(连接代码省略)
Session session = sshClient.startSession();
Command cmd = session.exec("ls -lsa");
BufferedReader reader = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
cmd.join(5, TimeUnit.SECONDS);
session.close();
✅ 关键点:
- 使用
BufferedReader
读取命令输出 join()
方法设置命令超时时间- 执行完毕后务必关闭会话
6. SCP 文件传输
SCP(Secure Copy)提供简单的文件传输方案。
6.1. 文件上传
String filePath = "/local/path/file.txt";
SSHClient ssh = new SSHClient();
// ...(连接代码省略)
ssh.useCompression(); // 启用压缩提升传输速度
ssh.newSCPFileTransfer()
.upload(new FileSystemFile(filePath), "/remote/upload/");
⚡ 性能优化:useCompression()
启用 zlib 压缩,大文件传输时效果显著。
6.2. 文件下载
String downloadPath = "/local/download/";
String fileName = "remote_file.txt";
SSHClient ssh = new SSHClient();
// ...(连接代码省略)
ssh.useCompression();
ssh.newSCPFileTransfer()
.download("/remote/upload/" + fileName, downloadPath);
7. SFTP 文件传输
SFTP(SSH File Transfer Protocol)提供更丰富的文件操作功能。
7.1. 文件上传
String filePath = "/local/path/file.txt";
SSHClient ssh = new SSHClient();
// ...(连接代码省略)
SFTPClient sftp = ssh.newSFTPClient();
sftp.put(new FileSystemFile(filePath), "/remote/upload/");
sftp.close();
7.2. 文件下载
String downloadPath = "/local/download/";
String fileName = "remote_file.txt";
SSHClient ssh = new SSHClient();
// ...(连接代码省略)
SFTPClient sftp = ssh.newSFTPClient();
sftp.get("/remote/upload/" + fileName, downloadPath);
sftp.close();
✅ 优势:SFTP 支持目录操作、文件权限管理等高级功能。
8. 本地端口转发
将远程服务端口映射到本地,实现安全访问:
SSHClient ssh = new SSHClient();
// ...(连接代码省略)
Parameters params = new Parameters(
ssh.getRemoteHostname(), // 远程主机
8081, // 本地端口
"internal-service.com", // 目标主机
80 // 目标端口
);
ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(params.getLocalHost(), params.getLocalPort()));
ssh.newLocalPortForwarder(params, ss).listen();
🔧 应用场景:安全访问内网服务,如数据库、管理后台等。
9. 远程端口转发
将本地服务暴露给远程服务器网络:
SSHClient ssh = new SSHClient();
// ...(连接代码省略)
ssh.getConnection()
.getKeepAlive()
.setKeepAliveInterval(5); // 保活间隔
ssh.getRemotePortForwarder()
.bind(
new Forward(8083), // 远程端口
new SocketForwardingConnectListener(
new InetSocketAddress("localhost", 8080) // 本地服务
)
);
ssh.getTransport().join(); // 保持连接
⚠️ 注意:需确保防火墙允许相应端口的访问。
10. 连接状态监控
通过 KeepAlive 机制检测连接状态:
String hostName = "192.168.1.100";
String userName = "admin";
String password = "securePassword123";
DefaultConfig defaultConfig = new DefaultConfig();
defaultConfig.setKeepAliveProvider(KeepAliveProvider.KEEP_ALIVE);
SSHClient ssh = new SSHClient(defaultConfig);
ssh.addHostKeyVerifier(new PromiscuousVerifier());
ssh.connect(hostName, 22);
ssh.getConnection()
.getKeepAlive()
.setKeepAliveInterval(5); // 5秒保活间隔
ssh.authPassword(userName, password);
// 示例:长时间运行的任务
Session session = ssh.startSession();
session.allocateDefaultPTY();
new CountDownLatch(1).await(); // 模拟长时间任务
session.close();
ssh.disconnect();
✅ 关键配置:
KeepAliveProvider.KEEP_ALIVE
启用保活机制setKeepAliveInterval()
设置保活间隔(建议 5-30 秒)
11. 总结
SSHJ 是一个功能全面的 Java SSH 客户端库,主要优势包括:
✅ 多种认证方式:密码/公钥认证灵活切换
✅ 双协议文件传输:SCP 简单高效,SFTP 功能丰富
✅ 端口转发能力:支持本地/远程端口转发
✅ 连接管理完善:提供保活机制和状态监控
对于需要 SSH 功能的 Java 项目,SSHJ 是一个值得考虑的解决方案。本文所有示例代码可在 GitHub 获取。