Рубрики
Без рубрики

SSH-Соединение С Java

Узнайте, как установить SSH – соединение с Java, используя две доступные библиотеки Java-JSch и Apache Mina SSHD.

Автор оригинала: Maja Joksovic.

1. введение

SSH , также известный как Secure Shell или Secure Socket Shell, – это сетевой протокол, который позволяет одному компьютеру безопасно подключаться к другому компьютеру по незащищенной сети. В этом уроке мы покажем, как установить соединение с удаленным SSH-сервером с помощью Java с помощью библиотек JSch и Apache MINA SSHD .

В наших примерах мы сначала откроем SSH-соединение, затем выполним одну команду, прочитаем вывод и запишем его в консоль и, наконец, закроем SSH-соединение. Мы постараемся сделать образец кода как можно более простым.

2. JSch

JSch – это Java-реализация SSH2, которая позволяет нам подключаться к SSH-серверу и использовать переадресацию портов, переадресацию X11 и передачу файлов. Кроме того, он лицензирован по лицензии BSD style и предоставляет нам простой способ установить SSH – соединение с Java.

Во-первых, давайте добавим зависимость JSch Maven в ваш pom.xml файл:


    com.jcraft
    jsch
    0.1.55

2.1. Реализация

Чтобы установить SSH-соединение с помощью JSch, нам нужны имя пользователя, пароль, 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, , что означает, что мы будем передавать команды оболочки на сервер.

Кроме того, мы должны установить выходной поток для нашего канала, в котором будет записан ответ сервера. После установления соединения с помощью метода channel.connect() команда передается, и полученный ответ записывается на консоль.

Давайте посмотрим как использовать различные параметры конфигурации, которые предлагает JSch :

  • StrictHostKeyChecking – указывает, будет ли приложение проверять, можно ли найти открытый ключ хоста среди известных хостов. Кроме того, доступны значения параметров ask , yes, и no , где ask – значение по умолчанию. Если мы установим этому свойству значение yes , JSch никогда автоматически не добавит ключ хоста в файл known_hosts и откажется подключаться к хостам, ключ хоста которых изменился. Это заставляет пользователя вручную добавлять все новые хосты. Если мы установим его в no , JSch автоматически добавит новый ключ хоста в список известных хостов
  • сжатие.s2c – указывает, следует ли использовать сжатие для потока данных с сервера в наше клиентское приложение. Доступные значения: zlib и none , где второе значение по умолчанию
  • сжатие.c2s – указывает, следует ли использовать сжатие для потока данных в направлении клиент-сервер. Доступные значения: zlib и none , где второе значение по умолчанию

Важно закрыть сеанс и канал SFTP после завершения связи с сервером, чтобы избежать утечки памяти .

3. Apache MINA SSHD

Apache MINA SSHD обеспечивает поддержку SSH для приложений на базе Java. Эта библиотека основана на Apache MINA, масштабируемой и высокопроизводительной библиотеке асинхронного ввода-вывода.

Давайте добавим зависимость Apache Mina SSHD Maven :


    org.apache.sshd
    sshd-core
    2.5.1

3.1. Реализация

Давайте посмотрим пример кода подключения к SSH-серверу с помощью Apache MINA SSHD:

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. Сначала мы устанавливаем соединение с SSH-сервером, используя экземпляр класса Ssh Client . Если мы инициализируем его с помощью SSHClient.setupDefaultClient(), мы сможем работать с экземпляром, который имеет конфигурацию по умолчанию, подходящую для большинства случаев использования. Это включает в себя шифры, сжатие, MAC, обмен ключами и подписи.

После этого мы создадим Клиентский канал и прикрепите к нему ByteArrayOutputStream , чтобы мы использовали его в качестве потока ответов. Как мы видим, SSHD требует определенных тайм-аутов для каждой операции. Он также позволяет нам определить, как долго он будет ждать ответа сервера после передачи команды, используя метод Channel.waitFor () .

Важно отметить, что SSHD запишет полный вывод консоли в поток ответов. JSch сделает это только с результатом выполнения команды.

Полная документация по Apache Mina SSHD доступна в официальном репозитории проекта GitHub .

4. Заключение

В этой статье показано, как установить SSH – соединение с Java с помощью двух доступных библиотек Java- JSch и Apache Mina SSHD. Мы также показали, как передать команду на удаленный сервер и получить результат выполнения. Кроме того, полные образцы кода доступны на GitHub .