Executando comandos em uma máquina remota de Java com JSCH
- 1055
- 298
- Spencer Emard
SSH é uma ferramenta diária de qualquer trabalho de administração do sistema Linux. É uma maneira fácil e segura de acessar máquinas remotas na rede, transferir dados e executar comandos remotos. Além do modo interativo, existem muitas ferramentas que permitem a automação de tarefas remotas que também dependem do ssh
Arquitetura de servidor/cliente. Para uma dessas ferramentas, você pode ler sobre Ansible no Ubuntu, por exemplo. Você também pode encontrar muitas implementações do cliente SSH, mas que tal acessar as habilidades que o SSH fornece do código?
JSCH é um projeto que implementa o protocolo SSH em Java. Com sua ajuda, você pode criar aplicativos capazes de se conectar e interagir com um servidor SSH remoto ou local. Dessa forma, seu aplicativo é capaz de gerenciar qualquer aspecto da máquina de destino que você possa concluir com seu cliente SSH nativo, o que fornece mais uma adição poderosa ao já vasto conjunto de ferramentas Java.
Neste artigo, importaremos o JSCH para o nosso projeto Java e desenvolveremos as peças mínimas de código necessárias para criar um aplicativo que possa fazer login no servidor SSH de uma máquina remota, executar alguns comandos no shell interativo remoto, fechar a sessão e depois apresenta o saída. Este aplicativo será mínimo, no entanto, pode dar uma dica do poder que fornece.
Neste tutorial, você aprenderá:
- Como importar o JSCH para o seu projeto Java
- Como configurar o ambiente de teste
- Como implementar a interface UserInfo em uma classe personalizada
- Como escrever um aplicativo que inicia sessão interativa SSH
Requisitos de software e convenções usadas
Categoria | Requisitos, convenções ou versão de software usada |
---|---|
Sistema | Fedora 30 |
Programas | OpenJdk 1.8, JSCH 0.1.55, netbeans 8.2 |
Outro | Acesso privilegiado ao seu sistema Linux como raiz ou através do sudo comando. |
Convenções | # - requer que os comandos Linux sejam executados com privilégios root diretamente como usuário root ou por uso de sudo comando$ - Requer que os comandos do Linux sejam executados como um usuário não privilegiado regular |
Introdução
Com a ajuda do JSCH, desenvolveremos um aplicativo que tentará fazer login LocalHost
através da ssh
, usando o nome de usuário teste
e senha teste
. Vamos assumir a porta padrão 22
O servidor SSH ouve e aceitará a impressão digital do servidor sem verificar sua validade. No login bem -sucedido, executaremos alguns comandos que poderíamos emitir em um shell remoto, logot e depois imprimir toda a saída recebida.
O seguinte código -fonte é apenas para fins de demonstração; Nunca use esse código na produção! Só para citar duas armadilhas, Não confie em nenhuma impressão digital do servidor por padrão, e lidar com exceções corretamente.
Nossas ferramentas consistirão em um desktop do Fedora (como cliente e servidor), um IDE recente do NetBeans e o (no momento da redação) mais recente JSCH estável. Observe, no entanto, que essas são apenas as ferramentas de escolha. Java é independente da plataforma e o servidor de destino pode estar do outro lado do planeta e pode ser qualquer sistema operacional que execute um adequado servidor ssh
.
Configurando o ambiente de teste
Precisaremos das credenciais acima para trabalhar LocalHost
. Em nosso exemplo, isso significa que precisamos de um usuário chamado "teste", com a senha "teste". Também precisaremos de um servidor SSH em execução.
Adicionando o usuário do teste
Vamos executar UserAdd
como raiz
:
# teste de userAdd
E defina a senha do novo usuário:
# Teste Passwd
Aqui precisamos fornecer a senha acima duas vezes. Isso é adequado em um ambiente de teste que é temporário e também inacessível do mundo exterior, mas não use senhas facilmente adivinhadas quando pode haver menor chance de acesso descontrolado.
Verificando o servidor SSH
Podemos verificar o status do servidor ssh
com Systemd
:
# status systemctl sshd
E comece se não estiver em execução:
# SystemCtl Start SSHD
Esta etapa pode ser necessária nas instalações da área de trabalho, pois algumas dessas configurações não executam o servidor SSH por padrão.
Testando a conectividade com o cliente nativo
Se nosso usuário estiver definido e o serviço estiver em execução, devemos fazer login usando as informações acima:
$ ssh teste@localhost
Precisamos aceitar a impressão digital do host e fornecer a senha. Se chegarmos ao shell, nosso ambiente de teste será concluído.
Obtenção e importação de JSCH para o nosso projeto
Baixando o arquivo
Precisamos baixar o código de byte do projeto JSCH para usar sua funcionalidade. Você pode encontrar o link apropriado na página inicial do JSCH. Vamos precisar do .jarra
Arquivo Java.
Criando o projeto em Netbeans
No começo, criamos um novo projeto vazio chamado sshremoteexample
em netbeans. Podemos simplesmente escolher "novo projeto" no menu de arquivos.
Criando um novo projeto.
Escolheremos a categoria "Java" e o projeto "Java Application".
Escolhendo a categoria para o projeto.Precisamos fornecer um nome para o projeto, neste caso "sshremoteexample".
Nomeando o projeto.No layout padrão, podemos encontrar a janela "Projetos" à esquerda. Lá, clicaremos com o botão direito do mouse no nó "bibliotecas" em nosso projeto recém-criado e selecione "Adicionar jar/pasta". Uma janela de um selecionador de arquivos será aberta, onde precisamos navegar para o .jarra
Arquivo que baixamos no site do desenvolvedor.
Após a seleção, o arquivo deve aparecer nas bibliotecas incluídas, se abrirmos o nó "bibliotecas".
JSCH importou com sucesso.Precisamos implementar o Informação de usuário
interface para usá -lo em nosso aplicativo. Para fazer isso, precisamos adicionar um novo Classe Java
ao nosso projeto clicando com o botão direito do mouse em nosso sshremoteexample
Pacote na janela do projeto, escolha "Novo", depois "Java Class ...".
Forneceremos o nome "sshremoteexampleuserinfo" como nome de classe.
Nomeando a nova aula de Java.Adicionando o código -fonte
sshremoteexampleUserinfo.Java
Para nossa implementação de interface, considere a seguinte fonte. É aqui que aceitamos a impressão digital do alvo cegamente. Não faça isso em um cenário do mundo real. Você pode editar o código -fonte clicando na classe na janela do projeto ou, se já estiver aberto, mude para ele com as guias na parte superior da janela do código -fonte.
pacote sshremoteexample; importar com.jcraft.JSCH.*; classe pública sshremoteexampleUserinfo implementa o userInfo private final string pwd; public sshremoteexampleUserinfo (nome de usuário da String, string senha) pwd = senha; @Override public String getPassPhrase () THROW NOVA UNSUPPORTEDOPERATIONEXCECTIMENTO ("GetPassphrase ainda não suportado."); @Override public String getPassword () return pwd; @Override public boolean PromptPassword (string string) /*mod* / return true; @Override public boolean PromptpassPhrase (string string) throw unsupportEdOperationException (" Promptpassphrase ainda não suportado."); @Override public boolean Promptyesno (string string) /*mod* / return true; @Override public void showMessage (string string)
cópia de Sshremoteexample.Java
Nossa classe principal será a sshremoteexample
classe com a seguinte fonte:
pacote sshremoteexample; importar com.jcraft.JSCH.*; importar java.io.ByteArrayInputStream; importar java.io.Ioexception; importar java.io.InputStream; importar java.NIO.CHARST.StandardCharSets; classe pública sshremoteexample public static void main (string [] args) string host = "localhost"; String user = "teste"; String senha = "teste"; String command = "hostname \ ndf -h \ nexit \ n"; tente jsch jsch = new jsch (); Sessão de sessão = JSCH.getSession (usuário, host, 22); sessão.setUserInfo (novo sshremoteexampleUserinfo (usuário, senha)); sessão.conectar(); Canal canal = sessão.OpenChannel ("Shell"); canal.setInputStream (novo ByteArrayInputStream (comando.GetBytes (StandardCharSets.Utf_8))); canal.setOutputStream (System.fora); InputStream em = canal.getInputStream (); Stringbuilder outbuff = new StringBuilder (); int exitstatus = -1; canal.conectar(); while (true) for (int c; ((c = em.leitura ())> = 0);) outbuff.anexar ((char) c); se (canal.isClosed ()) if (em.disponível ()> 0) Continue; exitstatus = canal.getExitStatus (); quebrar; canal.desconectar(); sessão.desconectar(); // Imprima o sistema de conteúdo do buffer.fora.Imprima (OtBuff.para sequenciar()); // Sistema de status de saída imprima.fora.print ("Status de saída da execução:" + exitstatus); if (exitstatus == 0) sistema.fora.print ("(ok) \ n"); else sistema.fora.print ("(Nok) \ n"); catch (ioexception | jschException ioex) sistema.errar.println (ioex.para sequenciar());
cópia de Observe que, neste exemplo, codificamos todos os detalhes necessários para a conexão: nome do host de destino, nome de usuário/senha e a string de comando a ser executada na sessão remota. Este não é um exemplo da vida real, mas serve ao seu propósito de demonstração.
Poderíamos mudar o alvo e as credenciais para executar o comando em um host remoto. Observe também que a sessão remota terá os privilégios do usuário que efetuará login. Eu não recomendo usar um usuário com altos privilégios - como raiz
- para teste, se a máquina de destino contiver dados ou serviços valiosos.
Executando o aplicativo
Podemos executar nosso aplicativo diretamente do IDE clicando no "Run Project (sshremoteexample)" no menu "Run", que fornecerá a saída na janela de saída abaixo do código -fonte. Também podemos escolher “Projeto Limpo e Construção (Sshremoteexample)” no mesmo menu, nesse caso o IDE produzirá o .jarra
Java Archive o pode ser executado sem o IDE.
A saída fornecida mostrará o caminho para o arquivo, semelhante ao seguinte (o caminho exato pode variar dependendo das configurações do IDE):
Para executar este aplicativo da linha de comando sem formiga, tente: java -jar "/var/Projects/sshremoteexample/dist/sshremoteexample.jarra "
Como pode ser adivinhado, podemos executar nosso aplicativo construído a partir da linha de comando e, se tudo correr bem, ele fornecerá uma saída semelhante ao seguinte.
$ java -jar "/var/Projects/sshshellexemple/dist/sshellexpleple ampler.jar "Último login: seg 29 14:27:08 2019 de 127.0.0.1 HostName DF -H Exit [Test@test1 ~] $ hostName test1.LinuxConfig.org [teste@test1 ~] $ df -h tamanho do sistema de arquivos usado use% use% montado em devtmpfs 3,9g 0 3,9g 0% /dev tmpfs 3,9g 127m 3,8g 4% /dev /shm tmpfs 3,9g 1 , 7m 3,9g 1% /execução tmpfs 3,9g 0 3,9g 0% /sys /fs /cgroup /dev /mapper /fedora_localhost-live-root 49g 15g 32g 32% /tmpfs 3,9g 6,1m 3 , 9g 1% /tmp /dev /sdb1 275g 121g 140g 47% /mnt /hdd_open /dev /sda2 976m 198m 711m 22% /boot /dev /mapper /fedora_localhost-Live-home 60g 50g 6,9g 88% /lar /dev/sda1 200m 18m 182m 9%/bota/efi tmpfs 789m 9,7m 779m 2%/run/user/1000 tmpfs 789m 0 789m 0%/run/user/1001 [test@test1] da execução: 0 (ok)
Observe que sua saída provavelmente será diferente, se nada mais, no nome do host, nomes de volume e tamanhos - mas, em geral, você deve ver um completo df -h
saída que você obteria em uma sessão SSH.
Pensamentos finais
Este exemplo simples destinado a mostrar o poder do projeto JSCH, se de uma maneira um pouco simplificada. Com acesso à máquina de teste e um cliente adequado, o comando simples seguinte forneceria as mesmas informações:
$ ssh teste@localhost "hostName; df -h"
E também não criaria uma sessão interativa. A mesma funcionalidade é fornecida pelo JSCH se você abrir o canal no modo de comando:
Canal canal = sessão.OpenChannel ("comando");
Dessa forma, você não precisa lidar com o fechamento da sessão com o saída
comando shell.
O verdadeiro poder deste projeto reside na capacidade de se conectar e interagir com os comandos da Shell Native Machine Trough, processar a saída e decidir a próxima ação programaticamente. Imagine um aplicativo multithread que gerencia possivelmente centenas de servidores por si só, e você terá a foto.
Tutoriais do Linux relacionados:
- Uma introdução à automação, ferramentas e técnicas do Linux
- Coisas para instalar no Ubuntu 20.04
- Ansible Tutorial para iniciantes no Linux
- Oracle Java Instalação no Ubuntu 20.04 fossa focal linux
- Como instalar Java no Manjaro Linux
- Linux: Instale Java
- Como executar operações de administração com Ansible…
- Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
- Mastering Bash Script Loops
- Ansible Vault Tutorial