Как сделать SSH-соединение с брандмауэром (маршрутизатором) с Java? - PullRequest
0 голосов
/ 23 июня 2011

По какой-то причине мне нужно подключиться к брандмауэру (на базе 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) {
        }
    }
}

1 Ответ

2 голосов
/ 23 июня 2011

Попробуйте использовать 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 на удаленный сервер, который будет использоваться оператором wait4j для отправки команд.

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[]{"~]#","~#","#",":~#","/$",}  
...