Для подключения ко второму серверу за брандмауэром, в принципе, есть два варианта.
Наивным было бы вызвать ssh
на первом сервере (из канала exec), указав правильный сервер. Для этого потребуется переадресация агента с помощью JSch, а также не предоставляется API JSch для доступа ко второму серверу, только командная строка ssh.
Лучше было бы использовать соединение с первым сервером для создания туннеля TCP и использовать этот туннель для соединения со вторым сервером. JSch Wiki содержит класс ProxySSH (вместе с некоторым примером кода), который позволяет использовать сеанс JSch в качестве туннеля для второго сеанса JSch. (Отказ от ответственности: этот класс был написан главным образом мной, при некоторой поддержке автора JSch.)
Если у вас есть подключение ко второму серверу, используйте канал shell
или серию каналов exec
для выполнения ваших команд. (См. Shell, Exec или Subsystem Channel в JSch Wiki для обзора, и Javadocs для подробностей.)
Для вашей unknown-host-key проблемы:
Версия secure будет собирать все ключи хоста (безопасным способом) и помещать их в файл known_hosts. (Если вы просто доверяете ключу, который вам преподносится, вы уязвимы для атаки «человек посередине». Если это не имеет значения в вашей сети, поскольку она физически защищена, это хорошо для вас.)
удобная версия устанавливает параметр конфигурации StrictHostKeyChecking
на no
- это добавит неизвестные ключи хоста в файл ключей хоста:
JSch.setConfig("StrictHostKeyChecking", "no");
(Вы также можете установить его индивидуально для сеансов, если вы хотите установить его только для сеансов с прокси, а не для сеанса туннеля. Или переопределить его для сеанса туннеля с помощью yes
или ask
- там MITM опасность может быть больше.)
A middle way будет включать фактический запрос пользователя (который затем должен сравнить отпечатки пальцев с некоторым списком) - для этого реализуйте интерфейс UserInfo
и предоставьте возражать против сессии. (JSch Wiki содержит пример реализации с использованием Swing JOptionPanes , который вы можете просто использовать, если ваша клиентская программа работает в системе с графическим интерфейсом.)
Чтобы сохранение принятых ключей хоста работало, вы должны использовать метод JSch.setKnownHosts
с аргументом имени файла, а не метод с аргументом InputStream - иначе ваш прием должен быть повторен для каждый перезапуск вашего клиента.