Java怎麼使用SSH連接服務器

1.簡介

SSH,也稱為安全外殼或安全套接字外殼,是一種網絡協議,允許一台計算機通過不安全的網絡安全地連接到另一台計算機。在本教程中,我們將展示如何使用JSch和Apache MINA SSHD庫通過Java與遠程SSH服務器建立連接

在我們的示例中,我們將首先打開SSH連接,然後執行一個命令,讀取輸出並將其寫入控制台,最後關閉SSH連接。我們將使示例代碼盡可能簡單。

2. JSch

JSch是SSH2的Java實現,它使我們可以連接到SSH服務器並使用端口轉發,X11轉發和文件傳輸。而且,它已獲得BSD樣式許可的許可,並為我們提供了一種與Java建立SSH連接的簡便方法。

首先,讓我們將JSch Maven依賴項添加到我們的pom.xml文件中:

<dependency>

 <groupId>com.jcraft</groupId>

 <artifactId>jsch</artifactId>

 <version>0.1.55</version>

 </dependency>

2.1 實現方式

要使用JSch建立SSH連接,我們需要一個用戶名,密碼,主機URL和SSH端口。默認的SSH端口是22,但是可能會發生這樣的情況,我們將服務器配置為使用其他端口進行SSH連接:

public static void listFolderStructure(String username, String password,

 String host, int port, String command) throws Exception {



 Session session = null;

 ChannelExec channel = null;



 try {

 session = new JSch().getSession(username, host, port);

 session.setPassword(password);

 session.setConfig("StrictHostKeyChecking", "no");

 session.connect();



 channel = (ChannelExec) session.openChannel("exec");

 channel.setCommand(command);

 ByteArrayOutputStream responseStream = new ByteArrayOutputStream();

 channel.setOutputStream(responseStream);

 channel.connect();



 while (channel.isConnected()) {

 Thread.sleep(100);

 }



 String responseString = new String(responseStream.toByteArray());

 System.out.println(responseString);

 } finally {

 if (session != null) {

 session.disconnect();

 }

 if (channel != null) {

 channel.disconnect();

 }

 }

 }

正如我們在代碼中看到的,我們首先創建一個客戶端會話並將其配置為連接到我們的SSH服務器。然後,我們創建一個用於與SSH服務器通信的客戶端通道,並在其中提供通道類型-在這種情況下為exec,這意味著我們將把Shell命令傳遞給服務器。

另外,我們應該為將要寫入服務器響應的通道設置輸出流。使用channel.connect()方法建立連接後,將傳遞命令,並將接收到的響應寫入控制台。

讓我們看看如何使用JSch提供的不同配置參數

  • StrictHostKeyChecking –指示應用程序是否將檢查是否可以在已知主機之間找到主機公鑰。另外,可用的參數值是askyes,no ,其中ask是默認值。如果我們將此屬性設置為yes ,那麼JSch將永遠不會將主機密鑰自動添加到known_hosts文件,並且它將拒絕連接主機密鑰已更改的主機。這將強制用戶手動添加所有新主機。如果將其設置為no ,那麼JSch將自動將新的主機密鑰添加到已知主機列表中
  • compression.s2c –指定是否對服務器到客戶端應用程序的數據流使用壓縮。可用值是zlibnone值,第二個是默認值
  • compression.c2s –指定是否在客戶端-服務器方向上對數據流使用壓縮。可用值是zlibnone值,第二個是默認值

與服務器的通信結束後關閉會話和SFTP通道很重要,以避免內存洩漏

3. Apache MINA SSHD

Apache MINA SSHD為基於Java的應用程序提供SSH支持。該庫基於Apache MINA(一種可擴展的高性能異步IO庫)。

讓我們添加Apache Mina SSHD Maven依賴項

<dependency>

 <groupId>org.apache.sshd</groupId>

 <artifactId>sshd-core</artifactId>

 <version>2.5.1</version>

 </dependency>

3.1 代碼實現

讓我們看一下使用Apache MINA SSHD連接到SSH服務器的代碼示例:

public static void listFolderStructure(String username, String password,

 String host, int port, long defaultTimeoutSeconds, String command) throws IOException {



 SshClient client = SshClient.setUpDefaultClient();

 client.start();



 try (ClientSession session = client.connect(username, host, port)

 .verify(defaultTimeoutSeconds, TimeUnit.SECONDS).getSession()) {

 session.addPasswordIdentity(password);

 session.auth().verify(defaultTimeoutSeconds, TimeUnit.SECONDS);



 try (ByteArrayOutputStream responseStream = new ByteArrayOutputStream();

 ClientChannel channel = session.createChannel(Channel.CHANNEL_SHELL)) {

 channel.setOut(responseStream);

 try {

 channel.open().verify(defaultTimeoutSeconds, TimeUnit.SECONDS);

 try (OutputStream pipedIn = channel.getInvertedIn()) {

 pipedIn.write(command.getBytes());

 pipedIn.flush();

 }



 channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),

 TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds));

 String responseString = new String(responseStream.toByteArray());

 System.out.println(responseString);

 } finally {

 channel.close(false);

 }

 }

 } finally {

 client.stop();

 }

 }

使用Apache MINA SSHD時,我們的事件序列與JSch類似。首先,我們使用SshClient類實例建立與SSH服務器的連接。如果我們使用SshClient.setupDefaultClient(),對其進行初始化,那麼我們將能夠使用具有適合大多數用例的默認配置的實例。這包括密碼,壓縮,MAC,密鑰交換和簽名。

在那之後,我們將創建ClientChannel並將ByteArrayOutputStream附加到它,以便將其用作響應流。如我們所見,SSHD需要為每個操作定義超時。它還允許我們使用Channel.waitFor()方法定義在命令傳遞後等待服務器響應的時間。

請務必注意, SSHD會將完整的控制台輸出寫入響應流。 JSch僅使用命令執行結果來執行此操作。

有關Apache Mina SSHD的完整文檔可在該項目的官方GitHub存儲庫中找到

4。結論

本文說明瞭如何使用兩個可用的Java庫(JSch和Apache Mina SSHD)與Java建立SSH連接。我們還展示瞭如何將命令傳遞到遠程服務器並獲得執行結果。另外,可以在GitHub上獲得完整的代碼示例。