对于一个Java程序而言,如果需要连接到一台linux服务器,我们可以有以下两种方式:
1. 通过用户名和密码连接
需要提供的参数:
host,port,user,password,maxWaitTime
缺点分析:
出于安全需要,一般服务器的密码会定期修改,程序部署后将不得不经常更新配置文件中的密码。
如果想避免密码过期的问题,可采用第二种方法,
2. 通过用户名和ssh private key file连接
需要提供的参数:
host,port,user,keyfile,passphrase,maxWaitTime
缺点分析:
因为Java程序必须和private key file在同一台机器上,将服务器的private key file复制到本地后,本地机器的安全措施可能会使private key file被窃取,威胁服务器安全。
下面以通过一个JSch实体生成一个ChannelSftp实体来分别演示以上两种连接方式。首先直接上代码
packagecom.jsch;
importjava.util.Vector;
importorg.apache.log4j.Logger;
importcom.jcraft.jsch.Channel;
importcom.jcraft.jsch.ChannelSftp;
importcom.jcraft.jsch.JSch;
importcom.jcraft.jsch.JSchException;
importcom.jcraft.jsch.Session;
importcom.jcraft.jsch.SftpException;
importcom.jcraft.jsch.UserInfo;
importcom.jcraft.jsch.ChannelSftp.LsEntry;
publicclassJSchChannel {
privatefinalLogger LOG = Logger.getLogger(JSchChannel.class);
privateString host;
privateString user;
privateString password;
privateintport;
privateintmaxWaitTime;
privateString keyfile;
privateString passphrase;
privatebooleansshKey;
privateChannelSftp sftp;
privateSession session;
publicJSchChannel(String host, String user, String password,intport,
intmaxWaitTime) {
this.host = host;
this.user = user;
this.password = password;
this.port = port;
this.maxWaitTime = maxWaitTime;
this.keyfile =null;
this.passphrase =null;
this.sshKey =false;
}
publicJSchChannel(String host, String user,intport,intmaxWaitTime,
String keyfile, String passphrase) {
this.host = host;
this.user = user;
this.password =null;
this.port = port;
this.maxWaitTime = maxWaitTime;
this.keyfile = keyfile;
this.passphrase = passphrase;
this.sshKey =true;
}
publicvoidopen()throwsJSchException {
JSch client = newJSch();
if(sshKey && keyfile !=null&& keyfile.length() >0) {
client.addIdentity(this.keyfile,this.passphrase);
}
session = client.getSession(this.user,this.host,this.port);
session.setUserInfo(newUserInfo() {
publicString getPassphrase() {
returnnull;
}
publicString getPassword() {
returnpassword;
}
publicbooleanpromptPassphrase(String arg0) {
returntrue;
}
publicbooleanpromptPassword(String arg0) {
returntrue;
}
publicbooleanpromptYesNo(String arg0) {
returntrue;
}
publicvoidshowMessage(String arg0) {
}
});
session.setTimeout(maxWaitTime);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
}
publicvoidclose() {
if(sftp !=null) {
sftp.disconnect();
sftp = null;
}
if(session !=null) {
session.disconnect();
session = null;
}
}
publicvoidcd(String path)throwsSftpException {
sftp.cd(path);
}
publicvoidpwd()throwsSftpException {
LOG.info(sftp.pwd());
}
publicvoidls()throwsSftpException {
Vector> vector = sftp.ls(".");
for(Object object : vector) {
if(objectinstanceofLsEntry) {
LsEntry entry = LsEntry.class.cast(object);
LOG.info(entry.getFilename());
}
}
}
publicvoidls(String path)throwsSftpException {
Vector> vector = sftp.ls(path);
for(Object object : vector) {
if(objectinstanceofLsEntry) {
LsEntry entry = LsEntry.class.cast(object);
LOG.info(entry.getFilename());
}
}
}
publicvoidrename(String oldPath, String newPath)throwsSftpException {
sftp.rename(oldPath, newPath);
}
publicvoidcp(String src, String dest)throwsSftpException {
intlastSlash = src.lastIndexOf("/");
String srcFile = src;
String srcDir = ".";
if(lastSlash > -1) {
srcFile = src.substring(lastSlash + 1);
srcDir = src.substring(0, lastSlash);
}
String temp = srcDir + "/temp_"+ srcFile;
rename(src, temp);
rename(temp, dest);
}
publicvoidrm(String file)throwsSftpException {
sftp.rm(file);
}
publicvoidmv(String src, String dest)throwsSftpException {
rename(src, dest);
}
publicvoidrmdir(String path)throwsSftpException {
sftp.rmdir(path);
}
publicvoidchmod(intpermissions, String path)throwsSftpException {
sftp.chmod(permissions, path);
}
}
为了方便测试和演示,我设置了一个sshKey在两种连接方式间切换。测试类可以参考以下代码
packagecom.jsch;
importcom.jcraft.jsch.JSchException;
importcom.jcraft.jsch.SftpException;
publicclassJustDoIt {
privatestaticfinalString host ="192.168.1.100";
privatestaticfinalString user ="root";
privatestaticfinalString password ="password";
privatestaticfinalintport =22;
privatestaticfinalintmaxWaitTime =10*1000;
privatestaticfinalString keyfile ="C:/id_rsa";
privatestaticfinalString passphrase ="";
privatestaticfinalbooleansshKey =true;
publicvoidbyJSchSSHKey()throwsJSchException, SftpException {
JSchChannel client = newJSchChannel(host, user, port, maxWaitTime,
keyfile, passphrase);
client.open();
client.ls();
}
publicvoidbyJSchPwd()throwsJSchException, SftpException {
JSchChannel client = newJSchChannel(host, user, password, port,
maxWaitTime);
client.open();
client.ls();
}
/**
* @param args
* @throws SftpException
* @throws JSchException
*/
publicstaticvoidmain(String[] args)throwsJSchException, SftpException {
// TODO Auto-generated method stub
JustDoIt doit = newJustDoIt();
if(sshKey) {
doit.byJSchSSHKey();
} else{
doit.byJSchPwd();
}
}
}看过以上简单的例子相信大家已经能明白如何使用用户名&密码和用户名&keyfile的方式来访问linux服务器。暂时不作关于
JSch的深入探讨。除了JSch,还有Scp可以支持用户名&密码和用户名&keyfile的方式来访问linux服务器,详情参见下一 篇博文。