Sei sulla pagina 1di 6

jsch_

JSch
uma biblioteca Java para
facilitar o uso do SSH
Executando comandos remotos e fazendo
conexão SSH dentro de programas Java
Durante a leitura do artigo iremos ver como a biblioteca
JSch pode facilitar o uso do protocolo SSH. Várias tare-
fas relacionadas ao uso do protocolo podem ser executa-
das facilmente através de programas Java usando esta bi-
blioteca.

André Luís Fonseca | andreluisfonseca@yahoo.com.br


é formado em Ciência da Computação pela Universidade Federal de São Carlos (UFSCar). Trabalha na empresa
NTT Data Brasil. Com mais de 11 anos de experiência, já trabalhou em empresas de diversos setores como:
Telecom, Bancos e Indústria utilizando Java, PHP e C. Possui as certificações SCJP, SCWCD, SCBCD e SCEA (I).

OSSH é um protocolo de rede


que suporta criptografia.
Ele é utilizado para realizar
versão do protocolo chamada de SSH-2 que foi ado-
tada como padrão e é usada até hoje. Mais detalhes
podem ser encontrados na RFC relativa ao protocolo
a troca segura de dados entre (consultar referências).
servidores, execução remota de Algumas das tarefas que podem ser executadas
serviços ou comandos além de com esse protocolo incluem:
outros serviços entre dois » logar em uma shell de um computador remoto
computadores ligados em » executar comandos em um computador remo-
rede. O protocolo SSH cria to
um canal seguro por cima de » realizar uma cópia segura de arquivos entre
uma rede insegura. O cliente computadores
SSH é um programa que usa » juntamente com o programa rsync realizar
o protocolo para se conectar a um operações de backup, cópia e espelhamento de
computador remoto. O servidor arquivos de maneira eficiente e segura entre
SSH é um programa que usa o computadores
protocolo para aceitar as cone- » redirecionar pacotes de dados através da cria-
xões de computadores remotos. ção de um túnel
O protocolo pode ser usa- A biblioteca JSch (Java Secure Shell) é uma im-
do por muitas aplicações em plementação de um cliente SSH escrita em Java. Foi
vários sistemas operacionais criada por uma empresa japonesa e disponibilizada
diferentes, Unix, Linux, Win- através da licença BSD. A licença BSD permite que
dows etc. Em 2006 foi criada uma o software distribuído sobre essa licença seja incor-

/ 48
porado a produtos proprietários. Algumas aplicações » criar um objeto JSch – onde ficam as configu-
que usam o JSch são: ANT, Eclipse, Netbeans, Maven, rações básicas como usuário e senha para a
JiRA, entre outras. conexão
Além do JSch temos outras bibliotecas criadas » criar uma sessão – a sessão deve ser recupera-
pela mesma empresa que são: da do objeto JSch
» WiredX e WeirdX – X Window Systems – um » conectar a sessão no host remoto passando as
X Window System é um programa e um pro- credenciais do usuário
tocolo de rede que prove uma interface gráfica » abrir um canal no host remoto de um deter-
GUI para administração remota de servidores minado tipo usando a sessão aberta no passo
(o primeiro é comercial, o segundo usa licença anterior
GPL) » executar os comandos desejados no canal
» JZlib – implementação em Java da biblioteca aberto com o host remoto
Zlib de compressão de arquivos » fechar o canal
» JCTerm – um emulador de terminal escrito em » fechar a sessão com o host
Java para o protocolo SSH A seguir, temos a implementação destes passos
» JOrbis – implementação em Java para traba- através de código Java.
lhar com compressão de arquivos de áudio
» JHttpTunnel – implementação em Java de um Listagem 1. Primeiro exemplo usando a biblioteca
Túnel HTTP JSch.
» JRexec – um cliente REXEC escrito em Java
/* As configurações da sessão são feitas no objeto jSch */
Este artigo está focado apenas na utilização da JSch jSch = new JSch();
biblioteca JSch. Mais detalhes dos outros projetos int port = 22;
podem ser encontrados no site da empresa (consul- String host = “localhost”;
tar referências). String username = “andre.fonseca”;
Session session = jSch.getSession(username, host, port);
Iniciando com o JSch, criando o session.setPassword(“pass”);

primeiro exemplo /*
No momento da escrita deste artigo a última * Conecta ao host sem pedir confirmação caso contrário
versão da biblioteca era a 0.1.4.9. No site do projeto * você pode adicionar a lista de hosts conhecidos
pode ser feito o download do JAR apenas ou então * usando o método setKnowHosts da classe JSch. Em
do arquivo ZiP o qual contém vários exemplos que * ambiente Linux recebe como parametro uma string
* que aponta para o arquivo home/foo/.ssh/known_hosts
podem ser testados através do ANT.
*/
Após o download crie um novo projeto Java na Properties config = new Properties();
sua iDE de preferência e adicione o JAR do JSch no config.put(“StrictHostKeyChecking”, “no”);
CLASSPATH da aplicação, no meu caso estou usando session.setConfig(config);
o Eclipse. /* Conecta a sessão usando um timeout */
Para realizar uma conexão SSH com o host re- session.connect(3000);
moto (servidor) os seguintes passos precisam ser
seguidos: /*

Entrada e Saída em Java


Entradas e Saídas de programas em Java são representadas por Streams ou Fluxos. Uma Stream pode re-
presentar um arquivo em disco, um dispositivo externo, um programa, um vetor em memória, entre outras
coisas. São vários os tipos de dados suportados por uma Stream, como, por exemplo: bytes simples, tipos
primitivos, caracteres, objetos etc.
Uma Stream pode apenas transmitir os dados da origem para o destino, ou então manipular ou transfor-
mar os dados de entrada antes de enviá-los para a saída. Sempre representa o mesmo modelo de dados:
uma Stream é uma sequência ordenada de bytes de tamanho indefinido.
O Java possui três objetos representando Streams que são: System.in, System.out e System.err. Esses três
objetos são inicializados automaticamente quando a JVM inicia. O primeiro representa a entrada padrão
(normalmente o teclado ou o console dos programas), o segundo representa a saída padrão enquanto o
último representa a saída padrão de erros.

49 \
* Abre um canal com a sessão do tipo shell
* para alterar o tipo altere o parâmetro do método
*/
Channel channel = session.openChannel(“shell”);
/* agora eu posso realizar as operações necessárias no
servidor remoto */

/* Desconecta do canal */
channel.disconnect();

/* Desconecta da sessão */
session.disconnect();

Figura 1. Selecione o pacote openssh na hora da instalação do


Uma sessão representa uma conexão com o servidor Cygwin.
SSH. Uma sessão pode ter um ou mais canais abertos
com o servidor ao mesmo tempo. Os tipos existentes
de canais são:
» shell – a stream aberta com o servidor SSH pos-
sui tanto os comandos como os parâmetros de
entrada dos comandos, funciona como se esti-
véssemos digitando comandos interativamente
na shell remota
» exec – os comandos são passados através do Figura 2. Serviço sshd iniciado no Windows.
método setCommand antes do canal estar co-
nectado com o servidor, funciona como se es-
tivéssemos executando um shell script na má- Testando outros exemplos do JSch
quina local Conforme já mencionamos, o JSch vem com vá-
» subsystem – neste caso as configurações do rios exemplos na pasta examples do arquivo ZiP. Va-
servidor SSH decidem o que deve ser feito, não mos falar agora um pouco dos principais.
a shell remota. Um uso comum é quando que-
remos fazer SFTP para o servidor SSH Shell.java
» direct-tcpip – este canal permite o redireciona- Este exemplo possibilita que o programa se co-
mento de streams para e do servidor SSH necte ao servidor sshd e retorne o prompt da shell.
» sftp – este canal se conecta a um servidor SFTP Ao rodar o exemplo no Eclipse você receberá um
popup perguntando o usuário de entrada, preencha
Preparando o ambiente com o usuário que você usou para instalar o pacote
Precisamos de um servidor SSH para testar os openssh no Cygwin (usuário Windows).
exemplos que vêm junto com o download do JSch.
A fim de testar estes exemplos localmente sem a
necessidade de um servidor remoto (em uma rede de
computadores) iremos instalar o pacote openssh do
Cygwin. O Cygwin é um emulador de sistemas Linux/
Unix para Windows. O openssh possui várias ferra-
mentas de conexão SSH além de uma implementação Figura 3. Preencha com o usuário do Windows.
de um servidor SSH (conhecido como sshd).
Para instalar o Cygwin basta fazer o download do Na sequência um novo popup irá perguntar a se-
arquivo setup.exe e seguir os passos descritos no link nha do usuário.
“instalando o Cygwin” nas referências do artigo (não
se esqueça de selecionar o pacote openssh na hora da
instalação).
Após configurar o openssh no Cygwin, podemos
verificar que um novo serviço foi instalado no Windo-
ws (consultar o link “Configurando um Servidor SSH Figura 4. Preencha com a senha do usuário Windows.
no Cygwin” nas referências do artigo).

/ 50
Como não estamos armazenando a chave de au-
// conecta no canal
tenticação no nosso computador toda vez que conec- channel.connect();
tarmos no servidor “localhost” (serviço sshd rodando // imprime no console do Eclipse o resultado do comando
no Cygwin) iremos receber a mensagem abaixo. Em executado
ambientes Linux esta chave é armazenada no arquivo byte[] tmp=new byte[1024];
~/.ssh/known_hosts. Clique em “Yes” para continuar. while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;

System.out.print(new String(tmp, 0, i));


}

Figura 5. Mensagem de “Warning”. if(channel.isClosed()){


System.out.println(“exit-status:
Listagem 2. Conectando no servidor sshd e recupe- “+channel.getExitStatus());
break;
rando o prompt de comando.
}
// abre uma sessão do tipo shell }
Channel channel=session.openChannel(“shell”);

// seta a Input Stream padrão (console do Eclipse) ScpTo.java


channel.setInputStream(System.in); Este exemplo mostra como copiar um arquivo da
máquina local para o servidor remoto. Antes de rodar
// seta a Output Stream padrão (console do Eclipse) o exemplo você deve editar as configurações do Eclip-
channel.setOutputStream(System.out); se (Run Configurations) para passar como argumento
a string “file1 user@remotehost:file2” onde file1 é o
caminho para o arquivo na máquina local e file2 é o
Exec.java caminho para o arquivo na máquina remota (Cygwin).
Este exemplo abre um canal do tipo “exec” e per-
gunta ao usuário que comando deve ser executado no
servidor remoto. Os comandos podem ser concatena-
dos usando o pipe “|”. Exibe no console do Eclipse o
resultado da execução do comando.

Figura 7. Digite nos argumentos da JVM os caminhos para a cópia


do arquivo.

Após rodar o exemplo você pode verificar no ter-


minal do Cygwin que o arquivo foi copiado para a
Figura 6. Digite o comando a ser executado no servidor remoto.
pasta home.

Listagem 3. Executando comandos no servidor


remoto.
// usuário digita o comando a ser executado
String command=JOptionPane.showInputDialog(
“Enter command”,
“set|grep SSH”);
// abre uma sessão do tipo “exec”
Channel channel=session.openChannel(“exec”);
Figura 8. Arquivo copiado para a máquina remota.
// atribuir para a sessão o comando digitado pelo usuário
((ChannelExec)channel).setCommand(command);
Listagem 4. Copiando um arquivo da máquina local
// define a saída de erros para o console do Eclipse para a máquina remota.
((ChannelExec)channel).setErrStream(System.err);
// recupera a stream de entrada do canal // cria o comando e adiciona no canal do tipo “exec”
InputStream in=channel.getInputStream(); String command = “scp -p -t” + rfile;

51 \
Channel channel = session.openChannel(“exec”);
((ChannelExec) channel).setCommand(command); I INFO: SSH_MSG_SERVICE_REQUEST sent
// recupera as streams de entrada/saida do scp remoto
INFO: SSH_MSG_SERVICE_ACCEPT received
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream(); INFO: Authentications that can continue: publickey,keyboard-
interactive,password
// envia o comando “C0644 tamanho_arquivo nome_ INFO: Next authentication method: publickey
arquivo”, onde o nome_arquivo INFO: Authentications that can continue: keyboard-
// não deve possuir ‘/’ interactive,password
long filesize = _lfile.length();
INFO: Next authentication method: keyboard-interactive
command = “C0644 “ + filesize + “ “;
if (lfile.lastIndexOf(‘/’) > 0) { INFO: Authentications that can continue: password
command += lfile.substring(lfile.lastIndexOf(‘/’) + 1); INFO: Next authentication method: password
} else { INFO: Authentication succeeded (password).
command += lfile;
}
command += “\n”;
out.write(command.getBytes()); Listagem 6. Criando um Logger para exibir as infor-
out.flush(); mações da conexão SSH com o servidor.
// envia o conteudo do arquivo para o servidor remoto // seta um logger personalizado
fis = new FileInputStream(lfile); JSch.setLogger(new MyLogger());
byte[] buf = new byte[1024];
while (true) { // define uma classe estatica para implementação
int len = fis.read(buf, 0, buf.length); de um logger
if (len <= 0) // personalizado
break; public static class MyLogger implements
out.write(buf, 0, len); // out.flush(); com.jcraft.jsch.Logger {
} static java.util.Hashtable name=
fis.close(); new java.util.Hashtable();
fis = null; static{
// send ‘\0’ name.put(new Integer(DEBUG), “DEBUG: “);
buf[0] = 0; name.put(new Integer(INFO), “INFO: “);
out.write(buf, 0, 1); name.put(new Integer(WARN), “WARN: “);
out.flush(); name.put(new Integer(ERROR), “ERROR: “);
out.close(); name.put(new Integer(FATAL), “FATAL: “);
}
public boolean isEnabled(int level){
Logger.java return true;
Este exemplo mostra como criar um logger para }
public void log(int level, String message){
recuperar as informações durante a conexão com o
System.err.print(name.get(new Integer(level)));
servidor. System.err.println(message);
}
Listagem 5. Listando informações da conexão SSH
}
com o servidor no console do Eclipse.

NFO: Connecting to localhost port 22 X11Forwarding.java


INFO: Connection established Este exemplo mostra como fazer “X11 Forwar-
INFO: Remote version string: SSH-2.0-OpenSSH_6.0 ding”. Esta técnica permite que você consiga execu-
tar aplicações gráficas no servidor remoto sendo que
INFO: Local version string: SSH-2.0-JSCH-0.1.49
a interface será executada na máquina local. Ou seja,
INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-
eu vou executar a aplicação no servidor e vou conse-
ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcf
our128,arcfour256 guir ver a interface na minha máquina local.
Para conseguir rodar este exemplo precisamos
INFO: CheckKexes: diffie-hellman-group14-sha1
iniciar o Cygwin/Xserver. No menu iniciar, na opção
INFO: diffie-hellman-group14-sha1 is not available. Cygwin-X clique em “XWin Server”. Na barra de ta-
INFO: SSH_MSG_NEWKEYS sent refas deve aparecer um ícone no formato de um “X”
INFO: SSH_MSG_NEWKEYS received mostrando que o XServer foi iniciado.
Rode o exemplo no Eclipse. Depois defina o

/ 52
display digitando o seguinte comando export DIS-
PLAY=’127.0.0.1:0’ no Console do Eclipse.
Agora você pode iniciar uma aplicação “GUi” di-
retamente pelo console do Eclipse, tente, por exem-
plo, rodando xlogo.exe & ou xclock.exe & no console.

Figura 10. Listando as opções disponíveis ao fazer o SFTP no con-


sole do Eclipse.

Figura 9. Iniciando o Cygwin/XServer. Podemos utilizar essa biblioteca dentro dos nossos
programas Java para facilitar a comunicação com ser-
vidores remotos através do protocolo SSH. Várias ta-
Listagem 7. Definindo as configurações para fazer o
refas podem ser executadas como: execução remota
X11 Forwarding.
de comandos, SCP, SFTP, X11 Forwarding etc.
String xhost=”127.0.0.1”; Essas funcionalidades podem ser integradas fa-
int xport=0;
cilmente com outros programas já existentes facili-
// define as propriedades xhost e xport
tando a automatização de tarefas repetitivas, como
// necessárias para fazer o X11 Forwarding backup, transferência de arquivos, entre outras.
session.setx11Host(xhost);
session.setX11Port(xport+6000); /referências
Channel channel=session.openChannel(“shell”); > Site do JCraft (contendo todos os projetos inclusive a
biblioteca JSch): http://www.jcraft.com/
channel.setXForwarding(true);
> Download do JAR do JSch : http://sourceforge.net/

// seta a Input Stream padrão (console do Eclipse) projects/jsch/files/jsch.jar/0.1.49/jsch-0.1.49.jar/download


channel.setInputStream(System.in); > Download do ZIP do JSch: http://sourceforge.net/
projects/jsch/files/jsch/0.1.49/jsch-0.1.49.zip/download
// seta a Output Stream padrão (console do Eclipse)
channel.setOutputStream(System.out); > Javadoc do projeto (não oficial): http://epaul.github.
com/jsch-documentation/javadoc/com/jcraft/jsch/package-
Sftp.java summary.html
Este exemplo abre um canal do tipo “sftp” (Secu- > Wiki: http://sourceforge.net/apps/mediawiki/jsch/index.
re File Transfer Protocol) com o servidor remoto pos- php?title=Main_Page
sibilitando que arquivos sejam acessados, transferi-
> Instalando o Cygwin: http://cygwin.com/install.html
dos e manuseados de forma segura entre a máquina
local e o servidor. Configurando um Servidor SSH no Cygwin: http://
Ao executar o exemplo no Eclipse, o usuário irá lifehacker.com/205090/geek-to-live--set-up-a-personal-
receber um prompt para se conectar no servidor e re- home-ssh-server
alizar as operações desejadas. Digite help no prompt > Arquitetura do Protocolo SSH: http://tools.ietf.org/html/
(console do Eclipse) para ver as opções disponíveis. rfc4251

> I/O Streams: http://docs.oracle.com/javase/tutorial/


Considerações Finais essential/io/streams.html
A biblioteca JSch (Java Secure Shell) é uma im-
plementação de um cliente SSH escrita em Java.

53 \

Potrebbero piacerti anche