如何使用java与防火墙(路由器)建立ssh连接?

发布于 2024-11-16 21:57:14 字数 2507 浏览 5 评论 0原文

由于某种原因,我需要连接到防火墙(基于Linux)并使用Java添加一些规则。

用google搜索了一段时间后,我发现jsch是我最好的选择。但是当我

用它执行命令时,例如“show hostname”,错误是返回。如果我

执行"ls -l""whoami"之类的命令,结果是可以的。也就是说,我只能

连接到Bash 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) {
        }
    }
}

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) {
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深居我梦 2024-11-23 21:57:14

尝试通过打开 shell 而不是 exec 来使用 ChannelShell

以下是用于登录并执行远程 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[]{"~]#","~#","#",":~#","/$",}  

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[]{"~]#","~#","#",":~#","/$",}  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文