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
–指示應用程序是否將檢查是否可以在已知主機之間找到主機公鑰。另外,可用的參數值是ask
,yes,
和no
,其中ask
是默認值。如果我們將此屬性設置為yes
,那麼JSch將永遠不會將主機密鑰自動添加到known_hosts
文件,並且它將拒絕連接主機密鑰已更改的主機。這將強制用戶手動添加所有新主機。如果將其設置為no
,那麼JSch將自動將新的主機密鑰添加到已知主機列表中 -
compression.s2c
–指定是否對服務器到客戶端應用程序的數據流使用壓縮。可用值是zlib
,none
值,第二個是默認值 -
compression.c2s
–指定是否在客戶端-服務器方向上對數據流使用壓縮。可用值是zlib
,none
值,第二個是默認值
與服務器的通信結束後,關閉會話和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上獲得完整的代碼示例。