首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java SSH 自動化利器:Ganymed SSH-2 庫實戰入門

     編輯:Java 相關知識

在需要從 Java 程式遠端執行 Linux 指令、傳輸檔案或建立通道時,Ganymed SSH-2 是一個純 Java 實作、零外部依賴(含加密算法)、支援 SSH-2 完整功能(Shell、Port Forwarding、SCP/SFTP、X11 Forwarding)的輕量級選擇。本文以最小化範例示範如何建立連線、認證、執行指令並讀取結果。

環境準備

  • JDK 1.4.2+ / 5.0+(現代專案建議 JDK 8+)
  • Maven 依賴(中央倉庫群組 ID 已遷移至 com.ganymed):
    <dependency>
        <groupId>com.ganymed</groupId>
        <artifactId>ganymed-ssh2</artifactId>
        <version>262</version> <!-- 或更新版本 -->
    </dependency>

核心 API 流程

  1. new Connection(hostname) 建立連線物件
  2. conn.connect() 發起 TCP 連線並完成 SSH 協議握手
  3. conn.authenticateWithPassword(user, pass) 密碼認證(亦支援 Public Key)
  4. conn.openSession() 開啟會話通道
  5. session.execCommand(cmd) 執行遠端指令
  6. 透過 session.getStdout() 讀取標準輸出(建議用 StreamGobbler 處理流)
  7. session.getExitStatus() 取得退出碼
  8. 關閉 Session 與 Connection 釋放資源

完整可運行範例

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;

public class SshExecutor {
    public static void main(String[] args) {
        String hostname = "192.168.0.1";
        String username = "root";
        String password = "password";

        try (Connection conn = new Connection(hostname)) {
            conn.connect();
            System.out.println("✅ TCP 連線與 SSH 握手成功");

            boolean authenticated = conn.authenticateWithPassword(username, password);
            if (!authenticated) throw new IOException("❌ 認證失敗,請檢查帳密或 SSH 伺服器設定");
            System.out.println("✅ 認證通過");

            try (Session sess = conn.openSession()) {
                sess.execCommand("uname -a");
                System.out.println("📋 遠端主機資訊:");

                // 使用 StreamGobbler 正確處理輸出流(含 stderr 合併)
                InputStream stdout = new StreamGobbler(sess.getStdout());
                try (BufferedReader br = new BufferedReader(new InputStreamReader(stdout))) {
                    String line;
                    while ((line = br.readLine()) != null) {
                        System.out.println(line);
                    }
                }

                Integer exitCode = sess.getExitStatus();
                System.out.println("🏁 指令退出碼: " + (exitCode != null ? exitCode : "N/A"));
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(2);
        }
    }
}

執行輸出範例

✅ TCP 連線與 SSH 握手成功
✅ 認證通過
📋 遠端主機資訊:
Linux localhost.localdomain 2.6.22 #1 SMP Wed Aug 13 11:24:59 CST 2008 i686 i686 i386 GNU/Linux
🏁 指令退出碼: 0

進階應用場景

  • 互動式 Shell:使用 session.startShell() 取代 execCommand,透過 stdin/stdout 實現持久終端機互動。
  • Port Forwarding:conn.createLocalPortForwarder(localPort, targetHost, targetPort) 實現本地埠映射至遠端服務(如跳板機連資料庫)。
  • SCP/SFTP:搭配 SCPClient 或 SFTPClient 進行檔案上傳下載。
  • 公鑰認證:conn.authenticateWithPublicKey(user, keyFile, keyPassphrase) 實現免密登入,提升自動化安全性。

常見坑點與對策

現象原因解決
IOException: "Authentication method password not supported"SSH 伺服器禁用密碼認證,僅允許公鑰改用公鑰認證,或修改 sshd_config 開啟 PasswordAuthentication
讀取 stdout 卡住/不完全未處理 stderr,導致緩衝區塞滿使用 StreamGobbler 同時消費 stdout/stderr,或合併讀取
中文亂碼遠端 Locale 或 Java 預設編碼不一致指定 new InputStreamReader(stdout, "UTF-8") 或遠端環境編碼
連線超時防火牆/安全組阻擋 22 埠檢查網路通達性、安全組規則、SSH 伺服器監聽地址

結語

Ganymed SSH-2 雖已停止維護(最後更新 2015 年),但其純 Java、零依賴、API 簡潔的特性,使其在輕量級自動化腳本、舊系統維護、嵌入式環境中仍具不可替代的價值。新專案若需更活躍的社群與現代特性(如 ProxyJump、Ed25519 金鑰),可評估 JSch (仍活躍) 或 Apache MINA SSHD。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved