出于某种原因,我需要连接到防火墙(基于Linux)并使用Java添加一些规则。
在谷歌搜索了一段时间之后,我发现 jsch 是我的最佳选择。但是当我
用它来执行命令,“ show hostname ”例如,返回错误。如果我
执行“ls -l”和“whoami”等命令,结果还可以。这就是说,我只能
连接到Bash Shell!我的问题是如何连接到防火墙shell?
我的测试代码如下:
import java.io.InputStream;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
public class SSHDemo {
public static void main(String[] args) {
SSHDemo t = new SSHDemo();
try {
t.go();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void go() throws Exception {
String host = "10.4.44.192";
String user = "root";
String password = "root";
int port = 22;
// int tunnelLocalPort = 9080;
// String tunnelRemoteHost = "10.4.44.192";
// int tunnelRemotePort = 8000;
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
localUserInfo lui = new localUserInfo();
session.setUserInfo(lui);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
channel.setInputStream(null);
//Pay attension to this line
channel.setCommand("show hostname");
channel.setErrStream(System.err);
channel.connect();
InputStream in=channel.getInputStream();
int i=0;
byte[] tmp=new byte[1024*1024];
while ((i = in.read(tmp, 0, tmp.length)) != -1) {
System.out.write(tmp, 0, i);
}
in.close();
channel.disconnect();
session.disconnect();
// session.setPortForwardingL(tunnelLocalPort,tunnelRemoteHost,tunnelRemotePort);
System.out.println("Connected");
}
class localUserInfo implements UserInfo {
String passwd;
public String getPassword() {
return passwd;
}
public boolean promptYesNo(String str) {
return true;
}
public String getPassphrase() {
return null;
}
public boolean promptPassphrase(String message) {
return true;
}
public boolean promptPassword(String message) {
return true;
}
public void showMessage(String message) {
}
}
}
答案 0 :(得分:2)
首先打开ChannelShell
而不是shell
,尝试使用exec
。
以下是用于登录和执行远程java类文件的小代码示例。
private Expect4j SSH(String hostname, String username,String password, int port) throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
if (password != null) {
session.setPassword(password);
}
Hashtable<String,String> config = new Hashtable<String,String>();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(60000);
channel = (ChannelShell) session.openChannel("shell");
Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());
channel.connect();
return expect;
}
此方法将打开SSH流到远程服务器,expect4j将使用该服务器发送命令。
private boolean executeCommands() {
boolean isSuccess = true;
Closure closure = new Closure() {
public void run(ExpectState expectState) throws Exception {
buffer.append(expectState.getBuffer());//buffer is string buffer for appending output of executed command
expectState.exp_continue();
}
};
List<Match> lstPattern = new ArrayList<Match>();
String[] regEx = SSHConstants.linuxPromptRegEx;
if (regEx != null && regEx.length > 0) {
synchronized (regEx) {
for (String regexElement : regEx) {//list of regx like, :>, /> etc. it is possible command prompts of your remote machine
try {
RegExpMatch mat = new RegExpMatch(regexElement, closure);
lstPattern.add(mat);
} catch (MalformedPatternException e) {
return false;
} catch(Exception e) {
return false;
}
}
lstPattern.add(new EofMatch( new Closure() { // should cause entire page to be collected
public void run(ExpectState state) {
}
}));
lstPattern.add(new TimeoutMatch(defaultTimeOut, new Closure() {
public void run(ExpectState state) {
}
}));
}
}
try {
Expect4j expect = SSH(objConfig.getHostAddress(), objConfig.getUserName(), objConfig.getPassword(), SSHConstants.SSH_PORT);
expect.setDefaultTimeout(defaultTimeOut);
if(isSuccess) {
for(String strCmd : lstCmds)
isSuccess = isSuccess(lstPattern,strCmd);
}
boolean isFailed = checkResult(expect.expect(lstPattern));
return !isFailed;
} catch (Exception ex) {
return false;
} finally {
closeConnection();
}
}
private boolean isSuccess(List<Match> objPattern,String strCommandPattern) {
try {
boolean isFailed = checkResult(expect.expect(objPattern));
if (!isFailed) {
expect.send(strCommandPattern);
expect.send("\r");
return true;
}
return false;
} catch (MalformedPatternException ex) {
return false;
} catch (Exception ex) {
return false;
}
}
private boolean checkResult(int intRetVal) {
if (intRetVal == SSHConstants.COMMAND_EXECUTION_SUCCESS_OPCODE) {
return true;
}
return false;
}
public static final int COMMAND_EXECUTION_SUCCESS_OPCODE = -2;
public static final String BACKSLASH_R = "\r";
public static final String BACKSLASH_N = "\n";
public static final String COLON_CHAR = ":";
public static String ENTER_CHARACTER = BACKSLASH_R;
public static final int SSH_PORT = 22;
public static String[] linuxPromptRegEx = new String[]{"~]#","~#","#",":~#","/$",}