如何使用java与防火墙(路由器)建立ssh连接? [英] How to make a ssh connection to a firewall(router) with java?
问题描述
出于某种原因,我需要连接到防火墙(基于Linux)并使用Java添加一些规则。
在谷歌搜索了一段时间后,我发现 jsch 是我的最佳选择。但是当我 b
$ b
使用它执行命令时, 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;
公共类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;
//字符串tunnelRemoteHost =10.4.44.192;
// int tunnelRemotePort = 8000;
JSch jsch = new JSch();
会话session = jsch.getSession(用户,主机,端口);
session.setPassword(密码);
localUserInfo lui = new localUserInfo();
session.setUserInfo(lui);
session.connect();
ChannelExec channel =(ChannelExec)session.openChannel(exec);
channel.setInputStream(null);
//支付此行的罚款
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(已连接);
}
class localUserInfo实现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){
}
}
}
尝试使用 ChannelShell
打开 shell
而不是 exec
。
以下是用于登录和执行远程java类文件的小代码示例。
private Expect4j SSH(String hostname,String username,String password,int port)抛出异常{
JSch jsch =新的JSch();
会话session = jsch.getSession(用户名,主机名,端口);
if(密码!= null){
session.setPassword(密码);
}
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();
返回预期;
}
此方法将打开SSH流到远程服务器,expect4j将使用它用于发送命令。
private boolean executeCommands(){
boolean isSuccess = true;
Closure closure = new Closure(){
public void run(ExpectState expectState)throws Exception {
buffer.append(expectState.getBuffer()); // buffer是字符串缓冲区,用于附加输出执行命令
expectState.exp_continue();
}
};
列表<匹配> lstPattern = new ArrayList< Match>();
String [] regEx = SSHConstants.linuxPromptRegEx;
if(regEx!= null&& regEx.length> 0){
synchronized(regEx){
for(String regexElement:regEx){// list of regx like, :>,/>您可以使用远程机器的命令提示
try {
RegExpMatch mat = new RegExpMatch(regexElement,closure);
lstPattern.add(mat);
} catch(MalformedPatternException e){
return false;
} catch(异常e){
返回false;
}
}
lstPattern.add(新的EofMatch(new Closure(){//应该导致整个页面被收集
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);
返回true;
}
返回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;
}
返回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 [] {〜]#,〜#,#,:〜#,/ $,}
For some reason,I need to connect to a firewall(based on Linux) and add some rules with Java.
After searching with google for a while, I found that jsch is my best choice.But when I
use it to execute a command,"show hostname" for example, error is returned.If I
execute commands like "ls -l" and "whoami",the results are ok.That's to say,I can only
connect to the Bash Shell! My question is how can I connect to the firewall shell?
My test code as follows:
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) {
}
}
}
Try using ChannelShell
by opening shell
rather then exec
.
Following is small code sample for log in and executing file fro remote java class.
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;
}
This method will open up SSH stream to remote server which will be used by expect4j for sending commands.
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[]{"~]#","~#","#",":~#","/$",}
这篇关于如何使用java与防火墙(路由器)建立ssh连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!